From decc786758d8d643f538d2f8dbcc655f6190c217 Mon Sep 17 00:00:00 2001 From: Tirumala Dilip Kumar Date: Fri, 6 Nov 2015 10:01:13 +0530 Subject: [PATCH 01/53] Added wrapX attribute to source object for each type --- src/services/olHelpers.js | 60 ++++++++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 20 deletions(-) diff --git a/src/services/olHelpers.js b/src/services/olHelpers.js index a526525f..5a27733a 100644 --- a/src/services/olHelpers.js +++ b/src/services/olHelpers.js @@ -207,7 +207,8 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ oSource = new ol.source.XYZ({ url: url, attributions: createAttribution(source), - tilePixelRatio: pixelRatio > 1 ? 2 : 1 + tilePixelRatio: pixelRatio > 1 ? 2 : 1, + wrapX: source.wrapX ? source.wrapX : true }); break; case 'ImageWMS': @@ -219,7 +220,8 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ url: source.url, attributions: createAttribution(source), crossOrigin: (typeof source.crossOrigin === 'undefined') ? 'anonymous' : source.crossOrigin, - params: source.params + params: source.params, + wrapX: source.wrapX ? source.wrapX : true }); break; @@ -232,7 +234,8 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ var wmsConfiguration = { crossOrigin: (typeof source.crossOrigin === 'undefined') ? 'anonymous' : source.crossOrigin, params: source.params, - attributions: createAttribution(source) + attributions: createAttribution(source), + wrapX: source.wrapX ? source.wrapX : true }; if (source.url) { @@ -264,7 +267,8 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ origin: source.tileGrid.origin, resolutions: source.tileGrid.resolutions, matrixIds: source.tileGrid.matrixIds - }) + }), + wrapX: source.wrapX ? source.wrapX : true }; if (isDefined(source.url)) { @@ -280,7 +284,8 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ case 'OSM': oSource = new ol.source.OSM({ - attributions: createAttribution(source) + attributions: createAttribution(source), + wrapX: source.wrapX ? source.wrapX : true }); if (source.url) { @@ -298,7 +303,8 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ key: source.key, attributions: createAttribution(source), imagerySet: source.imagerySet ? source.imagerySet : bingImagerySets[0], - culture: source.culture + culture: source.culture, + wrapX: source.wrapX ? source.wrapX : true }; if (source.maxZoom) { @@ -316,7 +322,8 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ oSource = new ol.source.MapQuest({ attributions: createAttribution(source), - layer: source.layer + layer: source.layer, + wrapX: source.wrapX ? source.wrapX : true }); break; @@ -332,7 +339,8 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ oSource = new ol.source.XYZ({ attributions: createAttribution(source), - url: _url + url: _url, + wrapX: source.wrapX ? source.wrapX : true }); break; @@ -347,7 +355,8 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ if (isDefined(source.url)) { oSource = new ol.source.Vector({ format: new ol.format.GeoJSON(), - url: source.url + url: source.url, + wrapX: source.wrapX ? source.wrapX : true }); } else { oSource = new ol.source.Vector(); @@ -382,7 +391,8 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ }).error(function(response) { $log(response); }); - } + }, + wrapX: source.wrapX ? source.wrapX : true }); } break; @@ -396,11 +406,13 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ if (source.url) { oSource = new ol.source.Vector({ format: new ol.format.TopoJSON(), - url: source.url + url: source.url, + wrapX: source.wrapX ? source.wrapX : true }); } else { oSource = new ol.source.Vector(angular.extend(source.topojson, { - format: new ol.format.TopoJSON() + format: new ol.format.TopoJSON(), + wrapX: source.wrapX ? source.wrapX : true })); } break; @@ -408,7 +420,8 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ oSource = new ol.source.TileJSON({ url: source.url, attributions: createAttribution(source), - crossOrigin: 'anonymous' + crossOrigin: 'anonymous', + wrapX: source.wrapX ? source.wrapX : true }); break; @@ -423,7 +436,8 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ format: source.format, tileGrid: new ol.tilegrid.createXYZ({ maxZoom: source.maxZoom || 19 - }) + }), + wrapX: source.wrapX ? source.wrapX : true }); break; @@ -452,7 +466,8 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ var url = source.url + z + '/' + x + '/' + y + '.png'; return url; - } + }, + wrapX: source.wrapX ? source.wrapX : true }); break; case 'TileImage': @@ -472,7 +487,8 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ .replace('{x}', x.toString()) .replace('{y}', y.toString()); return url; - } + }, + wrapX: source.wrapX ? source.wrapX : true }); break; case 'KML': @@ -481,7 +497,8 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ url: source.url, format: new ol.format.KML(), radius: source.radius, - extractStyles: extractStyles + extractStyles: extractStyles, + wrapX: source.wrapX ? source.wrapX : true }); break; case 'Stamen': @@ -490,7 +507,8 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ return; } oSource = new ol.source.Stamen({ - layer: source.layer + layer: source.layer, + wrapX: source.wrapX ? source.wrapX : true }); break; case 'ImageStatic': @@ -505,7 +523,8 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ imageSize: source.imageSize, projection: projection, imageExtent: projection.getExtent(), - imageLoadFunction: source.imageLoadFunction + imageLoadFunction: source.imageLoadFunction, + wrapX: source.wrapX ? source.wrapX : true }); break; case 'XYZ': @@ -516,7 +535,8 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ url: source.url, attributions: createAttribution(source), minZoom: source.minZoom, - maxZoom: source.maxZoom + maxZoom: source.maxZoom, + wrapX: source.wrapX ? source.wrapX : true }); break; } From 6315c599190de5c6cfcdd6d0fde0bb4f6c391544 Mon Sep 17 00:00:00 2001 From: Tirumala Dilip Kumar Date: Fri, 6 Nov 2015 15:08:32 +0530 Subject: [PATCH 02/53] Changes did for olHelpers to get in use of wrapX attribute for single map default it is for multiple maps. --- .gitignore | 1 - CONTRIBUTING.md | 2 +- dist/angular-openlayers-directive.css | 58 + dist/angular-openlayers-directive.js | 2228 +++++++++++++++++ dist/angular-openlayers-directive.min.js | 31 + ...ular-openlayers-directive.min.no-header.js | 2 + dist/angular-openlayers-directive.pre.js | 2228 +++++++++++++++++ src/services/olHelpers.js | 40 +- 8 files changed, 4568 insertions(+), 22 deletions(-) create mode 100644 dist/angular-openlayers-directive.css create mode 100644 dist/angular-openlayers-directive.js create mode 100644 dist/angular-openlayers-directive.min.js create mode 100644 dist/angular-openlayers-directive.min.no-header.js create mode 100644 dist/angular-openlayers-directive.pre.js diff --git a/.gitignore b/.gitignore index 57eb4608..352ad9bc 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,6 @@ lib temp node_modules/ bower_components/ -dist/ libpeerconnection.log *.swp .*.swp diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 50e30384..af335b9e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -139,7 +139,7 @@ Running "jshint:grunt" (jshint) task Running "concat:dist" (concat) task File "dist/angular-openlayers-directive.js" created. -Running "ngmin:directives" (ngmin) task +Running "ngAnnotate" (ngAnnotate) task ngminifying dist/angular-openlayers-directive.js Running "uglify:dist" (uglify) task diff --git a/dist/angular-openlayers-directive.css b/dist/angular-openlayers-directive.css new file mode 100644 index 00000000..fd9933e0 --- /dev/null +++ b/dist/angular-openlayers-directive.css @@ -0,0 +1,58 @@ +.popup-label { + background-color: #fff; + border: 2px #444 solid; + border-radius: 7px; + -webkit-box-shadow: 4px 4px 5px 0px rgba(50, 50, 50, 0.75); + -moz-box-shadow: 4px 4px 5px 0px rgba(50, 50, 50, 0.75); + box-shadow: 4px 4px 5px 0px rgba(50, 50, 50, 0.75); + color: #111; + font: 12px/20px "Helvetica Neue", Arial, Helvetica, sans-serif; + font-weight: bold; + padding: 3px 6px; + position: absolute; + white-space: nowrap; + top: -35px; + left: 20px; + display: none; +} + +.popup-label img { + vertical-align: middle; +} + +.popup-label.marker:before { + border-top: 6px solid transparent; + border-bottom: 6px solid transparent; + content: ""; + border-right: 6px solid black; + border-right-color: inherit; + position: absolute; + left: -8px; + top: 5px; +} + +.angular-openlayers-map:-moz-full-screen { + height: 100%; +} +.angular-openlayers-map:-webkit-full-screen { + height: 100%; +} +.angular-openlayers-map:full-screen { + height: 100%; +} + +.angular-openlayers-map:not(-moz-full-screen) { + height: 400px; +} + +.angular-openlayers-map:not(-webkit-full-screen) { + height: 400px; +} + +.angular-openlayers-map:not(full-screen) { + height: 400px; +} +.ol-full-screen { + position: absolute; + top: 50%; +} diff --git a/dist/angular-openlayers-directive.js b/dist/angular-openlayers-directive.js new file mode 100644 index 00000000..2c1e55c8 --- /dev/null +++ b/dist/angular-openlayers-directive.js @@ -0,0 +1,2228 @@ +(function (root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. + define(['ol'], function (ol) { + return root.angularOpenlayersDirective = factory(ol); + }); + } else { + // Browser globals + root.angularOpenlayersDirective = factory(root.ol); + } +}(this, function (ol) { +angular.module('openlayers-directive', ['ngSanitize']).directive('openlayers', ["$log", "$q", "$compile", "olHelpers", "olMapDefaults", "olData", function($log, $q, $compile, olHelpers, + olMapDefaults, olData) { + return { + restrict: 'EA', + transclude: true, + replace: true, + scope: { + center: '=olCenter', + defaults: '=olDefaults', + view: '=olView', + events: '=olEvents' + }, + template: '
', + controller: ["$scope", function($scope) { + var _map = $q.defer(); + $scope.getMap = function() { + return _map.promise; + }; + + $scope.setMap = function(map) { + _map.resolve(map); + }; + + this.getOpenlayersScope = function() { + return $scope; + }; + }], + link: function(scope, element, attrs) { + var isDefined = olHelpers.isDefined; + var createLayer = olHelpers.createLayer; + var setMapEvents = olHelpers.setMapEvents; + var setViewEvents = olHelpers.setViewEvents; + var createView = olHelpers.createView; + var defaults = olMapDefaults.setDefaults(scope); + + // Set width and height if they are defined + if (isDefined(attrs.width)) { + if (isNaN(attrs.width)) { + element.css('width', attrs.width); + } else { + element.css('width', attrs.width + 'px'); + } + } + + if (isDefined(attrs.height)) { + if (isNaN(attrs.height)) { + element.css('height', attrs.height); + } else { + element.css('height', attrs.height + 'px'); + } + } + + if (isDefined(attrs.lat)) { + defaults.center.lat = parseFloat(attrs.lat); + } + + if (isDefined(attrs.lon)) { + defaults.center.lon = parseFloat(attrs.lon); + } + + if (isDefined(attrs.zoom)) { + defaults.center.zoom = parseFloat(attrs.zoom); + } + + var controls = ol.control.defaults(defaults.controls); + var interactions = ol.interaction.defaults(defaults.interactions); + var view = createView(defaults.view); + + // Create the Openlayers Map Object with the options + var map = new ol.Map({ + target: element[0], + controls: controls, + interactions: interactions, + renderer: defaults.renderer, + view: view + }); + + // If no layer is defined, set the default tileLayer + if (!attrs.customLayers) { + var l = { + type: 'Tile', + source: { + type: 'OSM' + } + }; + var layer = createLayer(l, view.getProjection(), 'default'); + map.addLayer(layer); + map.set('default', true); + } + + if (!isDefined(attrs.olCenter)) { + var c = ol.proj.transform([defaults.center.lon, + defaults.center.lat + ], + defaults.center.projection, view.getProjection() + ); + view.setCenter(c); + view.setZoom(defaults.center.zoom); + } + + // Set the Default events for the map + setMapEvents(defaults.events, map, scope); + + //Set the Default events for the map view + setViewEvents(defaults.events, map, scope); + + // Resolve the map object to the promises + scope.setMap(map); + olData.setMap(map, attrs.id); + + } + }; + }]); + +angular.module('openlayers-directive').directive('olCenter', ["$log", "$location", "olMapDefaults", "olHelpers", function($log, $location, olMapDefaults, olHelpers) { + + return { + restrict: 'A', + scope: false, + replace: false, + require: 'openlayers', + + link: function(scope, element, attrs, controller) { + var safeApply = olHelpers.safeApply; + var isValidCenter = olHelpers.isValidCenter; + var isDefined = olHelpers.isDefined; + var isArray = olHelpers.isArray; + var isNumber = olHelpers.isNumber; + var isSameCenterOnMap = olHelpers.isSameCenterOnMap; + var setCenter = olHelpers.setCenter; + var setZoom = olHelpers.setZoom; + var olScope = controller.getOpenlayersScope(); + + olScope.getMap().then(function(map) { + var defaults = olMapDefaults.getDefaults(olScope); + var view = map.getView(); + var center = olScope.center; + + if (attrs.olCenter.search('-') !== -1) { + $log.error('[AngularJS - Openlayers] The "center" variable can\'t use ' + + 'a "-" on his key name: "' + attrs.center + '".'); + setCenter(view, defaults.view.projection, defaults.center, map); + return; + } + + if (!isDefined(center)) { + center = {}; + } + + if (!isValidCenter(center)) { + $log.warn('[AngularJS - Openlayers] invalid \'center\''); + center.lat = defaults.center.lat; + center.lon = defaults.center.lon; + center.zoom = defaults.center.zoom; + center.projection = defaults.center.projection; + } + + if (!center.projection) { + if (defaults.view.projection !== 'pixel') { + center.projection = defaults.center.projection; + } else { + center.projection = 'pixel'; + } + } + + if (!isNumber(center.zoom)) { + center.zoom = 1; + } + + setCenter(view, defaults.view.projection, center, map); + view.setZoom(center.zoom); + + var centerUrlHash; + if (center.centerUrlHash === true) { + var extractCenterFromUrl = function() { + var search = $location.search(); + var centerParam; + if (isDefined(search.c)) { + var cParam = search.c.split(':'); + if (cParam.length === 3) { + centerParam = { + lat: parseFloat(cParam[0]), + lon: parseFloat(cParam[1]), + zoom: parseInt(cParam[2], 10) + }; + } + } + return centerParam; + }; + centerUrlHash = extractCenterFromUrl(); + + olScope.$on('$locationChangeSuccess', function() { + var urlCenter = extractCenterFromUrl(); + if (urlCenter && !isSameCenterOnMap(urlCenter, map)) { + safeApply(olScope, function(scope) { + scope.center.lat = urlCenter.lat; + scope.center.lon = urlCenter.lon; + scope.center.zoom = urlCenter.zoom; + }); + } + }); + } + + var geolocation; + olScope.$watchCollection('center', function(center) { + + if (!center) { + return; + } + + if (!center.projection) { + center.projection = defaults.center.projection; + } + + if (center.autodiscover) { + if (!geolocation) { + geolocation = new ol.Geolocation({ + projection: ol.proj.get(center.projection) + }); + + geolocation.on('change', function() { + if (center.autodiscover) { + var location = geolocation.getPosition(); + safeApply(olScope, function(scope) { + scope.center.lat = location[1]; + scope.center.lon = location[0]; + scope.center.zoom = 12; + scope.center.autodiscover = false; + geolocation.setTracking(false); + }); + } + }); + } + geolocation.setTracking(true); + return; + } + + if (!isValidCenter(center)) { + $log.warn('[AngularJS - Openlayers] invalid \'center\''); + center = defaults.center; + } + + var viewCenter = view.getCenter(); + if (viewCenter) { + if (defaults.view.projection === 'pixel') { + view.setCenter(center.coord); + return; + } + var actualCenter = ol.proj.transform(viewCenter, defaults.view.projection, center.projection); + if (!(actualCenter[1] === center.lat && actualCenter[0] === center.lon)) { + setCenter(view, defaults.view.projection, center, map); + } + } + + if (view.getZoom() !== center.zoom) { + setZoom(view, center.zoom, map); + } + }); + + map.on('moveend', function() { + safeApply(olScope, function(scope) { + + if (!isDefined(scope.center)) { + return; + } + + var center = map.getView().getCenter(); + scope.center.zoom = view.getZoom(); + + if (defaults.view.projection === 'pixel') { + scope.center.coord = center; + return; + } + + if (scope.center) { + var proj = ol.proj.transform(center, defaults.view.projection, scope.center.projection); + scope.center.lat = proj[1]; + scope.center.lon = proj[0]; + + // Notify the controller about a change in the center position + olHelpers.notifyCenterUrlHashChanged(olScope, scope.center, $location.search()); + + // Calculate the bounds if needed + if (isArray(scope.center.bounds)) { + var extent = view.calculateExtent(map.getSize()); + var centerProjection = scope.center.projection; + var viewProjection = defaults.view.projection; + scope.center.bounds = ol.proj.transformExtent(extent, viewProjection, centerProjection); + } + } + }); + }); + + }); + } + }; +}]); + +angular.module('openlayers-directive').directive('olLayer', ["$log", "$q", "olMapDefaults", "olHelpers", function($log, $q, olMapDefaults, olHelpers) { + + return { + restrict: 'E', + scope: { + properties: '=olLayerProperties' + }, + replace: false, + require: '^openlayers', + link: function(scope, element, attrs, controller) { + var isDefined = olHelpers.isDefined; + var equals = olHelpers.equals; + var olScope = controller.getOpenlayersScope(); + var createLayer = olHelpers.createLayer; + var setVectorLayerEvents = olHelpers.setVectorLayerEvents; + var detectLayerType = olHelpers.detectLayerType; + var createStyle = olHelpers.createStyle; + var isBoolean = olHelpers.isBoolean; + var addLayerBeforeMarkers = olHelpers.addLayerBeforeMarkers; + var isNumber = olHelpers.isNumber; + var insertLayer = olHelpers.insertLayer; + var removeLayer = olHelpers.removeLayer; + var addLayerToGroup = olHelpers.addLayerToGroup; + var removeLayerFromGroup = olHelpers.removeLayerFromGroup; + var getGroup = olHelpers.getGroup; + + olScope.getMap().then(function(map) { + var projection = map.getView().getProjection(); + var defaults = olMapDefaults.setDefaults(olScope); + var layerCollection = map.getLayers(); + var olLayer; + + scope.$on('$destroy', function() { + if (scope.properties.group) { + removeLayerFromGroup(layerCollection, olLayer, scope.properties.group); + } else { + removeLayer(layerCollection, olLayer.index); + } + + map.removeLayer(olLayer); + }); + + if (!isDefined(scope.properties)) { + if (isDefined(attrs.sourceType) && isDefined(attrs.sourceUrl)) { + var l = { + source: { + url: attrs.sourceUrl, + type: attrs.sourceType + } + }; + + olLayer = createLayer(l, projection, attrs.layerName); + if (detectLayerType(l) === 'Vector') { + setVectorLayerEvents(defaults.events, map, scope, attrs.name); + } + addLayerBeforeMarkers(layerCollection, olLayer); + } + return; + } + + scope.$watch('properties', function(properties, oldProperties) { + if (!isDefined(properties.source) || !isDefined(properties.source.type)) { + return; + } + + if (!isDefined(properties.visible)) { + properties.visible = true; + return; + } + + if (!isDefined(properties.opacity)) { + properties.opacity = 1; + return; + } + + var style; + var group; + var collection; + if (!isDefined(olLayer)) { + olLayer = createLayer(properties, projection); + if (isDefined(properties.group)) { + addLayerToGroup(layerCollection, olLayer, properties.group); + } else if (isDefined(properties.index)) { + insertLayer(layerCollection, properties.index, olLayer); + } else { + addLayerBeforeMarkers(layerCollection, olLayer); + } + + if (detectLayerType(properties) === 'Vector') { + setVectorLayerEvents(defaults.events, map, scope, properties.name); + } + + if (isBoolean(properties.visible)) { + olLayer.setVisible(properties.visible); + } + + if (properties.opacity) { + olLayer.setOpacity(properties.opacity); + } + + if (angular.isArray(properties.extent)) { + olLayer.setExtent(properties.extent); + } + + if (properties.style) { + if (!angular.isFunction(properties.style)) { + style = createStyle(properties.style); + } else { + style = properties.style; + } + // not every layer has a setStyle method + if (olLayer.setStyle && angular.isFunction(olLayer.setStyle)) { + olLayer.setStyle(style); + } + } + + } else { + var isNewLayer = (function(olLayer) { + // this function can be used to verify whether a new layer instance has + // been created. This is needed in order to re-assign styles, opacity + // etc... + return function(layer) { + return layer !== olLayer; + }; + })(olLayer); + + // set source properties + if (isDefined(oldProperties) && !equals(properties.source, oldProperties.source)) { + var idx = olLayer.index; + collection = layerCollection; + group = olLayer.get('group'); + + if (group) { + collection = getGroup(layerCollection, group).getLayers(); + } + + collection.removeAt(idx); + + olLayer = createLayer(properties, projection); + olLayer.set('group', group); + + if (isDefined(olLayer)) { + insertLayer(collection, idx, olLayer); + + if (detectLayerType(properties) === 'Vector') { + setVectorLayerEvents(defaults.events, map, scope, properties.name); + } + } + } + + // set opacity + if (isDefined(oldProperties) && + properties.opacity !== oldProperties.opacity || isNewLayer(olLayer)) { + if (isNumber(properties.opacity) || isNumber(parseFloat(properties.opacity))) { + olLayer.setOpacity(properties.opacity); + } + } + + // set index + if (isDefined(properties.index) && properties.index !== olLayer.index) { + collection = layerCollection; + group = olLayer.get('group'); + + if (group) { + collection = getGroup(layerCollection, group).getLayers(); + } + + removeLayer(collection, olLayer.index); + insertLayer(collection, properties.index, olLayer); + } + + // set group + if (isDefined(properties.group) && properties.group !== oldProperties.group) { + removeLayerFromGroup(layerCollection, olLayer, oldProperties.group); + addLayerToGroup(layerCollection, olLayer, properties.group); + } + + // set visibility + if (isDefined(oldProperties) && + isBoolean(properties.visible) && + properties.visible !== oldProperties.visible || isNewLayer(olLayer)) { + olLayer.setVisible(properties.visible); + } + + // set style + if (isDefined(properties.style) && + !equals(properties.style, oldProperties.style) || isNewLayer(olLayer)) { + if (!angular.isFunction(properties.style)) { + style = createStyle(properties.style); + } else { + style = properties.style; + } + // not every layer has a setStyle method + if (olLayer.setStyle && angular.isFunction(olLayer.setStyle)) { + olLayer.setStyle(style); + } + } + } + }, true); + }); + } + }; +}]); + +angular.module('openlayers-directive').directive('olPath', ["$log", "$q", "olMapDefaults", "olHelpers", function($log, $q, olMapDefaults, olHelpers) { + + return { + restrict: 'E', + scope: { + properties: '=olGeomProperties' + }, + require: '^openlayers', + replace: true, + template: '', + + link: function(scope, element, attrs, controller) { + var isDefined = olHelpers.isDefined; + var createFeature = olHelpers.createFeature; + var createOverlay = olHelpers.createOverlay; + var createVectorLayer = olHelpers.createVectorLayer; + var insertLayer = olHelpers.insertLayer; + var removeLayer = olHelpers.removeLayer; + var olScope = controller.getOpenlayersScope(); + + olScope.getMap().then(function(map) { + var mapDefaults = olMapDefaults.getDefaults(olScope); + var viewProjection = mapDefaults.view.projection; + + var layer = createVectorLayer(); + var layerCollection = map.getLayers(); + + insertLayer(layerCollection, layerCollection.getLength(), layer); + + scope.$on('$destroy', function() { + removeLayer(layerCollection, layer.index); + }); + + if (isDefined(attrs.coords)) { + var proj = attrs.proj || 'EPSG:4326'; + var coords = JSON.parse(attrs.coords); + var data = { + type: 'Polygon', + coords: coords, + projection: proj, + style: mapDefaults.styles.path + }; + var feature = createFeature(data, viewProjection); + layer.getSource().addFeature(feature); + + if (attrs.message) { + scope.message = attrs.message; + var extent = feature.getGeometry().getExtent(); + var label = createOverlay(element, extent); + map.addOverlay(label); + } + return; + } + }); + } + }; +}]); + +angular.module('openlayers-directive').directive('olView', ["$log", "$q", "olData", "olMapDefaults", "olHelpers", function($log, $q, olData, olMapDefaults, olHelpers) { + return { + restrict: 'A', + scope: false, + replace: false, + require: 'openlayers', + link: function(scope, element, attrs, controller) { + var olScope = controller.getOpenlayersScope(); + var isNumber = olHelpers.isNumber; + var safeApply = olHelpers.safeApply; + var createView = olHelpers.createView; + + olScope.getMap().then(function(map) { + var defaults = olMapDefaults.getDefaults(olScope); + var view = olScope.view; + + if (!view.projection) { + view.projection = defaults.view.projection; + } + + if (!view.maxZoom) { + view.maxZoom = defaults.view.maxZoom; + } + + if (!view.minZoom) { + view.minZoom = defaults.view.minZoom; + } + + if (!view.rotation) { + view.rotation = defaults.view.rotation; + } + + var mapView = createView(view); + map.setView(mapView); + + olScope.$watchCollection('view', function(view) { + if (isNumber(view.rotation)) { + mapView.setRotation(view.rotation); + } + }); + + mapView.on('change:rotation', function() { + safeApply(olScope, function(scope) { + scope.view.rotation = map.getView().getRotation(); + }); + }); + + }); + } + }; +}]); + +angular.module('openlayers-directive').directive('olControl', ["$log", "$q", "olData", "olMapDefaults", "olHelpers", function($log, $q, olData, olMapDefaults, olHelpers) { + + return { + restrict: 'E', + scope: { + properties: '=olControlProperties' + }, + replace: false, + require: '^openlayers', + link: function(scope, element, attrs, controller) { + var isDefined = olHelpers.isDefined; + var olScope = controller.getOpenlayersScope(); + var olControl; + var olControlOps; + + olScope.getMap().then(function(map) { + var getControlClasses = olHelpers.getControlClasses; + var controlClasses = getControlClasses(); + + scope.$on('$destroy', function() { + map.removeControl(olControl); + }); + + if (!isDefined(scope.properties) || !isDefined(scope.properties.control)) { + if (attrs.name) { + if (isDefined(scope.properties)) { + olControlOps = scope.properties; + } + olControl = new controlClasses[attrs.name](olControlOps); + map.addControl(olControl); + } + return; + } + + olControl = scope.properties.control; + map.addControl(olControl); + }); + } + }; +}]); + +angular.module('openlayers-directive').directive('olMarker', ["$log", "$q", "olMapDefaults", "olHelpers", function($log, $q, olMapDefaults, olHelpers) { + + var getMarkerDefaults = function() { + return { + projection: 'EPSG:4326', + lat: 0, + lon: 0, + coord: [], + show: true, + showOnMouseOver: false, + showOnMouseClick: false, + keepOneOverlayVisible: false + }; + }; + + var markerLayerManager = (function() { + var mapDict = []; + + function getMapIndex(map) { + return mapDict.map(function(record) { + return record.map; + }).indexOf(map); + } + + return { + getInst: function getMarkerLayerInst(scope, map) { + var mapIndex = getMapIndex(map); + + if (mapIndex === -1) { + var markerLayer = olHelpers.createVectorLayer(); + markerLayer.set('markers', true); + map.addLayer(markerLayer); + mapDict.push({ + map: map, + markerLayer: markerLayer, + instScopes: [] + }); + mapIndex = mapDict.length - 1; + } + + mapDict[mapIndex].instScopes.push(scope); + + return mapDict[mapIndex].markerLayer; + }, + deregisterScope: function deregisterScope(scope, map) { + var mapIndex = getMapIndex(map); + if (mapIndex === -1) { + throw Error('This map has no markers'); + } + + var scopes = mapDict[mapIndex].instScopes; + var scopeIndex = scopes.indexOf(scope); + if (scopeIndex === -1) { + throw Error('Scope wan\'t registered'); + } + + scopes.splice(scopeIndex, 1); + + if (!scopes.length) { + map.removeLayer(mapDict[mapIndex].markerLayer); + delete mapDict[mapIndex]; + } + } + }; + })(); + return { + restrict: 'E', + scope: { + lat: '=lat', + lon: '=lon', + label: '=label', + properties: '=olMarkerProperties', + style: '=olStyle' + }, + transclude: true, + require: '^openlayers', + replace: true, + template: + '', + + link: function(scope, element, attrs, controller) { + var isDefined = olHelpers.isDefined; + var olScope = controller.getOpenlayersScope(); + var createFeature = olHelpers.createFeature; + var createOverlay = olHelpers.createOverlay; + + var hasTranscluded = element.find('ng-transclude').children().length > 0; + + olScope.getMap().then(function(map) { + var markerLayer = markerLayerManager.getInst(scope, map); + var data = getMarkerDefaults(); + + var mapDefaults = olMapDefaults.getDefaults(olScope); + var viewProjection = mapDefaults.view.projection; + var label; + var pos; + var marker; + + // This function handles dragging a marker + var pickOffset = null; + var pickProperties = null; + function handleDrag(evt) { + var coord = evt.coordinate; + var proj = map.getView().getProjection().getCode(); + if (proj === 'pixel') { + coord = coord.map(function(v) { + return parseInt(v, 10); + }); + } else { + coord = ol.proj.transform(coord, proj, 'EPSG:4326'); + } + + if (evt.type === 'pointerdown') { + // Get feature under mouse if any + var feature = map.forEachFeatureAtPixel(evt.pixel, function(feature) { + return feature; + }); + // Get associated marker properties + pickProperties = (feature ? feature.get('marker') : null); + if (!pickProperties || !pickProperties.draggable) { + pickProperties = null; + return; + } + map.getTarget().style.cursor = 'pointer'; + if (proj === 'pixel') { + pickOffset = [coord[0] - pickProperties.coord[0], coord[1] - pickProperties.coord[1]]; + } else { + pickOffset = [coord[0] - pickProperties.lon, coord[1] - pickProperties.lat]; + } + evt.preventDefault(); + } else if (pickOffset && pickProperties) { + if (evt.type === 'pointerup') { + map.getTarget().style.cursor = ''; + pickOffset = null; + pickProperties = null; + evt.preventDefault(); + } else if (evt.type === 'pointerdrag') { + evt.preventDefault(); + scope.$apply(function() { + // Add current delta to marker initial position + if (proj === 'pixel') { + pickProperties.coord[0] = coord[0] - pickOffset[0]; + pickProperties.coord[1] = coord[1] - pickOffset[1]; + } else { + pickProperties.lon = coord[0] - pickOffset[0]; + pickProperties.lat = coord[1] - pickOffset[1]; + } + }); + } + } + } + + // Setup generic handlers for marker drag + map.on('pointerdown', handleDrag); + map.on('pointerup', handleDrag); + map.on('pointerdrag', handleDrag); + + scope.$on('$destroy', function() { + markerLayer.getSource().removeFeature(marker); + if (isDefined(label)) { + map.removeOverlay(label); + } + markerLayerManager.deregisterScope(scope, map); + }); + + if (!isDefined(scope.properties)) { + data.lat = scope.lat ? scope.lat : data.lat; + data.lon = scope.lon ? scope.lon : data.lon; + data.message = attrs.message; + data.style = scope.style ? scope.style : mapDefaults.styles.marker; + + marker = createFeature(data, viewProjection); + if (!isDefined(marker)) { + $log.error('[AngularJS - Openlayers] Received invalid data on ' + + 'the marker.'); + } + // Add a link between the feature and the marker properties + marker.set('marker', scope); + markerLayer.getSource().addFeature(marker); + + if (data.message || hasTranscluded) { + scope.message = attrs.message; + pos = ol.proj.transform([data.lon, data.lat], data.projection, + viewProjection); + label = createOverlay(element, pos); + map.addOverlay(label); + } + return; + } + + scope.$watch('properties', function(properties) { + + // Remove previous listeners if any + map.getViewport().removeEventListener('mousemove', properties.handleInteraction); + map.getViewport().removeEventListener('click', properties.handleTapInteraction); + map.getViewport().querySelector('canvas.ol-unselectable').removeEventListener( + 'touchend', properties.handleTapInteraction); + map.getViewport().removeEventListener('mousemove', properties.showAtLeastOneOverlay); + map.getViewport().removeEventListener('click', properties.removeAllOverlays); + + // This function handles popup on mouse over/click + properties.handleInteraction = function(evt) { + if (properties.label.show) { + return; + } + var found = false; + var pixel = map.getEventPixel(evt); + var feature = map.forEachFeatureAtPixel(pixel, function(feature) { + return feature; + }); + + var actionTaken = false; + if (feature === marker) { + actionTaken = true; + found = true; + if (!isDefined(label)) { + if (data.projection === 'pixel') { + pos = properties.coord; + } else { + pos = ol.proj.transform([properties.lon, properties.lat], + data.projection, viewProjection); + } + label = createOverlay(element, pos); + map.addOverlay(label); + } + + if (properties.onClick && (evt.type === 'click' || evt.type === 'touchend')) { + scope.$apply(function() { + properties.onClick.call(marker, evt, properties); + }); + } + map.getTarget().style.cursor = 'pointer'; + } + + if (!found && label) { + actionTaken = true; + map.removeOverlay(label); + label = undefined; + map.getTarget().style.cursor = ''; + } + + if (actionTaken) { + evt.preventDefault(); + } + }; + + // Made to filter out click/tap events if both are being triggered on this platform + properties.handleTapInteraction = (function() { + var cooldownActive = false; + var prevTimeout; + + // Sets the cooldown flag to filter out any subsequent events within 500 ms + function activateCooldown() { + cooldownActive = true; + if (prevTimeout) { + clearTimeout(prevTimeout); + } + prevTimeout = setTimeout(function() { + cooldownActive = false; + prevTimeout = null; + }, 500); + } + + // Preventing from 'touchend' to be considered a tap, if fired immediately after 'touchmove' + map.getViewport().querySelector('canvas.ol-unselectable').addEventListener( + 'touchmove', activateCooldown); + + return function() { + if (!cooldownActive) { + properties.handleInteraction.apply(null, arguments); + activateCooldown(); + } + }; + })(); + + properties.showAtLeastOneOverlay = function(evt) { + if (properties.label.show) { + return; + } + var found = false; + var pixel = map.getEventPixel(evt); + var feature = map.forEachFeatureAtPixel(pixel, function(feature) { + return feature; + }); + + var actionTaken = false; + if (feature === marker) { + actionTaken = true; + found = true; + if (!isDefined(label)) { + if (data.projection === 'pixel') { + pos = data.coord; + } else { + pos = ol.proj.transform([data.lon, data.lat], + data.projection, viewProjection); + } + label = createOverlay(element, pos); + angular.forEach(map.getOverlays(), function(value) { + map.removeOverlay(value); + }); + map.addOverlay(label); + } + map.getTarget().style.cursor = 'pointer'; + } + + if (!found && label) { + actionTaken = true; + label = undefined; + map.getTarget().style.cursor = ''; + } + + if (actionTaken) { + evt.preventDefault(); + } + }; + + properties.removeAllOverlays = function(evt) { + angular.forEach(map.getOverlays(), function(value) { + map.removeOverlay(value); + }); + evt.preventDefault(); + }; + + if (!isDefined(marker)) { + data.projection = properties.projection ? properties.projection : + data.projection; + data.coord = properties.coord ? properties.coord : data.coord; + data.lat = properties.lat ? properties.lat : data.lat; + data.lon = properties.lon ? properties.lon : data.lon; + + if (isDefined(properties.style)) { + data.style = properties.style; + } else { + data.style = mapDefaults.styles.marker; + } + + marker = createFeature(data, viewProjection); + if (!isDefined(marker)) { + $log.error('[AngularJS - Openlayers] Received invalid data on ' + + 'the marker.'); + } + // Add a link between the feature and the marker properties + marker.set('marker', properties); + markerLayer.getSource().addFeature(marker); + } else { + var requestedPosition; + if (properties.projection === 'pixel') { + requestedPosition = properties.coord; + } else { + requestedPosition = ol.proj.transform([properties.lon, properties.lat], data.projection, + map.getView().getProjection()); + } + + if (!angular.equals(marker.getGeometry().getCoordinates(), requestedPosition)) { + var geometry = new ol.geom.Point(requestedPosition); + marker.setGeometry(geometry); + } + } + + if (isDefined(label)) { + map.removeOverlay(label); + } + + if (!isDefined(properties.label)) { + return; + } + + scope.message = properties.label.message; + if (!hasTranscluded && (!isDefined(scope.message) || scope.message.length === 0)) { + return; + } + + if (properties.label && properties.label.show === true) { + if (data.projection === 'pixel') { + pos = data.coord; + } else { + pos = ol.proj.transform([properties.lon, properties.lat], data.projection, + viewProjection); + } + label = createOverlay(element, pos); + map.addOverlay(label); + } + + if (label && properties.label && properties.label.show === false) { + map.removeOverlay(label); + label = undefined; + } + + // Then setup new ones according to properties + if (properties.label && properties.label.show === false && + properties.label.showOnMouseOver) { + map.getViewport().addEventListener('mousemove', properties.handleInteraction); + } + + if ((properties.label && properties.label.show === false && + properties.label.showOnMouseClick) || + properties.onClick) { + map.getViewport().addEventListener('click', properties.handleTapInteraction); + map.getViewport().querySelector('canvas.ol-unselectable').addEventListener( + 'touchend', properties.handleTapInteraction); + } + + if ((properties.label && properties.label.show === false && + properties.label.keepOneOverlayVisible)) { + map.getViewport().addEventListener('mousemove', properties.showAtLeastOneOverlay); + map.getViewport().addEventListener('click', properties.removeAllOverlays); + } + }, true); + }); + } + }; +}]); + +angular.module('openlayers-directive').service('olData', ["$log", "$q", "olHelpers", function($log, $q, olHelpers) { + + var obtainEffectiveMapId = olHelpers.obtainEffectiveMapId; + + var maps = {}; + + var setResolvedDefer = function(d, mapId) { + var id = obtainEffectiveMapId(d, mapId); + d[id].resolvedDefer = true; + }; + + var getUnresolvedDefer = function(d, mapId) { + var id = obtainEffectiveMapId(d, mapId); + var defer; + + if (!angular.isDefined(d[id]) || d[id].resolvedDefer === true) { + defer = $q.defer(); + d[id] = { + defer: defer, + resolvedDefer: false + }; + } else { + defer = d[id].defer; + } + return defer; + }; + + var getDefer = function(d, mapId) { + var id = obtainEffectiveMapId(d, mapId); + var defer; + + if (!angular.isDefined(d[id]) || d[id].resolvedDefer === false) { + defer = getUnresolvedDefer(d, mapId); + } else { + defer = d[id].defer; + } + return defer; + }; + + this.setMap = function(olMap, scopeId) { + var defer = getUnresolvedDefer(maps, scopeId); + defer.resolve(olMap); + setResolvedDefer(maps, scopeId); + }; + + this.getMap = function(scopeId) { + var defer = getDefer(maps, scopeId); + return defer.promise; + }; + +}]); + +angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$http", function($q, $log, $http) { + + var isDefined = function(value) { + return angular.isDefined(value); + }; + + var isDefinedAndNotNull = function(value) { + return angular.isDefined(value) && value !== null; + }; + + var setEvent = function(map, eventType, scope) { + map.on(eventType, function(event) { + var coord = event.coordinate; + var proj = map.getView().getProjection().getCode(); + if (proj === 'pixel') { + coord = coord.map(function(v) { + return parseInt(v, 10); + }); + } + scope.$emit('openlayers.map.' + eventType, { + 'coord': coord, + 'projection': proj, + 'event': event + }); + }); + }; + + var bingImagerySets = [ + 'Road', + 'Aerial', + 'AerialWithLabels', + 'collinsBart', + 'ordnanceSurvey' + ]; + + var getControlClasses = function() { + return { + attribution: ol.control.Attribution, + fullscreen: ol.control.FullScreen, + mouseposition: ol.control.MousePosition, + rotate: ol.control.Rotate, + scaleline: ol.control.ScaleLine, + zoom: ol.control.Zoom, + zoomslider: ol.control.ZoomSlider, + zoomtoextent: ol.control.ZoomToExtent + }; + }; + + var mapQuestLayers = ['osm', 'sat', 'hyb']; + + var esriBaseLayers = ['World_Imagery', 'World_Street_Map', 'World_Topo_Map', + 'World_Physical_Map', 'World_Terrain_Base', + 'Ocean_Basemap', 'NatGeo_World_Map']; + + var styleMap = { + 'style': ol.style.Style, + 'fill': ol.style.Fill, + 'stroke': ol.style.Stroke, + 'circle': ol.style.Circle, + 'icon': ol.style.Icon, + 'image': ol.style.Image, + 'regularshape': ol.style.RegularShape, + 'text': ol.style.Text + }; + + var optionalFactory = function(style, Constructor) { + if (Constructor && style instanceof Constructor) { + return style; + } else if (Constructor) { + return new Constructor(style); + } else { + return style; + } + }; + + //Parse the style tree calling the appropriate constructors. + //The keys in styleMap can be used and the OpenLayers constructors can be + //used directly. + var createStyle = function recursiveStyle(data, styleName) { + var style; + if (!styleName) { + styleName = 'style'; + style = data; + } else { + style = data[styleName]; + } + //Instead of defining one style for the layer, we've been given a style function + //to apply to each feature. + if (styleName === 'style' && data instanceof Function) { + return data; + } + + if (!(style instanceof Object)) { + return style; + } + + var styleObject; + if (Object.prototype.toString.call(style) === '[object Object]') { + styleObject = {}; + var styleConstructor = styleMap[styleName]; + if (styleConstructor && style instanceof styleConstructor) { + return style; + } + Object.getOwnPropertyNames(style).forEach(function(val, idx, array) { + //Consider the case + //image: { + // circle: { + // fill: { + // color: 'red' + // } + // } + // + //An ol.style.Circle is an instance of ol.style.Image, so we do not want to construct + //an Image and then construct a Circle. We assume that if we have an instanceof + //relationship, that the JSON parent has exactly one child. + //We check to see if an inheritance relationship exists. + //If it does, then for the parent we create an instance of the child. + var valConstructor = styleMap[val]; + if (styleConstructor && valConstructor && + valConstructor.prototype instanceof styleMap[styleName]) { + console.assert(array.length === 1, 'Extra parameters for ' + styleName); + styleObject = recursiveStyle(style, val); + return optionalFactory(styleObject, valConstructor); + } else { + styleObject[val] = recursiveStyle(style, val); + + // if the value is 'text' and it contains a String, then it should be interpreted + // as such, 'cause the text style might effectively contain a text to display + if (val !== 'text' && typeof styleObject[val] !== 'string') { + styleObject[val] = optionalFactory(styleObject[val], styleMap[val]); + } + } + }); + } else { + styleObject = style; + } + return optionalFactory(styleObject, styleMap[styleName]); + }; + + var detectLayerType = function(layer) { + if (layer.type) { + return layer.type; + } else { + switch (layer.source.type) { + case 'ImageWMS': + return 'Image'; + case 'ImageStatic': + return 'Image'; + case 'GeoJSON': + case 'JSONP': + case 'TopoJSON': + case 'KML': + case 'TileVector': + return 'Vector'; + default: + return 'Tile'; + } + } + }; + + var createProjection = function(view) { + var oProjection; + + switch (view.projection) { + case 'pixel': + if (!isDefined(view.extent)) { + $log.error('[AngularJS - Openlayers] - You must provide the extent of the image ' + + 'if using pixel projection'); + return; + } + oProjection = new ol.proj.Projection({ + code: 'pixel', + units: 'pixels', + extent: view.extent + }); + break; + default: + oProjection = new ol.proj.get(view.projection); + break; + } + + return oProjection; + }; + + var isValidStamenLayer = function(layer) { + return ['watercolor', 'terrain', 'toner'].indexOf(layer) !== -1; + }; + + var createSource = function(source, projection) { + var oSource; + + switch (source.type) { + case 'MapBox': + if (!source.mapId || !source.accessToken) { + $log.error('[AngularJS - Openlayers] - MapBox layer requires the map id and the access token'); + return; + } + var url = 'http://api.tiles.mapbox.com/v4/' + source.mapId + '/{z}/{x}/{y}.png?access_token=' + + source.accessToken; + + var pixelRatio = window.devicePixelRatio; + + if (pixelRatio > 1) { + url = url.replace('.png', '@2x.png'); + } + + oSource = new ol.source.XYZ({ + url: url, + attributions: createAttribution(source), + tilePixelRatio: pixelRatio > 1 ? 2 : 1, + wrapX: (source.wrapX === true) ? 1 : 0 + }); + break; + case 'ImageWMS': + if (!source.url || !source.params) { + $log.error('[AngularJS - Openlayers] - ImageWMS Layer needs ' + + 'valid server url and params properties'); + } + oSource = new ol.source.ImageWMS({ + url: source.url, + attributions: createAttribution(source), + crossOrigin: (typeof source.crossOrigin === 'undefined') ? 'anonymous' : source.crossOrigin, + params: source.params, + wrapX: source.wrapX ? 0 : 1 + }); + break; + + case 'TileWMS': + if ((!source.url && !source.urls) || !source.params) { + $log.error('[AngularJS - Openlayers] - TileWMS Layer needs ' + + 'valid url (or urls) and params properties'); + } + + var wmsConfiguration = { + crossOrigin: (typeof source.crossOrigin === 'undefined') ? 'anonymous' : source.crossOrigin, + params: source.params, + attributions: createAttribution(source), + wrapX: source.wrapX ? 0 : 1 + }; + + if (source.url) { + wmsConfiguration.url = source.url; + } + + if (source.urls) { + wmsConfiguration.urls = source.urls; + } + + oSource = new ol.source.TileWMS(wmsConfiguration); + break; + + case 'WMTS': + if ((!source.url && !source.urls) || !source.tileGrid) { + $log.error('[AngularJS - Openlayers] - WMTS Layer needs valid url ' + + '(or urls) and tileGrid properties'); + } + + var wmtsConfiguration = { + projection: projection, + layer: source.layer, + attributions: createAttribution(source), + matrixSet: (source.matrixSet === 'undefined') ? projection : source.matrixSet, + format: (source.format === 'undefined') ? 'image/jpeg' : source.format, + requestEncoding: (source.requestEncoding === 'undefined') ? + 'KVP' : source.requestEncoding, + tileGrid: new ol.tilegrid.WMTS({ + origin: source.tileGrid.origin, + resolutions: source.tileGrid.resolutions, + matrixIds: source.tileGrid.matrixIds + }), + wrapX: source.wrapX ? 0 : 1 + }; + + if (isDefined(source.url)) { + wmtsConfiguration.url = source.url; + } + + if (isDefined(source.urls)) { + wmtsConfiguration.urls = source.urls; + } + + oSource = new ol.source.WMTS(wmtsConfiguration); + break; + + case 'OSM': + oSource = new ol.source.OSM({ + attributions: createAttribution(source), + wrapX: (source.wrapX === true) ? 1 : 0 + }); + + if (source.url) { + oSource.setUrl(source.url); + } + + break; + case 'BingMaps': + if (!source.key) { + $log.error('[AngularJS - Openlayers] - You need an API key to show the Bing Maps.'); + return; + } + + var bingConfiguration = { + key: source.key, + attributions: createAttribution(source), + imagerySet: source.imagerySet ? source.imagerySet : bingImagerySets[0], + culture: source.culture, + wrapX: (source.wrapX === true) ? 1 : 0 + }; + + if (source.maxZoom) { + bingConfiguration.maxZoom = source.maxZoom; + } + + oSource = new ol.source.BingMaps(bingConfiguration); + break; + + case 'MapQuest': + if (!source.layer || mapQuestLayers.indexOf(source.layer) === -1) { + $log.error('[AngularJS - Openlayers] - MapQuest layers needs a valid \'layer\' property.'); + return; + } + + oSource = new ol.source.MapQuest({ + attributions: createAttribution(source), + layer: source.layer, + wrapX: (source.wrapX === true) ? 1 : 0 + }); + + break; + + case 'EsriBaseMaps': + if (!source.layer || esriBaseLayers.indexOf(source.layer) === -1) { + $log.error('[AngularJS - Openlayers] - ESRI layers needs a valid \'layer\' property.'); + return; + } + + var _urlBase = 'http://services.arcgisonline.com/ArcGIS/rest/services/'; + var _url = _urlBase + source.layer + '/MapServer/tile/{z}/{y}/{x}'; + + oSource = new ol.source.XYZ({ + attributions: createAttribution(source), + url: _url, + wrapX: (source.wrapX === true) ? 1 : 0 + }); + + break; + + case 'GeoJSON': + if (!(source.geojson || source.url)) { + $log.error('[AngularJS - Openlayers] - You need a geojson ' + + 'property to add a GeoJSON layer.'); + return; + } + + if (isDefined(source.url)) { + oSource = new ol.source.Vector({ + format: new ol.format.GeoJSON(), + url: source.url, + wrapX: (source.wrapX === true) ? 1 : 0 + }); + } else { + oSource = new ol.source.Vector(); + + var projectionToUse = projection; + if (isDefined(source.geojson.projection)) { + projectionToUse = source.geojson.projection; + } + + var geojsonFormat = new ol.format.GeoJSON(); + var features = geojsonFormat.readFeatures( + source.geojson.object, { featureProjection: projectionToUse }); + + oSource.addFeatures(features); + } + + break; + case 'JSONP': + if (!(source.url)) { + $log.error('[AngularJS - Openlayers] - You need an url properly configured to add a JSONP layer.'); + return; + } + + if (isDefined(source.url)) { + oSource = new ol.source.Vector({ + format: new ol.format.GeoJSON(), + loader: function(/*extent, resolution, projection*/) { + var url = source.url + + '&outputFormat=text/javascript&format_options=callback:JSON_CALLBACK'; + $http.jsonp(url, { cache: source.cache}).success(function(response) { + oSource.addFeatures(oSource.readFeatures(response)); + }).error(function(response) { + $log(response); + }); + }, + wrapX: (source.wrapX === true) ? 1 : 0 + }); + } + break; + case 'TopoJSON': + if (!(source.topojson || source.url)) { + $log.error('[AngularJS - Openlayers] - You need a topojson ' + + 'property to add a TopoJSON layer.'); + return; + } + + if (source.url) { + oSource = new ol.source.Vector({ + format: new ol.format.TopoJSON(), + url: source.url, + wrapX: (source.wrapX === true) ? 1 : 0 + }); + } else { + oSource = new ol.source.Vector(angular.extend(source.topojson, { + format: new ol.format.TopoJSON(), + wrapX: (source.wrapX === true) ? 1 : 0 + })); + } + break; + case 'TileJSON': + oSource = new ol.source.TileJSON({ + url: source.url, + attributions: createAttribution(source), + crossOrigin: 'anonymous', + wrapX: (source.wrapX === true) ? 1 : 0 + }); + break; + + case 'TileVector': + if (!source.url || !source.format) { + $log.error('[AngularJS - Openlayers] - TileVector Layer needs valid url and format properties'); + } + oSource = new ol.source.TileVector({ + url: source.url, + projection: projection, + attributions: createAttribution(source), + format: source.format, + tileGrid: new ol.tilegrid.createXYZ({ + maxZoom: source.maxZoom || 19 + }), + wrapX: (source.wrapX === true) ? 1 : 0 + }); + break; + + case 'TileTMS': + if (!source.url || !source.tileGrid) { + $log.error('[AngularJS - Openlayers] - TileTMS Layer needs valid url and tileGrid properties'); + } + oSource = new ol.source.TileImage({ + url: source.url, + maxExtent: source.maxExtent, + attributions: createAttribution(source), + tileGrid: new ol.tilegrid.TileGrid({ + origin: source.tileGrid.origin, + resolutions: source.tileGrid.resolutions + }), + tileUrlFunction: function(tileCoord) { + + var z = tileCoord[0]; + var x = tileCoord[1]; + var y = tileCoord[2]; //(1 << z) - tileCoord[2] - 1; + + if (x < 0 || y < 0) { + return ''; + } + + var url = source.url + z + '/' + x + '/' + y + '.png'; + + return url; + }, + wrapX: (source.wrapX === true) ? 1 : 0 + }); + break; + case 'TileImage': + oSource = new ol.source.TileImage({ + url: source.url, + attributions: createAttribution(source), + tileGrid: new ol.tilegrid.TileGrid({ + origin: source.tileGrid.origin, // top left corner of the pixel projection's extent + resolutions: source.tileGrid.resolutions + }), + tileUrlFunction: function(tileCoord/*, pixelRatio, projection*/) { + var z = tileCoord[0]; + var x = tileCoord[1]; + var y = -tileCoord[2] - 1; + var url = source.url + .replace('{z}', z.toString()) + .replace('{x}', x.toString()) + .replace('{y}', y.toString()); + return url; + }, + wrapX: (source.wrapX === true) ? 1 : 0 + }); + break; + case 'KML': + var extractStyles = source.extractStyles || false; + oSource = new ol.source.Vector({ + url: source.url, + format: new ol.format.KML(), + radius: source.radius, + extractStyles: extractStyles, + wrapX: (source.wrapX === true) ? 1 : 0 + }); + break; + case 'Stamen': + if (!source.layer || !isValidStamenLayer(source.layer)) { + $log.error('[AngularJS - Openlayers] - You need a valid Stamen layer.'); + return; + } + oSource = new ol.source.Stamen({ + layer: source.layer, + wrapX: (source.wrapX === true) ? 1 : 0 + }); + break; + case 'ImageStatic': + if (!source.url || !angular.isArray(source.imageSize) || source.imageSize.length !== 2) { + $log.error('[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.'); + return; + } + + oSource = new ol.source.ImageStatic({ + url: source.url, + attributions: createAttribution(source), + imageSize: source.imageSize, + projection: projection, + imageExtent: projection.getExtent(), + imageLoadFunction: source.imageLoadFunction, + wrapX: (source.wrapX === true) ? 1 : 0 + }); + break; + case 'XYZ': + if (!source.url) { + $log.error('[AngularJS - Openlayers] - XYZ Layer needs valid url and params properties'); + } + oSource = new ol.source.XYZ({ + url: source.url, + attributions: createAttribution(source), + minZoom: source.minZoom, + maxZoom: source.maxZoom, + wrapX: (source.wrapX === true) ? 1 : 0 + }); + break; + } + + // log a warning when no source could be created for the given type + if (!oSource) { + $log.warn('[AngularJS - Openlayers] - No source could be found for type "' + source.type + '"'); + } + + return oSource; + }; + + var createAttribution = function(source) { + var attributions = []; + if (isDefined(source.attribution)) { + attributions.unshift(new ol.Attribution({html: source.attribution})); + } + return attributions; + }; + + var createGroup = function(name) { + var olGroup = new ol.layer.Group(); + olGroup.set('name', name); + + return olGroup; + }; + + var getGroup = function(layers, name) { + var layer; + + angular.forEach(layers, function(l) { + if (l instanceof ol.layer.Group && l.get('name') === name) { + layer = l; + return; + } + }); + + return layer; + }; + + var addLayerBeforeMarkers = function(layers, layer) { + var markersIndex; + for (var i = 0; i < layers.getLength(); i++) { + var l = layers.item(i); + + if (l.get('markers')) { + markersIndex = i; + break; + } + } + + if (isDefined(markersIndex)) { + var markers = layers.item(markersIndex); + layer.index = markersIndex; + layers.setAt(markersIndex, layer); + markers.index = layers.getLength(); + layers.push(markers); + } else { + layer.index = layers.getLength(); + layers.push(layer); + } + + }; + + var removeLayer = function(layers, index) { + layers.removeAt(index); + for (var i = index; i < layers.getLength(); i++) { + var l = layers.item(i); + if (l === null) { + layers.insertAt(i, null); + break; + } else { + l.index = i; + } + } + }; + + return { + // Determine if a reference is defined + isDefined: isDefined, + + // Determine if a reference is a number + isNumber: function(value) { + return angular.isNumber(value); + }, + + createView: function(view) { + var projection = createProjection(view); + + return new ol.View({ + projection: projection, + maxZoom: view.maxZoom, + minZoom: view.minZoom, + extent: view.extent + }); + }, + + // Determine if a reference is defined and not null + isDefinedAndNotNull: isDefinedAndNotNull, + + // Determine if a reference is a string + isString: function(value) { + return angular.isString(value); + }, + + // Determine if a reference is an array + isArray: function(value) { + return angular.isArray(value); + }, + + // Determine if a reference is an object + isObject: function(value) { + return angular.isObject(value); + }, + + // Determine if two objects have the same properties + equals: function(o1, o2) { + return angular.equals(o1, o2); + }, + + isValidCenter: function(center) { + return angular.isDefined(center) && + (typeof center.autodiscover === 'boolean' || + angular.isNumber(center.lat) && angular.isNumber(center.lon) || + (angular.isArray(center.coord) && center.coord.length === 2 && + angular.isNumber(center.coord[0]) && angular.isNumber(center.coord[1])) || + (angular.isArray(center.bounds) && center.bounds.length === 4 && + angular.isNumber(center.bounds[0]) && angular.isNumber(center.bounds[1]) && + angular.isNumber(center.bounds[1]) && angular.isNumber(center.bounds[2]))); + }, + + safeApply: function($scope, fn) { + var phase = $scope.$root.$$phase; + if (phase === '$apply' || phase === '$digest') { + $scope.$eval(fn); + } else { + $scope.$apply(fn); + } + }, + + isSameCenterOnMap: function(center, map) { + var urlProj = center.projection || 'EPSG:4326'; + var urlCenter = [center.lon, center.lat]; + var mapProj = map.getView().getProjection(); + var mapCenter = ol.proj.transform(map.getView().getCenter(), mapProj, urlProj); + var zoom = map.getView().getZoom(); + if (mapCenter[1].toFixed(4) === urlCenter[1].toFixed(4) && + mapCenter[0].toFixed(4) === urlCenter[0].toFixed(4) && + zoom === center.zoom) { + return true; + } + return false; + }, + + setCenter: function(view, projection, newCenter, map) { + + if (map && view.getCenter()) { + var pan = ol.animation.pan({ + duration: 150, + source: (view.getCenter()) + }); + map.beforeRender(pan); + } + + if (newCenter.projection === projection) { + view.setCenter([newCenter.lon, newCenter.lat]); + } else { + var coord = [newCenter.lon, newCenter.lat]; + view.setCenter(ol.proj.transform(coord, newCenter.projection, projection)); + } + }, + + setZoom: function(view, zoom, map) { + var z = ol.animation.zoom({ + duration: 150, + resolution: map.getView().getResolution() + }); + map.beforeRender(z); + view.setZoom(zoom); + }, + + isBoolean: function(value) { + return typeof value === 'boolean'; + }, + + obtainEffectiveMapId: function(d, mapId) { + var id; + var i; + if (!angular.isDefined(mapId)) { + if (Object.keys(d).length === 1) { + for (i in d) { + if (d.hasOwnProperty(i)) { + id = i; + } + } + } else if (Object.keys(d).length === 0) { + id = 'main'; + } else { + $log.error('[AngularJS - Openlayers] - You have more than 1 map on the DOM, ' + + 'you must provide the map ID to the olData.getXXX call'); + } + } else { + id = mapId; + } + return id; + }, + + createStyle: createStyle, + + setMapEvents: function(events, map, scope) { + if (isDefined(events) && angular.isArray(events.map)) { + for (var i in events.map) { + var event = events.map[i]; + setEvent(map, event, scope); + } + } + }, + + setVectorLayerEvents: function(events, map, scope, layerName) { + if (isDefined(events) && angular.isArray(events.layers)) { + angular.forEach(events.layers, function(eventType) { + angular.element(map.getViewport()).on(eventType, function(evt) { + var pixel = map.getEventPixel(evt); + var feature = map.forEachFeatureAtPixel(pixel, function(feature, olLayer) { + // only return the feature if it is in this layer (based on the name) + return (isDefinedAndNotNull(olLayer) && olLayer.get('name') === layerName) ? feature : null; + }); + if (isDefinedAndNotNull(feature)) { + scope.$emit('openlayers.layers.' + layerName + '.' + eventType, feature, evt); + } + }); + }); + } + }, + + setViewEvents: function(events, map, scope) { + if (isDefined(events) && angular.isArray(events.view)) { + var view = map.getView(); + angular.forEach(events.view, function(eventType) { + view.on(eventType, function(event) { + scope.$emit('openlayers.view.' + eventType, view, event); + }); + }); + } + }, + + detectLayerType: detectLayerType, + + createLayer: function(layer, projection, name) { + var oLayer; + var type = detectLayerType(layer); + var oSource = createSource(layer.source, projection); + if (!oSource) { + return; + } + + // Manage clustering + if ((type === 'Vector') && layer.clustering) { + oSource = new ol.source.Cluster({ + source: oSource, + distance: layer.clusteringDistance, + }); + } + + switch (type) { + case 'Image': + oLayer = new ol.layer.Image({ source: oSource }); + break; + case 'Tile': + oLayer = new ol.layer.Tile({ source: oSource }); + break; + case 'Heatmap': + oLayer = new ol.layer.Heatmap({ source: oSource }); + break; + case 'Vector': + oLayer = new ol.layer.Vector({ source: oSource }); + break; + } + + // set a layer name if given + if (isDefined(name)) { + oLayer.set('name', name); + } else if (isDefined(layer.name)) { + oLayer.set('name', layer.name); + } + + return oLayer; + }, + + createVectorLayer: function() { + return new ol.layer.Vector({ + source: new ol.source.Vector() + }); + }, + + notifyCenterUrlHashChanged: function(scope, center, search) { + if (center.centerUrlHash) { + var centerUrlHash = center.lat.toFixed(4) + ':' + center.lon.toFixed(4) + ':' + center.zoom; + if (!isDefined(search.c) || search.c !== centerUrlHash) { + scope.$emit('centerUrlHash', centerUrlHash); + } + } + }, + + getControlClasses: getControlClasses, + + detectControls: function(controls) { + var actualControls = {}; + var controlClasses = getControlClasses(); + + controls.forEach(function(control) { + for (var i in controlClasses) { + if (control instanceof controlClasses[i]) { + actualControls[i] = control; + } + } + }); + + return actualControls; + }, + + createFeature: function(data, viewProjection) { + var geometry; + + switch (data.type) { + case 'Polygon': + geometry = new ol.geom.Polygon(data.coords); + break; + default: + if (isDefined(data.coord) && data.projection === 'pixel') { + geometry = new ol.geom.Point(data.coord); + } else { + geometry = new ol.geom.Point([data.lon, data.lat]); + } + break; + } + + if (isDefined(data.projection) && data.projection !== 'pixel') { + geometry = geometry.transform(data.projection, viewProjection); + } + + var feature = new ol.Feature({ + geometry: geometry + }); + + if (isDefined(data.style)) { + var style = createStyle(data.style); + feature.setStyle(style); + } + return feature; + }, + + addLayerBeforeMarkers: addLayerBeforeMarkers, + + getGroup: getGroup, + + addLayerToGroup: function(layers, layer, name) { + var groupLayer = getGroup(layers, name); + + if (!isDefined(groupLayer)) { + groupLayer = createGroup(name); + addLayerBeforeMarkers(layers,groupLayer); + } + + layer.set('group', name); + addLayerBeforeMarkers(groupLayer.getLayers(), layer); + }, + + removeLayerFromGroup: function(layers, layer, name) { + var groupLayer = getGroup(layers, name); + layer.set('group'); + removeLayer(groupLayer.getLayers(), layer.index); + }, + + removeLayer: removeLayer, + + insertLayer: function(layers, index, layer) { + if (layers.getLength() < index) { + while (layers.getLength() < index) { + layers.push(null); + } + layer.index = index; + layers.push(layer); + } else { + layer.index = index; + layers.insertAt(layer.index, layer); + for (var i = index + 1; i < layers.getLength(); i++) { + var l = layers.item(i); + if (l === null) { + layers.removeAt(i); + break; + } else { + l.index = i; + } + } + } + }, + + createOverlay: function(element, pos) { + element.css('display', 'block'); + var ov = new ol.Overlay({ + position: pos, + element: element, + positioning: 'center-left' + }); + + return ov; + } + }; +}]); + +angular.module('openlayers-directive').factory('olMapDefaults', ["$q", "olHelpers", function($q, olHelpers) { + + var base64icon = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAApCAYAAADAk4LOAAAGmklEQVRYw' + + '7VXeUyTZxjvNnfELFuyIzOabermMZEeQC/OclkO49CpOHXOLJl/CAURuYbQi3KLgEhbrhZ1aDwmaoGq' + + 'KII6odATmH/scDFbdC7LvFqOCc+e95s2VG50X/LLm/f4/Z7neY/ne18aANCmAr5E/xZf1uDOkTcGcWR' + + '6hl9247tT5U7Y6SNvWsKT63P58qbfeLJG8M5qcgTknrvvrdDbsT7Ml+tv82X6vVxJE33aRmgSyYtcWV' + + 'MqX97Yv2JvW39UhRE2HuyBL+t+gK1116ly06EeWFNlAmHxlQE0OMiV6mQCScusKRlhS3QLeVJdl1+23' + + 'h5dY4FNB3thrbYboqptEFlphTC1hSpJnbRvxP4NWgsE5Jyz86QNNi/5qSUTGuFk1gu54tN9wuK2wc3o' + + '+Wc13RCmsoBwEqzGcZsxsvCSy/9wJKf7UWf1mEY8JWfewc67UUoDbDjQC+FqK4QqLVMGGR9d2wurKzq' + + 'Bk3nqIT/9zLxRRjgZ9bqQgub+DdoeCC03Q8j+0QhFhBHR/eP3U/zCln7Uu+hihJ1+bBNffLIvmkyP0g' + + 'pBZWYXhKussK6mBz5HT6M1Nqpcp+mBCPXosYQfrekGvrjewd59/GvKCE7TbK/04/ZV5QZYVWmDwH1mF' + + '3xa2Q3ra3DBC5vBT1oP7PTj4C0+CcL8c7C2CtejqhuCnuIQHaKHzvcRfZpnylFfXsYJx3pNLwhKzRAw' + + 'AhEqG0SpusBHfAKkxw3w4627MPhoCH798z7s0ZnBJ/MEJbZSbXPhER2ih7p2ok/zSj2cEJDd4CAe+5W' + + 'YnBCgR2uruyEw6zRoW6/DWJ/OeAP8pd/BGtzOZKpG8oke0SX6GMmRk6GFlyAc59K32OTEinILRJRcha' + + 'h8HQwND8N435Z9Z0FY1EqtxUg+0SO6RJ/mmXz4VuS+DpxXC3gXmZwIL7dBSH4zKE50wESf8qwVgrP1E' + + 'IlTO5JP9Igu0aexdh28F1lmAEGJGfh7jE6ElyM5Rw/FDcYJjWhbeiBYoYNIpc2FT/SILivp0F1ipDWk' + + '4BIEo2VuodEJUifhbiltnNBIXPUFCMpthtAyqws/BPlEF/VbaIxErdxPphsU7rcCp8DohC+GvBIPJS/' + + 'tW2jtvTmmAeuNO8BNOYQeG8G/2OzCJ3q+soYB5i6NhMaKr17FSal7GIHheuV3uSCY8qYVuEm1cOzqdW' + + 'r7ku/R0BDoTT+DT+ohCM6/CCvKLKO4RI+dXPeAuaMqksaKrZ7L3FE5FIFbkIceeOZ2OcHO6wIhTkNo0' + + 'ffgjRGxEqogXHYUPHfWAC/lADpwGcLRY3aeK4/oRGCKYcZXPVoeX/kelVYY8dUGf8V5EBRbgJXT5QIP' + + 'hP9ePJi428JKOiEYhYXFBqou2Guh+p/mEB1/RfMw6rY7cxcjTrneI1FrDyuzUSRm9miwEJx8E/gUmql' + + 'yvHGkneiwErR21F3tNOK5Tf0yXaT+O7DgCvALTUBXdM4YhC/IawPU+2PduqMvuaR6eoxSwUk75ggqsY' + + 'J7VicsnwGIkZBSXKOUww73WGXyqP+J2/b9c+gi1YAg/xpwck3gJuucNrh5JvDPvQr0WFXf0piyt8f8/' + + 'WI0hV4pRxxkQZdJDfDJNOAmM0Ag8jyT6hz0WGXWuP94Yh2jcfjmXAGvHCMslRimDHYuHuDsy2QtHuIa' + + 'vznhbYURq5R57KpzBBRZKPJi8eQg48h4j8SDdowifdIrEVdU+gbO6QNvRRt4ZBthUaZhUnjlYObNagV' + + '3keoeru3rU7rcuceqU1mJBxy+BWZYlNEBH+0eH4vRiB+OYybU2hnblYlTvkHinM4m54YnxSyaZYSF6R' + + '3jwgP7udKLGIX6r/lbNa9N6y5MFynjWDtrHd75ZvTYAPO/6RgF0k76mQla3FGq7dO+cH8sKn0Vo7nDl' + + 'lwAhqwLPkxrHwWmHJOo+AKJ4rab5OgrM7rVu8eWb2Pu0Dh4eDgXoOfvp7Y7QeqknRmvcTBEyq9m/HQQ' + + 'SCSz6LHq3z0yzsNySRfMS253wl2KyRDbcZPcfJKjZmSEOjcxyi+Y8dUOtsIEH6R2wNykdqrkYJ0RV92' + + 'H0W58pkfQk7cKevsLK10Py8SdMGfXNXATY+pPbyJR/ET6n9nIfztNtZYRV9XniQu9IA2vOVgy4ir7GC' + + 'LVmmd+zjkH0eAF9Po6K61pmCXHxU5rHMYd1ftc3owjwRSVRzLjKvqZEty6cRUD7jGqiOdu5HG6MdHjN' + + 'cNYGqfDm5YRzLBBCCDl/2bk8a8gdbqcfwECu62Fg/HrggAAAABJRU5ErkJggg=='; + + var _getDefaults = function() { + return { + view: { + projection: 'EPSG:3857', + minZoom: undefined, + maxZoom: undefined, + rotation: 0, + extent: undefined + }, + center: { + lat: 0, + lon: 0, + zoom: 1, + autodiscover: false, + bounds: [], + centerUrlHash: false, + projection: 'EPSG:4326' + }, + styles: { + path: { + stroke: { + color: 'blue', + width: 8 + } + }, + marker: { + image: new ol.style.Icon({ + anchor: [0.5, 1], + anchorXUnits: 'fraction', + anchorYUnits: 'fraction', + opacity: 0.90, + src: base64icon + }) + } + }, + events: { + map: [], + markers: [], + layers: [] + }, + controls: { + attribution: true, + rotate: false, + zoom: true + }, + interactions: { + mouseWheelZoom: false + }, + renderer: 'canvas' + }; + }; + + var isDefined = olHelpers.isDefined; + var defaults = {}; + + // Get the _defaults dictionary, and override the properties defined by the user + return { + getDefaults: function(scope) { + if (!isDefined(scope)) { + for (var i in defaults) { + return defaults[i]; + } + } + return defaults[scope.$id]; + }, + + setDefaults: function(scope) { + var userDefaults = scope.defaults; + var scopeId = scope.$id; + var newDefaults = _getDefaults(); + + if (isDefined(userDefaults)) { + + if (isDefined(userDefaults.layers)) { + newDefaults.layers = angular.copy(userDefaults.layers); + } + + if (isDefined(userDefaults.controls)) { + newDefaults.controls = angular.copy(userDefaults.controls); + } + + if (isDefined(userDefaults.events)) { + newDefaults.events = angular.copy(userDefaults.events); + } + + if (isDefined(userDefaults.interactions)) { + newDefaults.interactions = angular.copy(userDefaults.interactions); + } + + if (isDefined(userDefaults.renderer)) { + newDefaults.renderer = userDefaults.renderer; + } + + if (isDefined(userDefaults.view)) { + newDefaults.view.maxZoom = userDefaults.view.maxZoom || newDefaults.view.maxZoom; + newDefaults.view.minZoom = userDefaults.view.minZoom || newDefaults.view.minZoom; + newDefaults.view.projection = userDefaults.view.projection || newDefaults.view.projection; + newDefaults.view.extent = userDefaults.view.extent || newDefaults.view.extent; + } + + if (isDefined(userDefaults.styles)) { + newDefaults.styles = angular.extend(newDefaults.styles, userDefaults.styles); + } + + } + + defaults[scopeId] = newDefaults; + return newDefaults; + } + }; +}]); + +})); \ No newline at end of file diff --git a/dist/angular-openlayers-directive.min.js b/dist/angular-openlayers-directive.min.js new file mode 100644 index 00000000..925988a4 --- /dev/null +++ b/dist/angular-openlayers-directive.min.js @@ -0,0 +1,31 @@ +/**! + * The MIT License + * + * Copyright (c) 2013 the angular-openlayers-directive Team, http://tombatossals.github.io/angular-openlayers-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-google-maps + * https://github.com/tombatossals/angular-openlayers-directive + * + * @authors https://github.com/tombatossals/angular-openlayers-directive/graphs/contributors + */ + +/*! angular-openlayers-directive 06-11-2015 */ +!function(a,b){"function"==typeof define&&define.amd?define(["ol"],function(c){return a.angularOpenlayersDirective=b(c)}):a.angularOpenlayersDirective=b(a.ol)}(this,function(a){angular.module("openlayers-directive",["ngSanitize"]).directive("openlayers",["$log","$q","$compile","olHelpers","olMapDefaults","olData",function(b,c,d,e,f,g){return{restrict:"EA",transclude:!0,replace:!0,scope:{center:"=olCenter",defaults:"=olDefaults",view:"=olView",events:"=olEvents"},template:'
',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p});if(!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d){if("pixel"===g.view.projection)return void i.setCenter(c.coord);var e=a.proj.transform(d,g.view.projection,c.projection);(e[1]!==c.lat||e[0]!==c.lon)&&p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}}),f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i))}else d=j(c,f),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i))}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)}),e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope();i.getMap().then(function(b){var d=e.getControlClasses,i=d();return a.$on("$destroy",function(){b.removeControl(f)}),h(a.properties)&&h(a.properties.control)?(f=a.properties.control,void b.addControl(f)):void(c.name&&(h(a.properties)&&(g=a.properties),f=new i[c.name](g),b.addControl(f)))})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return e.on("pointerdown",j),e.on("pointerup",j),e.on("pointerdrag",j),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e)}),k(c.properties)?void c.$watch("properties",function(d){if(e.getViewport().removeEventListener("mousemove",d.handleInteraction),e.getViewport().removeEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",d.handleTapInteraction),e.getViewport().removeEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",d.removeAllOverlays),d.handleInteraction=function(b){if(!d.label.show){var f=!1,g=e.getEventPixel(b),i=e.forEachFeatureAtPixel(g,function(a){return a}),j=!1;i===r&&(j=!0,f=!0,k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),!d.onClick||"click"!==b.type&&"touchend"!==b.type||c.$apply(function(){d.onClick.call(r,b,d)}),e.getTarget().style.cursor="pointer"),!f&&p&&(j=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),j&&b.preventDefault()}},d.handleTapInteraction=function(){function a(){c=!0,b&&clearTimeout(b),b=setTimeout(function(){c=!1,b=null},500)}var b,c=!1;return e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",a),function(){c||(d.handleInteraction.apply(null,arguments),a())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||d.onClick)&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q","olHelpers",function(a,b,c){var d=c.obtainEffectiveMapId,e={},f=function(a,b){var c=d(a,b);a[c].resolvedDefer=!0},g=function(a,c){var e,f=d(a,c);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},h=function(a,b){var c,e=d(a,b);return c=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:g(a,b)};this.setMap=function(a,b){var c=g(e,b);c.resolve(a),f(e,b)},this.getMap=function(a){var b=h(e,a);return b.promise}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function x(a,b){var c;if(b?c=a[b]:(b="style",c=a),"style"===b&&a instanceof Function)return a;if(!(c instanceof Object))return c;var d;if("[object Object]"===Object.prototype.toString.call(c)){d={};var e=l[b];if(e&&c instanceof e)return c;Object.getOwnPropertyNames(c).forEach(function(a,f,g){var h=l[a];return e&&h&&h.prototype instanceof l[b]?(console.assert(1===g.length,"Extra parameters for "+b),d=x(c,a),m(d,h)):(d[a]=x(c,a),void("text"!==a&&"string"!=typeof d[a]&&(d[a]=m(d[a],l[a]))))})}else d=c;return m(d,l[b])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"TileVector":return"Vector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");var i="http://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,l=window.devicePixelRatio;l>1&&(i=i.replace(".png","@2x.png")),g=new a.source.XYZ({url:i,attributions:s(b),tilePixelRatio:l>1?2:1,wrapX:b.wrapX===!0?1:0});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,attributions:s(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:b.params,wrapX:b.wrapX?0:1});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var m={crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:b.params,attributions:s(b),wrapX:b.wrapX?0:1};b.url&&(m.url=b.url),b.urls&&(m.urls=b.urls),g=new a.source.TileWMS(m);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var n={projection:f,layer:b.layer,attributions:s(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),wrapX:b.wrapX?0:1};e(b.url)&&(n.url=b.url),e(b.urls)&&(n.urls=b.urls),g=new a.source.WMTS(n);break;case"OSM":g=new a.source.OSM({attributions:s(b),wrapX:b.wrapX===!0?1:0}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var o={key:b.key,attributions:s(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:b.wrapX===!0?1:0};b.maxZoom&&(o.maxZoom=b.maxZoom),g=new a.source.BingMaps(o);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:s(b),layer:b.layer,wrapX:b.wrapX===!0?1:0});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var p="http://services.arcgisonline.com/ArcGIS/rest/services/",r=p+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:s(b),url:r,wrapX:b.wrapX===!0?1:0});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url,wrapX:b.wrapX===!0?1:0});else{g=new a.source.Vector;var t=f;e(b.geojson.projection)&&(t=b.geojson.projection);var u=new a.format.GeoJSON,v=u.readFeatures(b.geojson.object,{featureProjection:t});g.addFeatures(v)}break;case"JSONP":if(!b.url)return void c.error("[AngularJS - Openlayers] - You need an url properly configured to add a JSONP layer.");e(b.url)&&(g=new a.source.Vector({format:new a.format.GeoJSON,loader:function(){var a=b.url+"&outputFormat=text/javascript&format_options=callback:JSON_CALLBACK";d.jsonp(a,{cache:b.cache}).success(function(a){g.addFeatures(g.readFeatures(a))}).error(function(a){c(a)})},wrapX:b.wrapX===!0?1:0}));break;case"TopoJSON":if(!b.topojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a topojson property to add a TopoJSON layer.");g=b.url?new a.source.Vector({format:new a.format.TopoJSON,url:b.url,wrapX:b.wrapX===!0?1:0}):new a.source.Vector(angular.extend(b.topojson,{format:new a.format.TopoJSON,wrapX:b.wrapX===!0?1:0}));break;case"TileJSON":g=new a.source.TileJSON({url:b.url,attributions:s(b),crossOrigin:"anonymous",wrapX:b.wrapX===!0?1:0});break;case"TileVector":b.url&&b.format||c.error("[AngularJS - Openlayers] - TileVector Layer needs valid url and format properties"),g=new a.source.TileVector({url:b.url,projection:f,attributions:s(b),format:b.format,tileGrid:new a.tilegrid.createXYZ({maxZoom:b.maxZoom||19}),wrapX:b.wrapX===!0?1:0});break;case"TileTMS":b.url&&b.tileGrid||c.error("[AngularJS - Openlayers] - TileTMS Layer needs valid url and tileGrid properties"),g=new a.source.TileImage({url:b.url,maxExtent:b.maxExtent,attributions:s(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=a[2];if(0>d||0>e)return"";var f=b.url+c+"/"+d+"/"+e+".png";return f},wrapX:b.wrapX===!0?1:0});break;case"TileImage":g=new a.source.TileImage({url:b.url,attributions:s(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=-a[2]-1,f=b.url.replace("{z}",c.toString()).replace("{x}",d.toString()).replace("{y}",e.toString());return f},wrapX:b.wrapX===!0?1:0});break;case"KML":var w=b.extractStyles||!1;g=new a.source.Vector({url:b.url,format:new a.format.KML,radius:b.radius,extractStyles:w,wrapX:b.wrapX===!0?1:0});break;case"Stamen":if(!b.layer||!q(b.layer))return void c.error("[AngularJS - Openlayers] - You need a valid Stamen layer.");g=new a.source.Stamen({layer:b.layer,wrapX:b.wrapX===!0?1:0});break;case"ImageStatic":if(!b.url||!angular.isArray(b.imageSize)||2!==b.imageSize.length)return void c.error("[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.");g=new a.source.ImageStatic({url:b.url,attributions:s(b),imageSize:b.imageSize,projection:f,imageExtent:f.getExtent(),imageLoadFunction:b.imageLoadFunction,wrapX:b.wrapX===!0?1:0});break;case"XYZ":b.url||c.error("[AngularJS - Openlayers] - XYZ Layer needs valid url and params properties"),g=new a.source.XYZ({url:b.url,attributions:s(b),minZoom:b.minZoom,maxZoom:b.maxZoom,wrapX:b.wrapX===!0?1:0})}return g||c.warn('[AngularJS - Openlayers] - No source could be found for type "'+b.type+'"'),g},s=function(b){var c=[];return e(b.attribution)&&c.unshift(new a.Attribution({html:b.attribution})),c},t=function(b){var c=new a.layer.Group;return c.set("name",b),c},u=function(b,c){var d;return angular.forEach(b,function(b){return b instanceof a.layer.Group&&b.get("name")===c?void(d=b):void 0}),d},v=function(a,b){for(var c,d=0;d',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p});if(!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d){if("pixel"===g.view.projection)return void i.setCenter(c.coord);var e=a.proj.transform(d,g.view.projection,c.projection);(e[1]!==c.lat||e[0]!==c.lon)&&p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}}),f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i))}else d=j(c,f),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i))}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)}),e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope();i.getMap().then(function(b){var d=e.getControlClasses,i=d();return a.$on("$destroy",function(){b.removeControl(f)}),h(a.properties)&&h(a.properties.control)?(f=a.properties.control,void b.addControl(f)):void(c.name&&(h(a.properties)&&(g=a.properties),f=new i[c.name](g),b.addControl(f)))})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return e.on("pointerdown",j),e.on("pointerup",j),e.on("pointerdrag",j),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e)}),k(c.properties)?void c.$watch("properties",function(d){if(e.getViewport().removeEventListener("mousemove",d.handleInteraction),e.getViewport().removeEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",d.handleTapInteraction),e.getViewport().removeEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",d.removeAllOverlays),d.handleInteraction=function(b){if(!d.label.show){var f=!1,g=e.getEventPixel(b),i=e.forEachFeatureAtPixel(g,function(a){return a}),j=!1;i===r&&(j=!0,f=!0,k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),!d.onClick||"click"!==b.type&&"touchend"!==b.type||c.$apply(function(){d.onClick.call(r,b,d)}),e.getTarget().style.cursor="pointer"),!f&&p&&(j=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),j&&b.preventDefault()}},d.handleTapInteraction=function(){function a(){c=!0,b&&clearTimeout(b),b=setTimeout(function(){c=!1,b=null},500)}var b,c=!1;return e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",a),function(){c||(d.handleInteraction.apply(null,arguments),a())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||d.onClick)&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q","olHelpers",function(a,b,c){var d=c.obtainEffectiveMapId,e={},f=function(a,b){var c=d(a,b);a[c].resolvedDefer=!0},g=function(a,c){var e,f=d(a,c);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},h=function(a,b){var c,e=d(a,b);return c=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:g(a,b)};this.setMap=function(a,b){var c=g(e,b);c.resolve(a),f(e,b)},this.getMap=function(a){var b=h(e,a);return b.promise}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function x(a,b){var c;if(b?c=a[b]:(b="style",c=a),"style"===b&&a instanceof Function)return a;if(!(c instanceof Object))return c;var d;if("[object Object]"===Object.prototype.toString.call(c)){d={};var e=l[b];if(e&&c instanceof e)return c;Object.getOwnPropertyNames(c).forEach(function(a,f,g){var h=l[a];return e&&h&&h.prototype instanceof l[b]?(console.assert(1===g.length,"Extra parameters for "+b),d=x(c,a),m(d,h)):(d[a]=x(c,a),void("text"!==a&&"string"!=typeof d[a]&&(d[a]=m(d[a],l[a]))))})}else d=c;return m(d,l[b])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"TileVector":return"Vector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");var i="http://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,l=window.devicePixelRatio;l>1&&(i=i.replace(".png","@2x.png")),g=new a.source.XYZ({url:i,attributions:s(b),tilePixelRatio:l>1?2:1,wrapX:b.wrapX===!0?1:0});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,attributions:s(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:b.params,wrapX:b.wrapX?0:1});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var m={crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:b.params,attributions:s(b),wrapX:b.wrapX?0:1};b.url&&(m.url=b.url),b.urls&&(m.urls=b.urls),g=new a.source.TileWMS(m);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var n={projection:f,layer:b.layer,attributions:s(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),wrapX:b.wrapX?0:1};e(b.url)&&(n.url=b.url),e(b.urls)&&(n.urls=b.urls),g=new a.source.WMTS(n);break;case"OSM":g=new a.source.OSM({attributions:s(b),wrapX:b.wrapX===!0?1:0}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var o={key:b.key,attributions:s(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:b.wrapX===!0?1:0};b.maxZoom&&(o.maxZoom=b.maxZoom),g=new a.source.BingMaps(o);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:s(b),layer:b.layer,wrapX:b.wrapX===!0?1:0});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var p="http://services.arcgisonline.com/ArcGIS/rest/services/",r=p+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:s(b),url:r,wrapX:b.wrapX===!0?1:0});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url,wrapX:b.wrapX===!0?1:0});else{g=new a.source.Vector;var t=f;e(b.geojson.projection)&&(t=b.geojson.projection);var u=new a.format.GeoJSON,v=u.readFeatures(b.geojson.object,{featureProjection:t});g.addFeatures(v)}break;case"JSONP":if(!b.url)return void c.error("[AngularJS - Openlayers] - You need an url properly configured to add a JSONP layer.");e(b.url)&&(g=new a.source.Vector({format:new a.format.GeoJSON,loader:function(){var a=b.url+"&outputFormat=text/javascript&format_options=callback:JSON_CALLBACK";d.jsonp(a,{cache:b.cache}).success(function(a){g.addFeatures(g.readFeatures(a))}).error(function(a){c(a)})},wrapX:b.wrapX===!0?1:0}));break;case"TopoJSON":if(!b.topojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a topojson property to add a TopoJSON layer.");g=b.url?new a.source.Vector({format:new a.format.TopoJSON,url:b.url,wrapX:b.wrapX===!0?1:0}):new a.source.Vector(angular.extend(b.topojson,{format:new a.format.TopoJSON,wrapX:b.wrapX===!0?1:0}));break;case"TileJSON":g=new a.source.TileJSON({url:b.url,attributions:s(b),crossOrigin:"anonymous",wrapX:b.wrapX===!0?1:0});break;case"TileVector":b.url&&b.format||c.error("[AngularJS - Openlayers] - TileVector Layer needs valid url and format properties"),g=new a.source.TileVector({url:b.url,projection:f,attributions:s(b),format:b.format,tileGrid:new a.tilegrid.createXYZ({maxZoom:b.maxZoom||19}),wrapX:b.wrapX===!0?1:0});break;case"TileTMS":b.url&&b.tileGrid||c.error("[AngularJS - Openlayers] - TileTMS Layer needs valid url and tileGrid properties"),g=new a.source.TileImage({url:b.url,maxExtent:b.maxExtent,attributions:s(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=a[2];if(0>d||0>e)return"";var f=b.url+c+"/"+d+"/"+e+".png";return f},wrapX:b.wrapX===!0?1:0});break;case"TileImage":g=new a.source.TileImage({url:b.url,attributions:s(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=-a[2]-1,f=b.url.replace("{z}",c.toString()).replace("{x}",d.toString()).replace("{y}",e.toString());return f},wrapX:b.wrapX===!0?1:0});break;case"KML":var w=b.extractStyles||!1;g=new a.source.Vector({url:b.url,format:new a.format.KML,radius:b.radius,extractStyles:w,wrapX:b.wrapX===!0?1:0});break;case"Stamen":if(!b.layer||!q(b.layer))return void c.error("[AngularJS - Openlayers] - You need a valid Stamen layer.");g=new a.source.Stamen({layer:b.layer,wrapX:b.wrapX===!0?1:0});break;case"ImageStatic":if(!b.url||!angular.isArray(b.imageSize)||2!==b.imageSize.length)return void c.error("[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.");g=new a.source.ImageStatic({url:b.url,attributions:s(b),imageSize:b.imageSize,projection:f,imageExtent:f.getExtent(),imageLoadFunction:b.imageLoadFunction,wrapX:b.wrapX===!0?1:0});break;case"XYZ":b.url||c.error("[AngularJS - Openlayers] - XYZ Layer needs valid url and params properties"),g=new a.source.XYZ({url:b.url,attributions:s(b),minZoom:b.minZoom,maxZoom:b.maxZoom,wrapX:b.wrapX===!0?1:0})}return g||c.warn('[AngularJS - Openlayers] - No source could be found for type "'+b.type+'"'),g},s=function(b){var c=[];return e(b.attribution)&&c.unshift(new a.Attribution({html:b.attribution})),c},t=function(b){var c=new a.layer.Group;return c.set("name",b),c},u=function(b,c){var d;return angular.forEach(b,function(b){return b instanceof a.layer.Group&&b.get("name")===c?void(d=b):void 0}),d},v=function(a,b){for(var c,d=0;d', + controller: function($scope) { + var _map = $q.defer(); + $scope.getMap = function() { + return _map.promise; + }; + + $scope.setMap = function(map) { + _map.resolve(map); + }; + + this.getOpenlayersScope = function() { + return $scope; + }; + }, + link: function(scope, element, attrs) { + var isDefined = olHelpers.isDefined; + var createLayer = olHelpers.createLayer; + var setMapEvents = olHelpers.setMapEvents; + var setViewEvents = olHelpers.setViewEvents; + var createView = olHelpers.createView; + var defaults = olMapDefaults.setDefaults(scope); + + // Set width and height if they are defined + if (isDefined(attrs.width)) { + if (isNaN(attrs.width)) { + element.css('width', attrs.width); + } else { + element.css('width', attrs.width + 'px'); + } + } + + if (isDefined(attrs.height)) { + if (isNaN(attrs.height)) { + element.css('height', attrs.height); + } else { + element.css('height', attrs.height + 'px'); + } + } + + if (isDefined(attrs.lat)) { + defaults.center.lat = parseFloat(attrs.lat); + } + + if (isDefined(attrs.lon)) { + defaults.center.lon = parseFloat(attrs.lon); + } + + if (isDefined(attrs.zoom)) { + defaults.center.zoom = parseFloat(attrs.zoom); + } + + var controls = ol.control.defaults(defaults.controls); + var interactions = ol.interaction.defaults(defaults.interactions); + var view = createView(defaults.view); + + // Create the Openlayers Map Object with the options + var map = new ol.Map({ + target: element[0], + controls: controls, + interactions: interactions, + renderer: defaults.renderer, + view: view + }); + + // If no layer is defined, set the default tileLayer + if (!attrs.customLayers) { + var l = { + type: 'Tile', + source: { + type: 'OSM' + } + }; + var layer = createLayer(l, view.getProjection(), 'default'); + map.addLayer(layer); + map.set('default', true); + } + + if (!isDefined(attrs.olCenter)) { + var c = ol.proj.transform([defaults.center.lon, + defaults.center.lat + ], + defaults.center.projection, view.getProjection() + ); + view.setCenter(c); + view.setZoom(defaults.center.zoom); + } + + // Set the Default events for the map + setMapEvents(defaults.events, map, scope); + + //Set the Default events for the map view + setViewEvents(defaults.events, map, scope); + + // Resolve the map object to the promises + scope.setMap(map); + olData.setMap(map, attrs.id); + + } + }; + }); + +angular.module('openlayers-directive').directive('olCenter', function($log, $location, olMapDefaults, olHelpers) { + + return { + restrict: 'A', + scope: false, + replace: false, + require: 'openlayers', + + link: function(scope, element, attrs, controller) { + var safeApply = olHelpers.safeApply; + var isValidCenter = olHelpers.isValidCenter; + var isDefined = olHelpers.isDefined; + var isArray = olHelpers.isArray; + var isNumber = olHelpers.isNumber; + var isSameCenterOnMap = olHelpers.isSameCenterOnMap; + var setCenter = olHelpers.setCenter; + var setZoom = olHelpers.setZoom; + var olScope = controller.getOpenlayersScope(); + + olScope.getMap().then(function(map) { + var defaults = olMapDefaults.getDefaults(olScope); + var view = map.getView(); + var center = olScope.center; + + if (attrs.olCenter.search('-') !== -1) { + $log.error('[AngularJS - Openlayers] The "center" variable can\'t use ' + + 'a "-" on his key name: "' + attrs.center + '".'); + setCenter(view, defaults.view.projection, defaults.center, map); + return; + } + + if (!isDefined(center)) { + center = {}; + } + + if (!isValidCenter(center)) { + $log.warn('[AngularJS - Openlayers] invalid \'center\''); + center.lat = defaults.center.lat; + center.lon = defaults.center.lon; + center.zoom = defaults.center.zoom; + center.projection = defaults.center.projection; + } + + if (!center.projection) { + if (defaults.view.projection !== 'pixel') { + center.projection = defaults.center.projection; + } else { + center.projection = 'pixel'; + } + } + + if (!isNumber(center.zoom)) { + center.zoom = 1; + } + + setCenter(view, defaults.view.projection, center, map); + view.setZoom(center.zoom); + + var centerUrlHash; + if (center.centerUrlHash === true) { + var extractCenterFromUrl = function() { + var search = $location.search(); + var centerParam; + if (isDefined(search.c)) { + var cParam = search.c.split(':'); + if (cParam.length === 3) { + centerParam = { + lat: parseFloat(cParam[0]), + lon: parseFloat(cParam[1]), + zoom: parseInt(cParam[2], 10) + }; + } + } + return centerParam; + }; + centerUrlHash = extractCenterFromUrl(); + + olScope.$on('$locationChangeSuccess', function() { + var urlCenter = extractCenterFromUrl(); + if (urlCenter && !isSameCenterOnMap(urlCenter, map)) { + safeApply(olScope, function(scope) { + scope.center.lat = urlCenter.lat; + scope.center.lon = urlCenter.lon; + scope.center.zoom = urlCenter.zoom; + }); + } + }); + } + + var geolocation; + olScope.$watchCollection('center', function(center) { + + if (!center) { + return; + } + + if (!center.projection) { + center.projection = defaults.center.projection; + } + + if (center.autodiscover) { + if (!geolocation) { + geolocation = new ol.Geolocation({ + projection: ol.proj.get(center.projection) + }); + + geolocation.on('change', function() { + if (center.autodiscover) { + var location = geolocation.getPosition(); + safeApply(olScope, function(scope) { + scope.center.lat = location[1]; + scope.center.lon = location[0]; + scope.center.zoom = 12; + scope.center.autodiscover = false; + geolocation.setTracking(false); + }); + } + }); + } + geolocation.setTracking(true); + return; + } + + if (!isValidCenter(center)) { + $log.warn('[AngularJS - Openlayers] invalid \'center\''); + center = defaults.center; + } + + var viewCenter = view.getCenter(); + if (viewCenter) { + if (defaults.view.projection === 'pixel') { + view.setCenter(center.coord); + return; + } + var actualCenter = ol.proj.transform(viewCenter, defaults.view.projection, center.projection); + if (!(actualCenter[1] === center.lat && actualCenter[0] === center.lon)) { + setCenter(view, defaults.view.projection, center, map); + } + } + + if (view.getZoom() !== center.zoom) { + setZoom(view, center.zoom, map); + } + }); + + map.on('moveend', function() { + safeApply(olScope, function(scope) { + + if (!isDefined(scope.center)) { + return; + } + + var center = map.getView().getCenter(); + scope.center.zoom = view.getZoom(); + + if (defaults.view.projection === 'pixel') { + scope.center.coord = center; + return; + } + + if (scope.center) { + var proj = ol.proj.transform(center, defaults.view.projection, scope.center.projection); + scope.center.lat = proj[1]; + scope.center.lon = proj[0]; + + // Notify the controller about a change in the center position + olHelpers.notifyCenterUrlHashChanged(olScope, scope.center, $location.search()); + + // Calculate the bounds if needed + if (isArray(scope.center.bounds)) { + var extent = view.calculateExtent(map.getSize()); + var centerProjection = scope.center.projection; + var viewProjection = defaults.view.projection; + scope.center.bounds = ol.proj.transformExtent(extent, viewProjection, centerProjection); + } + } + }); + }); + + }); + } + }; +}); + +angular.module('openlayers-directive').directive('olLayer', function($log, $q, olMapDefaults, olHelpers) { + + return { + restrict: 'E', + scope: { + properties: '=olLayerProperties' + }, + replace: false, + require: '^openlayers', + link: function(scope, element, attrs, controller) { + var isDefined = olHelpers.isDefined; + var equals = olHelpers.equals; + var olScope = controller.getOpenlayersScope(); + var createLayer = olHelpers.createLayer; + var setVectorLayerEvents = olHelpers.setVectorLayerEvents; + var detectLayerType = olHelpers.detectLayerType; + var createStyle = olHelpers.createStyle; + var isBoolean = olHelpers.isBoolean; + var addLayerBeforeMarkers = olHelpers.addLayerBeforeMarkers; + var isNumber = olHelpers.isNumber; + var insertLayer = olHelpers.insertLayer; + var removeLayer = olHelpers.removeLayer; + var addLayerToGroup = olHelpers.addLayerToGroup; + var removeLayerFromGroup = olHelpers.removeLayerFromGroup; + var getGroup = olHelpers.getGroup; + + olScope.getMap().then(function(map) { + var projection = map.getView().getProjection(); + var defaults = olMapDefaults.setDefaults(olScope); + var layerCollection = map.getLayers(); + var olLayer; + + scope.$on('$destroy', function() { + if (scope.properties.group) { + removeLayerFromGroup(layerCollection, olLayer, scope.properties.group); + } else { + removeLayer(layerCollection, olLayer.index); + } + + map.removeLayer(olLayer); + }); + + if (!isDefined(scope.properties)) { + if (isDefined(attrs.sourceType) && isDefined(attrs.sourceUrl)) { + var l = { + source: { + url: attrs.sourceUrl, + type: attrs.sourceType + } + }; + + olLayer = createLayer(l, projection, attrs.layerName); + if (detectLayerType(l) === 'Vector') { + setVectorLayerEvents(defaults.events, map, scope, attrs.name); + } + addLayerBeforeMarkers(layerCollection, olLayer); + } + return; + } + + scope.$watch('properties', function(properties, oldProperties) { + if (!isDefined(properties.source) || !isDefined(properties.source.type)) { + return; + } + + if (!isDefined(properties.visible)) { + properties.visible = true; + return; + } + + if (!isDefined(properties.opacity)) { + properties.opacity = 1; + return; + } + + var style; + var group; + var collection; + if (!isDefined(olLayer)) { + olLayer = createLayer(properties, projection); + if (isDefined(properties.group)) { + addLayerToGroup(layerCollection, olLayer, properties.group); + } else if (isDefined(properties.index)) { + insertLayer(layerCollection, properties.index, olLayer); + } else { + addLayerBeforeMarkers(layerCollection, olLayer); + } + + if (detectLayerType(properties) === 'Vector') { + setVectorLayerEvents(defaults.events, map, scope, properties.name); + } + + if (isBoolean(properties.visible)) { + olLayer.setVisible(properties.visible); + } + + if (properties.opacity) { + olLayer.setOpacity(properties.opacity); + } + + if (angular.isArray(properties.extent)) { + olLayer.setExtent(properties.extent); + } + + if (properties.style) { + if (!angular.isFunction(properties.style)) { + style = createStyle(properties.style); + } else { + style = properties.style; + } + // not every layer has a setStyle method + if (olLayer.setStyle && angular.isFunction(olLayer.setStyle)) { + olLayer.setStyle(style); + } + } + + } else { + var isNewLayer = (function(olLayer) { + // this function can be used to verify whether a new layer instance has + // been created. This is needed in order to re-assign styles, opacity + // etc... + return function(layer) { + return layer !== olLayer; + }; + })(olLayer); + + // set source properties + if (isDefined(oldProperties) && !equals(properties.source, oldProperties.source)) { + var idx = olLayer.index; + collection = layerCollection; + group = olLayer.get('group'); + + if (group) { + collection = getGroup(layerCollection, group).getLayers(); + } + + collection.removeAt(idx); + + olLayer = createLayer(properties, projection); + olLayer.set('group', group); + + if (isDefined(olLayer)) { + insertLayer(collection, idx, olLayer); + + if (detectLayerType(properties) === 'Vector') { + setVectorLayerEvents(defaults.events, map, scope, properties.name); + } + } + } + + // set opacity + if (isDefined(oldProperties) && + properties.opacity !== oldProperties.opacity || isNewLayer(olLayer)) { + if (isNumber(properties.opacity) || isNumber(parseFloat(properties.opacity))) { + olLayer.setOpacity(properties.opacity); + } + } + + // set index + if (isDefined(properties.index) && properties.index !== olLayer.index) { + collection = layerCollection; + group = olLayer.get('group'); + + if (group) { + collection = getGroup(layerCollection, group).getLayers(); + } + + removeLayer(collection, olLayer.index); + insertLayer(collection, properties.index, olLayer); + } + + // set group + if (isDefined(properties.group) && properties.group !== oldProperties.group) { + removeLayerFromGroup(layerCollection, olLayer, oldProperties.group); + addLayerToGroup(layerCollection, olLayer, properties.group); + } + + // set visibility + if (isDefined(oldProperties) && + isBoolean(properties.visible) && + properties.visible !== oldProperties.visible || isNewLayer(olLayer)) { + olLayer.setVisible(properties.visible); + } + + // set style + if (isDefined(properties.style) && + !equals(properties.style, oldProperties.style) || isNewLayer(olLayer)) { + if (!angular.isFunction(properties.style)) { + style = createStyle(properties.style); + } else { + style = properties.style; + } + // not every layer has a setStyle method + if (olLayer.setStyle && angular.isFunction(olLayer.setStyle)) { + olLayer.setStyle(style); + } + } + } + }, true); + }); + } + }; +}); + +angular.module('openlayers-directive').directive('olPath', function($log, $q, olMapDefaults, olHelpers) { + + return { + restrict: 'E', + scope: { + properties: '=olGeomProperties' + }, + require: '^openlayers', + replace: true, + template: '', + + link: function(scope, element, attrs, controller) { + var isDefined = olHelpers.isDefined; + var createFeature = olHelpers.createFeature; + var createOverlay = olHelpers.createOverlay; + var createVectorLayer = olHelpers.createVectorLayer; + var insertLayer = olHelpers.insertLayer; + var removeLayer = olHelpers.removeLayer; + var olScope = controller.getOpenlayersScope(); + + olScope.getMap().then(function(map) { + var mapDefaults = olMapDefaults.getDefaults(olScope); + var viewProjection = mapDefaults.view.projection; + + var layer = createVectorLayer(); + var layerCollection = map.getLayers(); + + insertLayer(layerCollection, layerCollection.getLength(), layer); + + scope.$on('$destroy', function() { + removeLayer(layerCollection, layer.index); + }); + + if (isDefined(attrs.coords)) { + var proj = attrs.proj || 'EPSG:4326'; + var coords = JSON.parse(attrs.coords); + var data = { + type: 'Polygon', + coords: coords, + projection: proj, + style: mapDefaults.styles.path + }; + var feature = createFeature(data, viewProjection); + layer.getSource().addFeature(feature); + + if (attrs.message) { + scope.message = attrs.message; + var extent = feature.getGeometry().getExtent(); + var label = createOverlay(element, extent); + map.addOverlay(label); + } + return; + } + }); + } + }; +}); + +angular.module('openlayers-directive').directive('olView', function($log, $q, olData, olMapDefaults, olHelpers) { + return { + restrict: 'A', + scope: false, + replace: false, + require: 'openlayers', + link: function(scope, element, attrs, controller) { + var olScope = controller.getOpenlayersScope(); + var isNumber = olHelpers.isNumber; + var safeApply = olHelpers.safeApply; + var createView = olHelpers.createView; + + olScope.getMap().then(function(map) { + var defaults = olMapDefaults.getDefaults(olScope); + var view = olScope.view; + + if (!view.projection) { + view.projection = defaults.view.projection; + } + + if (!view.maxZoom) { + view.maxZoom = defaults.view.maxZoom; + } + + if (!view.minZoom) { + view.minZoom = defaults.view.minZoom; + } + + if (!view.rotation) { + view.rotation = defaults.view.rotation; + } + + var mapView = createView(view); + map.setView(mapView); + + olScope.$watchCollection('view', function(view) { + if (isNumber(view.rotation)) { + mapView.setRotation(view.rotation); + } + }); + + mapView.on('change:rotation', function() { + safeApply(olScope, function(scope) { + scope.view.rotation = map.getView().getRotation(); + }); + }); + + }); + } + }; +}); + +angular.module('openlayers-directive').directive('olControl', function($log, $q, olData, olMapDefaults, olHelpers) { + + return { + restrict: 'E', + scope: { + properties: '=olControlProperties' + }, + replace: false, + require: '^openlayers', + link: function(scope, element, attrs, controller) { + var isDefined = olHelpers.isDefined; + var olScope = controller.getOpenlayersScope(); + var olControl; + var olControlOps; + + olScope.getMap().then(function(map) { + var getControlClasses = olHelpers.getControlClasses; + var controlClasses = getControlClasses(); + + scope.$on('$destroy', function() { + map.removeControl(olControl); + }); + + if (!isDefined(scope.properties) || !isDefined(scope.properties.control)) { + if (attrs.name) { + if (isDefined(scope.properties)) { + olControlOps = scope.properties; + } + olControl = new controlClasses[attrs.name](olControlOps); + map.addControl(olControl); + } + return; + } + + olControl = scope.properties.control; + map.addControl(olControl); + }); + } + }; +}); + +angular.module('openlayers-directive').directive('olMarker', function($log, $q, olMapDefaults, olHelpers) { + + var getMarkerDefaults = function() { + return { + projection: 'EPSG:4326', + lat: 0, + lon: 0, + coord: [], + show: true, + showOnMouseOver: false, + showOnMouseClick: false, + keepOneOverlayVisible: false + }; + }; + + var markerLayerManager = (function() { + var mapDict = []; + + function getMapIndex(map) { + return mapDict.map(function(record) { + return record.map; + }).indexOf(map); + } + + return { + getInst: function getMarkerLayerInst(scope, map) { + var mapIndex = getMapIndex(map); + + if (mapIndex === -1) { + var markerLayer = olHelpers.createVectorLayer(); + markerLayer.set('markers', true); + map.addLayer(markerLayer); + mapDict.push({ + map: map, + markerLayer: markerLayer, + instScopes: [] + }); + mapIndex = mapDict.length - 1; + } + + mapDict[mapIndex].instScopes.push(scope); + + return mapDict[mapIndex].markerLayer; + }, + deregisterScope: function deregisterScope(scope, map) { + var mapIndex = getMapIndex(map); + if (mapIndex === -1) { + throw Error('This map has no markers'); + } + + var scopes = mapDict[mapIndex].instScopes; + var scopeIndex = scopes.indexOf(scope); + if (scopeIndex === -1) { + throw Error('Scope wan\'t registered'); + } + + scopes.splice(scopeIndex, 1); + + if (!scopes.length) { + map.removeLayer(mapDict[mapIndex].markerLayer); + delete mapDict[mapIndex]; + } + } + }; + })(); + return { + restrict: 'E', + scope: { + lat: '=lat', + lon: '=lon', + label: '=label', + properties: '=olMarkerProperties', + style: '=olStyle' + }, + transclude: true, + require: '^openlayers', + replace: true, + template: + '', + + link: function(scope, element, attrs, controller) { + var isDefined = olHelpers.isDefined; + var olScope = controller.getOpenlayersScope(); + var createFeature = olHelpers.createFeature; + var createOverlay = olHelpers.createOverlay; + + var hasTranscluded = element.find('ng-transclude').children().length > 0; + + olScope.getMap().then(function(map) { + var markerLayer = markerLayerManager.getInst(scope, map); + var data = getMarkerDefaults(); + + var mapDefaults = olMapDefaults.getDefaults(olScope); + var viewProjection = mapDefaults.view.projection; + var label; + var pos; + var marker; + + // This function handles dragging a marker + var pickOffset = null; + var pickProperties = null; + function handleDrag(evt) { + var coord = evt.coordinate; + var proj = map.getView().getProjection().getCode(); + if (proj === 'pixel') { + coord = coord.map(function(v) { + return parseInt(v, 10); + }); + } else { + coord = ol.proj.transform(coord, proj, 'EPSG:4326'); + } + + if (evt.type === 'pointerdown') { + // Get feature under mouse if any + var feature = map.forEachFeatureAtPixel(evt.pixel, function(feature) { + return feature; + }); + // Get associated marker properties + pickProperties = (feature ? feature.get('marker') : null); + if (!pickProperties || !pickProperties.draggable) { + pickProperties = null; + return; + } + map.getTarget().style.cursor = 'pointer'; + if (proj === 'pixel') { + pickOffset = [coord[0] - pickProperties.coord[0], coord[1] - pickProperties.coord[1]]; + } else { + pickOffset = [coord[0] - pickProperties.lon, coord[1] - pickProperties.lat]; + } + evt.preventDefault(); + } else if (pickOffset && pickProperties) { + if (evt.type === 'pointerup') { + map.getTarget().style.cursor = ''; + pickOffset = null; + pickProperties = null; + evt.preventDefault(); + } else if (evt.type === 'pointerdrag') { + evt.preventDefault(); + scope.$apply(function() { + // Add current delta to marker initial position + if (proj === 'pixel') { + pickProperties.coord[0] = coord[0] - pickOffset[0]; + pickProperties.coord[1] = coord[1] - pickOffset[1]; + } else { + pickProperties.lon = coord[0] - pickOffset[0]; + pickProperties.lat = coord[1] - pickOffset[1]; + } + }); + } + } + } + + // Setup generic handlers for marker drag + map.on('pointerdown', handleDrag); + map.on('pointerup', handleDrag); + map.on('pointerdrag', handleDrag); + + scope.$on('$destroy', function() { + markerLayer.getSource().removeFeature(marker); + if (isDefined(label)) { + map.removeOverlay(label); + } + markerLayerManager.deregisterScope(scope, map); + }); + + if (!isDefined(scope.properties)) { + data.lat = scope.lat ? scope.lat : data.lat; + data.lon = scope.lon ? scope.lon : data.lon; + data.message = attrs.message; + data.style = scope.style ? scope.style : mapDefaults.styles.marker; + + marker = createFeature(data, viewProjection); + if (!isDefined(marker)) { + $log.error('[AngularJS - Openlayers] Received invalid data on ' + + 'the marker.'); + } + // Add a link between the feature and the marker properties + marker.set('marker', scope); + markerLayer.getSource().addFeature(marker); + + if (data.message || hasTranscluded) { + scope.message = attrs.message; + pos = ol.proj.transform([data.lon, data.lat], data.projection, + viewProjection); + label = createOverlay(element, pos); + map.addOverlay(label); + } + return; + } + + scope.$watch('properties', function(properties) { + + // Remove previous listeners if any + map.getViewport().removeEventListener('mousemove', properties.handleInteraction); + map.getViewport().removeEventListener('click', properties.handleTapInteraction); + map.getViewport().querySelector('canvas.ol-unselectable').removeEventListener( + 'touchend', properties.handleTapInteraction); + map.getViewport().removeEventListener('mousemove', properties.showAtLeastOneOverlay); + map.getViewport().removeEventListener('click', properties.removeAllOverlays); + + // This function handles popup on mouse over/click + properties.handleInteraction = function(evt) { + if (properties.label.show) { + return; + } + var found = false; + var pixel = map.getEventPixel(evt); + var feature = map.forEachFeatureAtPixel(pixel, function(feature) { + return feature; + }); + + var actionTaken = false; + if (feature === marker) { + actionTaken = true; + found = true; + if (!isDefined(label)) { + if (data.projection === 'pixel') { + pos = properties.coord; + } else { + pos = ol.proj.transform([properties.lon, properties.lat], + data.projection, viewProjection); + } + label = createOverlay(element, pos); + map.addOverlay(label); + } + + if (properties.onClick && (evt.type === 'click' || evt.type === 'touchend')) { + scope.$apply(function() { + properties.onClick.call(marker, evt, properties); + }); + } + map.getTarget().style.cursor = 'pointer'; + } + + if (!found && label) { + actionTaken = true; + map.removeOverlay(label); + label = undefined; + map.getTarget().style.cursor = ''; + } + + if (actionTaken) { + evt.preventDefault(); + } + }; + + // Made to filter out click/tap events if both are being triggered on this platform + properties.handleTapInteraction = (function() { + var cooldownActive = false; + var prevTimeout; + + // Sets the cooldown flag to filter out any subsequent events within 500 ms + function activateCooldown() { + cooldownActive = true; + if (prevTimeout) { + clearTimeout(prevTimeout); + } + prevTimeout = setTimeout(function() { + cooldownActive = false; + prevTimeout = null; + }, 500); + } + + // Preventing from 'touchend' to be considered a tap, if fired immediately after 'touchmove' + map.getViewport().querySelector('canvas.ol-unselectable').addEventListener( + 'touchmove', activateCooldown); + + return function() { + if (!cooldownActive) { + properties.handleInteraction.apply(null, arguments); + activateCooldown(); + } + }; + })(); + + properties.showAtLeastOneOverlay = function(evt) { + if (properties.label.show) { + return; + } + var found = false; + var pixel = map.getEventPixel(evt); + var feature = map.forEachFeatureAtPixel(pixel, function(feature) { + return feature; + }); + + var actionTaken = false; + if (feature === marker) { + actionTaken = true; + found = true; + if (!isDefined(label)) { + if (data.projection === 'pixel') { + pos = data.coord; + } else { + pos = ol.proj.transform([data.lon, data.lat], + data.projection, viewProjection); + } + label = createOverlay(element, pos); + angular.forEach(map.getOverlays(), function(value) { + map.removeOverlay(value); + }); + map.addOverlay(label); + } + map.getTarget().style.cursor = 'pointer'; + } + + if (!found && label) { + actionTaken = true; + label = undefined; + map.getTarget().style.cursor = ''; + } + + if (actionTaken) { + evt.preventDefault(); + } + }; + + properties.removeAllOverlays = function(evt) { + angular.forEach(map.getOverlays(), function(value) { + map.removeOverlay(value); + }); + evt.preventDefault(); + }; + + if (!isDefined(marker)) { + data.projection = properties.projection ? properties.projection : + data.projection; + data.coord = properties.coord ? properties.coord : data.coord; + data.lat = properties.lat ? properties.lat : data.lat; + data.lon = properties.lon ? properties.lon : data.lon; + + if (isDefined(properties.style)) { + data.style = properties.style; + } else { + data.style = mapDefaults.styles.marker; + } + + marker = createFeature(data, viewProjection); + if (!isDefined(marker)) { + $log.error('[AngularJS - Openlayers] Received invalid data on ' + + 'the marker.'); + } + // Add a link between the feature and the marker properties + marker.set('marker', properties); + markerLayer.getSource().addFeature(marker); + } else { + var requestedPosition; + if (properties.projection === 'pixel') { + requestedPosition = properties.coord; + } else { + requestedPosition = ol.proj.transform([properties.lon, properties.lat], data.projection, + map.getView().getProjection()); + } + + if (!angular.equals(marker.getGeometry().getCoordinates(), requestedPosition)) { + var geometry = new ol.geom.Point(requestedPosition); + marker.setGeometry(geometry); + } + } + + if (isDefined(label)) { + map.removeOverlay(label); + } + + if (!isDefined(properties.label)) { + return; + } + + scope.message = properties.label.message; + if (!hasTranscluded && (!isDefined(scope.message) || scope.message.length === 0)) { + return; + } + + if (properties.label && properties.label.show === true) { + if (data.projection === 'pixel') { + pos = data.coord; + } else { + pos = ol.proj.transform([properties.lon, properties.lat], data.projection, + viewProjection); + } + label = createOverlay(element, pos); + map.addOverlay(label); + } + + if (label && properties.label && properties.label.show === false) { + map.removeOverlay(label); + label = undefined; + } + + // Then setup new ones according to properties + if (properties.label && properties.label.show === false && + properties.label.showOnMouseOver) { + map.getViewport().addEventListener('mousemove', properties.handleInteraction); + } + + if ((properties.label && properties.label.show === false && + properties.label.showOnMouseClick) || + properties.onClick) { + map.getViewport().addEventListener('click', properties.handleTapInteraction); + map.getViewport().querySelector('canvas.ol-unselectable').addEventListener( + 'touchend', properties.handleTapInteraction); + } + + if ((properties.label && properties.label.show === false && + properties.label.keepOneOverlayVisible)) { + map.getViewport().addEventListener('mousemove', properties.showAtLeastOneOverlay); + map.getViewport().addEventListener('click', properties.removeAllOverlays); + } + }, true); + }); + } + }; +}); + +angular.module('openlayers-directive').service('olData', function($log, $q, olHelpers) { + + var obtainEffectiveMapId = olHelpers.obtainEffectiveMapId; + + var maps = {}; + + var setResolvedDefer = function(d, mapId) { + var id = obtainEffectiveMapId(d, mapId); + d[id].resolvedDefer = true; + }; + + var getUnresolvedDefer = function(d, mapId) { + var id = obtainEffectiveMapId(d, mapId); + var defer; + + if (!angular.isDefined(d[id]) || d[id].resolvedDefer === true) { + defer = $q.defer(); + d[id] = { + defer: defer, + resolvedDefer: false + }; + } else { + defer = d[id].defer; + } + return defer; + }; + + var getDefer = function(d, mapId) { + var id = obtainEffectiveMapId(d, mapId); + var defer; + + if (!angular.isDefined(d[id]) || d[id].resolvedDefer === false) { + defer = getUnresolvedDefer(d, mapId); + } else { + defer = d[id].defer; + } + return defer; + }; + + this.setMap = function(olMap, scopeId) { + var defer = getUnresolvedDefer(maps, scopeId); + defer.resolve(olMap); + setResolvedDefer(maps, scopeId); + }; + + this.getMap = function(scopeId) { + var defer = getDefer(maps, scopeId); + return defer.promise; + }; + +}); + +angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $http) { + + var isDefined = function(value) { + return angular.isDefined(value); + }; + + var isDefinedAndNotNull = function(value) { + return angular.isDefined(value) && value !== null; + }; + + var setEvent = function(map, eventType, scope) { + map.on(eventType, function(event) { + var coord = event.coordinate; + var proj = map.getView().getProjection().getCode(); + if (proj === 'pixel') { + coord = coord.map(function(v) { + return parseInt(v, 10); + }); + } + scope.$emit('openlayers.map.' + eventType, { + 'coord': coord, + 'projection': proj, + 'event': event + }); + }); + }; + + var bingImagerySets = [ + 'Road', + 'Aerial', + 'AerialWithLabels', + 'collinsBart', + 'ordnanceSurvey' + ]; + + var getControlClasses = function() { + return { + attribution: ol.control.Attribution, + fullscreen: ol.control.FullScreen, + mouseposition: ol.control.MousePosition, + rotate: ol.control.Rotate, + scaleline: ol.control.ScaleLine, + zoom: ol.control.Zoom, + zoomslider: ol.control.ZoomSlider, + zoomtoextent: ol.control.ZoomToExtent + }; + }; + + var mapQuestLayers = ['osm', 'sat', 'hyb']; + + var esriBaseLayers = ['World_Imagery', 'World_Street_Map', 'World_Topo_Map', + 'World_Physical_Map', 'World_Terrain_Base', + 'Ocean_Basemap', 'NatGeo_World_Map']; + + var styleMap = { + 'style': ol.style.Style, + 'fill': ol.style.Fill, + 'stroke': ol.style.Stroke, + 'circle': ol.style.Circle, + 'icon': ol.style.Icon, + 'image': ol.style.Image, + 'regularshape': ol.style.RegularShape, + 'text': ol.style.Text + }; + + var optionalFactory = function(style, Constructor) { + if (Constructor && style instanceof Constructor) { + return style; + } else if (Constructor) { + return new Constructor(style); + } else { + return style; + } + }; + + //Parse the style tree calling the appropriate constructors. + //The keys in styleMap can be used and the OpenLayers constructors can be + //used directly. + var createStyle = function recursiveStyle(data, styleName) { + var style; + if (!styleName) { + styleName = 'style'; + style = data; + } else { + style = data[styleName]; + } + //Instead of defining one style for the layer, we've been given a style function + //to apply to each feature. + if (styleName === 'style' && data instanceof Function) { + return data; + } + + if (!(style instanceof Object)) { + return style; + } + + var styleObject; + if (Object.prototype.toString.call(style) === '[object Object]') { + styleObject = {}; + var styleConstructor = styleMap[styleName]; + if (styleConstructor && style instanceof styleConstructor) { + return style; + } + Object.getOwnPropertyNames(style).forEach(function(val, idx, array) { + //Consider the case + //image: { + // circle: { + // fill: { + // color: 'red' + // } + // } + // + //An ol.style.Circle is an instance of ol.style.Image, so we do not want to construct + //an Image and then construct a Circle. We assume that if we have an instanceof + //relationship, that the JSON parent has exactly one child. + //We check to see if an inheritance relationship exists. + //If it does, then for the parent we create an instance of the child. + var valConstructor = styleMap[val]; + if (styleConstructor && valConstructor && + valConstructor.prototype instanceof styleMap[styleName]) { + console.assert(array.length === 1, 'Extra parameters for ' + styleName); + styleObject = recursiveStyle(style, val); + return optionalFactory(styleObject, valConstructor); + } else { + styleObject[val] = recursiveStyle(style, val); + + // if the value is 'text' and it contains a String, then it should be interpreted + // as such, 'cause the text style might effectively contain a text to display + if (val !== 'text' && typeof styleObject[val] !== 'string') { + styleObject[val] = optionalFactory(styleObject[val], styleMap[val]); + } + } + }); + } else { + styleObject = style; + } + return optionalFactory(styleObject, styleMap[styleName]); + }; + + var detectLayerType = function(layer) { + if (layer.type) { + return layer.type; + } else { + switch (layer.source.type) { + case 'ImageWMS': + return 'Image'; + case 'ImageStatic': + return 'Image'; + case 'GeoJSON': + case 'JSONP': + case 'TopoJSON': + case 'KML': + case 'TileVector': + return 'Vector'; + default: + return 'Tile'; + } + } + }; + + var createProjection = function(view) { + var oProjection; + + switch (view.projection) { + case 'pixel': + if (!isDefined(view.extent)) { + $log.error('[AngularJS - Openlayers] - You must provide the extent of the image ' + + 'if using pixel projection'); + return; + } + oProjection = new ol.proj.Projection({ + code: 'pixel', + units: 'pixels', + extent: view.extent + }); + break; + default: + oProjection = new ol.proj.get(view.projection); + break; + } + + return oProjection; + }; + + var isValidStamenLayer = function(layer) { + return ['watercolor', 'terrain', 'toner'].indexOf(layer) !== -1; + }; + + var createSource = function(source, projection) { + var oSource; + + switch (source.type) { + case 'MapBox': + if (!source.mapId || !source.accessToken) { + $log.error('[AngularJS - Openlayers] - MapBox layer requires the map id and the access token'); + return; + } + var url = 'http://api.tiles.mapbox.com/v4/' + source.mapId + '/{z}/{x}/{y}.png?access_token=' + + source.accessToken; + + var pixelRatio = window.devicePixelRatio; + + if (pixelRatio > 1) { + url = url.replace('.png', '@2x.png'); + } + + oSource = new ol.source.XYZ({ + url: url, + attributions: createAttribution(source), + tilePixelRatio: pixelRatio > 1 ? 2 : 1, + wrapX: (source.wrapX === true) ? 1 : 0 + }); + break; + case 'ImageWMS': + if (!source.url || !source.params) { + $log.error('[AngularJS - Openlayers] - ImageWMS Layer needs ' + + 'valid server url and params properties'); + } + oSource = new ol.source.ImageWMS({ + url: source.url, + attributions: createAttribution(source), + crossOrigin: (typeof source.crossOrigin === 'undefined') ? 'anonymous' : source.crossOrigin, + params: source.params, + wrapX: source.wrapX ? 0 : 1 + }); + break; + + case 'TileWMS': + if ((!source.url && !source.urls) || !source.params) { + $log.error('[AngularJS - Openlayers] - TileWMS Layer needs ' + + 'valid url (or urls) and params properties'); + } + + var wmsConfiguration = { + crossOrigin: (typeof source.crossOrigin === 'undefined') ? 'anonymous' : source.crossOrigin, + params: source.params, + attributions: createAttribution(source), + wrapX: source.wrapX ? 0 : 1 + }; + + if (source.url) { + wmsConfiguration.url = source.url; + } + + if (source.urls) { + wmsConfiguration.urls = source.urls; + } + + oSource = new ol.source.TileWMS(wmsConfiguration); + break; + + case 'WMTS': + if ((!source.url && !source.urls) || !source.tileGrid) { + $log.error('[AngularJS - Openlayers] - WMTS Layer needs valid url ' + + '(or urls) and tileGrid properties'); + } + + var wmtsConfiguration = { + projection: projection, + layer: source.layer, + attributions: createAttribution(source), + matrixSet: (source.matrixSet === 'undefined') ? projection : source.matrixSet, + format: (source.format === 'undefined') ? 'image/jpeg' : source.format, + requestEncoding: (source.requestEncoding === 'undefined') ? + 'KVP' : source.requestEncoding, + tileGrid: new ol.tilegrid.WMTS({ + origin: source.tileGrid.origin, + resolutions: source.tileGrid.resolutions, + matrixIds: source.tileGrid.matrixIds + }), + wrapX: source.wrapX ? 0 : 1 + }; + + if (isDefined(source.url)) { + wmtsConfiguration.url = source.url; + } + + if (isDefined(source.urls)) { + wmtsConfiguration.urls = source.urls; + } + + oSource = new ol.source.WMTS(wmtsConfiguration); + break; + + case 'OSM': + oSource = new ol.source.OSM({ + attributions: createAttribution(source), + wrapX: (source.wrapX === true) ? 1 : 0 + }); + + if (source.url) { + oSource.setUrl(source.url); + } + + break; + case 'BingMaps': + if (!source.key) { + $log.error('[AngularJS - Openlayers] - You need an API key to show the Bing Maps.'); + return; + } + + var bingConfiguration = { + key: source.key, + attributions: createAttribution(source), + imagerySet: source.imagerySet ? source.imagerySet : bingImagerySets[0], + culture: source.culture, + wrapX: (source.wrapX === true) ? 1 : 0 + }; + + if (source.maxZoom) { + bingConfiguration.maxZoom = source.maxZoom; + } + + oSource = new ol.source.BingMaps(bingConfiguration); + break; + + case 'MapQuest': + if (!source.layer || mapQuestLayers.indexOf(source.layer) === -1) { + $log.error('[AngularJS - Openlayers] - MapQuest layers needs a valid \'layer\' property.'); + return; + } + + oSource = new ol.source.MapQuest({ + attributions: createAttribution(source), + layer: source.layer, + wrapX: (source.wrapX === true) ? 1 : 0 + }); + + break; + + case 'EsriBaseMaps': + if (!source.layer || esriBaseLayers.indexOf(source.layer) === -1) { + $log.error('[AngularJS - Openlayers] - ESRI layers needs a valid \'layer\' property.'); + return; + } + + var _urlBase = 'http://services.arcgisonline.com/ArcGIS/rest/services/'; + var _url = _urlBase + source.layer + '/MapServer/tile/{z}/{y}/{x}'; + + oSource = new ol.source.XYZ({ + attributions: createAttribution(source), + url: _url, + wrapX: (source.wrapX === true) ? 1 : 0 + }); + + break; + + case 'GeoJSON': + if (!(source.geojson || source.url)) { + $log.error('[AngularJS - Openlayers] - You need a geojson ' + + 'property to add a GeoJSON layer.'); + return; + } + + if (isDefined(source.url)) { + oSource = new ol.source.Vector({ + format: new ol.format.GeoJSON(), + url: source.url, + wrapX: (source.wrapX === true) ? 1 : 0 + }); + } else { + oSource = new ol.source.Vector(); + + var projectionToUse = projection; + if (isDefined(source.geojson.projection)) { + projectionToUse = source.geojson.projection; + } + + var geojsonFormat = new ol.format.GeoJSON(); + var features = geojsonFormat.readFeatures( + source.geojson.object, { featureProjection: projectionToUse }); + + oSource.addFeatures(features); + } + + break; + case 'JSONP': + if (!(source.url)) { + $log.error('[AngularJS - Openlayers] - You need an url properly configured to add a JSONP layer.'); + return; + } + + if (isDefined(source.url)) { + oSource = new ol.source.Vector({ + format: new ol.format.GeoJSON(), + loader: function(/*extent, resolution, projection*/) { + var url = source.url + + '&outputFormat=text/javascript&format_options=callback:JSON_CALLBACK'; + $http.jsonp(url, { cache: source.cache}).success(function(response) { + oSource.addFeatures(oSource.readFeatures(response)); + }).error(function(response) { + $log(response); + }); + }, + wrapX: (source.wrapX === true) ? 1 : 0 + }); + } + break; + case 'TopoJSON': + if (!(source.topojson || source.url)) { + $log.error('[AngularJS - Openlayers] - You need a topojson ' + + 'property to add a TopoJSON layer.'); + return; + } + + if (source.url) { + oSource = new ol.source.Vector({ + format: new ol.format.TopoJSON(), + url: source.url, + wrapX: (source.wrapX === true) ? 1 : 0 + }); + } else { + oSource = new ol.source.Vector(angular.extend(source.topojson, { + format: new ol.format.TopoJSON(), + wrapX: (source.wrapX === true) ? 1 : 0 + })); + } + break; + case 'TileJSON': + oSource = new ol.source.TileJSON({ + url: source.url, + attributions: createAttribution(source), + crossOrigin: 'anonymous', + wrapX: (source.wrapX === true) ? 1 : 0 + }); + break; + + case 'TileVector': + if (!source.url || !source.format) { + $log.error('[AngularJS - Openlayers] - TileVector Layer needs valid url and format properties'); + } + oSource = new ol.source.TileVector({ + url: source.url, + projection: projection, + attributions: createAttribution(source), + format: source.format, + tileGrid: new ol.tilegrid.createXYZ({ + maxZoom: source.maxZoom || 19 + }), + wrapX: (source.wrapX === true) ? 1 : 0 + }); + break; + + case 'TileTMS': + if (!source.url || !source.tileGrid) { + $log.error('[AngularJS - Openlayers] - TileTMS Layer needs valid url and tileGrid properties'); + } + oSource = new ol.source.TileImage({ + url: source.url, + maxExtent: source.maxExtent, + attributions: createAttribution(source), + tileGrid: new ol.tilegrid.TileGrid({ + origin: source.tileGrid.origin, + resolutions: source.tileGrid.resolutions + }), + tileUrlFunction: function(tileCoord) { + + var z = tileCoord[0]; + var x = tileCoord[1]; + var y = tileCoord[2]; //(1 << z) - tileCoord[2] - 1; + + if (x < 0 || y < 0) { + return ''; + } + + var url = source.url + z + '/' + x + '/' + y + '.png'; + + return url; + }, + wrapX: (source.wrapX === true) ? 1 : 0 + }); + break; + case 'TileImage': + oSource = new ol.source.TileImage({ + url: source.url, + attributions: createAttribution(source), + tileGrid: new ol.tilegrid.TileGrid({ + origin: source.tileGrid.origin, // top left corner of the pixel projection's extent + resolutions: source.tileGrid.resolutions + }), + tileUrlFunction: function(tileCoord/*, pixelRatio, projection*/) { + var z = tileCoord[0]; + var x = tileCoord[1]; + var y = -tileCoord[2] - 1; + var url = source.url + .replace('{z}', z.toString()) + .replace('{x}', x.toString()) + .replace('{y}', y.toString()); + return url; + }, + wrapX: (source.wrapX === true) ? 1 : 0 + }); + break; + case 'KML': + var extractStyles = source.extractStyles || false; + oSource = new ol.source.Vector({ + url: source.url, + format: new ol.format.KML(), + radius: source.radius, + extractStyles: extractStyles, + wrapX: (source.wrapX === true) ? 1 : 0 + }); + break; + case 'Stamen': + if (!source.layer || !isValidStamenLayer(source.layer)) { + $log.error('[AngularJS - Openlayers] - You need a valid Stamen layer.'); + return; + } + oSource = new ol.source.Stamen({ + layer: source.layer, + wrapX: (source.wrapX === true) ? 1 : 0 + }); + break; + case 'ImageStatic': + if (!source.url || !angular.isArray(source.imageSize) || source.imageSize.length !== 2) { + $log.error('[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.'); + return; + } + + oSource = new ol.source.ImageStatic({ + url: source.url, + attributions: createAttribution(source), + imageSize: source.imageSize, + projection: projection, + imageExtent: projection.getExtent(), + imageLoadFunction: source.imageLoadFunction, + wrapX: (source.wrapX === true) ? 1 : 0 + }); + break; + case 'XYZ': + if (!source.url) { + $log.error('[AngularJS - Openlayers] - XYZ Layer needs valid url and params properties'); + } + oSource = new ol.source.XYZ({ + url: source.url, + attributions: createAttribution(source), + minZoom: source.minZoom, + maxZoom: source.maxZoom, + wrapX: (source.wrapX === true) ? 1 : 0 + }); + break; + } + + // log a warning when no source could be created for the given type + if (!oSource) { + $log.warn('[AngularJS - Openlayers] - No source could be found for type "' + source.type + '"'); + } + + return oSource; + }; + + var createAttribution = function(source) { + var attributions = []; + if (isDefined(source.attribution)) { + attributions.unshift(new ol.Attribution({html: source.attribution})); + } + return attributions; + }; + + var createGroup = function(name) { + var olGroup = new ol.layer.Group(); + olGroup.set('name', name); + + return olGroup; + }; + + var getGroup = function(layers, name) { + var layer; + + angular.forEach(layers, function(l) { + if (l instanceof ol.layer.Group && l.get('name') === name) { + layer = l; + return; + } + }); + + return layer; + }; + + var addLayerBeforeMarkers = function(layers, layer) { + var markersIndex; + for (var i = 0; i < layers.getLength(); i++) { + var l = layers.item(i); + + if (l.get('markers')) { + markersIndex = i; + break; + } + } + + if (isDefined(markersIndex)) { + var markers = layers.item(markersIndex); + layer.index = markersIndex; + layers.setAt(markersIndex, layer); + markers.index = layers.getLength(); + layers.push(markers); + } else { + layer.index = layers.getLength(); + layers.push(layer); + } + + }; + + var removeLayer = function(layers, index) { + layers.removeAt(index); + for (var i = index; i < layers.getLength(); i++) { + var l = layers.item(i); + if (l === null) { + layers.insertAt(i, null); + break; + } else { + l.index = i; + } + } + }; + + return { + // Determine if a reference is defined + isDefined: isDefined, + + // Determine if a reference is a number + isNumber: function(value) { + return angular.isNumber(value); + }, + + createView: function(view) { + var projection = createProjection(view); + + return new ol.View({ + projection: projection, + maxZoom: view.maxZoom, + minZoom: view.minZoom, + extent: view.extent + }); + }, + + // Determine if a reference is defined and not null + isDefinedAndNotNull: isDefinedAndNotNull, + + // Determine if a reference is a string + isString: function(value) { + return angular.isString(value); + }, + + // Determine if a reference is an array + isArray: function(value) { + return angular.isArray(value); + }, + + // Determine if a reference is an object + isObject: function(value) { + return angular.isObject(value); + }, + + // Determine if two objects have the same properties + equals: function(o1, o2) { + return angular.equals(o1, o2); + }, + + isValidCenter: function(center) { + return angular.isDefined(center) && + (typeof center.autodiscover === 'boolean' || + angular.isNumber(center.lat) && angular.isNumber(center.lon) || + (angular.isArray(center.coord) && center.coord.length === 2 && + angular.isNumber(center.coord[0]) && angular.isNumber(center.coord[1])) || + (angular.isArray(center.bounds) && center.bounds.length === 4 && + angular.isNumber(center.bounds[0]) && angular.isNumber(center.bounds[1]) && + angular.isNumber(center.bounds[1]) && angular.isNumber(center.bounds[2]))); + }, + + safeApply: function($scope, fn) { + var phase = $scope.$root.$$phase; + if (phase === '$apply' || phase === '$digest') { + $scope.$eval(fn); + } else { + $scope.$apply(fn); + } + }, + + isSameCenterOnMap: function(center, map) { + var urlProj = center.projection || 'EPSG:4326'; + var urlCenter = [center.lon, center.lat]; + var mapProj = map.getView().getProjection(); + var mapCenter = ol.proj.transform(map.getView().getCenter(), mapProj, urlProj); + var zoom = map.getView().getZoom(); + if (mapCenter[1].toFixed(4) === urlCenter[1].toFixed(4) && + mapCenter[0].toFixed(4) === urlCenter[0].toFixed(4) && + zoom === center.zoom) { + return true; + } + return false; + }, + + setCenter: function(view, projection, newCenter, map) { + + if (map && view.getCenter()) { + var pan = ol.animation.pan({ + duration: 150, + source: (view.getCenter()) + }); + map.beforeRender(pan); + } + + if (newCenter.projection === projection) { + view.setCenter([newCenter.lon, newCenter.lat]); + } else { + var coord = [newCenter.lon, newCenter.lat]; + view.setCenter(ol.proj.transform(coord, newCenter.projection, projection)); + } + }, + + setZoom: function(view, zoom, map) { + var z = ol.animation.zoom({ + duration: 150, + resolution: map.getView().getResolution() + }); + map.beforeRender(z); + view.setZoom(zoom); + }, + + isBoolean: function(value) { + return typeof value === 'boolean'; + }, + + obtainEffectiveMapId: function(d, mapId) { + var id; + var i; + if (!angular.isDefined(mapId)) { + if (Object.keys(d).length === 1) { + for (i in d) { + if (d.hasOwnProperty(i)) { + id = i; + } + } + } else if (Object.keys(d).length === 0) { + id = 'main'; + } else { + $log.error('[AngularJS - Openlayers] - You have more than 1 map on the DOM, ' + + 'you must provide the map ID to the olData.getXXX call'); + } + } else { + id = mapId; + } + return id; + }, + + createStyle: createStyle, + + setMapEvents: function(events, map, scope) { + if (isDefined(events) && angular.isArray(events.map)) { + for (var i in events.map) { + var event = events.map[i]; + setEvent(map, event, scope); + } + } + }, + + setVectorLayerEvents: function(events, map, scope, layerName) { + if (isDefined(events) && angular.isArray(events.layers)) { + angular.forEach(events.layers, function(eventType) { + angular.element(map.getViewport()).on(eventType, function(evt) { + var pixel = map.getEventPixel(evt); + var feature = map.forEachFeatureAtPixel(pixel, function(feature, olLayer) { + // only return the feature if it is in this layer (based on the name) + return (isDefinedAndNotNull(olLayer) && olLayer.get('name') === layerName) ? feature : null; + }); + if (isDefinedAndNotNull(feature)) { + scope.$emit('openlayers.layers.' + layerName + '.' + eventType, feature, evt); + } + }); + }); + } + }, + + setViewEvents: function(events, map, scope) { + if (isDefined(events) && angular.isArray(events.view)) { + var view = map.getView(); + angular.forEach(events.view, function(eventType) { + view.on(eventType, function(event) { + scope.$emit('openlayers.view.' + eventType, view, event); + }); + }); + } + }, + + detectLayerType: detectLayerType, + + createLayer: function(layer, projection, name) { + var oLayer; + var type = detectLayerType(layer); + var oSource = createSource(layer.source, projection); + if (!oSource) { + return; + } + + // Manage clustering + if ((type === 'Vector') && layer.clustering) { + oSource = new ol.source.Cluster({ + source: oSource, + distance: layer.clusteringDistance, + }); + } + + switch (type) { + case 'Image': + oLayer = new ol.layer.Image({ source: oSource }); + break; + case 'Tile': + oLayer = new ol.layer.Tile({ source: oSource }); + break; + case 'Heatmap': + oLayer = new ol.layer.Heatmap({ source: oSource }); + break; + case 'Vector': + oLayer = new ol.layer.Vector({ source: oSource }); + break; + } + + // set a layer name if given + if (isDefined(name)) { + oLayer.set('name', name); + } else if (isDefined(layer.name)) { + oLayer.set('name', layer.name); + } + + return oLayer; + }, + + createVectorLayer: function() { + return new ol.layer.Vector({ + source: new ol.source.Vector() + }); + }, + + notifyCenterUrlHashChanged: function(scope, center, search) { + if (center.centerUrlHash) { + var centerUrlHash = center.lat.toFixed(4) + ':' + center.lon.toFixed(4) + ':' + center.zoom; + if (!isDefined(search.c) || search.c !== centerUrlHash) { + scope.$emit('centerUrlHash', centerUrlHash); + } + } + }, + + getControlClasses: getControlClasses, + + detectControls: function(controls) { + var actualControls = {}; + var controlClasses = getControlClasses(); + + controls.forEach(function(control) { + for (var i in controlClasses) { + if (control instanceof controlClasses[i]) { + actualControls[i] = control; + } + } + }); + + return actualControls; + }, + + createFeature: function(data, viewProjection) { + var geometry; + + switch (data.type) { + case 'Polygon': + geometry = new ol.geom.Polygon(data.coords); + break; + default: + if (isDefined(data.coord) && data.projection === 'pixel') { + geometry = new ol.geom.Point(data.coord); + } else { + geometry = new ol.geom.Point([data.lon, data.lat]); + } + break; + } + + if (isDefined(data.projection) && data.projection !== 'pixel') { + geometry = geometry.transform(data.projection, viewProjection); + } + + var feature = new ol.Feature({ + geometry: geometry + }); + + if (isDefined(data.style)) { + var style = createStyle(data.style); + feature.setStyle(style); + } + return feature; + }, + + addLayerBeforeMarkers: addLayerBeforeMarkers, + + getGroup: getGroup, + + addLayerToGroup: function(layers, layer, name) { + var groupLayer = getGroup(layers, name); + + if (!isDefined(groupLayer)) { + groupLayer = createGroup(name); + addLayerBeforeMarkers(layers,groupLayer); + } + + layer.set('group', name); + addLayerBeforeMarkers(groupLayer.getLayers(), layer); + }, + + removeLayerFromGroup: function(layers, layer, name) { + var groupLayer = getGroup(layers, name); + layer.set('group'); + removeLayer(groupLayer.getLayers(), layer.index); + }, + + removeLayer: removeLayer, + + insertLayer: function(layers, index, layer) { + if (layers.getLength() < index) { + while (layers.getLength() < index) { + layers.push(null); + } + layer.index = index; + layers.push(layer); + } else { + layer.index = index; + layers.insertAt(layer.index, layer); + for (var i = index + 1; i < layers.getLength(); i++) { + var l = layers.item(i); + if (l === null) { + layers.removeAt(i); + break; + } else { + l.index = i; + } + } + } + }, + + createOverlay: function(element, pos) { + element.css('display', 'block'); + var ov = new ol.Overlay({ + position: pos, + element: element, + positioning: 'center-left' + }); + + return ov; + } + }; +}); + +angular.module('openlayers-directive').factory('olMapDefaults', function($q, olHelpers) { + + var base64icon = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAApCAYAAADAk4LOAAAGmklEQVRYw' + + '7VXeUyTZxjvNnfELFuyIzOabermMZEeQC/OclkO49CpOHXOLJl/CAURuYbQi3KLgEhbrhZ1aDwmaoGq' + + 'KII6odATmH/scDFbdC7LvFqOCc+e95s2VG50X/LLm/f4/Z7neY/ne18aANCmAr5E/xZf1uDOkTcGcWR' + + '6hl9247tT5U7Y6SNvWsKT63P58qbfeLJG8M5qcgTknrvvrdDbsT7Ml+tv82X6vVxJE33aRmgSyYtcWV' + + 'MqX97Yv2JvW39UhRE2HuyBL+t+gK1116ly06EeWFNlAmHxlQE0OMiV6mQCScusKRlhS3QLeVJdl1+23' + + 'h5dY4FNB3thrbYboqptEFlphTC1hSpJnbRvxP4NWgsE5Jyz86QNNi/5qSUTGuFk1gu54tN9wuK2wc3o' + + '+Wc13RCmsoBwEqzGcZsxsvCSy/9wJKf7UWf1mEY8JWfewc67UUoDbDjQC+FqK4QqLVMGGR9d2wurKzq' + + 'Bk3nqIT/9zLxRRjgZ9bqQgub+DdoeCC03Q8j+0QhFhBHR/eP3U/zCln7Uu+hihJ1+bBNffLIvmkyP0g' + + 'pBZWYXhKussK6mBz5HT6M1Nqpcp+mBCPXosYQfrekGvrjewd59/GvKCE7TbK/04/ZV5QZYVWmDwH1mF' + + '3xa2Q3ra3DBC5vBT1oP7PTj4C0+CcL8c7C2CtejqhuCnuIQHaKHzvcRfZpnylFfXsYJx3pNLwhKzRAw' + + 'AhEqG0SpusBHfAKkxw3w4627MPhoCH798z7s0ZnBJ/MEJbZSbXPhER2ih7p2ok/zSj2cEJDd4CAe+5W' + + 'YnBCgR2uruyEw6zRoW6/DWJ/OeAP8pd/BGtzOZKpG8oke0SX6GMmRk6GFlyAc59K32OTEinILRJRcha' + + 'h8HQwND8N435Z9Z0FY1EqtxUg+0SO6RJ/mmXz4VuS+DpxXC3gXmZwIL7dBSH4zKE50wESf8qwVgrP1E' + + 'IlTO5JP9Igu0aexdh28F1lmAEGJGfh7jE6ElyM5Rw/FDcYJjWhbeiBYoYNIpc2FT/SILivp0F1ipDWk' + + '4BIEo2VuodEJUifhbiltnNBIXPUFCMpthtAyqws/BPlEF/VbaIxErdxPphsU7rcCp8DohC+GvBIPJS/' + + 'tW2jtvTmmAeuNO8BNOYQeG8G/2OzCJ3q+soYB5i6NhMaKr17FSal7GIHheuV3uSCY8qYVuEm1cOzqdW' + + 'r7ku/R0BDoTT+DT+ohCM6/CCvKLKO4RI+dXPeAuaMqksaKrZ7L3FE5FIFbkIceeOZ2OcHO6wIhTkNo0' + + 'ffgjRGxEqogXHYUPHfWAC/lADpwGcLRY3aeK4/oRGCKYcZXPVoeX/kelVYY8dUGf8V5EBRbgJXT5QIP' + + 'hP9ePJi428JKOiEYhYXFBqou2Guh+p/mEB1/RfMw6rY7cxcjTrneI1FrDyuzUSRm9miwEJx8E/gUmql' + + 'yvHGkneiwErR21F3tNOK5Tf0yXaT+O7DgCvALTUBXdM4YhC/IawPU+2PduqMvuaR6eoxSwUk75ggqsY' + + 'J7VicsnwGIkZBSXKOUww73WGXyqP+J2/b9c+gi1YAg/xpwck3gJuucNrh5JvDPvQr0WFXf0piyt8f8/' + + 'WI0hV4pRxxkQZdJDfDJNOAmM0Ag8jyT6hz0WGXWuP94Yh2jcfjmXAGvHCMslRimDHYuHuDsy2QtHuIa' + + 'vznhbYURq5R57KpzBBRZKPJi8eQg48h4j8SDdowifdIrEVdU+gbO6QNvRRt4ZBthUaZhUnjlYObNagV' + + '3keoeru3rU7rcuceqU1mJBxy+BWZYlNEBH+0eH4vRiB+OYybU2hnblYlTvkHinM4m54YnxSyaZYSF6R' + + '3jwgP7udKLGIX6r/lbNa9N6y5MFynjWDtrHd75ZvTYAPO/6RgF0k76mQla3FGq7dO+cH8sKn0Vo7nDl' + + 'lwAhqwLPkxrHwWmHJOo+AKJ4rab5OgrM7rVu8eWb2Pu0Dh4eDgXoOfvp7Y7QeqknRmvcTBEyq9m/HQQ' + + 'SCSz6LHq3z0yzsNySRfMS253wl2KyRDbcZPcfJKjZmSEOjcxyi+Y8dUOtsIEH6R2wNykdqrkYJ0RV92' + + 'H0W58pkfQk7cKevsLK10Py8SdMGfXNXATY+pPbyJR/ET6n9nIfztNtZYRV9XniQu9IA2vOVgy4ir7GC' + + 'LVmmd+zjkH0eAF9Po6K61pmCXHxU5rHMYd1ftc3owjwRSVRzLjKvqZEty6cRUD7jGqiOdu5HG6MdHjN' + + 'cNYGqfDm5YRzLBBCCDl/2bk8a8gdbqcfwECu62Fg/HrggAAAABJRU5ErkJggg=='; + + var _getDefaults = function() { + return { + view: { + projection: 'EPSG:3857', + minZoom: undefined, + maxZoom: undefined, + rotation: 0, + extent: undefined + }, + center: { + lat: 0, + lon: 0, + zoom: 1, + autodiscover: false, + bounds: [], + centerUrlHash: false, + projection: 'EPSG:4326' + }, + styles: { + path: { + stroke: { + color: 'blue', + width: 8 + } + }, + marker: { + image: new ol.style.Icon({ + anchor: [0.5, 1], + anchorXUnits: 'fraction', + anchorYUnits: 'fraction', + opacity: 0.90, + src: base64icon + }) + } + }, + events: { + map: [], + markers: [], + layers: [] + }, + controls: { + attribution: true, + rotate: false, + zoom: true + }, + interactions: { + mouseWheelZoom: false + }, + renderer: 'canvas' + }; + }; + + var isDefined = olHelpers.isDefined; + var defaults = {}; + + // Get the _defaults dictionary, and override the properties defined by the user + return { + getDefaults: function(scope) { + if (!isDefined(scope)) { + for (var i in defaults) { + return defaults[i]; + } + } + return defaults[scope.$id]; + }, + + setDefaults: function(scope) { + var userDefaults = scope.defaults; + var scopeId = scope.$id; + var newDefaults = _getDefaults(); + + if (isDefined(userDefaults)) { + + if (isDefined(userDefaults.layers)) { + newDefaults.layers = angular.copy(userDefaults.layers); + } + + if (isDefined(userDefaults.controls)) { + newDefaults.controls = angular.copy(userDefaults.controls); + } + + if (isDefined(userDefaults.events)) { + newDefaults.events = angular.copy(userDefaults.events); + } + + if (isDefined(userDefaults.interactions)) { + newDefaults.interactions = angular.copy(userDefaults.interactions); + } + + if (isDefined(userDefaults.renderer)) { + newDefaults.renderer = userDefaults.renderer; + } + + if (isDefined(userDefaults.view)) { + newDefaults.view.maxZoom = userDefaults.view.maxZoom || newDefaults.view.maxZoom; + newDefaults.view.minZoom = userDefaults.view.minZoom || newDefaults.view.minZoom; + newDefaults.view.projection = userDefaults.view.projection || newDefaults.view.projection; + newDefaults.view.extent = userDefaults.view.extent || newDefaults.view.extent; + } + + if (isDefined(userDefaults.styles)) { + newDefaults.styles = angular.extend(newDefaults.styles, userDefaults.styles); + } + + } + + defaults[scopeId] = newDefaults; + return newDefaults; + } + }; +}); + +})); \ No newline at end of file diff --git a/src/services/olHelpers.js b/src/services/olHelpers.js index 5a27733a..f53faeb5 100644 --- a/src/services/olHelpers.js +++ b/src/services/olHelpers.js @@ -208,7 +208,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ url: url, attributions: createAttribution(source), tilePixelRatio: pixelRatio > 1 ? 2 : 1, - wrapX: source.wrapX ? source.wrapX : true + wrapX: (source.wrapX === true) ? 1 : 0 }); break; case 'ImageWMS': @@ -221,7 +221,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ attributions: createAttribution(source), crossOrigin: (typeof source.crossOrigin === 'undefined') ? 'anonymous' : source.crossOrigin, params: source.params, - wrapX: source.wrapX ? source.wrapX : true + wrapX: source.wrapX ? 0 : 1 }); break; @@ -235,7 +235,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ crossOrigin: (typeof source.crossOrigin === 'undefined') ? 'anonymous' : source.crossOrigin, params: source.params, attributions: createAttribution(source), - wrapX: source.wrapX ? source.wrapX : true + wrapX: source.wrapX ? 0 : 1 }; if (source.url) { @@ -268,7 +268,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ resolutions: source.tileGrid.resolutions, matrixIds: source.tileGrid.matrixIds }), - wrapX: source.wrapX ? source.wrapX : true + wrapX: source.wrapX ? 0 : 1 }; if (isDefined(source.url)) { @@ -285,7 +285,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ case 'OSM': oSource = new ol.source.OSM({ attributions: createAttribution(source), - wrapX: source.wrapX ? source.wrapX : true + wrapX: (source.wrapX === true) ? 1 : 0 }); if (source.url) { @@ -304,7 +304,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ attributions: createAttribution(source), imagerySet: source.imagerySet ? source.imagerySet : bingImagerySets[0], culture: source.culture, - wrapX: source.wrapX ? source.wrapX : true + wrapX: (source.wrapX === true) ? 1 : 0 }; if (source.maxZoom) { @@ -323,7 +323,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ oSource = new ol.source.MapQuest({ attributions: createAttribution(source), layer: source.layer, - wrapX: source.wrapX ? source.wrapX : true + wrapX: (source.wrapX === true) ? 1 : 0 }); break; @@ -340,7 +340,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ oSource = new ol.source.XYZ({ attributions: createAttribution(source), url: _url, - wrapX: source.wrapX ? source.wrapX : true + wrapX: (source.wrapX === true) ? 1 : 0 }); break; @@ -356,7 +356,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ oSource = new ol.source.Vector({ format: new ol.format.GeoJSON(), url: source.url, - wrapX: source.wrapX ? source.wrapX : true + wrapX: (source.wrapX === true) ? 1 : 0 }); } else { oSource = new ol.source.Vector(); @@ -392,7 +392,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ $log(response); }); }, - wrapX: source.wrapX ? source.wrapX : true + wrapX: (source.wrapX === true) ? 1 : 0 }); } break; @@ -407,12 +407,12 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ oSource = new ol.source.Vector({ format: new ol.format.TopoJSON(), url: source.url, - wrapX: source.wrapX ? source.wrapX : true + wrapX: (source.wrapX === true) ? 1 : 0 }); } else { oSource = new ol.source.Vector(angular.extend(source.topojson, { format: new ol.format.TopoJSON(), - wrapX: source.wrapX ? source.wrapX : true + wrapX: (source.wrapX === true) ? 1 : 0 })); } break; @@ -421,7 +421,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ url: source.url, attributions: createAttribution(source), crossOrigin: 'anonymous', - wrapX: source.wrapX ? source.wrapX : true + wrapX: (source.wrapX === true) ? 1 : 0 }); break; @@ -437,7 +437,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ tileGrid: new ol.tilegrid.createXYZ({ maxZoom: source.maxZoom || 19 }), - wrapX: source.wrapX ? source.wrapX : true + wrapX: (source.wrapX === true) ? 1 : 0 }); break; @@ -467,7 +467,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ return url; }, - wrapX: source.wrapX ? source.wrapX : true + wrapX: (source.wrapX === true) ? 1 : 0 }); break; case 'TileImage': @@ -488,7 +488,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ .replace('{y}', y.toString()); return url; }, - wrapX: source.wrapX ? source.wrapX : true + wrapX: (source.wrapX === true) ? 1 : 0 }); break; case 'KML': @@ -498,7 +498,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ format: new ol.format.KML(), radius: source.radius, extractStyles: extractStyles, - wrapX: source.wrapX ? source.wrapX : true + wrapX: (source.wrapX === true) ? 1 : 0 }); break; case 'Stamen': @@ -508,7 +508,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ } oSource = new ol.source.Stamen({ layer: source.layer, - wrapX: source.wrapX ? source.wrapX : true + wrapX: (source.wrapX === true) ? 1 : 0 }); break; case 'ImageStatic': @@ -524,7 +524,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ projection: projection, imageExtent: projection.getExtent(), imageLoadFunction: source.imageLoadFunction, - wrapX: source.wrapX ? source.wrapX : true + wrapX: (source.wrapX === true) ? 1 : 0 }); break; case 'XYZ': @@ -536,7 +536,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ attributions: createAttribution(source), minZoom: source.minZoom, maxZoom: source.maxZoom, - wrapX: source.wrapX ? source.wrapX : true + wrapX: (source.wrapX === true) ? 1 : 0 }); break; } From 13b697fe0a080024b79fee0857315cb74db6b3ae Mon Sep 17 00:00:00 2001 From: Tirumala Dilip Kumar Date: Fri, 6 Nov 2015 15:25:24 +0530 Subject: [PATCH 03/53] added dist/ to .gitignore to give pullrequest --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 352ad9bc..57eb4608 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ lib temp node_modules/ bower_components/ +dist/ libpeerconnection.log *.swp .*.swp From 707abda2bf21178145d2d877ba5dc92d4491230c Mon Sep 17 00:00:00 2001 From: Tirumala Dilip Kumar Date: Fri, 6 Nov 2015 15:30:54 +0530 Subject: [PATCH 04/53] deleted dist folder for pull request --- dist/angular-openlayers-directive.css | 58 - dist/angular-openlayers-directive.js | 2228 ----------------- dist/angular-openlayers-directive.min.js | 31 - ...ular-openlayers-directive.min.no-header.js | 2 - dist/angular-openlayers-directive.pre.js | 2228 ----------------- 5 files changed, 4547 deletions(-) delete mode 100644 dist/angular-openlayers-directive.css delete mode 100644 dist/angular-openlayers-directive.js delete mode 100644 dist/angular-openlayers-directive.min.js delete mode 100644 dist/angular-openlayers-directive.min.no-header.js delete mode 100644 dist/angular-openlayers-directive.pre.js diff --git a/dist/angular-openlayers-directive.css b/dist/angular-openlayers-directive.css deleted file mode 100644 index fd9933e0..00000000 --- a/dist/angular-openlayers-directive.css +++ /dev/null @@ -1,58 +0,0 @@ -.popup-label { - background-color: #fff; - border: 2px #444 solid; - border-radius: 7px; - -webkit-box-shadow: 4px 4px 5px 0px rgba(50, 50, 50, 0.75); - -moz-box-shadow: 4px 4px 5px 0px rgba(50, 50, 50, 0.75); - box-shadow: 4px 4px 5px 0px rgba(50, 50, 50, 0.75); - color: #111; - font: 12px/20px "Helvetica Neue", Arial, Helvetica, sans-serif; - font-weight: bold; - padding: 3px 6px; - position: absolute; - white-space: nowrap; - top: -35px; - left: 20px; - display: none; -} - -.popup-label img { - vertical-align: middle; -} - -.popup-label.marker:before { - border-top: 6px solid transparent; - border-bottom: 6px solid transparent; - content: ""; - border-right: 6px solid black; - border-right-color: inherit; - position: absolute; - left: -8px; - top: 5px; -} - -.angular-openlayers-map:-moz-full-screen { - height: 100%; -} -.angular-openlayers-map:-webkit-full-screen { - height: 100%; -} -.angular-openlayers-map:full-screen { - height: 100%; -} - -.angular-openlayers-map:not(-moz-full-screen) { - height: 400px; -} - -.angular-openlayers-map:not(-webkit-full-screen) { - height: 400px; -} - -.angular-openlayers-map:not(full-screen) { - height: 400px; -} -.ol-full-screen { - position: absolute; - top: 50%; -} diff --git a/dist/angular-openlayers-directive.js b/dist/angular-openlayers-directive.js deleted file mode 100644 index 2c1e55c8..00000000 --- a/dist/angular-openlayers-directive.js +++ /dev/null @@ -1,2228 +0,0 @@ -(function (root, factory) { - if (typeof define === 'function' && define.amd) { - // AMD. - define(['ol'], function (ol) { - return root.angularOpenlayersDirective = factory(ol); - }); - } else { - // Browser globals - root.angularOpenlayersDirective = factory(root.ol); - } -}(this, function (ol) { -angular.module('openlayers-directive', ['ngSanitize']).directive('openlayers', ["$log", "$q", "$compile", "olHelpers", "olMapDefaults", "olData", function($log, $q, $compile, olHelpers, - olMapDefaults, olData) { - return { - restrict: 'EA', - transclude: true, - replace: true, - scope: { - center: '=olCenter', - defaults: '=olDefaults', - view: '=olView', - events: '=olEvents' - }, - template: '
', - controller: ["$scope", function($scope) { - var _map = $q.defer(); - $scope.getMap = function() { - return _map.promise; - }; - - $scope.setMap = function(map) { - _map.resolve(map); - }; - - this.getOpenlayersScope = function() { - return $scope; - }; - }], - link: function(scope, element, attrs) { - var isDefined = olHelpers.isDefined; - var createLayer = olHelpers.createLayer; - var setMapEvents = olHelpers.setMapEvents; - var setViewEvents = olHelpers.setViewEvents; - var createView = olHelpers.createView; - var defaults = olMapDefaults.setDefaults(scope); - - // Set width and height if they are defined - if (isDefined(attrs.width)) { - if (isNaN(attrs.width)) { - element.css('width', attrs.width); - } else { - element.css('width', attrs.width + 'px'); - } - } - - if (isDefined(attrs.height)) { - if (isNaN(attrs.height)) { - element.css('height', attrs.height); - } else { - element.css('height', attrs.height + 'px'); - } - } - - if (isDefined(attrs.lat)) { - defaults.center.lat = parseFloat(attrs.lat); - } - - if (isDefined(attrs.lon)) { - defaults.center.lon = parseFloat(attrs.lon); - } - - if (isDefined(attrs.zoom)) { - defaults.center.zoom = parseFloat(attrs.zoom); - } - - var controls = ol.control.defaults(defaults.controls); - var interactions = ol.interaction.defaults(defaults.interactions); - var view = createView(defaults.view); - - // Create the Openlayers Map Object with the options - var map = new ol.Map({ - target: element[0], - controls: controls, - interactions: interactions, - renderer: defaults.renderer, - view: view - }); - - // If no layer is defined, set the default tileLayer - if (!attrs.customLayers) { - var l = { - type: 'Tile', - source: { - type: 'OSM' - } - }; - var layer = createLayer(l, view.getProjection(), 'default'); - map.addLayer(layer); - map.set('default', true); - } - - if (!isDefined(attrs.olCenter)) { - var c = ol.proj.transform([defaults.center.lon, - defaults.center.lat - ], - defaults.center.projection, view.getProjection() - ); - view.setCenter(c); - view.setZoom(defaults.center.zoom); - } - - // Set the Default events for the map - setMapEvents(defaults.events, map, scope); - - //Set the Default events for the map view - setViewEvents(defaults.events, map, scope); - - // Resolve the map object to the promises - scope.setMap(map); - olData.setMap(map, attrs.id); - - } - }; - }]); - -angular.module('openlayers-directive').directive('olCenter', ["$log", "$location", "olMapDefaults", "olHelpers", function($log, $location, olMapDefaults, olHelpers) { - - return { - restrict: 'A', - scope: false, - replace: false, - require: 'openlayers', - - link: function(scope, element, attrs, controller) { - var safeApply = olHelpers.safeApply; - var isValidCenter = olHelpers.isValidCenter; - var isDefined = olHelpers.isDefined; - var isArray = olHelpers.isArray; - var isNumber = olHelpers.isNumber; - var isSameCenterOnMap = olHelpers.isSameCenterOnMap; - var setCenter = olHelpers.setCenter; - var setZoom = olHelpers.setZoom; - var olScope = controller.getOpenlayersScope(); - - olScope.getMap().then(function(map) { - var defaults = olMapDefaults.getDefaults(olScope); - var view = map.getView(); - var center = olScope.center; - - if (attrs.olCenter.search('-') !== -1) { - $log.error('[AngularJS - Openlayers] The "center" variable can\'t use ' + - 'a "-" on his key name: "' + attrs.center + '".'); - setCenter(view, defaults.view.projection, defaults.center, map); - return; - } - - if (!isDefined(center)) { - center = {}; - } - - if (!isValidCenter(center)) { - $log.warn('[AngularJS - Openlayers] invalid \'center\''); - center.lat = defaults.center.lat; - center.lon = defaults.center.lon; - center.zoom = defaults.center.zoom; - center.projection = defaults.center.projection; - } - - if (!center.projection) { - if (defaults.view.projection !== 'pixel') { - center.projection = defaults.center.projection; - } else { - center.projection = 'pixel'; - } - } - - if (!isNumber(center.zoom)) { - center.zoom = 1; - } - - setCenter(view, defaults.view.projection, center, map); - view.setZoom(center.zoom); - - var centerUrlHash; - if (center.centerUrlHash === true) { - var extractCenterFromUrl = function() { - var search = $location.search(); - var centerParam; - if (isDefined(search.c)) { - var cParam = search.c.split(':'); - if (cParam.length === 3) { - centerParam = { - lat: parseFloat(cParam[0]), - lon: parseFloat(cParam[1]), - zoom: parseInt(cParam[2], 10) - }; - } - } - return centerParam; - }; - centerUrlHash = extractCenterFromUrl(); - - olScope.$on('$locationChangeSuccess', function() { - var urlCenter = extractCenterFromUrl(); - if (urlCenter && !isSameCenterOnMap(urlCenter, map)) { - safeApply(olScope, function(scope) { - scope.center.lat = urlCenter.lat; - scope.center.lon = urlCenter.lon; - scope.center.zoom = urlCenter.zoom; - }); - } - }); - } - - var geolocation; - olScope.$watchCollection('center', function(center) { - - if (!center) { - return; - } - - if (!center.projection) { - center.projection = defaults.center.projection; - } - - if (center.autodiscover) { - if (!geolocation) { - geolocation = new ol.Geolocation({ - projection: ol.proj.get(center.projection) - }); - - geolocation.on('change', function() { - if (center.autodiscover) { - var location = geolocation.getPosition(); - safeApply(olScope, function(scope) { - scope.center.lat = location[1]; - scope.center.lon = location[0]; - scope.center.zoom = 12; - scope.center.autodiscover = false; - geolocation.setTracking(false); - }); - } - }); - } - geolocation.setTracking(true); - return; - } - - if (!isValidCenter(center)) { - $log.warn('[AngularJS - Openlayers] invalid \'center\''); - center = defaults.center; - } - - var viewCenter = view.getCenter(); - if (viewCenter) { - if (defaults.view.projection === 'pixel') { - view.setCenter(center.coord); - return; - } - var actualCenter = ol.proj.transform(viewCenter, defaults.view.projection, center.projection); - if (!(actualCenter[1] === center.lat && actualCenter[0] === center.lon)) { - setCenter(view, defaults.view.projection, center, map); - } - } - - if (view.getZoom() !== center.zoom) { - setZoom(view, center.zoom, map); - } - }); - - map.on('moveend', function() { - safeApply(olScope, function(scope) { - - if (!isDefined(scope.center)) { - return; - } - - var center = map.getView().getCenter(); - scope.center.zoom = view.getZoom(); - - if (defaults.view.projection === 'pixel') { - scope.center.coord = center; - return; - } - - if (scope.center) { - var proj = ol.proj.transform(center, defaults.view.projection, scope.center.projection); - scope.center.lat = proj[1]; - scope.center.lon = proj[0]; - - // Notify the controller about a change in the center position - olHelpers.notifyCenterUrlHashChanged(olScope, scope.center, $location.search()); - - // Calculate the bounds if needed - if (isArray(scope.center.bounds)) { - var extent = view.calculateExtent(map.getSize()); - var centerProjection = scope.center.projection; - var viewProjection = defaults.view.projection; - scope.center.bounds = ol.proj.transformExtent(extent, viewProjection, centerProjection); - } - } - }); - }); - - }); - } - }; -}]); - -angular.module('openlayers-directive').directive('olLayer', ["$log", "$q", "olMapDefaults", "olHelpers", function($log, $q, olMapDefaults, olHelpers) { - - return { - restrict: 'E', - scope: { - properties: '=olLayerProperties' - }, - replace: false, - require: '^openlayers', - link: function(scope, element, attrs, controller) { - var isDefined = olHelpers.isDefined; - var equals = olHelpers.equals; - var olScope = controller.getOpenlayersScope(); - var createLayer = olHelpers.createLayer; - var setVectorLayerEvents = olHelpers.setVectorLayerEvents; - var detectLayerType = olHelpers.detectLayerType; - var createStyle = olHelpers.createStyle; - var isBoolean = olHelpers.isBoolean; - var addLayerBeforeMarkers = olHelpers.addLayerBeforeMarkers; - var isNumber = olHelpers.isNumber; - var insertLayer = olHelpers.insertLayer; - var removeLayer = olHelpers.removeLayer; - var addLayerToGroup = olHelpers.addLayerToGroup; - var removeLayerFromGroup = olHelpers.removeLayerFromGroup; - var getGroup = olHelpers.getGroup; - - olScope.getMap().then(function(map) { - var projection = map.getView().getProjection(); - var defaults = olMapDefaults.setDefaults(olScope); - var layerCollection = map.getLayers(); - var olLayer; - - scope.$on('$destroy', function() { - if (scope.properties.group) { - removeLayerFromGroup(layerCollection, olLayer, scope.properties.group); - } else { - removeLayer(layerCollection, olLayer.index); - } - - map.removeLayer(olLayer); - }); - - if (!isDefined(scope.properties)) { - if (isDefined(attrs.sourceType) && isDefined(attrs.sourceUrl)) { - var l = { - source: { - url: attrs.sourceUrl, - type: attrs.sourceType - } - }; - - olLayer = createLayer(l, projection, attrs.layerName); - if (detectLayerType(l) === 'Vector') { - setVectorLayerEvents(defaults.events, map, scope, attrs.name); - } - addLayerBeforeMarkers(layerCollection, olLayer); - } - return; - } - - scope.$watch('properties', function(properties, oldProperties) { - if (!isDefined(properties.source) || !isDefined(properties.source.type)) { - return; - } - - if (!isDefined(properties.visible)) { - properties.visible = true; - return; - } - - if (!isDefined(properties.opacity)) { - properties.opacity = 1; - return; - } - - var style; - var group; - var collection; - if (!isDefined(olLayer)) { - olLayer = createLayer(properties, projection); - if (isDefined(properties.group)) { - addLayerToGroup(layerCollection, olLayer, properties.group); - } else if (isDefined(properties.index)) { - insertLayer(layerCollection, properties.index, olLayer); - } else { - addLayerBeforeMarkers(layerCollection, olLayer); - } - - if (detectLayerType(properties) === 'Vector') { - setVectorLayerEvents(defaults.events, map, scope, properties.name); - } - - if (isBoolean(properties.visible)) { - olLayer.setVisible(properties.visible); - } - - if (properties.opacity) { - olLayer.setOpacity(properties.opacity); - } - - if (angular.isArray(properties.extent)) { - olLayer.setExtent(properties.extent); - } - - if (properties.style) { - if (!angular.isFunction(properties.style)) { - style = createStyle(properties.style); - } else { - style = properties.style; - } - // not every layer has a setStyle method - if (olLayer.setStyle && angular.isFunction(olLayer.setStyle)) { - olLayer.setStyle(style); - } - } - - } else { - var isNewLayer = (function(olLayer) { - // this function can be used to verify whether a new layer instance has - // been created. This is needed in order to re-assign styles, opacity - // etc... - return function(layer) { - return layer !== olLayer; - }; - })(olLayer); - - // set source properties - if (isDefined(oldProperties) && !equals(properties.source, oldProperties.source)) { - var idx = olLayer.index; - collection = layerCollection; - group = olLayer.get('group'); - - if (group) { - collection = getGroup(layerCollection, group).getLayers(); - } - - collection.removeAt(idx); - - olLayer = createLayer(properties, projection); - olLayer.set('group', group); - - if (isDefined(olLayer)) { - insertLayer(collection, idx, olLayer); - - if (detectLayerType(properties) === 'Vector') { - setVectorLayerEvents(defaults.events, map, scope, properties.name); - } - } - } - - // set opacity - if (isDefined(oldProperties) && - properties.opacity !== oldProperties.opacity || isNewLayer(olLayer)) { - if (isNumber(properties.opacity) || isNumber(parseFloat(properties.opacity))) { - olLayer.setOpacity(properties.opacity); - } - } - - // set index - if (isDefined(properties.index) && properties.index !== olLayer.index) { - collection = layerCollection; - group = olLayer.get('group'); - - if (group) { - collection = getGroup(layerCollection, group).getLayers(); - } - - removeLayer(collection, olLayer.index); - insertLayer(collection, properties.index, olLayer); - } - - // set group - if (isDefined(properties.group) && properties.group !== oldProperties.group) { - removeLayerFromGroup(layerCollection, olLayer, oldProperties.group); - addLayerToGroup(layerCollection, olLayer, properties.group); - } - - // set visibility - if (isDefined(oldProperties) && - isBoolean(properties.visible) && - properties.visible !== oldProperties.visible || isNewLayer(olLayer)) { - olLayer.setVisible(properties.visible); - } - - // set style - if (isDefined(properties.style) && - !equals(properties.style, oldProperties.style) || isNewLayer(olLayer)) { - if (!angular.isFunction(properties.style)) { - style = createStyle(properties.style); - } else { - style = properties.style; - } - // not every layer has a setStyle method - if (olLayer.setStyle && angular.isFunction(olLayer.setStyle)) { - olLayer.setStyle(style); - } - } - } - }, true); - }); - } - }; -}]); - -angular.module('openlayers-directive').directive('olPath', ["$log", "$q", "olMapDefaults", "olHelpers", function($log, $q, olMapDefaults, olHelpers) { - - return { - restrict: 'E', - scope: { - properties: '=olGeomProperties' - }, - require: '^openlayers', - replace: true, - template: '', - - link: function(scope, element, attrs, controller) { - var isDefined = olHelpers.isDefined; - var createFeature = olHelpers.createFeature; - var createOverlay = olHelpers.createOverlay; - var createVectorLayer = olHelpers.createVectorLayer; - var insertLayer = olHelpers.insertLayer; - var removeLayer = olHelpers.removeLayer; - var olScope = controller.getOpenlayersScope(); - - olScope.getMap().then(function(map) { - var mapDefaults = olMapDefaults.getDefaults(olScope); - var viewProjection = mapDefaults.view.projection; - - var layer = createVectorLayer(); - var layerCollection = map.getLayers(); - - insertLayer(layerCollection, layerCollection.getLength(), layer); - - scope.$on('$destroy', function() { - removeLayer(layerCollection, layer.index); - }); - - if (isDefined(attrs.coords)) { - var proj = attrs.proj || 'EPSG:4326'; - var coords = JSON.parse(attrs.coords); - var data = { - type: 'Polygon', - coords: coords, - projection: proj, - style: mapDefaults.styles.path - }; - var feature = createFeature(data, viewProjection); - layer.getSource().addFeature(feature); - - if (attrs.message) { - scope.message = attrs.message; - var extent = feature.getGeometry().getExtent(); - var label = createOverlay(element, extent); - map.addOverlay(label); - } - return; - } - }); - } - }; -}]); - -angular.module('openlayers-directive').directive('olView', ["$log", "$q", "olData", "olMapDefaults", "olHelpers", function($log, $q, olData, olMapDefaults, olHelpers) { - return { - restrict: 'A', - scope: false, - replace: false, - require: 'openlayers', - link: function(scope, element, attrs, controller) { - var olScope = controller.getOpenlayersScope(); - var isNumber = olHelpers.isNumber; - var safeApply = olHelpers.safeApply; - var createView = olHelpers.createView; - - olScope.getMap().then(function(map) { - var defaults = olMapDefaults.getDefaults(olScope); - var view = olScope.view; - - if (!view.projection) { - view.projection = defaults.view.projection; - } - - if (!view.maxZoom) { - view.maxZoom = defaults.view.maxZoom; - } - - if (!view.minZoom) { - view.minZoom = defaults.view.minZoom; - } - - if (!view.rotation) { - view.rotation = defaults.view.rotation; - } - - var mapView = createView(view); - map.setView(mapView); - - olScope.$watchCollection('view', function(view) { - if (isNumber(view.rotation)) { - mapView.setRotation(view.rotation); - } - }); - - mapView.on('change:rotation', function() { - safeApply(olScope, function(scope) { - scope.view.rotation = map.getView().getRotation(); - }); - }); - - }); - } - }; -}]); - -angular.module('openlayers-directive').directive('olControl', ["$log", "$q", "olData", "olMapDefaults", "olHelpers", function($log, $q, olData, olMapDefaults, olHelpers) { - - return { - restrict: 'E', - scope: { - properties: '=olControlProperties' - }, - replace: false, - require: '^openlayers', - link: function(scope, element, attrs, controller) { - var isDefined = olHelpers.isDefined; - var olScope = controller.getOpenlayersScope(); - var olControl; - var olControlOps; - - olScope.getMap().then(function(map) { - var getControlClasses = olHelpers.getControlClasses; - var controlClasses = getControlClasses(); - - scope.$on('$destroy', function() { - map.removeControl(olControl); - }); - - if (!isDefined(scope.properties) || !isDefined(scope.properties.control)) { - if (attrs.name) { - if (isDefined(scope.properties)) { - olControlOps = scope.properties; - } - olControl = new controlClasses[attrs.name](olControlOps); - map.addControl(olControl); - } - return; - } - - olControl = scope.properties.control; - map.addControl(olControl); - }); - } - }; -}]); - -angular.module('openlayers-directive').directive('olMarker', ["$log", "$q", "olMapDefaults", "olHelpers", function($log, $q, olMapDefaults, olHelpers) { - - var getMarkerDefaults = function() { - return { - projection: 'EPSG:4326', - lat: 0, - lon: 0, - coord: [], - show: true, - showOnMouseOver: false, - showOnMouseClick: false, - keepOneOverlayVisible: false - }; - }; - - var markerLayerManager = (function() { - var mapDict = []; - - function getMapIndex(map) { - return mapDict.map(function(record) { - return record.map; - }).indexOf(map); - } - - return { - getInst: function getMarkerLayerInst(scope, map) { - var mapIndex = getMapIndex(map); - - if (mapIndex === -1) { - var markerLayer = olHelpers.createVectorLayer(); - markerLayer.set('markers', true); - map.addLayer(markerLayer); - mapDict.push({ - map: map, - markerLayer: markerLayer, - instScopes: [] - }); - mapIndex = mapDict.length - 1; - } - - mapDict[mapIndex].instScopes.push(scope); - - return mapDict[mapIndex].markerLayer; - }, - deregisterScope: function deregisterScope(scope, map) { - var mapIndex = getMapIndex(map); - if (mapIndex === -1) { - throw Error('This map has no markers'); - } - - var scopes = mapDict[mapIndex].instScopes; - var scopeIndex = scopes.indexOf(scope); - if (scopeIndex === -1) { - throw Error('Scope wan\'t registered'); - } - - scopes.splice(scopeIndex, 1); - - if (!scopes.length) { - map.removeLayer(mapDict[mapIndex].markerLayer); - delete mapDict[mapIndex]; - } - } - }; - })(); - return { - restrict: 'E', - scope: { - lat: '=lat', - lon: '=lon', - label: '=label', - properties: '=olMarkerProperties', - style: '=olStyle' - }, - transclude: true, - require: '^openlayers', - replace: true, - template: - '', - - link: function(scope, element, attrs, controller) { - var isDefined = olHelpers.isDefined; - var olScope = controller.getOpenlayersScope(); - var createFeature = olHelpers.createFeature; - var createOverlay = olHelpers.createOverlay; - - var hasTranscluded = element.find('ng-transclude').children().length > 0; - - olScope.getMap().then(function(map) { - var markerLayer = markerLayerManager.getInst(scope, map); - var data = getMarkerDefaults(); - - var mapDefaults = olMapDefaults.getDefaults(olScope); - var viewProjection = mapDefaults.view.projection; - var label; - var pos; - var marker; - - // This function handles dragging a marker - var pickOffset = null; - var pickProperties = null; - function handleDrag(evt) { - var coord = evt.coordinate; - var proj = map.getView().getProjection().getCode(); - if (proj === 'pixel') { - coord = coord.map(function(v) { - return parseInt(v, 10); - }); - } else { - coord = ol.proj.transform(coord, proj, 'EPSG:4326'); - } - - if (evt.type === 'pointerdown') { - // Get feature under mouse if any - var feature = map.forEachFeatureAtPixel(evt.pixel, function(feature) { - return feature; - }); - // Get associated marker properties - pickProperties = (feature ? feature.get('marker') : null); - if (!pickProperties || !pickProperties.draggable) { - pickProperties = null; - return; - } - map.getTarget().style.cursor = 'pointer'; - if (proj === 'pixel') { - pickOffset = [coord[0] - pickProperties.coord[0], coord[1] - pickProperties.coord[1]]; - } else { - pickOffset = [coord[0] - pickProperties.lon, coord[1] - pickProperties.lat]; - } - evt.preventDefault(); - } else if (pickOffset && pickProperties) { - if (evt.type === 'pointerup') { - map.getTarget().style.cursor = ''; - pickOffset = null; - pickProperties = null; - evt.preventDefault(); - } else if (evt.type === 'pointerdrag') { - evt.preventDefault(); - scope.$apply(function() { - // Add current delta to marker initial position - if (proj === 'pixel') { - pickProperties.coord[0] = coord[0] - pickOffset[0]; - pickProperties.coord[1] = coord[1] - pickOffset[1]; - } else { - pickProperties.lon = coord[0] - pickOffset[0]; - pickProperties.lat = coord[1] - pickOffset[1]; - } - }); - } - } - } - - // Setup generic handlers for marker drag - map.on('pointerdown', handleDrag); - map.on('pointerup', handleDrag); - map.on('pointerdrag', handleDrag); - - scope.$on('$destroy', function() { - markerLayer.getSource().removeFeature(marker); - if (isDefined(label)) { - map.removeOverlay(label); - } - markerLayerManager.deregisterScope(scope, map); - }); - - if (!isDefined(scope.properties)) { - data.lat = scope.lat ? scope.lat : data.lat; - data.lon = scope.lon ? scope.lon : data.lon; - data.message = attrs.message; - data.style = scope.style ? scope.style : mapDefaults.styles.marker; - - marker = createFeature(data, viewProjection); - if (!isDefined(marker)) { - $log.error('[AngularJS - Openlayers] Received invalid data on ' + - 'the marker.'); - } - // Add a link between the feature and the marker properties - marker.set('marker', scope); - markerLayer.getSource().addFeature(marker); - - if (data.message || hasTranscluded) { - scope.message = attrs.message; - pos = ol.proj.transform([data.lon, data.lat], data.projection, - viewProjection); - label = createOverlay(element, pos); - map.addOverlay(label); - } - return; - } - - scope.$watch('properties', function(properties) { - - // Remove previous listeners if any - map.getViewport().removeEventListener('mousemove', properties.handleInteraction); - map.getViewport().removeEventListener('click', properties.handleTapInteraction); - map.getViewport().querySelector('canvas.ol-unselectable').removeEventListener( - 'touchend', properties.handleTapInteraction); - map.getViewport().removeEventListener('mousemove', properties.showAtLeastOneOverlay); - map.getViewport().removeEventListener('click', properties.removeAllOverlays); - - // This function handles popup on mouse over/click - properties.handleInteraction = function(evt) { - if (properties.label.show) { - return; - } - var found = false; - var pixel = map.getEventPixel(evt); - var feature = map.forEachFeatureAtPixel(pixel, function(feature) { - return feature; - }); - - var actionTaken = false; - if (feature === marker) { - actionTaken = true; - found = true; - if (!isDefined(label)) { - if (data.projection === 'pixel') { - pos = properties.coord; - } else { - pos = ol.proj.transform([properties.lon, properties.lat], - data.projection, viewProjection); - } - label = createOverlay(element, pos); - map.addOverlay(label); - } - - if (properties.onClick && (evt.type === 'click' || evt.type === 'touchend')) { - scope.$apply(function() { - properties.onClick.call(marker, evt, properties); - }); - } - map.getTarget().style.cursor = 'pointer'; - } - - if (!found && label) { - actionTaken = true; - map.removeOverlay(label); - label = undefined; - map.getTarget().style.cursor = ''; - } - - if (actionTaken) { - evt.preventDefault(); - } - }; - - // Made to filter out click/tap events if both are being triggered on this platform - properties.handleTapInteraction = (function() { - var cooldownActive = false; - var prevTimeout; - - // Sets the cooldown flag to filter out any subsequent events within 500 ms - function activateCooldown() { - cooldownActive = true; - if (prevTimeout) { - clearTimeout(prevTimeout); - } - prevTimeout = setTimeout(function() { - cooldownActive = false; - prevTimeout = null; - }, 500); - } - - // Preventing from 'touchend' to be considered a tap, if fired immediately after 'touchmove' - map.getViewport().querySelector('canvas.ol-unselectable').addEventListener( - 'touchmove', activateCooldown); - - return function() { - if (!cooldownActive) { - properties.handleInteraction.apply(null, arguments); - activateCooldown(); - } - }; - })(); - - properties.showAtLeastOneOverlay = function(evt) { - if (properties.label.show) { - return; - } - var found = false; - var pixel = map.getEventPixel(evt); - var feature = map.forEachFeatureAtPixel(pixel, function(feature) { - return feature; - }); - - var actionTaken = false; - if (feature === marker) { - actionTaken = true; - found = true; - if (!isDefined(label)) { - if (data.projection === 'pixel') { - pos = data.coord; - } else { - pos = ol.proj.transform([data.lon, data.lat], - data.projection, viewProjection); - } - label = createOverlay(element, pos); - angular.forEach(map.getOverlays(), function(value) { - map.removeOverlay(value); - }); - map.addOverlay(label); - } - map.getTarget().style.cursor = 'pointer'; - } - - if (!found && label) { - actionTaken = true; - label = undefined; - map.getTarget().style.cursor = ''; - } - - if (actionTaken) { - evt.preventDefault(); - } - }; - - properties.removeAllOverlays = function(evt) { - angular.forEach(map.getOverlays(), function(value) { - map.removeOverlay(value); - }); - evt.preventDefault(); - }; - - if (!isDefined(marker)) { - data.projection = properties.projection ? properties.projection : - data.projection; - data.coord = properties.coord ? properties.coord : data.coord; - data.lat = properties.lat ? properties.lat : data.lat; - data.lon = properties.lon ? properties.lon : data.lon; - - if (isDefined(properties.style)) { - data.style = properties.style; - } else { - data.style = mapDefaults.styles.marker; - } - - marker = createFeature(data, viewProjection); - if (!isDefined(marker)) { - $log.error('[AngularJS - Openlayers] Received invalid data on ' + - 'the marker.'); - } - // Add a link between the feature and the marker properties - marker.set('marker', properties); - markerLayer.getSource().addFeature(marker); - } else { - var requestedPosition; - if (properties.projection === 'pixel') { - requestedPosition = properties.coord; - } else { - requestedPosition = ol.proj.transform([properties.lon, properties.lat], data.projection, - map.getView().getProjection()); - } - - if (!angular.equals(marker.getGeometry().getCoordinates(), requestedPosition)) { - var geometry = new ol.geom.Point(requestedPosition); - marker.setGeometry(geometry); - } - } - - if (isDefined(label)) { - map.removeOverlay(label); - } - - if (!isDefined(properties.label)) { - return; - } - - scope.message = properties.label.message; - if (!hasTranscluded && (!isDefined(scope.message) || scope.message.length === 0)) { - return; - } - - if (properties.label && properties.label.show === true) { - if (data.projection === 'pixel') { - pos = data.coord; - } else { - pos = ol.proj.transform([properties.lon, properties.lat], data.projection, - viewProjection); - } - label = createOverlay(element, pos); - map.addOverlay(label); - } - - if (label && properties.label && properties.label.show === false) { - map.removeOverlay(label); - label = undefined; - } - - // Then setup new ones according to properties - if (properties.label && properties.label.show === false && - properties.label.showOnMouseOver) { - map.getViewport().addEventListener('mousemove', properties.handleInteraction); - } - - if ((properties.label && properties.label.show === false && - properties.label.showOnMouseClick) || - properties.onClick) { - map.getViewport().addEventListener('click', properties.handleTapInteraction); - map.getViewport().querySelector('canvas.ol-unselectable').addEventListener( - 'touchend', properties.handleTapInteraction); - } - - if ((properties.label && properties.label.show === false && - properties.label.keepOneOverlayVisible)) { - map.getViewport().addEventListener('mousemove', properties.showAtLeastOneOverlay); - map.getViewport().addEventListener('click', properties.removeAllOverlays); - } - }, true); - }); - } - }; -}]); - -angular.module('openlayers-directive').service('olData', ["$log", "$q", "olHelpers", function($log, $q, olHelpers) { - - var obtainEffectiveMapId = olHelpers.obtainEffectiveMapId; - - var maps = {}; - - var setResolvedDefer = function(d, mapId) { - var id = obtainEffectiveMapId(d, mapId); - d[id].resolvedDefer = true; - }; - - var getUnresolvedDefer = function(d, mapId) { - var id = obtainEffectiveMapId(d, mapId); - var defer; - - if (!angular.isDefined(d[id]) || d[id].resolvedDefer === true) { - defer = $q.defer(); - d[id] = { - defer: defer, - resolvedDefer: false - }; - } else { - defer = d[id].defer; - } - return defer; - }; - - var getDefer = function(d, mapId) { - var id = obtainEffectiveMapId(d, mapId); - var defer; - - if (!angular.isDefined(d[id]) || d[id].resolvedDefer === false) { - defer = getUnresolvedDefer(d, mapId); - } else { - defer = d[id].defer; - } - return defer; - }; - - this.setMap = function(olMap, scopeId) { - var defer = getUnresolvedDefer(maps, scopeId); - defer.resolve(olMap); - setResolvedDefer(maps, scopeId); - }; - - this.getMap = function(scopeId) { - var defer = getDefer(maps, scopeId); - return defer.promise; - }; - -}]); - -angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$http", function($q, $log, $http) { - - var isDefined = function(value) { - return angular.isDefined(value); - }; - - var isDefinedAndNotNull = function(value) { - return angular.isDefined(value) && value !== null; - }; - - var setEvent = function(map, eventType, scope) { - map.on(eventType, function(event) { - var coord = event.coordinate; - var proj = map.getView().getProjection().getCode(); - if (proj === 'pixel') { - coord = coord.map(function(v) { - return parseInt(v, 10); - }); - } - scope.$emit('openlayers.map.' + eventType, { - 'coord': coord, - 'projection': proj, - 'event': event - }); - }); - }; - - var bingImagerySets = [ - 'Road', - 'Aerial', - 'AerialWithLabels', - 'collinsBart', - 'ordnanceSurvey' - ]; - - var getControlClasses = function() { - return { - attribution: ol.control.Attribution, - fullscreen: ol.control.FullScreen, - mouseposition: ol.control.MousePosition, - rotate: ol.control.Rotate, - scaleline: ol.control.ScaleLine, - zoom: ol.control.Zoom, - zoomslider: ol.control.ZoomSlider, - zoomtoextent: ol.control.ZoomToExtent - }; - }; - - var mapQuestLayers = ['osm', 'sat', 'hyb']; - - var esriBaseLayers = ['World_Imagery', 'World_Street_Map', 'World_Topo_Map', - 'World_Physical_Map', 'World_Terrain_Base', - 'Ocean_Basemap', 'NatGeo_World_Map']; - - var styleMap = { - 'style': ol.style.Style, - 'fill': ol.style.Fill, - 'stroke': ol.style.Stroke, - 'circle': ol.style.Circle, - 'icon': ol.style.Icon, - 'image': ol.style.Image, - 'regularshape': ol.style.RegularShape, - 'text': ol.style.Text - }; - - var optionalFactory = function(style, Constructor) { - if (Constructor && style instanceof Constructor) { - return style; - } else if (Constructor) { - return new Constructor(style); - } else { - return style; - } - }; - - //Parse the style tree calling the appropriate constructors. - //The keys in styleMap can be used and the OpenLayers constructors can be - //used directly. - var createStyle = function recursiveStyle(data, styleName) { - var style; - if (!styleName) { - styleName = 'style'; - style = data; - } else { - style = data[styleName]; - } - //Instead of defining one style for the layer, we've been given a style function - //to apply to each feature. - if (styleName === 'style' && data instanceof Function) { - return data; - } - - if (!(style instanceof Object)) { - return style; - } - - var styleObject; - if (Object.prototype.toString.call(style) === '[object Object]') { - styleObject = {}; - var styleConstructor = styleMap[styleName]; - if (styleConstructor && style instanceof styleConstructor) { - return style; - } - Object.getOwnPropertyNames(style).forEach(function(val, idx, array) { - //Consider the case - //image: { - // circle: { - // fill: { - // color: 'red' - // } - // } - // - //An ol.style.Circle is an instance of ol.style.Image, so we do not want to construct - //an Image and then construct a Circle. We assume that if we have an instanceof - //relationship, that the JSON parent has exactly one child. - //We check to see if an inheritance relationship exists. - //If it does, then for the parent we create an instance of the child. - var valConstructor = styleMap[val]; - if (styleConstructor && valConstructor && - valConstructor.prototype instanceof styleMap[styleName]) { - console.assert(array.length === 1, 'Extra parameters for ' + styleName); - styleObject = recursiveStyle(style, val); - return optionalFactory(styleObject, valConstructor); - } else { - styleObject[val] = recursiveStyle(style, val); - - // if the value is 'text' and it contains a String, then it should be interpreted - // as such, 'cause the text style might effectively contain a text to display - if (val !== 'text' && typeof styleObject[val] !== 'string') { - styleObject[val] = optionalFactory(styleObject[val], styleMap[val]); - } - } - }); - } else { - styleObject = style; - } - return optionalFactory(styleObject, styleMap[styleName]); - }; - - var detectLayerType = function(layer) { - if (layer.type) { - return layer.type; - } else { - switch (layer.source.type) { - case 'ImageWMS': - return 'Image'; - case 'ImageStatic': - return 'Image'; - case 'GeoJSON': - case 'JSONP': - case 'TopoJSON': - case 'KML': - case 'TileVector': - return 'Vector'; - default: - return 'Tile'; - } - } - }; - - var createProjection = function(view) { - var oProjection; - - switch (view.projection) { - case 'pixel': - if (!isDefined(view.extent)) { - $log.error('[AngularJS - Openlayers] - You must provide the extent of the image ' + - 'if using pixel projection'); - return; - } - oProjection = new ol.proj.Projection({ - code: 'pixel', - units: 'pixels', - extent: view.extent - }); - break; - default: - oProjection = new ol.proj.get(view.projection); - break; - } - - return oProjection; - }; - - var isValidStamenLayer = function(layer) { - return ['watercolor', 'terrain', 'toner'].indexOf(layer) !== -1; - }; - - var createSource = function(source, projection) { - var oSource; - - switch (source.type) { - case 'MapBox': - if (!source.mapId || !source.accessToken) { - $log.error('[AngularJS - Openlayers] - MapBox layer requires the map id and the access token'); - return; - } - var url = 'http://api.tiles.mapbox.com/v4/' + source.mapId + '/{z}/{x}/{y}.png?access_token=' + - source.accessToken; - - var pixelRatio = window.devicePixelRatio; - - if (pixelRatio > 1) { - url = url.replace('.png', '@2x.png'); - } - - oSource = new ol.source.XYZ({ - url: url, - attributions: createAttribution(source), - tilePixelRatio: pixelRatio > 1 ? 2 : 1, - wrapX: (source.wrapX === true) ? 1 : 0 - }); - break; - case 'ImageWMS': - if (!source.url || !source.params) { - $log.error('[AngularJS - Openlayers] - ImageWMS Layer needs ' + - 'valid server url and params properties'); - } - oSource = new ol.source.ImageWMS({ - url: source.url, - attributions: createAttribution(source), - crossOrigin: (typeof source.crossOrigin === 'undefined') ? 'anonymous' : source.crossOrigin, - params: source.params, - wrapX: source.wrapX ? 0 : 1 - }); - break; - - case 'TileWMS': - if ((!source.url && !source.urls) || !source.params) { - $log.error('[AngularJS - Openlayers] - TileWMS Layer needs ' + - 'valid url (or urls) and params properties'); - } - - var wmsConfiguration = { - crossOrigin: (typeof source.crossOrigin === 'undefined') ? 'anonymous' : source.crossOrigin, - params: source.params, - attributions: createAttribution(source), - wrapX: source.wrapX ? 0 : 1 - }; - - if (source.url) { - wmsConfiguration.url = source.url; - } - - if (source.urls) { - wmsConfiguration.urls = source.urls; - } - - oSource = new ol.source.TileWMS(wmsConfiguration); - break; - - case 'WMTS': - if ((!source.url && !source.urls) || !source.tileGrid) { - $log.error('[AngularJS - Openlayers] - WMTS Layer needs valid url ' + - '(or urls) and tileGrid properties'); - } - - var wmtsConfiguration = { - projection: projection, - layer: source.layer, - attributions: createAttribution(source), - matrixSet: (source.matrixSet === 'undefined') ? projection : source.matrixSet, - format: (source.format === 'undefined') ? 'image/jpeg' : source.format, - requestEncoding: (source.requestEncoding === 'undefined') ? - 'KVP' : source.requestEncoding, - tileGrid: new ol.tilegrid.WMTS({ - origin: source.tileGrid.origin, - resolutions: source.tileGrid.resolutions, - matrixIds: source.tileGrid.matrixIds - }), - wrapX: source.wrapX ? 0 : 1 - }; - - if (isDefined(source.url)) { - wmtsConfiguration.url = source.url; - } - - if (isDefined(source.urls)) { - wmtsConfiguration.urls = source.urls; - } - - oSource = new ol.source.WMTS(wmtsConfiguration); - break; - - case 'OSM': - oSource = new ol.source.OSM({ - attributions: createAttribution(source), - wrapX: (source.wrapX === true) ? 1 : 0 - }); - - if (source.url) { - oSource.setUrl(source.url); - } - - break; - case 'BingMaps': - if (!source.key) { - $log.error('[AngularJS - Openlayers] - You need an API key to show the Bing Maps.'); - return; - } - - var bingConfiguration = { - key: source.key, - attributions: createAttribution(source), - imagerySet: source.imagerySet ? source.imagerySet : bingImagerySets[0], - culture: source.culture, - wrapX: (source.wrapX === true) ? 1 : 0 - }; - - if (source.maxZoom) { - bingConfiguration.maxZoom = source.maxZoom; - } - - oSource = new ol.source.BingMaps(bingConfiguration); - break; - - case 'MapQuest': - if (!source.layer || mapQuestLayers.indexOf(source.layer) === -1) { - $log.error('[AngularJS - Openlayers] - MapQuest layers needs a valid \'layer\' property.'); - return; - } - - oSource = new ol.source.MapQuest({ - attributions: createAttribution(source), - layer: source.layer, - wrapX: (source.wrapX === true) ? 1 : 0 - }); - - break; - - case 'EsriBaseMaps': - if (!source.layer || esriBaseLayers.indexOf(source.layer) === -1) { - $log.error('[AngularJS - Openlayers] - ESRI layers needs a valid \'layer\' property.'); - return; - } - - var _urlBase = 'http://services.arcgisonline.com/ArcGIS/rest/services/'; - var _url = _urlBase + source.layer + '/MapServer/tile/{z}/{y}/{x}'; - - oSource = new ol.source.XYZ({ - attributions: createAttribution(source), - url: _url, - wrapX: (source.wrapX === true) ? 1 : 0 - }); - - break; - - case 'GeoJSON': - if (!(source.geojson || source.url)) { - $log.error('[AngularJS - Openlayers] - You need a geojson ' + - 'property to add a GeoJSON layer.'); - return; - } - - if (isDefined(source.url)) { - oSource = new ol.source.Vector({ - format: new ol.format.GeoJSON(), - url: source.url, - wrapX: (source.wrapX === true) ? 1 : 0 - }); - } else { - oSource = new ol.source.Vector(); - - var projectionToUse = projection; - if (isDefined(source.geojson.projection)) { - projectionToUse = source.geojson.projection; - } - - var geojsonFormat = new ol.format.GeoJSON(); - var features = geojsonFormat.readFeatures( - source.geojson.object, { featureProjection: projectionToUse }); - - oSource.addFeatures(features); - } - - break; - case 'JSONP': - if (!(source.url)) { - $log.error('[AngularJS - Openlayers] - You need an url properly configured to add a JSONP layer.'); - return; - } - - if (isDefined(source.url)) { - oSource = new ol.source.Vector({ - format: new ol.format.GeoJSON(), - loader: function(/*extent, resolution, projection*/) { - var url = source.url + - '&outputFormat=text/javascript&format_options=callback:JSON_CALLBACK'; - $http.jsonp(url, { cache: source.cache}).success(function(response) { - oSource.addFeatures(oSource.readFeatures(response)); - }).error(function(response) { - $log(response); - }); - }, - wrapX: (source.wrapX === true) ? 1 : 0 - }); - } - break; - case 'TopoJSON': - if (!(source.topojson || source.url)) { - $log.error('[AngularJS - Openlayers] - You need a topojson ' + - 'property to add a TopoJSON layer.'); - return; - } - - if (source.url) { - oSource = new ol.source.Vector({ - format: new ol.format.TopoJSON(), - url: source.url, - wrapX: (source.wrapX === true) ? 1 : 0 - }); - } else { - oSource = new ol.source.Vector(angular.extend(source.topojson, { - format: new ol.format.TopoJSON(), - wrapX: (source.wrapX === true) ? 1 : 0 - })); - } - break; - case 'TileJSON': - oSource = new ol.source.TileJSON({ - url: source.url, - attributions: createAttribution(source), - crossOrigin: 'anonymous', - wrapX: (source.wrapX === true) ? 1 : 0 - }); - break; - - case 'TileVector': - if (!source.url || !source.format) { - $log.error('[AngularJS - Openlayers] - TileVector Layer needs valid url and format properties'); - } - oSource = new ol.source.TileVector({ - url: source.url, - projection: projection, - attributions: createAttribution(source), - format: source.format, - tileGrid: new ol.tilegrid.createXYZ({ - maxZoom: source.maxZoom || 19 - }), - wrapX: (source.wrapX === true) ? 1 : 0 - }); - break; - - case 'TileTMS': - if (!source.url || !source.tileGrid) { - $log.error('[AngularJS - Openlayers] - TileTMS Layer needs valid url and tileGrid properties'); - } - oSource = new ol.source.TileImage({ - url: source.url, - maxExtent: source.maxExtent, - attributions: createAttribution(source), - tileGrid: new ol.tilegrid.TileGrid({ - origin: source.tileGrid.origin, - resolutions: source.tileGrid.resolutions - }), - tileUrlFunction: function(tileCoord) { - - var z = tileCoord[0]; - var x = tileCoord[1]; - var y = tileCoord[2]; //(1 << z) - tileCoord[2] - 1; - - if (x < 0 || y < 0) { - return ''; - } - - var url = source.url + z + '/' + x + '/' + y + '.png'; - - return url; - }, - wrapX: (source.wrapX === true) ? 1 : 0 - }); - break; - case 'TileImage': - oSource = new ol.source.TileImage({ - url: source.url, - attributions: createAttribution(source), - tileGrid: new ol.tilegrid.TileGrid({ - origin: source.tileGrid.origin, // top left corner of the pixel projection's extent - resolutions: source.tileGrid.resolutions - }), - tileUrlFunction: function(tileCoord/*, pixelRatio, projection*/) { - var z = tileCoord[0]; - var x = tileCoord[1]; - var y = -tileCoord[2] - 1; - var url = source.url - .replace('{z}', z.toString()) - .replace('{x}', x.toString()) - .replace('{y}', y.toString()); - return url; - }, - wrapX: (source.wrapX === true) ? 1 : 0 - }); - break; - case 'KML': - var extractStyles = source.extractStyles || false; - oSource = new ol.source.Vector({ - url: source.url, - format: new ol.format.KML(), - radius: source.radius, - extractStyles: extractStyles, - wrapX: (source.wrapX === true) ? 1 : 0 - }); - break; - case 'Stamen': - if (!source.layer || !isValidStamenLayer(source.layer)) { - $log.error('[AngularJS - Openlayers] - You need a valid Stamen layer.'); - return; - } - oSource = new ol.source.Stamen({ - layer: source.layer, - wrapX: (source.wrapX === true) ? 1 : 0 - }); - break; - case 'ImageStatic': - if (!source.url || !angular.isArray(source.imageSize) || source.imageSize.length !== 2) { - $log.error('[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.'); - return; - } - - oSource = new ol.source.ImageStatic({ - url: source.url, - attributions: createAttribution(source), - imageSize: source.imageSize, - projection: projection, - imageExtent: projection.getExtent(), - imageLoadFunction: source.imageLoadFunction, - wrapX: (source.wrapX === true) ? 1 : 0 - }); - break; - case 'XYZ': - if (!source.url) { - $log.error('[AngularJS - Openlayers] - XYZ Layer needs valid url and params properties'); - } - oSource = new ol.source.XYZ({ - url: source.url, - attributions: createAttribution(source), - minZoom: source.minZoom, - maxZoom: source.maxZoom, - wrapX: (source.wrapX === true) ? 1 : 0 - }); - break; - } - - // log a warning when no source could be created for the given type - if (!oSource) { - $log.warn('[AngularJS - Openlayers] - No source could be found for type "' + source.type + '"'); - } - - return oSource; - }; - - var createAttribution = function(source) { - var attributions = []; - if (isDefined(source.attribution)) { - attributions.unshift(new ol.Attribution({html: source.attribution})); - } - return attributions; - }; - - var createGroup = function(name) { - var olGroup = new ol.layer.Group(); - olGroup.set('name', name); - - return olGroup; - }; - - var getGroup = function(layers, name) { - var layer; - - angular.forEach(layers, function(l) { - if (l instanceof ol.layer.Group && l.get('name') === name) { - layer = l; - return; - } - }); - - return layer; - }; - - var addLayerBeforeMarkers = function(layers, layer) { - var markersIndex; - for (var i = 0; i < layers.getLength(); i++) { - var l = layers.item(i); - - if (l.get('markers')) { - markersIndex = i; - break; - } - } - - if (isDefined(markersIndex)) { - var markers = layers.item(markersIndex); - layer.index = markersIndex; - layers.setAt(markersIndex, layer); - markers.index = layers.getLength(); - layers.push(markers); - } else { - layer.index = layers.getLength(); - layers.push(layer); - } - - }; - - var removeLayer = function(layers, index) { - layers.removeAt(index); - for (var i = index; i < layers.getLength(); i++) { - var l = layers.item(i); - if (l === null) { - layers.insertAt(i, null); - break; - } else { - l.index = i; - } - } - }; - - return { - // Determine if a reference is defined - isDefined: isDefined, - - // Determine if a reference is a number - isNumber: function(value) { - return angular.isNumber(value); - }, - - createView: function(view) { - var projection = createProjection(view); - - return new ol.View({ - projection: projection, - maxZoom: view.maxZoom, - minZoom: view.minZoom, - extent: view.extent - }); - }, - - // Determine if a reference is defined and not null - isDefinedAndNotNull: isDefinedAndNotNull, - - // Determine if a reference is a string - isString: function(value) { - return angular.isString(value); - }, - - // Determine if a reference is an array - isArray: function(value) { - return angular.isArray(value); - }, - - // Determine if a reference is an object - isObject: function(value) { - return angular.isObject(value); - }, - - // Determine if two objects have the same properties - equals: function(o1, o2) { - return angular.equals(o1, o2); - }, - - isValidCenter: function(center) { - return angular.isDefined(center) && - (typeof center.autodiscover === 'boolean' || - angular.isNumber(center.lat) && angular.isNumber(center.lon) || - (angular.isArray(center.coord) && center.coord.length === 2 && - angular.isNumber(center.coord[0]) && angular.isNumber(center.coord[1])) || - (angular.isArray(center.bounds) && center.bounds.length === 4 && - angular.isNumber(center.bounds[0]) && angular.isNumber(center.bounds[1]) && - angular.isNumber(center.bounds[1]) && angular.isNumber(center.bounds[2]))); - }, - - safeApply: function($scope, fn) { - var phase = $scope.$root.$$phase; - if (phase === '$apply' || phase === '$digest') { - $scope.$eval(fn); - } else { - $scope.$apply(fn); - } - }, - - isSameCenterOnMap: function(center, map) { - var urlProj = center.projection || 'EPSG:4326'; - var urlCenter = [center.lon, center.lat]; - var mapProj = map.getView().getProjection(); - var mapCenter = ol.proj.transform(map.getView().getCenter(), mapProj, urlProj); - var zoom = map.getView().getZoom(); - if (mapCenter[1].toFixed(4) === urlCenter[1].toFixed(4) && - mapCenter[0].toFixed(4) === urlCenter[0].toFixed(4) && - zoom === center.zoom) { - return true; - } - return false; - }, - - setCenter: function(view, projection, newCenter, map) { - - if (map && view.getCenter()) { - var pan = ol.animation.pan({ - duration: 150, - source: (view.getCenter()) - }); - map.beforeRender(pan); - } - - if (newCenter.projection === projection) { - view.setCenter([newCenter.lon, newCenter.lat]); - } else { - var coord = [newCenter.lon, newCenter.lat]; - view.setCenter(ol.proj.transform(coord, newCenter.projection, projection)); - } - }, - - setZoom: function(view, zoom, map) { - var z = ol.animation.zoom({ - duration: 150, - resolution: map.getView().getResolution() - }); - map.beforeRender(z); - view.setZoom(zoom); - }, - - isBoolean: function(value) { - return typeof value === 'boolean'; - }, - - obtainEffectiveMapId: function(d, mapId) { - var id; - var i; - if (!angular.isDefined(mapId)) { - if (Object.keys(d).length === 1) { - for (i in d) { - if (d.hasOwnProperty(i)) { - id = i; - } - } - } else if (Object.keys(d).length === 0) { - id = 'main'; - } else { - $log.error('[AngularJS - Openlayers] - You have more than 1 map on the DOM, ' + - 'you must provide the map ID to the olData.getXXX call'); - } - } else { - id = mapId; - } - return id; - }, - - createStyle: createStyle, - - setMapEvents: function(events, map, scope) { - if (isDefined(events) && angular.isArray(events.map)) { - for (var i in events.map) { - var event = events.map[i]; - setEvent(map, event, scope); - } - } - }, - - setVectorLayerEvents: function(events, map, scope, layerName) { - if (isDefined(events) && angular.isArray(events.layers)) { - angular.forEach(events.layers, function(eventType) { - angular.element(map.getViewport()).on(eventType, function(evt) { - var pixel = map.getEventPixel(evt); - var feature = map.forEachFeatureAtPixel(pixel, function(feature, olLayer) { - // only return the feature if it is in this layer (based on the name) - return (isDefinedAndNotNull(olLayer) && olLayer.get('name') === layerName) ? feature : null; - }); - if (isDefinedAndNotNull(feature)) { - scope.$emit('openlayers.layers.' + layerName + '.' + eventType, feature, evt); - } - }); - }); - } - }, - - setViewEvents: function(events, map, scope) { - if (isDefined(events) && angular.isArray(events.view)) { - var view = map.getView(); - angular.forEach(events.view, function(eventType) { - view.on(eventType, function(event) { - scope.$emit('openlayers.view.' + eventType, view, event); - }); - }); - } - }, - - detectLayerType: detectLayerType, - - createLayer: function(layer, projection, name) { - var oLayer; - var type = detectLayerType(layer); - var oSource = createSource(layer.source, projection); - if (!oSource) { - return; - } - - // Manage clustering - if ((type === 'Vector') && layer.clustering) { - oSource = new ol.source.Cluster({ - source: oSource, - distance: layer.clusteringDistance, - }); - } - - switch (type) { - case 'Image': - oLayer = new ol.layer.Image({ source: oSource }); - break; - case 'Tile': - oLayer = new ol.layer.Tile({ source: oSource }); - break; - case 'Heatmap': - oLayer = new ol.layer.Heatmap({ source: oSource }); - break; - case 'Vector': - oLayer = new ol.layer.Vector({ source: oSource }); - break; - } - - // set a layer name if given - if (isDefined(name)) { - oLayer.set('name', name); - } else if (isDefined(layer.name)) { - oLayer.set('name', layer.name); - } - - return oLayer; - }, - - createVectorLayer: function() { - return new ol.layer.Vector({ - source: new ol.source.Vector() - }); - }, - - notifyCenterUrlHashChanged: function(scope, center, search) { - if (center.centerUrlHash) { - var centerUrlHash = center.lat.toFixed(4) + ':' + center.lon.toFixed(4) + ':' + center.zoom; - if (!isDefined(search.c) || search.c !== centerUrlHash) { - scope.$emit('centerUrlHash', centerUrlHash); - } - } - }, - - getControlClasses: getControlClasses, - - detectControls: function(controls) { - var actualControls = {}; - var controlClasses = getControlClasses(); - - controls.forEach(function(control) { - for (var i in controlClasses) { - if (control instanceof controlClasses[i]) { - actualControls[i] = control; - } - } - }); - - return actualControls; - }, - - createFeature: function(data, viewProjection) { - var geometry; - - switch (data.type) { - case 'Polygon': - geometry = new ol.geom.Polygon(data.coords); - break; - default: - if (isDefined(data.coord) && data.projection === 'pixel') { - geometry = new ol.geom.Point(data.coord); - } else { - geometry = new ol.geom.Point([data.lon, data.lat]); - } - break; - } - - if (isDefined(data.projection) && data.projection !== 'pixel') { - geometry = geometry.transform(data.projection, viewProjection); - } - - var feature = new ol.Feature({ - geometry: geometry - }); - - if (isDefined(data.style)) { - var style = createStyle(data.style); - feature.setStyle(style); - } - return feature; - }, - - addLayerBeforeMarkers: addLayerBeforeMarkers, - - getGroup: getGroup, - - addLayerToGroup: function(layers, layer, name) { - var groupLayer = getGroup(layers, name); - - if (!isDefined(groupLayer)) { - groupLayer = createGroup(name); - addLayerBeforeMarkers(layers,groupLayer); - } - - layer.set('group', name); - addLayerBeforeMarkers(groupLayer.getLayers(), layer); - }, - - removeLayerFromGroup: function(layers, layer, name) { - var groupLayer = getGroup(layers, name); - layer.set('group'); - removeLayer(groupLayer.getLayers(), layer.index); - }, - - removeLayer: removeLayer, - - insertLayer: function(layers, index, layer) { - if (layers.getLength() < index) { - while (layers.getLength() < index) { - layers.push(null); - } - layer.index = index; - layers.push(layer); - } else { - layer.index = index; - layers.insertAt(layer.index, layer); - for (var i = index + 1; i < layers.getLength(); i++) { - var l = layers.item(i); - if (l === null) { - layers.removeAt(i); - break; - } else { - l.index = i; - } - } - } - }, - - createOverlay: function(element, pos) { - element.css('display', 'block'); - var ov = new ol.Overlay({ - position: pos, - element: element, - positioning: 'center-left' - }); - - return ov; - } - }; -}]); - -angular.module('openlayers-directive').factory('olMapDefaults', ["$q", "olHelpers", function($q, olHelpers) { - - var base64icon = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAApCAYAAADAk4LOAAAGmklEQVRYw' + - '7VXeUyTZxjvNnfELFuyIzOabermMZEeQC/OclkO49CpOHXOLJl/CAURuYbQi3KLgEhbrhZ1aDwmaoGq' + - 'KII6odATmH/scDFbdC7LvFqOCc+e95s2VG50X/LLm/f4/Z7neY/ne18aANCmAr5E/xZf1uDOkTcGcWR' + - '6hl9247tT5U7Y6SNvWsKT63P58qbfeLJG8M5qcgTknrvvrdDbsT7Ml+tv82X6vVxJE33aRmgSyYtcWV' + - 'MqX97Yv2JvW39UhRE2HuyBL+t+gK1116ly06EeWFNlAmHxlQE0OMiV6mQCScusKRlhS3QLeVJdl1+23' + - 'h5dY4FNB3thrbYboqptEFlphTC1hSpJnbRvxP4NWgsE5Jyz86QNNi/5qSUTGuFk1gu54tN9wuK2wc3o' + - '+Wc13RCmsoBwEqzGcZsxsvCSy/9wJKf7UWf1mEY8JWfewc67UUoDbDjQC+FqK4QqLVMGGR9d2wurKzq' + - 'Bk3nqIT/9zLxRRjgZ9bqQgub+DdoeCC03Q8j+0QhFhBHR/eP3U/zCln7Uu+hihJ1+bBNffLIvmkyP0g' + - 'pBZWYXhKussK6mBz5HT6M1Nqpcp+mBCPXosYQfrekGvrjewd59/GvKCE7TbK/04/ZV5QZYVWmDwH1mF' + - '3xa2Q3ra3DBC5vBT1oP7PTj4C0+CcL8c7C2CtejqhuCnuIQHaKHzvcRfZpnylFfXsYJx3pNLwhKzRAw' + - 'AhEqG0SpusBHfAKkxw3w4627MPhoCH798z7s0ZnBJ/MEJbZSbXPhER2ih7p2ok/zSj2cEJDd4CAe+5W' + - 'YnBCgR2uruyEw6zRoW6/DWJ/OeAP8pd/BGtzOZKpG8oke0SX6GMmRk6GFlyAc59K32OTEinILRJRcha' + - 'h8HQwND8N435Z9Z0FY1EqtxUg+0SO6RJ/mmXz4VuS+DpxXC3gXmZwIL7dBSH4zKE50wESf8qwVgrP1E' + - 'IlTO5JP9Igu0aexdh28F1lmAEGJGfh7jE6ElyM5Rw/FDcYJjWhbeiBYoYNIpc2FT/SILivp0F1ipDWk' + - '4BIEo2VuodEJUifhbiltnNBIXPUFCMpthtAyqws/BPlEF/VbaIxErdxPphsU7rcCp8DohC+GvBIPJS/' + - 'tW2jtvTmmAeuNO8BNOYQeG8G/2OzCJ3q+soYB5i6NhMaKr17FSal7GIHheuV3uSCY8qYVuEm1cOzqdW' + - 'r7ku/R0BDoTT+DT+ohCM6/CCvKLKO4RI+dXPeAuaMqksaKrZ7L3FE5FIFbkIceeOZ2OcHO6wIhTkNo0' + - 'ffgjRGxEqogXHYUPHfWAC/lADpwGcLRY3aeK4/oRGCKYcZXPVoeX/kelVYY8dUGf8V5EBRbgJXT5QIP' + - 'hP9ePJi428JKOiEYhYXFBqou2Guh+p/mEB1/RfMw6rY7cxcjTrneI1FrDyuzUSRm9miwEJx8E/gUmql' + - 'yvHGkneiwErR21F3tNOK5Tf0yXaT+O7DgCvALTUBXdM4YhC/IawPU+2PduqMvuaR6eoxSwUk75ggqsY' + - 'J7VicsnwGIkZBSXKOUww73WGXyqP+J2/b9c+gi1YAg/xpwck3gJuucNrh5JvDPvQr0WFXf0piyt8f8/' + - 'WI0hV4pRxxkQZdJDfDJNOAmM0Ag8jyT6hz0WGXWuP94Yh2jcfjmXAGvHCMslRimDHYuHuDsy2QtHuIa' + - 'vznhbYURq5R57KpzBBRZKPJi8eQg48h4j8SDdowifdIrEVdU+gbO6QNvRRt4ZBthUaZhUnjlYObNagV' + - '3keoeru3rU7rcuceqU1mJBxy+BWZYlNEBH+0eH4vRiB+OYybU2hnblYlTvkHinM4m54YnxSyaZYSF6R' + - '3jwgP7udKLGIX6r/lbNa9N6y5MFynjWDtrHd75ZvTYAPO/6RgF0k76mQla3FGq7dO+cH8sKn0Vo7nDl' + - 'lwAhqwLPkxrHwWmHJOo+AKJ4rab5OgrM7rVu8eWb2Pu0Dh4eDgXoOfvp7Y7QeqknRmvcTBEyq9m/HQQ' + - 'SCSz6LHq3z0yzsNySRfMS253wl2KyRDbcZPcfJKjZmSEOjcxyi+Y8dUOtsIEH6R2wNykdqrkYJ0RV92' + - 'H0W58pkfQk7cKevsLK10Py8SdMGfXNXATY+pPbyJR/ET6n9nIfztNtZYRV9XniQu9IA2vOVgy4ir7GC' + - 'LVmmd+zjkH0eAF9Po6K61pmCXHxU5rHMYd1ftc3owjwRSVRzLjKvqZEty6cRUD7jGqiOdu5HG6MdHjN' + - 'cNYGqfDm5YRzLBBCCDl/2bk8a8gdbqcfwECu62Fg/HrggAAAABJRU5ErkJggg=='; - - var _getDefaults = function() { - return { - view: { - projection: 'EPSG:3857', - minZoom: undefined, - maxZoom: undefined, - rotation: 0, - extent: undefined - }, - center: { - lat: 0, - lon: 0, - zoom: 1, - autodiscover: false, - bounds: [], - centerUrlHash: false, - projection: 'EPSG:4326' - }, - styles: { - path: { - stroke: { - color: 'blue', - width: 8 - } - }, - marker: { - image: new ol.style.Icon({ - anchor: [0.5, 1], - anchorXUnits: 'fraction', - anchorYUnits: 'fraction', - opacity: 0.90, - src: base64icon - }) - } - }, - events: { - map: [], - markers: [], - layers: [] - }, - controls: { - attribution: true, - rotate: false, - zoom: true - }, - interactions: { - mouseWheelZoom: false - }, - renderer: 'canvas' - }; - }; - - var isDefined = olHelpers.isDefined; - var defaults = {}; - - // Get the _defaults dictionary, and override the properties defined by the user - return { - getDefaults: function(scope) { - if (!isDefined(scope)) { - for (var i in defaults) { - return defaults[i]; - } - } - return defaults[scope.$id]; - }, - - setDefaults: function(scope) { - var userDefaults = scope.defaults; - var scopeId = scope.$id; - var newDefaults = _getDefaults(); - - if (isDefined(userDefaults)) { - - if (isDefined(userDefaults.layers)) { - newDefaults.layers = angular.copy(userDefaults.layers); - } - - if (isDefined(userDefaults.controls)) { - newDefaults.controls = angular.copy(userDefaults.controls); - } - - if (isDefined(userDefaults.events)) { - newDefaults.events = angular.copy(userDefaults.events); - } - - if (isDefined(userDefaults.interactions)) { - newDefaults.interactions = angular.copy(userDefaults.interactions); - } - - if (isDefined(userDefaults.renderer)) { - newDefaults.renderer = userDefaults.renderer; - } - - if (isDefined(userDefaults.view)) { - newDefaults.view.maxZoom = userDefaults.view.maxZoom || newDefaults.view.maxZoom; - newDefaults.view.minZoom = userDefaults.view.minZoom || newDefaults.view.minZoom; - newDefaults.view.projection = userDefaults.view.projection || newDefaults.view.projection; - newDefaults.view.extent = userDefaults.view.extent || newDefaults.view.extent; - } - - if (isDefined(userDefaults.styles)) { - newDefaults.styles = angular.extend(newDefaults.styles, userDefaults.styles); - } - - } - - defaults[scopeId] = newDefaults; - return newDefaults; - } - }; -}]); - -})); \ No newline at end of file diff --git a/dist/angular-openlayers-directive.min.js b/dist/angular-openlayers-directive.min.js deleted file mode 100644 index 925988a4..00000000 --- a/dist/angular-openlayers-directive.min.js +++ /dev/null @@ -1,31 +0,0 @@ -/**! - * The MIT License - * - * Copyright (c) 2013 the angular-openlayers-directive Team, http://tombatossals.github.io/angular-openlayers-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-google-maps - * https://github.com/tombatossals/angular-openlayers-directive - * - * @authors https://github.com/tombatossals/angular-openlayers-directive/graphs/contributors - */ - -/*! angular-openlayers-directive 06-11-2015 */ -!function(a,b){"function"==typeof define&&define.amd?define(["ol"],function(c){return a.angularOpenlayersDirective=b(c)}):a.angularOpenlayersDirective=b(a.ol)}(this,function(a){angular.module("openlayers-directive",["ngSanitize"]).directive("openlayers",["$log","$q","$compile","olHelpers","olMapDefaults","olData",function(b,c,d,e,f,g){return{restrict:"EA",transclude:!0,replace:!0,scope:{center:"=olCenter",defaults:"=olDefaults",view:"=olView",events:"=olEvents"},template:'
',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p});if(!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d){if("pixel"===g.view.projection)return void i.setCenter(c.coord);var e=a.proj.transform(d,g.view.projection,c.projection);(e[1]!==c.lat||e[0]!==c.lon)&&p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}}),f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i))}else d=j(c,f),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i))}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)}),e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope();i.getMap().then(function(b){var d=e.getControlClasses,i=d();return a.$on("$destroy",function(){b.removeControl(f)}),h(a.properties)&&h(a.properties.control)?(f=a.properties.control,void b.addControl(f)):void(c.name&&(h(a.properties)&&(g=a.properties),f=new i[c.name](g),b.addControl(f)))})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return e.on("pointerdown",j),e.on("pointerup",j),e.on("pointerdrag",j),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e)}),k(c.properties)?void c.$watch("properties",function(d){if(e.getViewport().removeEventListener("mousemove",d.handleInteraction),e.getViewport().removeEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",d.handleTapInteraction),e.getViewport().removeEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",d.removeAllOverlays),d.handleInteraction=function(b){if(!d.label.show){var f=!1,g=e.getEventPixel(b),i=e.forEachFeatureAtPixel(g,function(a){return a}),j=!1;i===r&&(j=!0,f=!0,k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),!d.onClick||"click"!==b.type&&"touchend"!==b.type||c.$apply(function(){d.onClick.call(r,b,d)}),e.getTarget().style.cursor="pointer"),!f&&p&&(j=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),j&&b.preventDefault()}},d.handleTapInteraction=function(){function a(){c=!0,b&&clearTimeout(b),b=setTimeout(function(){c=!1,b=null},500)}var b,c=!1;return e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",a),function(){c||(d.handleInteraction.apply(null,arguments),a())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||d.onClick)&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q","olHelpers",function(a,b,c){var d=c.obtainEffectiveMapId,e={},f=function(a,b){var c=d(a,b);a[c].resolvedDefer=!0},g=function(a,c){var e,f=d(a,c);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},h=function(a,b){var c,e=d(a,b);return c=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:g(a,b)};this.setMap=function(a,b){var c=g(e,b);c.resolve(a),f(e,b)},this.getMap=function(a){var b=h(e,a);return b.promise}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function x(a,b){var c;if(b?c=a[b]:(b="style",c=a),"style"===b&&a instanceof Function)return a;if(!(c instanceof Object))return c;var d;if("[object Object]"===Object.prototype.toString.call(c)){d={};var e=l[b];if(e&&c instanceof e)return c;Object.getOwnPropertyNames(c).forEach(function(a,f,g){var h=l[a];return e&&h&&h.prototype instanceof l[b]?(console.assert(1===g.length,"Extra parameters for "+b),d=x(c,a),m(d,h)):(d[a]=x(c,a),void("text"!==a&&"string"!=typeof d[a]&&(d[a]=m(d[a],l[a]))))})}else d=c;return m(d,l[b])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"TileVector":return"Vector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");var i="http://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,l=window.devicePixelRatio;l>1&&(i=i.replace(".png","@2x.png")),g=new a.source.XYZ({url:i,attributions:s(b),tilePixelRatio:l>1?2:1,wrapX:b.wrapX===!0?1:0});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,attributions:s(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:b.params,wrapX:b.wrapX?0:1});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var m={crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:b.params,attributions:s(b),wrapX:b.wrapX?0:1};b.url&&(m.url=b.url),b.urls&&(m.urls=b.urls),g=new a.source.TileWMS(m);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var n={projection:f,layer:b.layer,attributions:s(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),wrapX:b.wrapX?0:1};e(b.url)&&(n.url=b.url),e(b.urls)&&(n.urls=b.urls),g=new a.source.WMTS(n);break;case"OSM":g=new a.source.OSM({attributions:s(b),wrapX:b.wrapX===!0?1:0}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var o={key:b.key,attributions:s(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:b.wrapX===!0?1:0};b.maxZoom&&(o.maxZoom=b.maxZoom),g=new a.source.BingMaps(o);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:s(b),layer:b.layer,wrapX:b.wrapX===!0?1:0});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var p="http://services.arcgisonline.com/ArcGIS/rest/services/",r=p+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:s(b),url:r,wrapX:b.wrapX===!0?1:0});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url,wrapX:b.wrapX===!0?1:0});else{g=new a.source.Vector;var t=f;e(b.geojson.projection)&&(t=b.geojson.projection);var u=new a.format.GeoJSON,v=u.readFeatures(b.geojson.object,{featureProjection:t});g.addFeatures(v)}break;case"JSONP":if(!b.url)return void c.error("[AngularJS - Openlayers] - You need an url properly configured to add a JSONP layer.");e(b.url)&&(g=new a.source.Vector({format:new a.format.GeoJSON,loader:function(){var a=b.url+"&outputFormat=text/javascript&format_options=callback:JSON_CALLBACK";d.jsonp(a,{cache:b.cache}).success(function(a){g.addFeatures(g.readFeatures(a))}).error(function(a){c(a)})},wrapX:b.wrapX===!0?1:0}));break;case"TopoJSON":if(!b.topojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a topojson property to add a TopoJSON layer.");g=b.url?new a.source.Vector({format:new a.format.TopoJSON,url:b.url,wrapX:b.wrapX===!0?1:0}):new a.source.Vector(angular.extend(b.topojson,{format:new a.format.TopoJSON,wrapX:b.wrapX===!0?1:0}));break;case"TileJSON":g=new a.source.TileJSON({url:b.url,attributions:s(b),crossOrigin:"anonymous",wrapX:b.wrapX===!0?1:0});break;case"TileVector":b.url&&b.format||c.error("[AngularJS - Openlayers] - TileVector Layer needs valid url and format properties"),g=new a.source.TileVector({url:b.url,projection:f,attributions:s(b),format:b.format,tileGrid:new a.tilegrid.createXYZ({maxZoom:b.maxZoom||19}),wrapX:b.wrapX===!0?1:0});break;case"TileTMS":b.url&&b.tileGrid||c.error("[AngularJS - Openlayers] - TileTMS Layer needs valid url and tileGrid properties"),g=new a.source.TileImage({url:b.url,maxExtent:b.maxExtent,attributions:s(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=a[2];if(0>d||0>e)return"";var f=b.url+c+"/"+d+"/"+e+".png";return f},wrapX:b.wrapX===!0?1:0});break;case"TileImage":g=new a.source.TileImage({url:b.url,attributions:s(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=-a[2]-1,f=b.url.replace("{z}",c.toString()).replace("{x}",d.toString()).replace("{y}",e.toString());return f},wrapX:b.wrapX===!0?1:0});break;case"KML":var w=b.extractStyles||!1;g=new a.source.Vector({url:b.url,format:new a.format.KML,radius:b.radius,extractStyles:w,wrapX:b.wrapX===!0?1:0});break;case"Stamen":if(!b.layer||!q(b.layer))return void c.error("[AngularJS - Openlayers] - You need a valid Stamen layer.");g=new a.source.Stamen({layer:b.layer,wrapX:b.wrapX===!0?1:0});break;case"ImageStatic":if(!b.url||!angular.isArray(b.imageSize)||2!==b.imageSize.length)return void c.error("[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.");g=new a.source.ImageStatic({url:b.url,attributions:s(b),imageSize:b.imageSize,projection:f,imageExtent:f.getExtent(),imageLoadFunction:b.imageLoadFunction,wrapX:b.wrapX===!0?1:0});break;case"XYZ":b.url||c.error("[AngularJS - Openlayers] - XYZ Layer needs valid url and params properties"),g=new a.source.XYZ({url:b.url,attributions:s(b),minZoom:b.minZoom,maxZoom:b.maxZoom,wrapX:b.wrapX===!0?1:0})}return g||c.warn('[AngularJS - Openlayers] - No source could be found for type "'+b.type+'"'),g},s=function(b){var c=[];return e(b.attribution)&&c.unshift(new a.Attribution({html:b.attribution})),c},t=function(b){var c=new a.layer.Group;return c.set("name",b),c},u=function(b,c){var d;return angular.forEach(b,function(b){return b instanceof a.layer.Group&&b.get("name")===c?void(d=b):void 0}),d},v=function(a,b){for(var c,d=0;d',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p});if(!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d){if("pixel"===g.view.projection)return void i.setCenter(c.coord);var e=a.proj.transform(d,g.view.projection,c.projection);(e[1]!==c.lat||e[0]!==c.lon)&&p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}}),f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i))}else d=j(c,f),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i))}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)}),e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope();i.getMap().then(function(b){var d=e.getControlClasses,i=d();return a.$on("$destroy",function(){b.removeControl(f)}),h(a.properties)&&h(a.properties.control)?(f=a.properties.control,void b.addControl(f)):void(c.name&&(h(a.properties)&&(g=a.properties),f=new i[c.name](g),b.addControl(f)))})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return e.on("pointerdown",j),e.on("pointerup",j),e.on("pointerdrag",j),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e)}),k(c.properties)?void c.$watch("properties",function(d){if(e.getViewport().removeEventListener("mousemove",d.handleInteraction),e.getViewport().removeEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",d.handleTapInteraction),e.getViewport().removeEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",d.removeAllOverlays),d.handleInteraction=function(b){if(!d.label.show){var f=!1,g=e.getEventPixel(b),i=e.forEachFeatureAtPixel(g,function(a){return a}),j=!1;i===r&&(j=!0,f=!0,k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),!d.onClick||"click"!==b.type&&"touchend"!==b.type||c.$apply(function(){d.onClick.call(r,b,d)}),e.getTarget().style.cursor="pointer"),!f&&p&&(j=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),j&&b.preventDefault()}},d.handleTapInteraction=function(){function a(){c=!0,b&&clearTimeout(b),b=setTimeout(function(){c=!1,b=null},500)}var b,c=!1;return e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",a),function(){c||(d.handleInteraction.apply(null,arguments),a())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||d.onClick)&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q","olHelpers",function(a,b,c){var d=c.obtainEffectiveMapId,e={},f=function(a,b){var c=d(a,b);a[c].resolvedDefer=!0},g=function(a,c){var e,f=d(a,c);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},h=function(a,b){var c,e=d(a,b);return c=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:g(a,b)};this.setMap=function(a,b){var c=g(e,b);c.resolve(a),f(e,b)},this.getMap=function(a){var b=h(e,a);return b.promise}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function x(a,b){var c;if(b?c=a[b]:(b="style",c=a),"style"===b&&a instanceof Function)return a;if(!(c instanceof Object))return c;var d;if("[object Object]"===Object.prototype.toString.call(c)){d={};var e=l[b];if(e&&c instanceof e)return c;Object.getOwnPropertyNames(c).forEach(function(a,f,g){var h=l[a];return e&&h&&h.prototype instanceof l[b]?(console.assert(1===g.length,"Extra parameters for "+b),d=x(c,a),m(d,h)):(d[a]=x(c,a),void("text"!==a&&"string"!=typeof d[a]&&(d[a]=m(d[a],l[a]))))})}else d=c;return m(d,l[b])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"TileVector":return"Vector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");var i="http://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,l=window.devicePixelRatio;l>1&&(i=i.replace(".png","@2x.png")),g=new a.source.XYZ({url:i,attributions:s(b),tilePixelRatio:l>1?2:1,wrapX:b.wrapX===!0?1:0});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,attributions:s(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:b.params,wrapX:b.wrapX?0:1});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var m={crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:b.params,attributions:s(b),wrapX:b.wrapX?0:1};b.url&&(m.url=b.url),b.urls&&(m.urls=b.urls),g=new a.source.TileWMS(m);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var n={projection:f,layer:b.layer,attributions:s(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),wrapX:b.wrapX?0:1};e(b.url)&&(n.url=b.url),e(b.urls)&&(n.urls=b.urls),g=new a.source.WMTS(n);break;case"OSM":g=new a.source.OSM({attributions:s(b),wrapX:b.wrapX===!0?1:0}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var o={key:b.key,attributions:s(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:b.wrapX===!0?1:0};b.maxZoom&&(o.maxZoom=b.maxZoom),g=new a.source.BingMaps(o);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:s(b),layer:b.layer,wrapX:b.wrapX===!0?1:0});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var p="http://services.arcgisonline.com/ArcGIS/rest/services/",r=p+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:s(b),url:r,wrapX:b.wrapX===!0?1:0});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url,wrapX:b.wrapX===!0?1:0});else{g=new a.source.Vector;var t=f;e(b.geojson.projection)&&(t=b.geojson.projection);var u=new a.format.GeoJSON,v=u.readFeatures(b.geojson.object,{featureProjection:t});g.addFeatures(v)}break;case"JSONP":if(!b.url)return void c.error("[AngularJS - Openlayers] - You need an url properly configured to add a JSONP layer.");e(b.url)&&(g=new a.source.Vector({format:new a.format.GeoJSON,loader:function(){var a=b.url+"&outputFormat=text/javascript&format_options=callback:JSON_CALLBACK";d.jsonp(a,{cache:b.cache}).success(function(a){g.addFeatures(g.readFeatures(a))}).error(function(a){c(a)})},wrapX:b.wrapX===!0?1:0}));break;case"TopoJSON":if(!b.topojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a topojson property to add a TopoJSON layer.");g=b.url?new a.source.Vector({format:new a.format.TopoJSON,url:b.url,wrapX:b.wrapX===!0?1:0}):new a.source.Vector(angular.extend(b.topojson,{format:new a.format.TopoJSON,wrapX:b.wrapX===!0?1:0}));break;case"TileJSON":g=new a.source.TileJSON({url:b.url,attributions:s(b),crossOrigin:"anonymous",wrapX:b.wrapX===!0?1:0});break;case"TileVector":b.url&&b.format||c.error("[AngularJS - Openlayers] - TileVector Layer needs valid url and format properties"),g=new a.source.TileVector({url:b.url,projection:f,attributions:s(b),format:b.format,tileGrid:new a.tilegrid.createXYZ({maxZoom:b.maxZoom||19}),wrapX:b.wrapX===!0?1:0});break;case"TileTMS":b.url&&b.tileGrid||c.error("[AngularJS - Openlayers] - TileTMS Layer needs valid url and tileGrid properties"),g=new a.source.TileImage({url:b.url,maxExtent:b.maxExtent,attributions:s(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=a[2];if(0>d||0>e)return"";var f=b.url+c+"/"+d+"/"+e+".png";return f},wrapX:b.wrapX===!0?1:0});break;case"TileImage":g=new a.source.TileImage({url:b.url,attributions:s(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=-a[2]-1,f=b.url.replace("{z}",c.toString()).replace("{x}",d.toString()).replace("{y}",e.toString());return f},wrapX:b.wrapX===!0?1:0});break;case"KML":var w=b.extractStyles||!1;g=new a.source.Vector({url:b.url,format:new a.format.KML,radius:b.radius,extractStyles:w,wrapX:b.wrapX===!0?1:0});break;case"Stamen":if(!b.layer||!q(b.layer))return void c.error("[AngularJS - Openlayers] - You need a valid Stamen layer.");g=new a.source.Stamen({layer:b.layer,wrapX:b.wrapX===!0?1:0});break;case"ImageStatic":if(!b.url||!angular.isArray(b.imageSize)||2!==b.imageSize.length)return void c.error("[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.");g=new a.source.ImageStatic({url:b.url,attributions:s(b),imageSize:b.imageSize,projection:f,imageExtent:f.getExtent(),imageLoadFunction:b.imageLoadFunction,wrapX:b.wrapX===!0?1:0});break;case"XYZ":b.url||c.error("[AngularJS - Openlayers] - XYZ Layer needs valid url and params properties"),g=new a.source.XYZ({url:b.url,attributions:s(b),minZoom:b.minZoom,maxZoom:b.maxZoom,wrapX:b.wrapX===!0?1:0})}return g||c.warn('[AngularJS - Openlayers] - No source could be found for type "'+b.type+'"'),g},s=function(b){var c=[];return e(b.attribution)&&c.unshift(new a.Attribution({html:b.attribution})),c},t=function(b){var c=new a.layer.Group;return c.set("name",b),c},u=function(b,c){var d;return angular.forEach(b,function(b){return b instanceof a.layer.Group&&b.get("name")===c?void(d=b):void 0}),d},v=function(a,b){for(var c,d=0;d', - controller: function($scope) { - var _map = $q.defer(); - $scope.getMap = function() { - return _map.promise; - }; - - $scope.setMap = function(map) { - _map.resolve(map); - }; - - this.getOpenlayersScope = function() { - return $scope; - }; - }, - link: function(scope, element, attrs) { - var isDefined = olHelpers.isDefined; - var createLayer = olHelpers.createLayer; - var setMapEvents = olHelpers.setMapEvents; - var setViewEvents = olHelpers.setViewEvents; - var createView = olHelpers.createView; - var defaults = olMapDefaults.setDefaults(scope); - - // Set width and height if they are defined - if (isDefined(attrs.width)) { - if (isNaN(attrs.width)) { - element.css('width', attrs.width); - } else { - element.css('width', attrs.width + 'px'); - } - } - - if (isDefined(attrs.height)) { - if (isNaN(attrs.height)) { - element.css('height', attrs.height); - } else { - element.css('height', attrs.height + 'px'); - } - } - - if (isDefined(attrs.lat)) { - defaults.center.lat = parseFloat(attrs.lat); - } - - if (isDefined(attrs.lon)) { - defaults.center.lon = parseFloat(attrs.lon); - } - - if (isDefined(attrs.zoom)) { - defaults.center.zoom = parseFloat(attrs.zoom); - } - - var controls = ol.control.defaults(defaults.controls); - var interactions = ol.interaction.defaults(defaults.interactions); - var view = createView(defaults.view); - - // Create the Openlayers Map Object with the options - var map = new ol.Map({ - target: element[0], - controls: controls, - interactions: interactions, - renderer: defaults.renderer, - view: view - }); - - // If no layer is defined, set the default tileLayer - if (!attrs.customLayers) { - var l = { - type: 'Tile', - source: { - type: 'OSM' - } - }; - var layer = createLayer(l, view.getProjection(), 'default'); - map.addLayer(layer); - map.set('default', true); - } - - if (!isDefined(attrs.olCenter)) { - var c = ol.proj.transform([defaults.center.lon, - defaults.center.lat - ], - defaults.center.projection, view.getProjection() - ); - view.setCenter(c); - view.setZoom(defaults.center.zoom); - } - - // Set the Default events for the map - setMapEvents(defaults.events, map, scope); - - //Set the Default events for the map view - setViewEvents(defaults.events, map, scope); - - // Resolve the map object to the promises - scope.setMap(map); - olData.setMap(map, attrs.id); - - } - }; - }); - -angular.module('openlayers-directive').directive('olCenter', function($log, $location, olMapDefaults, olHelpers) { - - return { - restrict: 'A', - scope: false, - replace: false, - require: 'openlayers', - - link: function(scope, element, attrs, controller) { - var safeApply = olHelpers.safeApply; - var isValidCenter = olHelpers.isValidCenter; - var isDefined = olHelpers.isDefined; - var isArray = olHelpers.isArray; - var isNumber = olHelpers.isNumber; - var isSameCenterOnMap = olHelpers.isSameCenterOnMap; - var setCenter = olHelpers.setCenter; - var setZoom = olHelpers.setZoom; - var olScope = controller.getOpenlayersScope(); - - olScope.getMap().then(function(map) { - var defaults = olMapDefaults.getDefaults(olScope); - var view = map.getView(); - var center = olScope.center; - - if (attrs.olCenter.search('-') !== -1) { - $log.error('[AngularJS - Openlayers] The "center" variable can\'t use ' + - 'a "-" on his key name: "' + attrs.center + '".'); - setCenter(view, defaults.view.projection, defaults.center, map); - return; - } - - if (!isDefined(center)) { - center = {}; - } - - if (!isValidCenter(center)) { - $log.warn('[AngularJS - Openlayers] invalid \'center\''); - center.lat = defaults.center.lat; - center.lon = defaults.center.lon; - center.zoom = defaults.center.zoom; - center.projection = defaults.center.projection; - } - - if (!center.projection) { - if (defaults.view.projection !== 'pixel') { - center.projection = defaults.center.projection; - } else { - center.projection = 'pixel'; - } - } - - if (!isNumber(center.zoom)) { - center.zoom = 1; - } - - setCenter(view, defaults.view.projection, center, map); - view.setZoom(center.zoom); - - var centerUrlHash; - if (center.centerUrlHash === true) { - var extractCenterFromUrl = function() { - var search = $location.search(); - var centerParam; - if (isDefined(search.c)) { - var cParam = search.c.split(':'); - if (cParam.length === 3) { - centerParam = { - lat: parseFloat(cParam[0]), - lon: parseFloat(cParam[1]), - zoom: parseInt(cParam[2], 10) - }; - } - } - return centerParam; - }; - centerUrlHash = extractCenterFromUrl(); - - olScope.$on('$locationChangeSuccess', function() { - var urlCenter = extractCenterFromUrl(); - if (urlCenter && !isSameCenterOnMap(urlCenter, map)) { - safeApply(olScope, function(scope) { - scope.center.lat = urlCenter.lat; - scope.center.lon = urlCenter.lon; - scope.center.zoom = urlCenter.zoom; - }); - } - }); - } - - var geolocation; - olScope.$watchCollection('center', function(center) { - - if (!center) { - return; - } - - if (!center.projection) { - center.projection = defaults.center.projection; - } - - if (center.autodiscover) { - if (!geolocation) { - geolocation = new ol.Geolocation({ - projection: ol.proj.get(center.projection) - }); - - geolocation.on('change', function() { - if (center.autodiscover) { - var location = geolocation.getPosition(); - safeApply(olScope, function(scope) { - scope.center.lat = location[1]; - scope.center.lon = location[0]; - scope.center.zoom = 12; - scope.center.autodiscover = false; - geolocation.setTracking(false); - }); - } - }); - } - geolocation.setTracking(true); - return; - } - - if (!isValidCenter(center)) { - $log.warn('[AngularJS - Openlayers] invalid \'center\''); - center = defaults.center; - } - - var viewCenter = view.getCenter(); - if (viewCenter) { - if (defaults.view.projection === 'pixel') { - view.setCenter(center.coord); - return; - } - var actualCenter = ol.proj.transform(viewCenter, defaults.view.projection, center.projection); - if (!(actualCenter[1] === center.lat && actualCenter[0] === center.lon)) { - setCenter(view, defaults.view.projection, center, map); - } - } - - if (view.getZoom() !== center.zoom) { - setZoom(view, center.zoom, map); - } - }); - - map.on('moveend', function() { - safeApply(olScope, function(scope) { - - if (!isDefined(scope.center)) { - return; - } - - var center = map.getView().getCenter(); - scope.center.zoom = view.getZoom(); - - if (defaults.view.projection === 'pixel') { - scope.center.coord = center; - return; - } - - if (scope.center) { - var proj = ol.proj.transform(center, defaults.view.projection, scope.center.projection); - scope.center.lat = proj[1]; - scope.center.lon = proj[0]; - - // Notify the controller about a change in the center position - olHelpers.notifyCenterUrlHashChanged(olScope, scope.center, $location.search()); - - // Calculate the bounds if needed - if (isArray(scope.center.bounds)) { - var extent = view.calculateExtent(map.getSize()); - var centerProjection = scope.center.projection; - var viewProjection = defaults.view.projection; - scope.center.bounds = ol.proj.transformExtent(extent, viewProjection, centerProjection); - } - } - }); - }); - - }); - } - }; -}); - -angular.module('openlayers-directive').directive('olLayer', function($log, $q, olMapDefaults, olHelpers) { - - return { - restrict: 'E', - scope: { - properties: '=olLayerProperties' - }, - replace: false, - require: '^openlayers', - link: function(scope, element, attrs, controller) { - var isDefined = olHelpers.isDefined; - var equals = olHelpers.equals; - var olScope = controller.getOpenlayersScope(); - var createLayer = olHelpers.createLayer; - var setVectorLayerEvents = olHelpers.setVectorLayerEvents; - var detectLayerType = olHelpers.detectLayerType; - var createStyle = olHelpers.createStyle; - var isBoolean = olHelpers.isBoolean; - var addLayerBeforeMarkers = olHelpers.addLayerBeforeMarkers; - var isNumber = olHelpers.isNumber; - var insertLayer = olHelpers.insertLayer; - var removeLayer = olHelpers.removeLayer; - var addLayerToGroup = olHelpers.addLayerToGroup; - var removeLayerFromGroup = olHelpers.removeLayerFromGroup; - var getGroup = olHelpers.getGroup; - - olScope.getMap().then(function(map) { - var projection = map.getView().getProjection(); - var defaults = olMapDefaults.setDefaults(olScope); - var layerCollection = map.getLayers(); - var olLayer; - - scope.$on('$destroy', function() { - if (scope.properties.group) { - removeLayerFromGroup(layerCollection, olLayer, scope.properties.group); - } else { - removeLayer(layerCollection, olLayer.index); - } - - map.removeLayer(olLayer); - }); - - if (!isDefined(scope.properties)) { - if (isDefined(attrs.sourceType) && isDefined(attrs.sourceUrl)) { - var l = { - source: { - url: attrs.sourceUrl, - type: attrs.sourceType - } - }; - - olLayer = createLayer(l, projection, attrs.layerName); - if (detectLayerType(l) === 'Vector') { - setVectorLayerEvents(defaults.events, map, scope, attrs.name); - } - addLayerBeforeMarkers(layerCollection, olLayer); - } - return; - } - - scope.$watch('properties', function(properties, oldProperties) { - if (!isDefined(properties.source) || !isDefined(properties.source.type)) { - return; - } - - if (!isDefined(properties.visible)) { - properties.visible = true; - return; - } - - if (!isDefined(properties.opacity)) { - properties.opacity = 1; - return; - } - - var style; - var group; - var collection; - if (!isDefined(olLayer)) { - olLayer = createLayer(properties, projection); - if (isDefined(properties.group)) { - addLayerToGroup(layerCollection, olLayer, properties.group); - } else if (isDefined(properties.index)) { - insertLayer(layerCollection, properties.index, olLayer); - } else { - addLayerBeforeMarkers(layerCollection, olLayer); - } - - if (detectLayerType(properties) === 'Vector') { - setVectorLayerEvents(defaults.events, map, scope, properties.name); - } - - if (isBoolean(properties.visible)) { - olLayer.setVisible(properties.visible); - } - - if (properties.opacity) { - olLayer.setOpacity(properties.opacity); - } - - if (angular.isArray(properties.extent)) { - olLayer.setExtent(properties.extent); - } - - if (properties.style) { - if (!angular.isFunction(properties.style)) { - style = createStyle(properties.style); - } else { - style = properties.style; - } - // not every layer has a setStyle method - if (olLayer.setStyle && angular.isFunction(olLayer.setStyle)) { - olLayer.setStyle(style); - } - } - - } else { - var isNewLayer = (function(olLayer) { - // this function can be used to verify whether a new layer instance has - // been created. This is needed in order to re-assign styles, opacity - // etc... - return function(layer) { - return layer !== olLayer; - }; - })(olLayer); - - // set source properties - if (isDefined(oldProperties) && !equals(properties.source, oldProperties.source)) { - var idx = olLayer.index; - collection = layerCollection; - group = olLayer.get('group'); - - if (group) { - collection = getGroup(layerCollection, group).getLayers(); - } - - collection.removeAt(idx); - - olLayer = createLayer(properties, projection); - olLayer.set('group', group); - - if (isDefined(olLayer)) { - insertLayer(collection, idx, olLayer); - - if (detectLayerType(properties) === 'Vector') { - setVectorLayerEvents(defaults.events, map, scope, properties.name); - } - } - } - - // set opacity - if (isDefined(oldProperties) && - properties.opacity !== oldProperties.opacity || isNewLayer(olLayer)) { - if (isNumber(properties.opacity) || isNumber(parseFloat(properties.opacity))) { - olLayer.setOpacity(properties.opacity); - } - } - - // set index - if (isDefined(properties.index) && properties.index !== olLayer.index) { - collection = layerCollection; - group = olLayer.get('group'); - - if (group) { - collection = getGroup(layerCollection, group).getLayers(); - } - - removeLayer(collection, olLayer.index); - insertLayer(collection, properties.index, olLayer); - } - - // set group - if (isDefined(properties.group) && properties.group !== oldProperties.group) { - removeLayerFromGroup(layerCollection, olLayer, oldProperties.group); - addLayerToGroup(layerCollection, olLayer, properties.group); - } - - // set visibility - if (isDefined(oldProperties) && - isBoolean(properties.visible) && - properties.visible !== oldProperties.visible || isNewLayer(olLayer)) { - olLayer.setVisible(properties.visible); - } - - // set style - if (isDefined(properties.style) && - !equals(properties.style, oldProperties.style) || isNewLayer(olLayer)) { - if (!angular.isFunction(properties.style)) { - style = createStyle(properties.style); - } else { - style = properties.style; - } - // not every layer has a setStyle method - if (olLayer.setStyle && angular.isFunction(olLayer.setStyle)) { - olLayer.setStyle(style); - } - } - } - }, true); - }); - } - }; -}); - -angular.module('openlayers-directive').directive('olPath', function($log, $q, olMapDefaults, olHelpers) { - - return { - restrict: 'E', - scope: { - properties: '=olGeomProperties' - }, - require: '^openlayers', - replace: true, - template: '', - - link: function(scope, element, attrs, controller) { - var isDefined = olHelpers.isDefined; - var createFeature = olHelpers.createFeature; - var createOverlay = olHelpers.createOverlay; - var createVectorLayer = olHelpers.createVectorLayer; - var insertLayer = olHelpers.insertLayer; - var removeLayer = olHelpers.removeLayer; - var olScope = controller.getOpenlayersScope(); - - olScope.getMap().then(function(map) { - var mapDefaults = olMapDefaults.getDefaults(olScope); - var viewProjection = mapDefaults.view.projection; - - var layer = createVectorLayer(); - var layerCollection = map.getLayers(); - - insertLayer(layerCollection, layerCollection.getLength(), layer); - - scope.$on('$destroy', function() { - removeLayer(layerCollection, layer.index); - }); - - if (isDefined(attrs.coords)) { - var proj = attrs.proj || 'EPSG:4326'; - var coords = JSON.parse(attrs.coords); - var data = { - type: 'Polygon', - coords: coords, - projection: proj, - style: mapDefaults.styles.path - }; - var feature = createFeature(data, viewProjection); - layer.getSource().addFeature(feature); - - if (attrs.message) { - scope.message = attrs.message; - var extent = feature.getGeometry().getExtent(); - var label = createOverlay(element, extent); - map.addOverlay(label); - } - return; - } - }); - } - }; -}); - -angular.module('openlayers-directive').directive('olView', function($log, $q, olData, olMapDefaults, olHelpers) { - return { - restrict: 'A', - scope: false, - replace: false, - require: 'openlayers', - link: function(scope, element, attrs, controller) { - var olScope = controller.getOpenlayersScope(); - var isNumber = olHelpers.isNumber; - var safeApply = olHelpers.safeApply; - var createView = olHelpers.createView; - - olScope.getMap().then(function(map) { - var defaults = olMapDefaults.getDefaults(olScope); - var view = olScope.view; - - if (!view.projection) { - view.projection = defaults.view.projection; - } - - if (!view.maxZoom) { - view.maxZoom = defaults.view.maxZoom; - } - - if (!view.minZoom) { - view.minZoom = defaults.view.minZoom; - } - - if (!view.rotation) { - view.rotation = defaults.view.rotation; - } - - var mapView = createView(view); - map.setView(mapView); - - olScope.$watchCollection('view', function(view) { - if (isNumber(view.rotation)) { - mapView.setRotation(view.rotation); - } - }); - - mapView.on('change:rotation', function() { - safeApply(olScope, function(scope) { - scope.view.rotation = map.getView().getRotation(); - }); - }); - - }); - } - }; -}); - -angular.module('openlayers-directive').directive('olControl', function($log, $q, olData, olMapDefaults, olHelpers) { - - return { - restrict: 'E', - scope: { - properties: '=olControlProperties' - }, - replace: false, - require: '^openlayers', - link: function(scope, element, attrs, controller) { - var isDefined = olHelpers.isDefined; - var olScope = controller.getOpenlayersScope(); - var olControl; - var olControlOps; - - olScope.getMap().then(function(map) { - var getControlClasses = olHelpers.getControlClasses; - var controlClasses = getControlClasses(); - - scope.$on('$destroy', function() { - map.removeControl(olControl); - }); - - if (!isDefined(scope.properties) || !isDefined(scope.properties.control)) { - if (attrs.name) { - if (isDefined(scope.properties)) { - olControlOps = scope.properties; - } - olControl = new controlClasses[attrs.name](olControlOps); - map.addControl(olControl); - } - return; - } - - olControl = scope.properties.control; - map.addControl(olControl); - }); - } - }; -}); - -angular.module('openlayers-directive').directive('olMarker', function($log, $q, olMapDefaults, olHelpers) { - - var getMarkerDefaults = function() { - return { - projection: 'EPSG:4326', - lat: 0, - lon: 0, - coord: [], - show: true, - showOnMouseOver: false, - showOnMouseClick: false, - keepOneOverlayVisible: false - }; - }; - - var markerLayerManager = (function() { - var mapDict = []; - - function getMapIndex(map) { - return mapDict.map(function(record) { - return record.map; - }).indexOf(map); - } - - return { - getInst: function getMarkerLayerInst(scope, map) { - var mapIndex = getMapIndex(map); - - if (mapIndex === -1) { - var markerLayer = olHelpers.createVectorLayer(); - markerLayer.set('markers', true); - map.addLayer(markerLayer); - mapDict.push({ - map: map, - markerLayer: markerLayer, - instScopes: [] - }); - mapIndex = mapDict.length - 1; - } - - mapDict[mapIndex].instScopes.push(scope); - - return mapDict[mapIndex].markerLayer; - }, - deregisterScope: function deregisterScope(scope, map) { - var mapIndex = getMapIndex(map); - if (mapIndex === -1) { - throw Error('This map has no markers'); - } - - var scopes = mapDict[mapIndex].instScopes; - var scopeIndex = scopes.indexOf(scope); - if (scopeIndex === -1) { - throw Error('Scope wan\'t registered'); - } - - scopes.splice(scopeIndex, 1); - - if (!scopes.length) { - map.removeLayer(mapDict[mapIndex].markerLayer); - delete mapDict[mapIndex]; - } - } - }; - })(); - return { - restrict: 'E', - scope: { - lat: '=lat', - lon: '=lon', - label: '=label', - properties: '=olMarkerProperties', - style: '=olStyle' - }, - transclude: true, - require: '^openlayers', - replace: true, - template: - '', - - link: function(scope, element, attrs, controller) { - var isDefined = olHelpers.isDefined; - var olScope = controller.getOpenlayersScope(); - var createFeature = olHelpers.createFeature; - var createOverlay = olHelpers.createOverlay; - - var hasTranscluded = element.find('ng-transclude').children().length > 0; - - olScope.getMap().then(function(map) { - var markerLayer = markerLayerManager.getInst(scope, map); - var data = getMarkerDefaults(); - - var mapDefaults = olMapDefaults.getDefaults(olScope); - var viewProjection = mapDefaults.view.projection; - var label; - var pos; - var marker; - - // This function handles dragging a marker - var pickOffset = null; - var pickProperties = null; - function handleDrag(evt) { - var coord = evt.coordinate; - var proj = map.getView().getProjection().getCode(); - if (proj === 'pixel') { - coord = coord.map(function(v) { - return parseInt(v, 10); - }); - } else { - coord = ol.proj.transform(coord, proj, 'EPSG:4326'); - } - - if (evt.type === 'pointerdown') { - // Get feature under mouse if any - var feature = map.forEachFeatureAtPixel(evt.pixel, function(feature) { - return feature; - }); - // Get associated marker properties - pickProperties = (feature ? feature.get('marker') : null); - if (!pickProperties || !pickProperties.draggable) { - pickProperties = null; - return; - } - map.getTarget().style.cursor = 'pointer'; - if (proj === 'pixel') { - pickOffset = [coord[0] - pickProperties.coord[0], coord[1] - pickProperties.coord[1]]; - } else { - pickOffset = [coord[0] - pickProperties.lon, coord[1] - pickProperties.lat]; - } - evt.preventDefault(); - } else if (pickOffset && pickProperties) { - if (evt.type === 'pointerup') { - map.getTarget().style.cursor = ''; - pickOffset = null; - pickProperties = null; - evt.preventDefault(); - } else if (evt.type === 'pointerdrag') { - evt.preventDefault(); - scope.$apply(function() { - // Add current delta to marker initial position - if (proj === 'pixel') { - pickProperties.coord[0] = coord[0] - pickOffset[0]; - pickProperties.coord[1] = coord[1] - pickOffset[1]; - } else { - pickProperties.lon = coord[0] - pickOffset[0]; - pickProperties.lat = coord[1] - pickOffset[1]; - } - }); - } - } - } - - // Setup generic handlers for marker drag - map.on('pointerdown', handleDrag); - map.on('pointerup', handleDrag); - map.on('pointerdrag', handleDrag); - - scope.$on('$destroy', function() { - markerLayer.getSource().removeFeature(marker); - if (isDefined(label)) { - map.removeOverlay(label); - } - markerLayerManager.deregisterScope(scope, map); - }); - - if (!isDefined(scope.properties)) { - data.lat = scope.lat ? scope.lat : data.lat; - data.lon = scope.lon ? scope.lon : data.lon; - data.message = attrs.message; - data.style = scope.style ? scope.style : mapDefaults.styles.marker; - - marker = createFeature(data, viewProjection); - if (!isDefined(marker)) { - $log.error('[AngularJS - Openlayers] Received invalid data on ' + - 'the marker.'); - } - // Add a link between the feature and the marker properties - marker.set('marker', scope); - markerLayer.getSource().addFeature(marker); - - if (data.message || hasTranscluded) { - scope.message = attrs.message; - pos = ol.proj.transform([data.lon, data.lat], data.projection, - viewProjection); - label = createOverlay(element, pos); - map.addOverlay(label); - } - return; - } - - scope.$watch('properties', function(properties) { - - // Remove previous listeners if any - map.getViewport().removeEventListener('mousemove', properties.handleInteraction); - map.getViewport().removeEventListener('click', properties.handleTapInteraction); - map.getViewport().querySelector('canvas.ol-unselectable').removeEventListener( - 'touchend', properties.handleTapInteraction); - map.getViewport().removeEventListener('mousemove', properties.showAtLeastOneOverlay); - map.getViewport().removeEventListener('click', properties.removeAllOverlays); - - // This function handles popup on mouse over/click - properties.handleInteraction = function(evt) { - if (properties.label.show) { - return; - } - var found = false; - var pixel = map.getEventPixel(evt); - var feature = map.forEachFeatureAtPixel(pixel, function(feature) { - return feature; - }); - - var actionTaken = false; - if (feature === marker) { - actionTaken = true; - found = true; - if (!isDefined(label)) { - if (data.projection === 'pixel') { - pos = properties.coord; - } else { - pos = ol.proj.transform([properties.lon, properties.lat], - data.projection, viewProjection); - } - label = createOverlay(element, pos); - map.addOverlay(label); - } - - if (properties.onClick && (evt.type === 'click' || evt.type === 'touchend')) { - scope.$apply(function() { - properties.onClick.call(marker, evt, properties); - }); - } - map.getTarget().style.cursor = 'pointer'; - } - - if (!found && label) { - actionTaken = true; - map.removeOverlay(label); - label = undefined; - map.getTarget().style.cursor = ''; - } - - if (actionTaken) { - evt.preventDefault(); - } - }; - - // Made to filter out click/tap events if both are being triggered on this platform - properties.handleTapInteraction = (function() { - var cooldownActive = false; - var prevTimeout; - - // Sets the cooldown flag to filter out any subsequent events within 500 ms - function activateCooldown() { - cooldownActive = true; - if (prevTimeout) { - clearTimeout(prevTimeout); - } - prevTimeout = setTimeout(function() { - cooldownActive = false; - prevTimeout = null; - }, 500); - } - - // Preventing from 'touchend' to be considered a tap, if fired immediately after 'touchmove' - map.getViewport().querySelector('canvas.ol-unselectable').addEventListener( - 'touchmove', activateCooldown); - - return function() { - if (!cooldownActive) { - properties.handleInteraction.apply(null, arguments); - activateCooldown(); - } - }; - })(); - - properties.showAtLeastOneOverlay = function(evt) { - if (properties.label.show) { - return; - } - var found = false; - var pixel = map.getEventPixel(evt); - var feature = map.forEachFeatureAtPixel(pixel, function(feature) { - return feature; - }); - - var actionTaken = false; - if (feature === marker) { - actionTaken = true; - found = true; - if (!isDefined(label)) { - if (data.projection === 'pixel') { - pos = data.coord; - } else { - pos = ol.proj.transform([data.lon, data.lat], - data.projection, viewProjection); - } - label = createOverlay(element, pos); - angular.forEach(map.getOverlays(), function(value) { - map.removeOverlay(value); - }); - map.addOverlay(label); - } - map.getTarget().style.cursor = 'pointer'; - } - - if (!found && label) { - actionTaken = true; - label = undefined; - map.getTarget().style.cursor = ''; - } - - if (actionTaken) { - evt.preventDefault(); - } - }; - - properties.removeAllOverlays = function(evt) { - angular.forEach(map.getOverlays(), function(value) { - map.removeOverlay(value); - }); - evt.preventDefault(); - }; - - if (!isDefined(marker)) { - data.projection = properties.projection ? properties.projection : - data.projection; - data.coord = properties.coord ? properties.coord : data.coord; - data.lat = properties.lat ? properties.lat : data.lat; - data.lon = properties.lon ? properties.lon : data.lon; - - if (isDefined(properties.style)) { - data.style = properties.style; - } else { - data.style = mapDefaults.styles.marker; - } - - marker = createFeature(data, viewProjection); - if (!isDefined(marker)) { - $log.error('[AngularJS - Openlayers] Received invalid data on ' + - 'the marker.'); - } - // Add a link between the feature and the marker properties - marker.set('marker', properties); - markerLayer.getSource().addFeature(marker); - } else { - var requestedPosition; - if (properties.projection === 'pixel') { - requestedPosition = properties.coord; - } else { - requestedPosition = ol.proj.transform([properties.lon, properties.lat], data.projection, - map.getView().getProjection()); - } - - if (!angular.equals(marker.getGeometry().getCoordinates(), requestedPosition)) { - var geometry = new ol.geom.Point(requestedPosition); - marker.setGeometry(geometry); - } - } - - if (isDefined(label)) { - map.removeOverlay(label); - } - - if (!isDefined(properties.label)) { - return; - } - - scope.message = properties.label.message; - if (!hasTranscluded && (!isDefined(scope.message) || scope.message.length === 0)) { - return; - } - - if (properties.label && properties.label.show === true) { - if (data.projection === 'pixel') { - pos = data.coord; - } else { - pos = ol.proj.transform([properties.lon, properties.lat], data.projection, - viewProjection); - } - label = createOverlay(element, pos); - map.addOverlay(label); - } - - if (label && properties.label && properties.label.show === false) { - map.removeOverlay(label); - label = undefined; - } - - // Then setup new ones according to properties - if (properties.label && properties.label.show === false && - properties.label.showOnMouseOver) { - map.getViewport().addEventListener('mousemove', properties.handleInteraction); - } - - if ((properties.label && properties.label.show === false && - properties.label.showOnMouseClick) || - properties.onClick) { - map.getViewport().addEventListener('click', properties.handleTapInteraction); - map.getViewport().querySelector('canvas.ol-unselectable').addEventListener( - 'touchend', properties.handleTapInteraction); - } - - if ((properties.label && properties.label.show === false && - properties.label.keepOneOverlayVisible)) { - map.getViewport().addEventListener('mousemove', properties.showAtLeastOneOverlay); - map.getViewport().addEventListener('click', properties.removeAllOverlays); - } - }, true); - }); - } - }; -}); - -angular.module('openlayers-directive').service('olData', function($log, $q, olHelpers) { - - var obtainEffectiveMapId = olHelpers.obtainEffectiveMapId; - - var maps = {}; - - var setResolvedDefer = function(d, mapId) { - var id = obtainEffectiveMapId(d, mapId); - d[id].resolvedDefer = true; - }; - - var getUnresolvedDefer = function(d, mapId) { - var id = obtainEffectiveMapId(d, mapId); - var defer; - - if (!angular.isDefined(d[id]) || d[id].resolvedDefer === true) { - defer = $q.defer(); - d[id] = { - defer: defer, - resolvedDefer: false - }; - } else { - defer = d[id].defer; - } - return defer; - }; - - var getDefer = function(d, mapId) { - var id = obtainEffectiveMapId(d, mapId); - var defer; - - if (!angular.isDefined(d[id]) || d[id].resolvedDefer === false) { - defer = getUnresolvedDefer(d, mapId); - } else { - defer = d[id].defer; - } - return defer; - }; - - this.setMap = function(olMap, scopeId) { - var defer = getUnresolvedDefer(maps, scopeId); - defer.resolve(olMap); - setResolvedDefer(maps, scopeId); - }; - - this.getMap = function(scopeId) { - var defer = getDefer(maps, scopeId); - return defer.promise; - }; - -}); - -angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $http) { - - var isDefined = function(value) { - return angular.isDefined(value); - }; - - var isDefinedAndNotNull = function(value) { - return angular.isDefined(value) && value !== null; - }; - - var setEvent = function(map, eventType, scope) { - map.on(eventType, function(event) { - var coord = event.coordinate; - var proj = map.getView().getProjection().getCode(); - if (proj === 'pixel') { - coord = coord.map(function(v) { - return parseInt(v, 10); - }); - } - scope.$emit('openlayers.map.' + eventType, { - 'coord': coord, - 'projection': proj, - 'event': event - }); - }); - }; - - var bingImagerySets = [ - 'Road', - 'Aerial', - 'AerialWithLabels', - 'collinsBart', - 'ordnanceSurvey' - ]; - - var getControlClasses = function() { - return { - attribution: ol.control.Attribution, - fullscreen: ol.control.FullScreen, - mouseposition: ol.control.MousePosition, - rotate: ol.control.Rotate, - scaleline: ol.control.ScaleLine, - zoom: ol.control.Zoom, - zoomslider: ol.control.ZoomSlider, - zoomtoextent: ol.control.ZoomToExtent - }; - }; - - var mapQuestLayers = ['osm', 'sat', 'hyb']; - - var esriBaseLayers = ['World_Imagery', 'World_Street_Map', 'World_Topo_Map', - 'World_Physical_Map', 'World_Terrain_Base', - 'Ocean_Basemap', 'NatGeo_World_Map']; - - var styleMap = { - 'style': ol.style.Style, - 'fill': ol.style.Fill, - 'stroke': ol.style.Stroke, - 'circle': ol.style.Circle, - 'icon': ol.style.Icon, - 'image': ol.style.Image, - 'regularshape': ol.style.RegularShape, - 'text': ol.style.Text - }; - - var optionalFactory = function(style, Constructor) { - if (Constructor && style instanceof Constructor) { - return style; - } else if (Constructor) { - return new Constructor(style); - } else { - return style; - } - }; - - //Parse the style tree calling the appropriate constructors. - //The keys in styleMap can be used and the OpenLayers constructors can be - //used directly. - var createStyle = function recursiveStyle(data, styleName) { - var style; - if (!styleName) { - styleName = 'style'; - style = data; - } else { - style = data[styleName]; - } - //Instead of defining one style for the layer, we've been given a style function - //to apply to each feature. - if (styleName === 'style' && data instanceof Function) { - return data; - } - - if (!(style instanceof Object)) { - return style; - } - - var styleObject; - if (Object.prototype.toString.call(style) === '[object Object]') { - styleObject = {}; - var styleConstructor = styleMap[styleName]; - if (styleConstructor && style instanceof styleConstructor) { - return style; - } - Object.getOwnPropertyNames(style).forEach(function(val, idx, array) { - //Consider the case - //image: { - // circle: { - // fill: { - // color: 'red' - // } - // } - // - //An ol.style.Circle is an instance of ol.style.Image, so we do not want to construct - //an Image and then construct a Circle. We assume that if we have an instanceof - //relationship, that the JSON parent has exactly one child. - //We check to see if an inheritance relationship exists. - //If it does, then for the parent we create an instance of the child. - var valConstructor = styleMap[val]; - if (styleConstructor && valConstructor && - valConstructor.prototype instanceof styleMap[styleName]) { - console.assert(array.length === 1, 'Extra parameters for ' + styleName); - styleObject = recursiveStyle(style, val); - return optionalFactory(styleObject, valConstructor); - } else { - styleObject[val] = recursiveStyle(style, val); - - // if the value is 'text' and it contains a String, then it should be interpreted - // as such, 'cause the text style might effectively contain a text to display - if (val !== 'text' && typeof styleObject[val] !== 'string') { - styleObject[val] = optionalFactory(styleObject[val], styleMap[val]); - } - } - }); - } else { - styleObject = style; - } - return optionalFactory(styleObject, styleMap[styleName]); - }; - - var detectLayerType = function(layer) { - if (layer.type) { - return layer.type; - } else { - switch (layer.source.type) { - case 'ImageWMS': - return 'Image'; - case 'ImageStatic': - return 'Image'; - case 'GeoJSON': - case 'JSONP': - case 'TopoJSON': - case 'KML': - case 'TileVector': - return 'Vector'; - default: - return 'Tile'; - } - } - }; - - var createProjection = function(view) { - var oProjection; - - switch (view.projection) { - case 'pixel': - if (!isDefined(view.extent)) { - $log.error('[AngularJS - Openlayers] - You must provide the extent of the image ' + - 'if using pixel projection'); - return; - } - oProjection = new ol.proj.Projection({ - code: 'pixel', - units: 'pixels', - extent: view.extent - }); - break; - default: - oProjection = new ol.proj.get(view.projection); - break; - } - - return oProjection; - }; - - var isValidStamenLayer = function(layer) { - return ['watercolor', 'terrain', 'toner'].indexOf(layer) !== -1; - }; - - var createSource = function(source, projection) { - var oSource; - - switch (source.type) { - case 'MapBox': - if (!source.mapId || !source.accessToken) { - $log.error('[AngularJS - Openlayers] - MapBox layer requires the map id and the access token'); - return; - } - var url = 'http://api.tiles.mapbox.com/v4/' + source.mapId + '/{z}/{x}/{y}.png?access_token=' + - source.accessToken; - - var pixelRatio = window.devicePixelRatio; - - if (pixelRatio > 1) { - url = url.replace('.png', '@2x.png'); - } - - oSource = new ol.source.XYZ({ - url: url, - attributions: createAttribution(source), - tilePixelRatio: pixelRatio > 1 ? 2 : 1, - wrapX: (source.wrapX === true) ? 1 : 0 - }); - break; - case 'ImageWMS': - if (!source.url || !source.params) { - $log.error('[AngularJS - Openlayers] - ImageWMS Layer needs ' + - 'valid server url and params properties'); - } - oSource = new ol.source.ImageWMS({ - url: source.url, - attributions: createAttribution(source), - crossOrigin: (typeof source.crossOrigin === 'undefined') ? 'anonymous' : source.crossOrigin, - params: source.params, - wrapX: source.wrapX ? 0 : 1 - }); - break; - - case 'TileWMS': - if ((!source.url && !source.urls) || !source.params) { - $log.error('[AngularJS - Openlayers] - TileWMS Layer needs ' + - 'valid url (or urls) and params properties'); - } - - var wmsConfiguration = { - crossOrigin: (typeof source.crossOrigin === 'undefined') ? 'anonymous' : source.crossOrigin, - params: source.params, - attributions: createAttribution(source), - wrapX: source.wrapX ? 0 : 1 - }; - - if (source.url) { - wmsConfiguration.url = source.url; - } - - if (source.urls) { - wmsConfiguration.urls = source.urls; - } - - oSource = new ol.source.TileWMS(wmsConfiguration); - break; - - case 'WMTS': - if ((!source.url && !source.urls) || !source.tileGrid) { - $log.error('[AngularJS - Openlayers] - WMTS Layer needs valid url ' + - '(or urls) and tileGrid properties'); - } - - var wmtsConfiguration = { - projection: projection, - layer: source.layer, - attributions: createAttribution(source), - matrixSet: (source.matrixSet === 'undefined') ? projection : source.matrixSet, - format: (source.format === 'undefined') ? 'image/jpeg' : source.format, - requestEncoding: (source.requestEncoding === 'undefined') ? - 'KVP' : source.requestEncoding, - tileGrid: new ol.tilegrid.WMTS({ - origin: source.tileGrid.origin, - resolutions: source.tileGrid.resolutions, - matrixIds: source.tileGrid.matrixIds - }), - wrapX: source.wrapX ? 0 : 1 - }; - - if (isDefined(source.url)) { - wmtsConfiguration.url = source.url; - } - - if (isDefined(source.urls)) { - wmtsConfiguration.urls = source.urls; - } - - oSource = new ol.source.WMTS(wmtsConfiguration); - break; - - case 'OSM': - oSource = new ol.source.OSM({ - attributions: createAttribution(source), - wrapX: (source.wrapX === true) ? 1 : 0 - }); - - if (source.url) { - oSource.setUrl(source.url); - } - - break; - case 'BingMaps': - if (!source.key) { - $log.error('[AngularJS - Openlayers] - You need an API key to show the Bing Maps.'); - return; - } - - var bingConfiguration = { - key: source.key, - attributions: createAttribution(source), - imagerySet: source.imagerySet ? source.imagerySet : bingImagerySets[0], - culture: source.culture, - wrapX: (source.wrapX === true) ? 1 : 0 - }; - - if (source.maxZoom) { - bingConfiguration.maxZoom = source.maxZoom; - } - - oSource = new ol.source.BingMaps(bingConfiguration); - break; - - case 'MapQuest': - if (!source.layer || mapQuestLayers.indexOf(source.layer) === -1) { - $log.error('[AngularJS - Openlayers] - MapQuest layers needs a valid \'layer\' property.'); - return; - } - - oSource = new ol.source.MapQuest({ - attributions: createAttribution(source), - layer: source.layer, - wrapX: (source.wrapX === true) ? 1 : 0 - }); - - break; - - case 'EsriBaseMaps': - if (!source.layer || esriBaseLayers.indexOf(source.layer) === -1) { - $log.error('[AngularJS - Openlayers] - ESRI layers needs a valid \'layer\' property.'); - return; - } - - var _urlBase = 'http://services.arcgisonline.com/ArcGIS/rest/services/'; - var _url = _urlBase + source.layer + '/MapServer/tile/{z}/{y}/{x}'; - - oSource = new ol.source.XYZ({ - attributions: createAttribution(source), - url: _url, - wrapX: (source.wrapX === true) ? 1 : 0 - }); - - break; - - case 'GeoJSON': - if (!(source.geojson || source.url)) { - $log.error('[AngularJS - Openlayers] - You need a geojson ' + - 'property to add a GeoJSON layer.'); - return; - } - - if (isDefined(source.url)) { - oSource = new ol.source.Vector({ - format: new ol.format.GeoJSON(), - url: source.url, - wrapX: (source.wrapX === true) ? 1 : 0 - }); - } else { - oSource = new ol.source.Vector(); - - var projectionToUse = projection; - if (isDefined(source.geojson.projection)) { - projectionToUse = source.geojson.projection; - } - - var geojsonFormat = new ol.format.GeoJSON(); - var features = geojsonFormat.readFeatures( - source.geojson.object, { featureProjection: projectionToUse }); - - oSource.addFeatures(features); - } - - break; - case 'JSONP': - if (!(source.url)) { - $log.error('[AngularJS - Openlayers] - You need an url properly configured to add a JSONP layer.'); - return; - } - - if (isDefined(source.url)) { - oSource = new ol.source.Vector({ - format: new ol.format.GeoJSON(), - loader: function(/*extent, resolution, projection*/) { - var url = source.url + - '&outputFormat=text/javascript&format_options=callback:JSON_CALLBACK'; - $http.jsonp(url, { cache: source.cache}).success(function(response) { - oSource.addFeatures(oSource.readFeatures(response)); - }).error(function(response) { - $log(response); - }); - }, - wrapX: (source.wrapX === true) ? 1 : 0 - }); - } - break; - case 'TopoJSON': - if (!(source.topojson || source.url)) { - $log.error('[AngularJS - Openlayers] - You need a topojson ' + - 'property to add a TopoJSON layer.'); - return; - } - - if (source.url) { - oSource = new ol.source.Vector({ - format: new ol.format.TopoJSON(), - url: source.url, - wrapX: (source.wrapX === true) ? 1 : 0 - }); - } else { - oSource = new ol.source.Vector(angular.extend(source.topojson, { - format: new ol.format.TopoJSON(), - wrapX: (source.wrapX === true) ? 1 : 0 - })); - } - break; - case 'TileJSON': - oSource = new ol.source.TileJSON({ - url: source.url, - attributions: createAttribution(source), - crossOrigin: 'anonymous', - wrapX: (source.wrapX === true) ? 1 : 0 - }); - break; - - case 'TileVector': - if (!source.url || !source.format) { - $log.error('[AngularJS - Openlayers] - TileVector Layer needs valid url and format properties'); - } - oSource = new ol.source.TileVector({ - url: source.url, - projection: projection, - attributions: createAttribution(source), - format: source.format, - tileGrid: new ol.tilegrid.createXYZ({ - maxZoom: source.maxZoom || 19 - }), - wrapX: (source.wrapX === true) ? 1 : 0 - }); - break; - - case 'TileTMS': - if (!source.url || !source.tileGrid) { - $log.error('[AngularJS - Openlayers] - TileTMS Layer needs valid url and tileGrid properties'); - } - oSource = new ol.source.TileImage({ - url: source.url, - maxExtent: source.maxExtent, - attributions: createAttribution(source), - tileGrid: new ol.tilegrid.TileGrid({ - origin: source.tileGrid.origin, - resolutions: source.tileGrid.resolutions - }), - tileUrlFunction: function(tileCoord) { - - var z = tileCoord[0]; - var x = tileCoord[1]; - var y = tileCoord[2]; //(1 << z) - tileCoord[2] - 1; - - if (x < 0 || y < 0) { - return ''; - } - - var url = source.url + z + '/' + x + '/' + y + '.png'; - - return url; - }, - wrapX: (source.wrapX === true) ? 1 : 0 - }); - break; - case 'TileImage': - oSource = new ol.source.TileImage({ - url: source.url, - attributions: createAttribution(source), - tileGrid: new ol.tilegrid.TileGrid({ - origin: source.tileGrid.origin, // top left corner of the pixel projection's extent - resolutions: source.tileGrid.resolutions - }), - tileUrlFunction: function(tileCoord/*, pixelRatio, projection*/) { - var z = tileCoord[0]; - var x = tileCoord[1]; - var y = -tileCoord[2] - 1; - var url = source.url - .replace('{z}', z.toString()) - .replace('{x}', x.toString()) - .replace('{y}', y.toString()); - return url; - }, - wrapX: (source.wrapX === true) ? 1 : 0 - }); - break; - case 'KML': - var extractStyles = source.extractStyles || false; - oSource = new ol.source.Vector({ - url: source.url, - format: new ol.format.KML(), - radius: source.radius, - extractStyles: extractStyles, - wrapX: (source.wrapX === true) ? 1 : 0 - }); - break; - case 'Stamen': - if (!source.layer || !isValidStamenLayer(source.layer)) { - $log.error('[AngularJS - Openlayers] - You need a valid Stamen layer.'); - return; - } - oSource = new ol.source.Stamen({ - layer: source.layer, - wrapX: (source.wrapX === true) ? 1 : 0 - }); - break; - case 'ImageStatic': - if (!source.url || !angular.isArray(source.imageSize) || source.imageSize.length !== 2) { - $log.error('[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.'); - return; - } - - oSource = new ol.source.ImageStatic({ - url: source.url, - attributions: createAttribution(source), - imageSize: source.imageSize, - projection: projection, - imageExtent: projection.getExtent(), - imageLoadFunction: source.imageLoadFunction, - wrapX: (source.wrapX === true) ? 1 : 0 - }); - break; - case 'XYZ': - if (!source.url) { - $log.error('[AngularJS - Openlayers] - XYZ Layer needs valid url and params properties'); - } - oSource = new ol.source.XYZ({ - url: source.url, - attributions: createAttribution(source), - minZoom: source.minZoom, - maxZoom: source.maxZoom, - wrapX: (source.wrapX === true) ? 1 : 0 - }); - break; - } - - // log a warning when no source could be created for the given type - if (!oSource) { - $log.warn('[AngularJS - Openlayers] - No source could be found for type "' + source.type + '"'); - } - - return oSource; - }; - - var createAttribution = function(source) { - var attributions = []; - if (isDefined(source.attribution)) { - attributions.unshift(new ol.Attribution({html: source.attribution})); - } - return attributions; - }; - - var createGroup = function(name) { - var olGroup = new ol.layer.Group(); - olGroup.set('name', name); - - return olGroup; - }; - - var getGroup = function(layers, name) { - var layer; - - angular.forEach(layers, function(l) { - if (l instanceof ol.layer.Group && l.get('name') === name) { - layer = l; - return; - } - }); - - return layer; - }; - - var addLayerBeforeMarkers = function(layers, layer) { - var markersIndex; - for (var i = 0; i < layers.getLength(); i++) { - var l = layers.item(i); - - if (l.get('markers')) { - markersIndex = i; - break; - } - } - - if (isDefined(markersIndex)) { - var markers = layers.item(markersIndex); - layer.index = markersIndex; - layers.setAt(markersIndex, layer); - markers.index = layers.getLength(); - layers.push(markers); - } else { - layer.index = layers.getLength(); - layers.push(layer); - } - - }; - - var removeLayer = function(layers, index) { - layers.removeAt(index); - for (var i = index; i < layers.getLength(); i++) { - var l = layers.item(i); - if (l === null) { - layers.insertAt(i, null); - break; - } else { - l.index = i; - } - } - }; - - return { - // Determine if a reference is defined - isDefined: isDefined, - - // Determine if a reference is a number - isNumber: function(value) { - return angular.isNumber(value); - }, - - createView: function(view) { - var projection = createProjection(view); - - return new ol.View({ - projection: projection, - maxZoom: view.maxZoom, - minZoom: view.minZoom, - extent: view.extent - }); - }, - - // Determine if a reference is defined and not null - isDefinedAndNotNull: isDefinedAndNotNull, - - // Determine if a reference is a string - isString: function(value) { - return angular.isString(value); - }, - - // Determine if a reference is an array - isArray: function(value) { - return angular.isArray(value); - }, - - // Determine if a reference is an object - isObject: function(value) { - return angular.isObject(value); - }, - - // Determine if two objects have the same properties - equals: function(o1, o2) { - return angular.equals(o1, o2); - }, - - isValidCenter: function(center) { - return angular.isDefined(center) && - (typeof center.autodiscover === 'boolean' || - angular.isNumber(center.lat) && angular.isNumber(center.lon) || - (angular.isArray(center.coord) && center.coord.length === 2 && - angular.isNumber(center.coord[0]) && angular.isNumber(center.coord[1])) || - (angular.isArray(center.bounds) && center.bounds.length === 4 && - angular.isNumber(center.bounds[0]) && angular.isNumber(center.bounds[1]) && - angular.isNumber(center.bounds[1]) && angular.isNumber(center.bounds[2]))); - }, - - safeApply: function($scope, fn) { - var phase = $scope.$root.$$phase; - if (phase === '$apply' || phase === '$digest') { - $scope.$eval(fn); - } else { - $scope.$apply(fn); - } - }, - - isSameCenterOnMap: function(center, map) { - var urlProj = center.projection || 'EPSG:4326'; - var urlCenter = [center.lon, center.lat]; - var mapProj = map.getView().getProjection(); - var mapCenter = ol.proj.transform(map.getView().getCenter(), mapProj, urlProj); - var zoom = map.getView().getZoom(); - if (mapCenter[1].toFixed(4) === urlCenter[1].toFixed(4) && - mapCenter[0].toFixed(4) === urlCenter[0].toFixed(4) && - zoom === center.zoom) { - return true; - } - return false; - }, - - setCenter: function(view, projection, newCenter, map) { - - if (map && view.getCenter()) { - var pan = ol.animation.pan({ - duration: 150, - source: (view.getCenter()) - }); - map.beforeRender(pan); - } - - if (newCenter.projection === projection) { - view.setCenter([newCenter.lon, newCenter.lat]); - } else { - var coord = [newCenter.lon, newCenter.lat]; - view.setCenter(ol.proj.transform(coord, newCenter.projection, projection)); - } - }, - - setZoom: function(view, zoom, map) { - var z = ol.animation.zoom({ - duration: 150, - resolution: map.getView().getResolution() - }); - map.beforeRender(z); - view.setZoom(zoom); - }, - - isBoolean: function(value) { - return typeof value === 'boolean'; - }, - - obtainEffectiveMapId: function(d, mapId) { - var id; - var i; - if (!angular.isDefined(mapId)) { - if (Object.keys(d).length === 1) { - for (i in d) { - if (d.hasOwnProperty(i)) { - id = i; - } - } - } else if (Object.keys(d).length === 0) { - id = 'main'; - } else { - $log.error('[AngularJS - Openlayers] - You have more than 1 map on the DOM, ' + - 'you must provide the map ID to the olData.getXXX call'); - } - } else { - id = mapId; - } - return id; - }, - - createStyle: createStyle, - - setMapEvents: function(events, map, scope) { - if (isDefined(events) && angular.isArray(events.map)) { - for (var i in events.map) { - var event = events.map[i]; - setEvent(map, event, scope); - } - } - }, - - setVectorLayerEvents: function(events, map, scope, layerName) { - if (isDefined(events) && angular.isArray(events.layers)) { - angular.forEach(events.layers, function(eventType) { - angular.element(map.getViewport()).on(eventType, function(evt) { - var pixel = map.getEventPixel(evt); - var feature = map.forEachFeatureAtPixel(pixel, function(feature, olLayer) { - // only return the feature if it is in this layer (based on the name) - return (isDefinedAndNotNull(olLayer) && olLayer.get('name') === layerName) ? feature : null; - }); - if (isDefinedAndNotNull(feature)) { - scope.$emit('openlayers.layers.' + layerName + '.' + eventType, feature, evt); - } - }); - }); - } - }, - - setViewEvents: function(events, map, scope) { - if (isDefined(events) && angular.isArray(events.view)) { - var view = map.getView(); - angular.forEach(events.view, function(eventType) { - view.on(eventType, function(event) { - scope.$emit('openlayers.view.' + eventType, view, event); - }); - }); - } - }, - - detectLayerType: detectLayerType, - - createLayer: function(layer, projection, name) { - var oLayer; - var type = detectLayerType(layer); - var oSource = createSource(layer.source, projection); - if (!oSource) { - return; - } - - // Manage clustering - if ((type === 'Vector') && layer.clustering) { - oSource = new ol.source.Cluster({ - source: oSource, - distance: layer.clusteringDistance, - }); - } - - switch (type) { - case 'Image': - oLayer = new ol.layer.Image({ source: oSource }); - break; - case 'Tile': - oLayer = new ol.layer.Tile({ source: oSource }); - break; - case 'Heatmap': - oLayer = new ol.layer.Heatmap({ source: oSource }); - break; - case 'Vector': - oLayer = new ol.layer.Vector({ source: oSource }); - break; - } - - // set a layer name if given - if (isDefined(name)) { - oLayer.set('name', name); - } else if (isDefined(layer.name)) { - oLayer.set('name', layer.name); - } - - return oLayer; - }, - - createVectorLayer: function() { - return new ol.layer.Vector({ - source: new ol.source.Vector() - }); - }, - - notifyCenterUrlHashChanged: function(scope, center, search) { - if (center.centerUrlHash) { - var centerUrlHash = center.lat.toFixed(4) + ':' + center.lon.toFixed(4) + ':' + center.zoom; - if (!isDefined(search.c) || search.c !== centerUrlHash) { - scope.$emit('centerUrlHash', centerUrlHash); - } - } - }, - - getControlClasses: getControlClasses, - - detectControls: function(controls) { - var actualControls = {}; - var controlClasses = getControlClasses(); - - controls.forEach(function(control) { - for (var i in controlClasses) { - if (control instanceof controlClasses[i]) { - actualControls[i] = control; - } - } - }); - - return actualControls; - }, - - createFeature: function(data, viewProjection) { - var geometry; - - switch (data.type) { - case 'Polygon': - geometry = new ol.geom.Polygon(data.coords); - break; - default: - if (isDefined(data.coord) && data.projection === 'pixel') { - geometry = new ol.geom.Point(data.coord); - } else { - geometry = new ol.geom.Point([data.lon, data.lat]); - } - break; - } - - if (isDefined(data.projection) && data.projection !== 'pixel') { - geometry = geometry.transform(data.projection, viewProjection); - } - - var feature = new ol.Feature({ - geometry: geometry - }); - - if (isDefined(data.style)) { - var style = createStyle(data.style); - feature.setStyle(style); - } - return feature; - }, - - addLayerBeforeMarkers: addLayerBeforeMarkers, - - getGroup: getGroup, - - addLayerToGroup: function(layers, layer, name) { - var groupLayer = getGroup(layers, name); - - if (!isDefined(groupLayer)) { - groupLayer = createGroup(name); - addLayerBeforeMarkers(layers,groupLayer); - } - - layer.set('group', name); - addLayerBeforeMarkers(groupLayer.getLayers(), layer); - }, - - removeLayerFromGroup: function(layers, layer, name) { - var groupLayer = getGroup(layers, name); - layer.set('group'); - removeLayer(groupLayer.getLayers(), layer.index); - }, - - removeLayer: removeLayer, - - insertLayer: function(layers, index, layer) { - if (layers.getLength() < index) { - while (layers.getLength() < index) { - layers.push(null); - } - layer.index = index; - layers.push(layer); - } else { - layer.index = index; - layers.insertAt(layer.index, layer); - for (var i = index + 1; i < layers.getLength(); i++) { - var l = layers.item(i); - if (l === null) { - layers.removeAt(i); - break; - } else { - l.index = i; - } - } - } - }, - - createOverlay: function(element, pos) { - element.css('display', 'block'); - var ov = new ol.Overlay({ - position: pos, - element: element, - positioning: 'center-left' - }); - - return ov; - } - }; -}); - -angular.module('openlayers-directive').factory('olMapDefaults', function($q, olHelpers) { - - var base64icon = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAApCAYAAADAk4LOAAAGmklEQVRYw' + - '7VXeUyTZxjvNnfELFuyIzOabermMZEeQC/OclkO49CpOHXOLJl/CAURuYbQi3KLgEhbrhZ1aDwmaoGq' + - 'KII6odATmH/scDFbdC7LvFqOCc+e95s2VG50X/LLm/f4/Z7neY/ne18aANCmAr5E/xZf1uDOkTcGcWR' + - '6hl9247tT5U7Y6SNvWsKT63P58qbfeLJG8M5qcgTknrvvrdDbsT7Ml+tv82X6vVxJE33aRmgSyYtcWV' + - 'MqX97Yv2JvW39UhRE2HuyBL+t+gK1116ly06EeWFNlAmHxlQE0OMiV6mQCScusKRlhS3QLeVJdl1+23' + - 'h5dY4FNB3thrbYboqptEFlphTC1hSpJnbRvxP4NWgsE5Jyz86QNNi/5qSUTGuFk1gu54tN9wuK2wc3o' + - '+Wc13RCmsoBwEqzGcZsxsvCSy/9wJKf7UWf1mEY8JWfewc67UUoDbDjQC+FqK4QqLVMGGR9d2wurKzq' + - 'Bk3nqIT/9zLxRRjgZ9bqQgub+DdoeCC03Q8j+0QhFhBHR/eP3U/zCln7Uu+hihJ1+bBNffLIvmkyP0g' + - 'pBZWYXhKussK6mBz5HT6M1Nqpcp+mBCPXosYQfrekGvrjewd59/GvKCE7TbK/04/ZV5QZYVWmDwH1mF' + - '3xa2Q3ra3DBC5vBT1oP7PTj4C0+CcL8c7C2CtejqhuCnuIQHaKHzvcRfZpnylFfXsYJx3pNLwhKzRAw' + - 'AhEqG0SpusBHfAKkxw3w4627MPhoCH798z7s0ZnBJ/MEJbZSbXPhER2ih7p2ok/zSj2cEJDd4CAe+5W' + - 'YnBCgR2uruyEw6zRoW6/DWJ/OeAP8pd/BGtzOZKpG8oke0SX6GMmRk6GFlyAc59K32OTEinILRJRcha' + - 'h8HQwND8N435Z9Z0FY1EqtxUg+0SO6RJ/mmXz4VuS+DpxXC3gXmZwIL7dBSH4zKE50wESf8qwVgrP1E' + - 'IlTO5JP9Igu0aexdh28F1lmAEGJGfh7jE6ElyM5Rw/FDcYJjWhbeiBYoYNIpc2FT/SILivp0F1ipDWk' + - '4BIEo2VuodEJUifhbiltnNBIXPUFCMpthtAyqws/BPlEF/VbaIxErdxPphsU7rcCp8DohC+GvBIPJS/' + - 'tW2jtvTmmAeuNO8BNOYQeG8G/2OzCJ3q+soYB5i6NhMaKr17FSal7GIHheuV3uSCY8qYVuEm1cOzqdW' + - 'r7ku/R0BDoTT+DT+ohCM6/CCvKLKO4RI+dXPeAuaMqksaKrZ7L3FE5FIFbkIceeOZ2OcHO6wIhTkNo0' + - 'ffgjRGxEqogXHYUPHfWAC/lADpwGcLRY3aeK4/oRGCKYcZXPVoeX/kelVYY8dUGf8V5EBRbgJXT5QIP' + - 'hP9ePJi428JKOiEYhYXFBqou2Guh+p/mEB1/RfMw6rY7cxcjTrneI1FrDyuzUSRm9miwEJx8E/gUmql' + - 'yvHGkneiwErR21F3tNOK5Tf0yXaT+O7DgCvALTUBXdM4YhC/IawPU+2PduqMvuaR6eoxSwUk75ggqsY' + - 'J7VicsnwGIkZBSXKOUww73WGXyqP+J2/b9c+gi1YAg/xpwck3gJuucNrh5JvDPvQr0WFXf0piyt8f8/' + - 'WI0hV4pRxxkQZdJDfDJNOAmM0Ag8jyT6hz0WGXWuP94Yh2jcfjmXAGvHCMslRimDHYuHuDsy2QtHuIa' + - 'vznhbYURq5R57KpzBBRZKPJi8eQg48h4j8SDdowifdIrEVdU+gbO6QNvRRt4ZBthUaZhUnjlYObNagV' + - '3keoeru3rU7rcuceqU1mJBxy+BWZYlNEBH+0eH4vRiB+OYybU2hnblYlTvkHinM4m54YnxSyaZYSF6R' + - '3jwgP7udKLGIX6r/lbNa9N6y5MFynjWDtrHd75ZvTYAPO/6RgF0k76mQla3FGq7dO+cH8sKn0Vo7nDl' + - 'lwAhqwLPkxrHwWmHJOo+AKJ4rab5OgrM7rVu8eWb2Pu0Dh4eDgXoOfvp7Y7QeqknRmvcTBEyq9m/HQQ' + - 'SCSz6LHq3z0yzsNySRfMS253wl2KyRDbcZPcfJKjZmSEOjcxyi+Y8dUOtsIEH6R2wNykdqrkYJ0RV92' + - 'H0W58pkfQk7cKevsLK10Py8SdMGfXNXATY+pPbyJR/ET6n9nIfztNtZYRV9XniQu9IA2vOVgy4ir7GC' + - 'LVmmd+zjkH0eAF9Po6K61pmCXHxU5rHMYd1ftc3owjwRSVRzLjKvqZEty6cRUD7jGqiOdu5HG6MdHjN' + - 'cNYGqfDm5YRzLBBCCDl/2bk8a8gdbqcfwECu62Fg/HrggAAAABJRU5ErkJggg=='; - - var _getDefaults = function() { - return { - view: { - projection: 'EPSG:3857', - minZoom: undefined, - maxZoom: undefined, - rotation: 0, - extent: undefined - }, - center: { - lat: 0, - lon: 0, - zoom: 1, - autodiscover: false, - bounds: [], - centerUrlHash: false, - projection: 'EPSG:4326' - }, - styles: { - path: { - stroke: { - color: 'blue', - width: 8 - } - }, - marker: { - image: new ol.style.Icon({ - anchor: [0.5, 1], - anchorXUnits: 'fraction', - anchorYUnits: 'fraction', - opacity: 0.90, - src: base64icon - }) - } - }, - events: { - map: [], - markers: [], - layers: [] - }, - controls: { - attribution: true, - rotate: false, - zoom: true - }, - interactions: { - mouseWheelZoom: false - }, - renderer: 'canvas' - }; - }; - - var isDefined = olHelpers.isDefined; - var defaults = {}; - - // Get the _defaults dictionary, and override the properties defined by the user - return { - getDefaults: function(scope) { - if (!isDefined(scope)) { - for (var i in defaults) { - return defaults[i]; - } - } - return defaults[scope.$id]; - }, - - setDefaults: function(scope) { - var userDefaults = scope.defaults; - var scopeId = scope.$id; - var newDefaults = _getDefaults(); - - if (isDefined(userDefaults)) { - - if (isDefined(userDefaults.layers)) { - newDefaults.layers = angular.copy(userDefaults.layers); - } - - if (isDefined(userDefaults.controls)) { - newDefaults.controls = angular.copy(userDefaults.controls); - } - - if (isDefined(userDefaults.events)) { - newDefaults.events = angular.copy(userDefaults.events); - } - - if (isDefined(userDefaults.interactions)) { - newDefaults.interactions = angular.copy(userDefaults.interactions); - } - - if (isDefined(userDefaults.renderer)) { - newDefaults.renderer = userDefaults.renderer; - } - - if (isDefined(userDefaults.view)) { - newDefaults.view.maxZoom = userDefaults.view.maxZoom || newDefaults.view.maxZoom; - newDefaults.view.minZoom = userDefaults.view.minZoom || newDefaults.view.minZoom; - newDefaults.view.projection = userDefaults.view.projection || newDefaults.view.projection; - newDefaults.view.extent = userDefaults.view.extent || newDefaults.view.extent; - } - - if (isDefined(userDefaults.styles)) { - newDefaults.styles = angular.extend(newDefaults.styles, userDefaults.styles); - } - - } - - defaults[scopeId] = newDefaults; - return newDefaults; - } - }; -}); - -})); \ No newline at end of file From 36f6ac21d6aace68a6ffbadf25cbd20b34a02cd4 Mon Sep 17 00:00:00 2001 From: Tirumala Dilip Kumar Date: Fri, 6 Nov 2015 15:52:40 +0530 Subject: [PATCH 05/53] added check condtion undefined wrapX --- src/services/olHelpers.js | 40 +++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/services/olHelpers.js b/src/services/olHelpers.js index f53faeb5..a7767a80 100644 --- a/src/services/olHelpers.js +++ b/src/services/olHelpers.js @@ -208,7 +208,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ url: url, attributions: createAttribution(source), tilePixelRatio: pixelRatio > 1 ? 2 : 1, - wrapX: (source.wrapX === true) ? 1 : 0 + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX }); break; case 'ImageWMS': @@ -221,7 +221,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ attributions: createAttribution(source), crossOrigin: (typeof source.crossOrigin === 'undefined') ? 'anonymous' : source.crossOrigin, params: source.params, - wrapX: source.wrapX ? 0 : 1 + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX }); break; @@ -235,7 +235,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ crossOrigin: (typeof source.crossOrigin === 'undefined') ? 'anonymous' : source.crossOrigin, params: source.params, attributions: createAttribution(source), - wrapX: source.wrapX ? 0 : 1 + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX }; if (source.url) { @@ -268,7 +268,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ resolutions: source.tileGrid.resolutions, matrixIds: source.tileGrid.matrixIds }), - wrapX: source.wrapX ? 0 : 1 + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX }; if (isDefined(source.url)) { @@ -285,7 +285,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ case 'OSM': oSource = new ol.source.OSM({ attributions: createAttribution(source), - wrapX: (source.wrapX === true) ? 1 : 0 + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX }); if (source.url) { @@ -304,7 +304,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ attributions: createAttribution(source), imagerySet: source.imagerySet ? source.imagerySet : bingImagerySets[0], culture: source.culture, - wrapX: (source.wrapX === true) ? 1 : 0 + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX }; if (source.maxZoom) { @@ -323,7 +323,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ oSource = new ol.source.MapQuest({ attributions: createAttribution(source), layer: source.layer, - wrapX: (source.wrapX === true) ? 1 : 0 + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX }); break; @@ -340,7 +340,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ oSource = new ol.source.XYZ({ attributions: createAttribution(source), url: _url, - wrapX: (source.wrapX === true) ? 1 : 0 + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX }); break; @@ -356,7 +356,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ oSource = new ol.source.Vector({ format: new ol.format.GeoJSON(), url: source.url, - wrapX: (source.wrapX === true) ? 1 : 0 + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX }); } else { oSource = new ol.source.Vector(); @@ -392,7 +392,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ $log(response); }); }, - wrapX: (source.wrapX === true) ? 1 : 0 + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX }); } break; @@ -407,12 +407,12 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ oSource = new ol.source.Vector({ format: new ol.format.TopoJSON(), url: source.url, - wrapX: (source.wrapX === true) ? 1 : 0 + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX }); } else { oSource = new ol.source.Vector(angular.extend(source.topojson, { format: new ol.format.TopoJSON(), - wrapX: (source.wrapX === true) ? 1 : 0 + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX })); } break; @@ -421,7 +421,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ url: source.url, attributions: createAttribution(source), crossOrigin: 'anonymous', - wrapX: (source.wrapX === true) ? 1 : 0 + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX }); break; @@ -437,7 +437,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ tileGrid: new ol.tilegrid.createXYZ({ maxZoom: source.maxZoom || 19 }), - wrapX: (source.wrapX === true) ? 1 : 0 + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX }); break; @@ -467,7 +467,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ return url; }, - wrapX: (source.wrapX === true) ? 1 : 0 + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX }); break; case 'TileImage': @@ -488,7 +488,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ .replace('{y}', y.toString()); return url; }, - wrapX: (source.wrapX === true) ? 1 : 0 + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX }); break; case 'KML': @@ -498,7 +498,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ format: new ol.format.KML(), radius: source.radius, extractStyles: extractStyles, - wrapX: (source.wrapX === true) ? 1 : 0 + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX }); break; case 'Stamen': @@ -508,7 +508,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ } oSource = new ol.source.Stamen({ layer: source.layer, - wrapX: (source.wrapX === true) ? 1 : 0 + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX }); break; case 'ImageStatic': @@ -524,7 +524,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ projection: projection, imageExtent: projection.getExtent(), imageLoadFunction: source.imageLoadFunction, - wrapX: (source.wrapX === true) ? 1 : 0 + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX }); break; case 'XYZ': @@ -536,7 +536,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ attributions: createAttribution(source), minZoom: source.minZoom, maxZoom: source.maxZoom, - wrapX: (source.wrapX === true) ? 1 : 0 + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX }); break; } From 13001ac505f7d4f775f026c0ecae10d967c22bd1 Mon Sep 17 00:00:00 2001 From: Tirumala Dilip Kumar Date: Fri, 6 Nov 2015 15:58:51 +0530 Subject: [PATCH 06/53] For project specific --- .gitignore | 1 - dist/angular-openlayers-directive.js | 2228 +++++++++++++++++ dist/angular-openlayers-directive.min.js | 32 + ...ular-openlayers-directive.min.no-header.js | 3 + dist/angular-openlayers-directive.pre.js | 2228 +++++++++++++++++ 5 files changed, 4491 insertions(+), 1 deletion(-) create mode 100644 dist/angular-openlayers-directive.js create mode 100644 dist/angular-openlayers-directive.min.js create mode 100644 dist/angular-openlayers-directive.min.no-header.js create mode 100644 dist/angular-openlayers-directive.pre.js diff --git a/.gitignore b/.gitignore index 57eb4608..352ad9bc 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,6 @@ lib temp node_modules/ bower_components/ -dist/ libpeerconnection.log *.swp .*.swp diff --git a/dist/angular-openlayers-directive.js b/dist/angular-openlayers-directive.js new file mode 100644 index 00000000..94615a23 --- /dev/null +++ b/dist/angular-openlayers-directive.js @@ -0,0 +1,2228 @@ +(function (root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. + define(['ol'], function (ol) { + return root.angularOpenlayersDirective = factory(ol); + }); + } else { + // Browser globals + root.angularOpenlayersDirective = factory(root.ol); + } +}(this, function (ol) { +angular.module('openlayers-directive', ['ngSanitize']).directive('openlayers', ["$log", "$q", "$compile", "olHelpers", "olMapDefaults", "olData", function($log, $q, $compile, olHelpers, + olMapDefaults, olData) { + return { + restrict: 'EA', + transclude: true, + replace: true, + scope: { + center: '=olCenter', + defaults: '=olDefaults', + view: '=olView', + events: '=olEvents' + }, + template: '
', + controller: ["$scope", function($scope) { + var _map = $q.defer(); + $scope.getMap = function() { + return _map.promise; + }; + + $scope.setMap = function(map) { + _map.resolve(map); + }; + + this.getOpenlayersScope = function() { + return $scope; + }; + }], + link: function(scope, element, attrs) { + var isDefined = olHelpers.isDefined; + var createLayer = olHelpers.createLayer; + var setMapEvents = olHelpers.setMapEvents; + var setViewEvents = olHelpers.setViewEvents; + var createView = olHelpers.createView; + var defaults = olMapDefaults.setDefaults(scope); + + // Set width and height if they are defined + if (isDefined(attrs.width)) { + if (isNaN(attrs.width)) { + element.css('width', attrs.width); + } else { + element.css('width', attrs.width + 'px'); + } + } + + if (isDefined(attrs.height)) { + if (isNaN(attrs.height)) { + element.css('height', attrs.height); + } else { + element.css('height', attrs.height + 'px'); + } + } + + if (isDefined(attrs.lat)) { + defaults.center.lat = parseFloat(attrs.lat); + } + + if (isDefined(attrs.lon)) { + defaults.center.lon = parseFloat(attrs.lon); + } + + if (isDefined(attrs.zoom)) { + defaults.center.zoom = parseFloat(attrs.zoom); + } + + var controls = ol.control.defaults(defaults.controls); + var interactions = ol.interaction.defaults(defaults.interactions); + var view = createView(defaults.view); + + // Create the Openlayers Map Object with the options + var map = new ol.Map({ + target: element[0], + controls: controls, + interactions: interactions, + renderer: defaults.renderer, + view: view + }); + + // If no layer is defined, set the default tileLayer + if (!attrs.customLayers) { + var l = { + type: 'Tile', + source: { + type: 'OSM' + } + }; + var layer = createLayer(l, view.getProjection(), 'default'); + map.addLayer(layer); + map.set('default', true); + } + + if (!isDefined(attrs.olCenter)) { + var c = ol.proj.transform([defaults.center.lon, + defaults.center.lat + ], + defaults.center.projection, view.getProjection() + ); + view.setCenter(c); + view.setZoom(defaults.center.zoom); + } + + // Set the Default events for the map + setMapEvents(defaults.events, map, scope); + + //Set the Default events for the map view + setViewEvents(defaults.events, map, scope); + + // Resolve the map object to the promises + scope.setMap(map); + olData.setMap(map, attrs.id); + + } + }; + }]); + +angular.module('openlayers-directive').directive('olCenter', ["$log", "$location", "olMapDefaults", "olHelpers", function($log, $location, olMapDefaults, olHelpers) { + + return { + restrict: 'A', + scope: false, + replace: false, + require: 'openlayers', + + link: function(scope, element, attrs, controller) { + var safeApply = olHelpers.safeApply; + var isValidCenter = olHelpers.isValidCenter; + var isDefined = olHelpers.isDefined; + var isArray = olHelpers.isArray; + var isNumber = olHelpers.isNumber; + var isSameCenterOnMap = olHelpers.isSameCenterOnMap; + var setCenter = olHelpers.setCenter; + var setZoom = olHelpers.setZoom; + var olScope = controller.getOpenlayersScope(); + + olScope.getMap().then(function(map) { + var defaults = olMapDefaults.getDefaults(olScope); + var view = map.getView(); + var center = olScope.center; + + if (attrs.olCenter.search('-') !== -1) { + $log.error('[AngularJS - Openlayers] The "center" variable can\'t use ' + + 'a "-" on his key name: "' + attrs.center + '".'); + setCenter(view, defaults.view.projection, defaults.center, map); + return; + } + + if (!isDefined(center)) { + center = {}; + } + + if (!isValidCenter(center)) { + $log.warn('[AngularJS - Openlayers] invalid \'center\''); + center.lat = defaults.center.lat; + center.lon = defaults.center.lon; + center.zoom = defaults.center.zoom; + center.projection = defaults.center.projection; + } + + if (!center.projection) { + if (defaults.view.projection !== 'pixel') { + center.projection = defaults.center.projection; + } else { + center.projection = 'pixel'; + } + } + + if (!isNumber(center.zoom)) { + center.zoom = 1; + } + + setCenter(view, defaults.view.projection, center, map); + view.setZoom(center.zoom); + + var centerUrlHash; + if (center.centerUrlHash === true) { + var extractCenterFromUrl = function() { + var search = $location.search(); + var centerParam; + if (isDefined(search.c)) { + var cParam = search.c.split(':'); + if (cParam.length === 3) { + centerParam = { + lat: parseFloat(cParam[0]), + lon: parseFloat(cParam[1]), + zoom: parseInt(cParam[2], 10) + }; + } + } + return centerParam; + }; + centerUrlHash = extractCenterFromUrl(); + + olScope.$on('$locationChangeSuccess', function() { + var urlCenter = extractCenterFromUrl(); + if (urlCenter && !isSameCenterOnMap(urlCenter, map)) { + safeApply(olScope, function(scope) { + scope.center.lat = urlCenter.lat; + scope.center.lon = urlCenter.lon; + scope.center.zoom = urlCenter.zoom; + }); + } + }); + } + + var geolocation; + olScope.$watchCollection('center', function(center) { + + if (!center) { + return; + } + + if (!center.projection) { + center.projection = defaults.center.projection; + } + + if (center.autodiscover) { + if (!geolocation) { + geolocation = new ol.Geolocation({ + projection: ol.proj.get(center.projection) + }); + + geolocation.on('change', function() { + if (center.autodiscover) { + var location = geolocation.getPosition(); + safeApply(olScope, function(scope) { + scope.center.lat = location[1]; + scope.center.lon = location[0]; + scope.center.zoom = 12; + scope.center.autodiscover = false; + geolocation.setTracking(false); + }); + } + }); + } + geolocation.setTracking(true); + return; + } + + if (!isValidCenter(center)) { + $log.warn('[AngularJS - Openlayers] invalid \'center\''); + center = defaults.center; + } + + var viewCenter = view.getCenter(); + if (viewCenter) { + if (defaults.view.projection === 'pixel') { + view.setCenter(center.coord); + return; + } + var actualCenter = ol.proj.transform(viewCenter, defaults.view.projection, center.projection); + if (!(actualCenter[1] === center.lat && actualCenter[0] === center.lon)) { + setCenter(view, defaults.view.projection, center, map); + } + } + + if (view.getZoom() !== center.zoom) { + setZoom(view, center.zoom, map); + } + }); + + map.on('moveend', function() { + safeApply(olScope, function(scope) { + + if (!isDefined(scope.center)) { + return; + } + + var center = map.getView().getCenter(); + scope.center.zoom = view.getZoom(); + + if (defaults.view.projection === 'pixel') { + scope.center.coord = center; + return; + } + + if (scope.center) { + var proj = ol.proj.transform(center, defaults.view.projection, scope.center.projection); + scope.center.lat = proj[1]; + scope.center.lon = proj[0]; + + // Notify the controller about a change in the center position + olHelpers.notifyCenterUrlHashChanged(olScope, scope.center, $location.search()); + + // Calculate the bounds if needed + if (isArray(scope.center.bounds)) { + var extent = view.calculateExtent(map.getSize()); + var centerProjection = scope.center.projection; + var viewProjection = defaults.view.projection; + scope.center.bounds = ol.proj.transformExtent(extent, viewProjection, centerProjection); + } + } + }); + }); + + }); + } + }; +}]); + +angular.module('openlayers-directive').directive('olLayer', ["$log", "$q", "olMapDefaults", "olHelpers", function($log, $q, olMapDefaults, olHelpers) { + + return { + restrict: 'E', + scope: { + properties: '=olLayerProperties' + }, + replace: false, + require: '^openlayers', + link: function(scope, element, attrs, controller) { + var isDefined = olHelpers.isDefined; + var equals = olHelpers.equals; + var olScope = controller.getOpenlayersScope(); + var createLayer = olHelpers.createLayer; + var setVectorLayerEvents = olHelpers.setVectorLayerEvents; + var detectLayerType = olHelpers.detectLayerType; + var createStyle = olHelpers.createStyle; + var isBoolean = olHelpers.isBoolean; + var addLayerBeforeMarkers = olHelpers.addLayerBeforeMarkers; + var isNumber = olHelpers.isNumber; + var insertLayer = olHelpers.insertLayer; + var removeLayer = olHelpers.removeLayer; + var addLayerToGroup = olHelpers.addLayerToGroup; + var removeLayerFromGroup = olHelpers.removeLayerFromGroup; + var getGroup = olHelpers.getGroup; + + olScope.getMap().then(function(map) { + var projection = map.getView().getProjection(); + var defaults = olMapDefaults.setDefaults(olScope); + var layerCollection = map.getLayers(); + var olLayer; + + scope.$on('$destroy', function() { + if (scope.properties.group) { + removeLayerFromGroup(layerCollection, olLayer, scope.properties.group); + } else { + removeLayer(layerCollection, olLayer.index); + } + + map.removeLayer(olLayer); + }); + + if (!isDefined(scope.properties)) { + if (isDefined(attrs.sourceType) && isDefined(attrs.sourceUrl)) { + var l = { + source: { + url: attrs.sourceUrl, + type: attrs.sourceType + } + }; + + olLayer = createLayer(l, projection, attrs.layerName); + if (detectLayerType(l) === 'Vector') { + setVectorLayerEvents(defaults.events, map, scope, attrs.name); + } + addLayerBeforeMarkers(layerCollection, olLayer); + } + return; + } + + scope.$watch('properties', function(properties, oldProperties) { + if (!isDefined(properties.source) || !isDefined(properties.source.type)) { + return; + } + + if (!isDefined(properties.visible)) { + properties.visible = true; + return; + } + + if (!isDefined(properties.opacity)) { + properties.opacity = 1; + return; + } + + var style; + var group; + var collection; + if (!isDefined(olLayer)) { + olLayer = createLayer(properties, projection); + if (isDefined(properties.group)) { + addLayerToGroup(layerCollection, olLayer, properties.group); + } else if (isDefined(properties.index)) { + insertLayer(layerCollection, properties.index, olLayer); + } else { + addLayerBeforeMarkers(layerCollection, olLayer); + } + + if (detectLayerType(properties) === 'Vector') { + setVectorLayerEvents(defaults.events, map, scope, properties.name); + } + + if (isBoolean(properties.visible)) { + olLayer.setVisible(properties.visible); + } + + if (properties.opacity) { + olLayer.setOpacity(properties.opacity); + } + + if (angular.isArray(properties.extent)) { + olLayer.setExtent(properties.extent); + } + + if (properties.style) { + if (!angular.isFunction(properties.style)) { + style = createStyle(properties.style); + } else { + style = properties.style; + } + // not every layer has a setStyle method + if (olLayer.setStyle && angular.isFunction(olLayer.setStyle)) { + olLayer.setStyle(style); + } + } + + } else { + var isNewLayer = (function(olLayer) { + // this function can be used to verify whether a new layer instance has + // been created. This is needed in order to re-assign styles, opacity + // etc... + return function(layer) { + return layer !== olLayer; + }; + })(olLayer); + + // set source properties + if (isDefined(oldProperties) && !equals(properties.source, oldProperties.source)) { + var idx = olLayer.index; + collection = layerCollection; + group = olLayer.get('group'); + + if (group) { + collection = getGroup(layerCollection, group).getLayers(); + } + + collection.removeAt(idx); + + olLayer = createLayer(properties, projection); + olLayer.set('group', group); + + if (isDefined(olLayer)) { + insertLayer(collection, idx, olLayer); + + if (detectLayerType(properties) === 'Vector') { + setVectorLayerEvents(defaults.events, map, scope, properties.name); + } + } + } + + // set opacity + if (isDefined(oldProperties) && + properties.opacity !== oldProperties.opacity || isNewLayer(olLayer)) { + if (isNumber(properties.opacity) || isNumber(parseFloat(properties.opacity))) { + olLayer.setOpacity(properties.opacity); + } + } + + // set index + if (isDefined(properties.index) && properties.index !== olLayer.index) { + collection = layerCollection; + group = olLayer.get('group'); + + if (group) { + collection = getGroup(layerCollection, group).getLayers(); + } + + removeLayer(collection, olLayer.index); + insertLayer(collection, properties.index, olLayer); + } + + // set group + if (isDefined(properties.group) && properties.group !== oldProperties.group) { + removeLayerFromGroup(layerCollection, olLayer, oldProperties.group); + addLayerToGroup(layerCollection, olLayer, properties.group); + } + + // set visibility + if (isDefined(oldProperties) && + isBoolean(properties.visible) && + properties.visible !== oldProperties.visible || isNewLayer(olLayer)) { + olLayer.setVisible(properties.visible); + } + + // set style + if (isDefined(properties.style) && + !equals(properties.style, oldProperties.style) || isNewLayer(olLayer)) { + if (!angular.isFunction(properties.style)) { + style = createStyle(properties.style); + } else { + style = properties.style; + } + // not every layer has a setStyle method + if (olLayer.setStyle && angular.isFunction(olLayer.setStyle)) { + olLayer.setStyle(style); + } + } + } + }, true); + }); + } + }; +}]); + +angular.module('openlayers-directive').directive('olPath', ["$log", "$q", "olMapDefaults", "olHelpers", function($log, $q, olMapDefaults, olHelpers) { + + return { + restrict: 'E', + scope: { + properties: '=olGeomProperties' + }, + require: '^openlayers', + replace: true, + template: '', + + link: function(scope, element, attrs, controller) { + var isDefined = olHelpers.isDefined; + var createFeature = olHelpers.createFeature; + var createOverlay = olHelpers.createOverlay; + var createVectorLayer = olHelpers.createVectorLayer; + var insertLayer = olHelpers.insertLayer; + var removeLayer = olHelpers.removeLayer; + var olScope = controller.getOpenlayersScope(); + + olScope.getMap().then(function(map) { + var mapDefaults = olMapDefaults.getDefaults(olScope); + var viewProjection = mapDefaults.view.projection; + + var layer = createVectorLayer(); + var layerCollection = map.getLayers(); + + insertLayer(layerCollection, layerCollection.getLength(), layer); + + scope.$on('$destroy', function() { + removeLayer(layerCollection, layer.index); + }); + + if (isDefined(attrs.coords)) { + var proj = attrs.proj || 'EPSG:4326'; + var coords = JSON.parse(attrs.coords); + var data = { + type: 'Polygon', + coords: coords, + projection: proj, + style: mapDefaults.styles.path + }; + var feature = createFeature(data, viewProjection); + layer.getSource().addFeature(feature); + + if (attrs.message) { + scope.message = attrs.message; + var extent = feature.getGeometry().getExtent(); + var label = createOverlay(element, extent); + map.addOverlay(label); + } + return; + } + }); + } + }; +}]); + +angular.module('openlayers-directive').directive('olView', ["$log", "$q", "olData", "olMapDefaults", "olHelpers", function($log, $q, olData, olMapDefaults, olHelpers) { + return { + restrict: 'A', + scope: false, + replace: false, + require: 'openlayers', + link: function(scope, element, attrs, controller) { + var olScope = controller.getOpenlayersScope(); + var isNumber = olHelpers.isNumber; + var safeApply = olHelpers.safeApply; + var createView = olHelpers.createView; + + olScope.getMap().then(function(map) { + var defaults = olMapDefaults.getDefaults(olScope); + var view = olScope.view; + + if (!view.projection) { + view.projection = defaults.view.projection; + } + + if (!view.maxZoom) { + view.maxZoom = defaults.view.maxZoom; + } + + if (!view.minZoom) { + view.minZoom = defaults.view.minZoom; + } + + if (!view.rotation) { + view.rotation = defaults.view.rotation; + } + + var mapView = createView(view); + map.setView(mapView); + + olScope.$watchCollection('view', function(view) { + if (isNumber(view.rotation)) { + mapView.setRotation(view.rotation); + } + }); + + mapView.on('change:rotation', function() { + safeApply(olScope, function(scope) { + scope.view.rotation = map.getView().getRotation(); + }); + }); + + }); + } + }; +}]); + +angular.module('openlayers-directive').directive('olControl', ["$log", "$q", "olData", "olMapDefaults", "olHelpers", function($log, $q, olData, olMapDefaults, olHelpers) { + + return { + restrict: 'E', + scope: { + properties: '=olControlProperties' + }, + replace: false, + require: '^openlayers', + link: function(scope, element, attrs, controller) { + var isDefined = olHelpers.isDefined; + var olScope = controller.getOpenlayersScope(); + var olControl; + var olControlOps; + + olScope.getMap().then(function(map) { + var getControlClasses = olHelpers.getControlClasses; + var controlClasses = getControlClasses(); + + scope.$on('$destroy', function() { + map.removeControl(olControl); + }); + + if (!isDefined(scope.properties) || !isDefined(scope.properties.control)) { + if (attrs.name) { + if (isDefined(scope.properties)) { + olControlOps = scope.properties; + } + olControl = new controlClasses[attrs.name](olControlOps); + map.addControl(olControl); + } + return; + } + + olControl = scope.properties.control; + map.addControl(olControl); + }); + } + }; +}]); + +angular.module('openlayers-directive').directive('olMarker', ["$log", "$q", "olMapDefaults", "olHelpers", function($log, $q, olMapDefaults, olHelpers) { + + var getMarkerDefaults = function() { + return { + projection: 'EPSG:4326', + lat: 0, + lon: 0, + coord: [], + show: true, + showOnMouseOver: false, + showOnMouseClick: false, + keepOneOverlayVisible: false + }; + }; + + var markerLayerManager = (function() { + var mapDict = []; + + function getMapIndex(map) { + return mapDict.map(function(record) { + return record.map; + }).indexOf(map); + } + + return { + getInst: function getMarkerLayerInst(scope, map) { + var mapIndex = getMapIndex(map); + + if (mapIndex === -1) { + var markerLayer = olHelpers.createVectorLayer(); + markerLayer.set('markers', true); + map.addLayer(markerLayer); + mapDict.push({ + map: map, + markerLayer: markerLayer, + instScopes: [] + }); + mapIndex = mapDict.length - 1; + } + + mapDict[mapIndex].instScopes.push(scope); + + return mapDict[mapIndex].markerLayer; + }, + deregisterScope: function deregisterScope(scope, map) { + var mapIndex = getMapIndex(map); + if (mapIndex === -1) { + throw Error('This map has no markers'); + } + + var scopes = mapDict[mapIndex].instScopes; + var scopeIndex = scopes.indexOf(scope); + if (scopeIndex === -1) { + throw Error('Scope wan\'t registered'); + } + + scopes.splice(scopeIndex, 1); + + if (!scopes.length) { + map.removeLayer(mapDict[mapIndex].markerLayer); + delete mapDict[mapIndex]; + } + } + }; + })(); + return { + restrict: 'E', + scope: { + lat: '=lat', + lon: '=lon', + label: '=label', + properties: '=olMarkerProperties', + style: '=olStyle' + }, + transclude: true, + require: '^openlayers', + replace: true, + template: + '', + + link: function(scope, element, attrs, controller) { + var isDefined = olHelpers.isDefined; + var olScope = controller.getOpenlayersScope(); + var createFeature = olHelpers.createFeature; + var createOverlay = olHelpers.createOverlay; + + var hasTranscluded = element.find('ng-transclude').children().length > 0; + + olScope.getMap().then(function(map) { + var markerLayer = markerLayerManager.getInst(scope, map); + var data = getMarkerDefaults(); + + var mapDefaults = olMapDefaults.getDefaults(olScope); + var viewProjection = mapDefaults.view.projection; + var label; + var pos; + var marker; + + // This function handles dragging a marker + var pickOffset = null; + var pickProperties = null; + function handleDrag(evt) { + var coord = evt.coordinate; + var proj = map.getView().getProjection().getCode(); + if (proj === 'pixel') { + coord = coord.map(function(v) { + return parseInt(v, 10); + }); + } else { + coord = ol.proj.transform(coord, proj, 'EPSG:4326'); + } + + if (evt.type === 'pointerdown') { + // Get feature under mouse if any + var feature = map.forEachFeatureAtPixel(evt.pixel, function(feature) { + return feature; + }); + // Get associated marker properties + pickProperties = (feature ? feature.get('marker') : null); + if (!pickProperties || !pickProperties.draggable) { + pickProperties = null; + return; + } + map.getTarget().style.cursor = 'pointer'; + if (proj === 'pixel') { + pickOffset = [coord[0] - pickProperties.coord[0], coord[1] - pickProperties.coord[1]]; + } else { + pickOffset = [coord[0] - pickProperties.lon, coord[1] - pickProperties.lat]; + } + evt.preventDefault(); + } else if (pickOffset && pickProperties) { + if (evt.type === 'pointerup') { + map.getTarget().style.cursor = ''; + pickOffset = null; + pickProperties = null; + evt.preventDefault(); + } else if (evt.type === 'pointerdrag') { + evt.preventDefault(); + scope.$apply(function() { + // Add current delta to marker initial position + if (proj === 'pixel') { + pickProperties.coord[0] = coord[0] - pickOffset[0]; + pickProperties.coord[1] = coord[1] - pickOffset[1]; + } else { + pickProperties.lon = coord[0] - pickOffset[0]; + pickProperties.lat = coord[1] - pickOffset[1]; + } + }); + } + } + } + + // Setup generic handlers for marker drag + map.on('pointerdown', handleDrag); + map.on('pointerup', handleDrag); + map.on('pointerdrag', handleDrag); + + scope.$on('$destroy', function() { + markerLayer.getSource().removeFeature(marker); + if (isDefined(label)) { + map.removeOverlay(label); + } + markerLayerManager.deregisterScope(scope, map); + }); + + if (!isDefined(scope.properties)) { + data.lat = scope.lat ? scope.lat : data.lat; + data.lon = scope.lon ? scope.lon : data.lon; + data.message = attrs.message; + data.style = scope.style ? scope.style : mapDefaults.styles.marker; + + marker = createFeature(data, viewProjection); + if (!isDefined(marker)) { + $log.error('[AngularJS - Openlayers] Received invalid data on ' + + 'the marker.'); + } + // Add a link between the feature and the marker properties + marker.set('marker', scope); + markerLayer.getSource().addFeature(marker); + + if (data.message || hasTranscluded) { + scope.message = attrs.message; + pos = ol.proj.transform([data.lon, data.lat], data.projection, + viewProjection); + label = createOverlay(element, pos); + map.addOverlay(label); + } + return; + } + + scope.$watch('properties', function(properties) { + + // Remove previous listeners if any + map.getViewport().removeEventListener('mousemove', properties.handleInteraction); + map.getViewport().removeEventListener('click', properties.handleTapInteraction); + map.getViewport().querySelector('canvas.ol-unselectable').removeEventListener( + 'touchend', properties.handleTapInteraction); + map.getViewport().removeEventListener('mousemove', properties.showAtLeastOneOverlay); + map.getViewport().removeEventListener('click', properties.removeAllOverlays); + + // This function handles popup on mouse over/click + properties.handleInteraction = function(evt) { + if (properties.label.show) { + return; + } + var found = false; + var pixel = map.getEventPixel(evt); + var feature = map.forEachFeatureAtPixel(pixel, function(feature) { + return feature; + }); + + var actionTaken = false; + if (feature === marker) { + actionTaken = true; + found = true; + if (!isDefined(label)) { + if (data.projection === 'pixel') { + pos = properties.coord; + } else { + pos = ol.proj.transform([properties.lon, properties.lat], + data.projection, viewProjection); + } + label = createOverlay(element, pos); + map.addOverlay(label); + } + + if (properties.onClick && (evt.type === 'click' || evt.type === 'touchend')) { + scope.$apply(function() { + properties.onClick.call(marker, evt, properties); + }); + } + map.getTarget().style.cursor = 'pointer'; + } + + if (!found && label) { + actionTaken = true; + map.removeOverlay(label); + label = undefined; + map.getTarget().style.cursor = ''; + } + + if (actionTaken) { + evt.preventDefault(); + } + }; + + // Made to filter out click/tap events if both are being triggered on this platform + properties.handleTapInteraction = (function() { + var cooldownActive = false; + var prevTimeout; + + // Sets the cooldown flag to filter out any subsequent events within 500 ms + function activateCooldown() { + cooldownActive = true; + if (prevTimeout) { + clearTimeout(prevTimeout); + } + prevTimeout = setTimeout(function() { + cooldownActive = false; + prevTimeout = null; + }, 500); + } + + // Preventing from 'touchend' to be considered a tap, if fired immediately after 'touchmove' + map.getViewport().querySelector('canvas.ol-unselectable').addEventListener( + 'touchmove', activateCooldown); + + return function() { + if (!cooldownActive) { + properties.handleInteraction.apply(null, arguments); + activateCooldown(); + } + }; + })(); + + properties.showAtLeastOneOverlay = function(evt) { + if (properties.label.show) { + return; + } + var found = false; + var pixel = map.getEventPixel(evt); + var feature = map.forEachFeatureAtPixel(pixel, function(feature) { + return feature; + }); + + var actionTaken = false; + if (feature === marker) { + actionTaken = true; + found = true; + if (!isDefined(label)) { + if (data.projection === 'pixel') { + pos = data.coord; + } else { + pos = ol.proj.transform([data.lon, data.lat], + data.projection, viewProjection); + } + label = createOverlay(element, pos); + angular.forEach(map.getOverlays(), function(value) { + map.removeOverlay(value); + }); + map.addOverlay(label); + } + map.getTarget().style.cursor = 'pointer'; + } + + if (!found && label) { + actionTaken = true; + label = undefined; + map.getTarget().style.cursor = ''; + } + + if (actionTaken) { + evt.preventDefault(); + } + }; + + properties.removeAllOverlays = function(evt) { + angular.forEach(map.getOverlays(), function(value) { + map.removeOverlay(value); + }); + evt.preventDefault(); + }; + + if (!isDefined(marker)) { + data.projection = properties.projection ? properties.projection : + data.projection; + data.coord = properties.coord ? properties.coord : data.coord; + data.lat = properties.lat ? properties.lat : data.lat; + data.lon = properties.lon ? properties.lon : data.lon; + + if (isDefined(properties.style)) { + data.style = properties.style; + } else { + data.style = mapDefaults.styles.marker; + } + + marker = createFeature(data, viewProjection); + if (!isDefined(marker)) { + $log.error('[AngularJS - Openlayers] Received invalid data on ' + + 'the marker.'); + } + // Add a link between the feature and the marker properties + marker.set('marker', properties); + markerLayer.getSource().addFeature(marker); + } else { + var requestedPosition; + if (properties.projection === 'pixel') { + requestedPosition = properties.coord; + } else { + requestedPosition = ol.proj.transform([properties.lon, properties.lat], data.projection, + map.getView().getProjection()); + } + + if (!angular.equals(marker.getGeometry().getCoordinates(), requestedPosition)) { + var geometry = new ol.geom.Point(requestedPosition); + marker.setGeometry(geometry); + } + } + + if (isDefined(label)) { + map.removeOverlay(label); + } + + if (!isDefined(properties.label)) { + return; + } + + scope.message = properties.label.message; + if (!hasTranscluded && (!isDefined(scope.message) || scope.message.length === 0)) { + return; + } + + if (properties.label && properties.label.show === true) { + if (data.projection === 'pixel') { + pos = data.coord; + } else { + pos = ol.proj.transform([properties.lon, properties.lat], data.projection, + viewProjection); + } + label = createOverlay(element, pos); + map.addOverlay(label); + } + + if (label && properties.label && properties.label.show === false) { + map.removeOverlay(label); + label = undefined; + } + + // Then setup new ones according to properties + if (properties.label && properties.label.show === false && + properties.label.showOnMouseOver) { + map.getViewport().addEventListener('mousemove', properties.handleInteraction); + } + + if ((properties.label && properties.label.show === false && + properties.label.showOnMouseClick) || + properties.onClick) { + map.getViewport().addEventListener('click', properties.handleTapInteraction); + map.getViewport().querySelector('canvas.ol-unselectable').addEventListener( + 'touchend', properties.handleTapInteraction); + } + + if ((properties.label && properties.label.show === false && + properties.label.keepOneOverlayVisible)) { + map.getViewport().addEventListener('mousemove', properties.showAtLeastOneOverlay); + map.getViewport().addEventListener('click', properties.removeAllOverlays); + } + }, true); + }); + } + }; +}]); + +angular.module('openlayers-directive').service('olData', ["$log", "$q", "olHelpers", function($log, $q, olHelpers) { + + var obtainEffectiveMapId = olHelpers.obtainEffectiveMapId; + + var maps = {}; + + var setResolvedDefer = function(d, mapId) { + var id = obtainEffectiveMapId(d, mapId); + d[id].resolvedDefer = true; + }; + + var getUnresolvedDefer = function(d, mapId) { + var id = obtainEffectiveMapId(d, mapId); + var defer; + + if (!angular.isDefined(d[id]) || d[id].resolvedDefer === true) { + defer = $q.defer(); + d[id] = { + defer: defer, + resolvedDefer: false + }; + } else { + defer = d[id].defer; + } + return defer; + }; + + var getDefer = function(d, mapId) { + var id = obtainEffectiveMapId(d, mapId); + var defer; + + if (!angular.isDefined(d[id]) || d[id].resolvedDefer === false) { + defer = getUnresolvedDefer(d, mapId); + } else { + defer = d[id].defer; + } + return defer; + }; + + this.setMap = function(olMap, scopeId) { + var defer = getUnresolvedDefer(maps, scopeId); + defer.resolve(olMap); + setResolvedDefer(maps, scopeId); + }; + + this.getMap = function(scopeId) { + var defer = getDefer(maps, scopeId); + return defer.promise; + }; + +}]); + +angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$http", function($q, $log, $http) { + + var isDefined = function(value) { + return angular.isDefined(value); + }; + + var isDefinedAndNotNull = function(value) { + return angular.isDefined(value) && value !== null; + }; + + var setEvent = function(map, eventType, scope) { + map.on(eventType, function(event) { + var coord = event.coordinate; + var proj = map.getView().getProjection().getCode(); + if (proj === 'pixel') { + coord = coord.map(function(v) { + return parseInt(v, 10); + }); + } + scope.$emit('openlayers.map.' + eventType, { + 'coord': coord, + 'projection': proj, + 'event': event + }); + }); + }; + + var bingImagerySets = [ + 'Road', + 'Aerial', + 'AerialWithLabels', + 'collinsBart', + 'ordnanceSurvey' + ]; + + var getControlClasses = function() { + return { + attribution: ol.control.Attribution, + fullscreen: ol.control.FullScreen, + mouseposition: ol.control.MousePosition, + rotate: ol.control.Rotate, + scaleline: ol.control.ScaleLine, + zoom: ol.control.Zoom, + zoomslider: ol.control.ZoomSlider, + zoomtoextent: ol.control.ZoomToExtent + }; + }; + + var mapQuestLayers = ['osm', 'sat', 'hyb']; + + var esriBaseLayers = ['World_Imagery', 'World_Street_Map', 'World_Topo_Map', + 'World_Physical_Map', 'World_Terrain_Base', + 'Ocean_Basemap', 'NatGeo_World_Map']; + + var styleMap = { + 'style': ol.style.Style, + 'fill': ol.style.Fill, + 'stroke': ol.style.Stroke, + 'circle': ol.style.Circle, + 'icon': ol.style.Icon, + 'image': ol.style.Image, + 'regularshape': ol.style.RegularShape, + 'text': ol.style.Text + }; + + var optionalFactory = function(style, Constructor) { + if (Constructor && style instanceof Constructor) { + return style; + } else if (Constructor) { + return new Constructor(style); + } else { + return style; + } + }; + + //Parse the style tree calling the appropriate constructors. + //The keys in styleMap can be used and the OpenLayers constructors can be + //used directly. + var createStyle = function recursiveStyle(data, styleName) { + var style; + if (!styleName) { + styleName = 'style'; + style = data; + } else { + style = data[styleName]; + } + //Instead of defining one style for the layer, we've been given a style function + //to apply to each feature. + if (styleName === 'style' && data instanceof Function) { + return data; + } + + if (!(style instanceof Object)) { + return style; + } + + var styleObject; + if (Object.prototype.toString.call(style) === '[object Object]') { + styleObject = {}; + var styleConstructor = styleMap[styleName]; + if (styleConstructor && style instanceof styleConstructor) { + return style; + } + Object.getOwnPropertyNames(style).forEach(function(val, idx, array) { + //Consider the case + //image: { + // circle: { + // fill: { + // color: 'red' + // } + // } + // + //An ol.style.Circle is an instance of ol.style.Image, so we do not want to construct + //an Image and then construct a Circle. We assume that if we have an instanceof + //relationship, that the JSON parent has exactly one child. + //We check to see if an inheritance relationship exists. + //If it does, then for the parent we create an instance of the child. + var valConstructor = styleMap[val]; + if (styleConstructor && valConstructor && + valConstructor.prototype instanceof styleMap[styleName]) { + console.assert(array.length === 1, 'Extra parameters for ' + styleName); + styleObject = recursiveStyle(style, val); + return optionalFactory(styleObject, valConstructor); + } else { + styleObject[val] = recursiveStyle(style, val); + + // if the value is 'text' and it contains a String, then it should be interpreted + // as such, 'cause the text style might effectively contain a text to display + if (val !== 'text' && typeof styleObject[val] !== 'string') { + styleObject[val] = optionalFactory(styleObject[val], styleMap[val]); + } + } + }); + } else { + styleObject = style; + } + return optionalFactory(styleObject, styleMap[styleName]); + }; + + var detectLayerType = function(layer) { + if (layer.type) { + return layer.type; + } else { + switch (layer.source.type) { + case 'ImageWMS': + return 'Image'; + case 'ImageStatic': + return 'Image'; + case 'GeoJSON': + case 'JSONP': + case 'TopoJSON': + case 'KML': + case 'TileVector': + return 'Vector'; + default: + return 'Tile'; + } + } + }; + + var createProjection = function(view) { + var oProjection; + + switch (view.projection) { + case 'pixel': + if (!isDefined(view.extent)) { + $log.error('[AngularJS - Openlayers] - You must provide the extent of the image ' + + 'if using pixel projection'); + return; + } + oProjection = new ol.proj.Projection({ + code: 'pixel', + units: 'pixels', + extent: view.extent + }); + break; + default: + oProjection = new ol.proj.get(view.projection); + break; + } + + return oProjection; + }; + + var isValidStamenLayer = function(layer) { + return ['watercolor', 'terrain', 'toner'].indexOf(layer) !== -1; + }; + + var createSource = function(source, projection) { + var oSource; + + switch (source.type) { + case 'MapBox': + if (!source.mapId || !source.accessToken) { + $log.error('[AngularJS - Openlayers] - MapBox layer requires the map id and the access token'); + return; + } + var url = 'http://api.tiles.mapbox.com/v4/' + source.mapId + '/{z}/{x}/{y}.png?access_token=' + + source.accessToken; + + var pixelRatio = window.devicePixelRatio; + + if (pixelRatio > 1) { + url = url.replace('.png', '@2x.png'); + } + + oSource = new ol.source.XYZ({ + url: url, + attributions: createAttribution(source), + tilePixelRatio: pixelRatio > 1 ? 2 : 1, + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + }); + break; + case 'ImageWMS': + if (!source.url || !source.params) { + $log.error('[AngularJS - Openlayers] - ImageWMS Layer needs ' + + 'valid server url and params properties'); + } + oSource = new ol.source.ImageWMS({ + url: source.url, + attributions: createAttribution(source), + crossOrigin: (typeof source.crossOrigin === 'undefined') ? 'anonymous' : source.crossOrigin, + params: source.params, + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + }); + break; + + case 'TileWMS': + if ((!source.url && !source.urls) || !source.params) { + $log.error('[AngularJS - Openlayers] - TileWMS Layer needs ' + + 'valid url (or urls) and params properties'); + } + + var wmsConfiguration = { + crossOrigin: (typeof source.crossOrigin === 'undefined') ? 'anonymous' : source.crossOrigin, + params: source.params, + attributions: createAttribution(source), + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + }; + + if (source.url) { + wmsConfiguration.url = source.url; + } + + if (source.urls) { + wmsConfiguration.urls = source.urls; + } + + oSource = new ol.source.TileWMS(wmsConfiguration); + break; + + case 'WMTS': + if ((!source.url && !source.urls) || !source.tileGrid) { + $log.error('[AngularJS - Openlayers] - WMTS Layer needs valid url ' + + '(or urls) and tileGrid properties'); + } + + var wmtsConfiguration = { + projection: projection, + layer: source.layer, + attributions: createAttribution(source), + matrixSet: (source.matrixSet === 'undefined') ? projection : source.matrixSet, + format: (source.format === 'undefined') ? 'image/jpeg' : source.format, + requestEncoding: (source.requestEncoding === 'undefined') ? + 'KVP' : source.requestEncoding, + tileGrid: new ol.tilegrid.WMTS({ + origin: source.tileGrid.origin, + resolutions: source.tileGrid.resolutions, + matrixIds: source.tileGrid.matrixIds + }), + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + }; + + if (isDefined(source.url)) { + wmtsConfiguration.url = source.url; + } + + if (isDefined(source.urls)) { + wmtsConfiguration.urls = source.urls; + } + + oSource = new ol.source.WMTS(wmtsConfiguration); + break; + + case 'OSM': + oSource = new ol.source.OSM({ + attributions: createAttribution(source), + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + }); + + if (source.url) { + oSource.setUrl(source.url); + } + + break; + case 'BingMaps': + if (!source.key) { + $log.error('[AngularJS - Openlayers] - You need an API key to show the Bing Maps.'); + return; + } + + var bingConfiguration = { + key: source.key, + attributions: createAttribution(source), + imagerySet: source.imagerySet ? source.imagerySet : bingImagerySets[0], + culture: source.culture, + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + }; + + if (source.maxZoom) { + bingConfiguration.maxZoom = source.maxZoom; + } + + oSource = new ol.source.BingMaps(bingConfiguration); + break; + + case 'MapQuest': + if (!source.layer || mapQuestLayers.indexOf(source.layer) === -1) { + $log.error('[AngularJS - Openlayers] - MapQuest layers needs a valid \'layer\' property.'); + return; + } + + oSource = new ol.source.MapQuest({ + attributions: createAttribution(source), + layer: source.layer, + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + }); + + break; + + case 'EsriBaseMaps': + if (!source.layer || esriBaseLayers.indexOf(source.layer) === -1) { + $log.error('[AngularJS - Openlayers] - ESRI layers needs a valid \'layer\' property.'); + return; + } + + var _urlBase = 'http://services.arcgisonline.com/ArcGIS/rest/services/'; + var _url = _urlBase + source.layer + '/MapServer/tile/{z}/{y}/{x}'; + + oSource = new ol.source.XYZ({ + attributions: createAttribution(source), + url: _url, + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + }); + + break; + + case 'GeoJSON': + if (!(source.geojson || source.url)) { + $log.error('[AngularJS - Openlayers] - You need a geojson ' + + 'property to add a GeoJSON layer.'); + return; + } + + if (isDefined(source.url)) { + oSource = new ol.source.Vector({ + format: new ol.format.GeoJSON(), + url: source.url, + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + }); + } else { + oSource = new ol.source.Vector(); + + var projectionToUse = projection; + if (isDefined(source.geojson.projection)) { + projectionToUse = source.geojson.projection; + } + + var geojsonFormat = new ol.format.GeoJSON(); + var features = geojsonFormat.readFeatures( + source.geojson.object, { featureProjection: projectionToUse }); + + oSource.addFeatures(features); + } + + break; + case 'JSONP': + if (!(source.url)) { + $log.error('[AngularJS - Openlayers] - You need an url properly configured to add a JSONP layer.'); + return; + } + + if (isDefined(source.url)) { + oSource = new ol.source.Vector({ + format: new ol.format.GeoJSON(), + loader: function(/*extent, resolution, projection*/) { + var url = source.url + + '&outputFormat=text/javascript&format_options=callback:JSON_CALLBACK'; + $http.jsonp(url, { cache: source.cache}).success(function(response) { + oSource.addFeatures(oSource.readFeatures(response)); + }).error(function(response) { + $log(response); + }); + }, + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + }); + } + break; + case 'TopoJSON': + if (!(source.topojson || source.url)) { + $log.error('[AngularJS - Openlayers] - You need a topojson ' + + 'property to add a TopoJSON layer.'); + return; + } + + if (source.url) { + oSource = new ol.source.Vector({ + format: new ol.format.TopoJSON(), + url: source.url, + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + }); + } else { + oSource = new ol.source.Vector(angular.extend(source.topojson, { + format: new ol.format.TopoJSON(), + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + })); + } + break; + case 'TileJSON': + oSource = new ol.source.TileJSON({ + url: source.url, + attributions: createAttribution(source), + crossOrigin: 'anonymous', + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + }); + break; + + case 'TileVector': + if (!source.url || !source.format) { + $log.error('[AngularJS - Openlayers] - TileVector Layer needs valid url and format properties'); + } + oSource = new ol.source.TileVector({ + url: source.url, + projection: projection, + attributions: createAttribution(source), + format: source.format, + tileGrid: new ol.tilegrid.createXYZ({ + maxZoom: source.maxZoom || 19 + }), + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + }); + break; + + case 'TileTMS': + if (!source.url || !source.tileGrid) { + $log.error('[AngularJS - Openlayers] - TileTMS Layer needs valid url and tileGrid properties'); + } + oSource = new ol.source.TileImage({ + url: source.url, + maxExtent: source.maxExtent, + attributions: createAttribution(source), + tileGrid: new ol.tilegrid.TileGrid({ + origin: source.tileGrid.origin, + resolutions: source.tileGrid.resolutions + }), + tileUrlFunction: function(tileCoord) { + + var z = tileCoord[0]; + var x = tileCoord[1]; + var y = tileCoord[2]; //(1 << z) - tileCoord[2] - 1; + + if (x < 0 || y < 0) { + return ''; + } + + var url = source.url + z + '/' + x + '/' + y + '.png'; + + return url; + }, + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + }); + break; + case 'TileImage': + oSource = new ol.source.TileImage({ + url: source.url, + attributions: createAttribution(source), + tileGrid: new ol.tilegrid.TileGrid({ + origin: source.tileGrid.origin, // top left corner of the pixel projection's extent + resolutions: source.tileGrid.resolutions + }), + tileUrlFunction: function(tileCoord/*, pixelRatio, projection*/) { + var z = tileCoord[0]; + var x = tileCoord[1]; + var y = -tileCoord[2] - 1; + var url = source.url + .replace('{z}', z.toString()) + .replace('{x}', x.toString()) + .replace('{y}', y.toString()); + return url; + }, + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + }); + break; + case 'KML': + var extractStyles = source.extractStyles || false; + oSource = new ol.source.Vector({ + url: source.url, + format: new ol.format.KML(), + radius: source.radius, + extractStyles: extractStyles, + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + }); + break; + case 'Stamen': + if (!source.layer || !isValidStamenLayer(source.layer)) { + $log.error('[AngularJS - Openlayers] - You need a valid Stamen layer.'); + return; + } + oSource = new ol.source.Stamen({ + layer: source.layer, + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + }); + break; + case 'ImageStatic': + if (!source.url || !angular.isArray(source.imageSize) || source.imageSize.length !== 2) { + $log.error('[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.'); + return; + } + + oSource = new ol.source.ImageStatic({ + url: source.url, + attributions: createAttribution(source), + imageSize: source.imageSize, + projection: projection, + imageExtent: projection.getExtent(), + imageLoadFunction: source.imageLoadFunction, + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + }); + break; + case 'XYZ': + if (!source.url) { + $log.error('[AngularJS - Openlayers] - XYZ Layer needs valid url and params properties'); + } + oSource = new ol.source.XYZ({ + url: source.url, + attributions: createAttribution(source), + minZoom: source.minZoom, + maxZoom: source.maxZoom, + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + }); + break; + } + + // log a warning when no source could be created for the given type + if (!oSource) { + $log.warn('[AngularJS - Openlayers] - No source could be found for type "' + source.type + '"'); + } + + return oSource; + }; + + var createAttribution = function(source) { + var attributions = []; + if (isDefined(source.attribution)) { + attributions.unshift(new ol.Attribution({html: source.attribution})); + } + return attributions; + }; + + var createGroup = function(name) { + var olGroup = new ol.layer.Group(); + olGroup.set('name', name); + + return olGroup; + }; + + var getGroup = function(layers, name) { + var layer; + + angular.forEach(layers, function(l) { + if (l instanceof ol.layer.Group && l.get('name') === name) { + layer = l; + return; + } + }); + + return layer; + }; + + var addLayerBeforeMarkers = function(layers, layer) { + var markersIndex; + for (var i = 0; i < layers.getLength(); i++) { + var l = layers.item(i); + + if (l.get('markers')) { + markersIndex = i; + break; + } + } + + if (isDefined(markersIndex)) { + var markers = layers.item(markersIndex); + layer.index = markersIndex; + layers.setAt(markersIndex, layer); + markers.index = layers.getLength(); + layers.push(markers); + } else { + layer.index = layers.getLength(); + layers.push(layer); + } + + }; + + var removeLayer = function(layers, index) { + layers.removeAt(index); + for (var i = index; i < layers.getLength(); i++) { + var l = layers.item(i); + if (l === null) { + layers.insertAt(i, null); + break; + } else { + l.index = i; + } + } + }; + + return { + // Determine if a reference is defined + isDefined: isDefined, + + // Determine if a reference is a number + isNumber: function(value) { + return angular.isNumber(value); + }, + + createView: function(view) { + var projection = createProjection(view); + + return new ol.View({ + projection: projection, + maxZoom: view.maxZoom, + minZoom: view.minZoom, + extent: view.extent + }); + }, + + // Determine if a reference is defined and not null + isDefinedAndNotNull: isDefinedAndNotNull, + + // Determine if a reference is a string + isString: function(value) { + return angular.isString(value); + }, + + // Determine if a reference is an array + isArray: function(value) { + return angular.isArray(value); + }, + + // Determine if a reference is an object + isObject: function(value) { + return angular.isObject(value); + }, + + // Determine if two objects have the same properties + equals: function(o1, o2) { + return angular.equals(o1, o2); + }, + + isValidCenter: function(center) { + return angular.isDefined(center) && + (typeof center.autodiscover === 'boolean' || + angular.isNumber(center.lat) && angular.isNumber(center.lon) || + (angular.isArray(center.coord) && center.coord.length === 2 && + angular.isNumber(center.coord[0]) && angular.isNumber(center.coord[1])) || + (angular.isArray(center.bounds) && center.bounds.length === 4 && + angular.isNumber(center.bounds[0]) && angular.isNumber(center.bounds[1]) && + angular.isNumber(center.bounds[1]) && angular.isNumber(center.bounds[2]))); + }, + + safeApply: function($scope, fn) { + var phase = $scope.$root.$$phase; + if (phase === '$apply' || phase === '$digest') { + $scope.$eval(fn); + } else { + $scope.$apply(fn); + } + }, + + isSameCenterOnMap: function(center, map) { + var urlProj = center.projection || 'EPSG:4326'; + var urlCenter = [center.lon, center.lat]; + var mapProj = map.getView().getProjection(); + var mapCenter = ol.proj.transform(map.getView().getCenter(), mapProj, urlProj); + var zoom = map.getView().getZoom(); + if (mapCenter[1].toFixed(4) === urlCenter[1].toFixed(4) && + mapCenter[0].toFixed(4) === urlCenter[0].toFixed(4) && + zoom === center.zoom) { + return true; + } + return false; + }, + + setCenter: function(view, projection, newCenter, map) { + + if (map && view.getCenter()) { + var pan = ol.animation.pan({ + duration: 150, + source: (view.getCenter()) + }); + map.beforeRender(pan); + } + + if (newCenter.projection === projection) { + view.setCenter([newCenter.lon, newCenter.lat]); + } else { + var coord = [newCenter.lon, newCenter.lat]; + view.setCenter(ol.proj.transform(coord, newCenter.projection, projection)); + } + }, + + setZoom: function(view, zoom, map) { + var z = ol.animation.zoom({ + duration: 150, + resolution: map.getView().getResolution() + }); + map.beforeRender(z); + view.setZoom(zoom); + }, + + isBoolean: function(value) { + return typeof value === 'boolean'; + }, + + obtainEffectiveMapId: function(d, mapId) { + var id; + var i; + if (!angular.isDefined(mapId)) { + if (Object.keys(d).length === 1) { + for (i in d) { + if (d.hasOwnProperty(i)) { + id = i; + } + } + } else if (Object.keys(d).length === 0) { + id = 'main'; + } else { + $log.error('[AngularJS - Openlayers] - You have more than 1 map on the DOM, ' + + 'you must provide the map ID to the olData.getXXX call'); + } + } else { + id = mapId; + } + return id; + }, + + createStyle: createStyle, + + setMapEvents: function(events, map, scope) { + if (isDefined(events) && angular.isArray(events.map)) { + for (var i in events.map) { + var event = events.map[i]; + setEvent(map, event, scope); + } + } + }, + + setVectorLayerEvents: function(events, map, scope, layerName) { + if (isDefined(events) && angular.isArray(events.layers)) { + angular.forEach(events.layers, function(eventType) { + angular.element(map.getViewport()).on(eventType, function(evt) { + var pixel = map.getEventPixel(evt); + var feature = map.forEachFeatureAtPixel(pixel, function(feature, olLayer) { + // only return the feature if it is in this layer (based on the name) + return (isDefinedAndNotNull(olLayer) && olLayer.get('name') === layerName) ? feature : null; + }); + if (isDefinedAndNotNull(feature)) { + scope.$emit('openlayers.layers.' + layerName + '.' + eventType, feature, evt); + } + }); + }); + } + }, + + setViewEvents: function(events, map, scope) { + if (isDefined(events) && angular.isArray(events.view)) { + var view = map.getView(); + angular.forEach(events.view, function(eventType) { + view.on(eventType, function(event) { + scope.$emit('openlayers.view.' + eventType, view, event); + }); + }); + } + }, + + detectLayerType: detectLayerType, + + createLayer: function(layer, projection, name) { + var oLayer; + var type = detectLayerType(layer); + var oSource = createSource(layer.source, projection); + if (!oSource) { + return; + } + + // Manage clustering + if ((type === 'Vector') && layer.clustering) { + oSource = new ol.source.Cluster({ + source: oSource, + distance: layer.clusteringDistance, + }); + } + + switch (type) { + case 'Image': + oLayer = new ol.layer.Image({ source: oSource }); + break; + case 'Tile': + oLayer = new ol.layer.Tile({ source: oSource }); + break; + case 'Heatmap': + oLayer = new ol.layer.Heatmap({ source: oSource }); + break; + case 'Vector': + oLayer = new ol.layer.Vector({ source: oSource }); + break; + } + + // set a layer name if given + if (isDefined(name)) { + oLayer.set('name', name); + } else if (isDefined(layer.name)) { + oLayer.set('name', layer.name); + } + + return oLayer; + }, + + createVectorLayer: function() { + return new ol.layer.Vector({ + source: new ol.source.Vector() + }); + }, + + notifyCenterUrlHashChanged: function(scope, center, search) { + if (center.centerUrlHash) { + var centerUrlHash = center.lat.toFixed(4) + ':' + center.lon.toFixed(4) + ':' + center.zoom; + if (!isDefined(search.c) || search.c !== centerUrlHash) { + scope.$emit('centerUrlHash', centerUrlHash); + } + } + }, + + getControlClasses: getControlClasses, + + detectControls: function(controls) { + var actualControls = {}; + var controlClasses = getControlClasses(); + + controls.forEach(function(control) { + for (var i in controlClasses) { + if (control instanceof controlClasses[i]) { + actualControls[i] = control; + } + } + }); + + return actualControls; + }, + + createFeature: function(data, viewProjection) { + var geometry; + + switch (data.type) { + case 'Polygon': + geometry = new ol.geom.Polygon(data.coords); + break; + default: + if (isDefined(data.coord) && data.projection === 'pixel') { + geometry = new ol.geom.Point(data.coord); + } else { + geometry = new ol.geom.Point([data.lon, data.lat]); + } + break; + } + + if (isDefined(data.projection) && data.projection !== 'pixel') { + geometry = geometry.transform(data.projection, viewProjection); + } + + var feature = new ol.Feature({ + geometry: geometry + }); + + if (isDefined(data.style)) { + var style = createStyle(data.style); + feature.setStyle(style); + } + return feature; + }, + + addLayerBeforeMarkers: addLayerBeforeMarkers, + + getGroup: getGroup, + + addLayerToGroup: function(layers, layer, name) { + var groupLayer = getGroup(layers, name); + + if (!isDefined(groupLayer)) { + groupLayer = createGroup(name); + addLayerBeforeMarkers(layers,groupLayer); + } + + layer.set('group', name); + addLayerBeforeMarkers(groupLayer.getLayers(), layer); + }, + + removeLayerFromGroup: function(layers, layer, name) { + var groupLayer = getGroup(layers, name); + layer.set('group'); + removeLayer(groupLayer.getLayers(), layer.index); + }, + + removeLayer: removeLayer, + + insertLayer: function(layers, index, layer) { + if (layers.getLength() < index) { + while (layers.getLength() < index) { + layers.push(null); + } + layer.index = index; + layers.push(layer); + } else { + layer.index = index; + layers.insertAt(layer.index, layer); + for (var i = index + 1; i < layers.getLength(); i++) { + var l = layers.item(i); + if (l === null) { + layers.removeAt(i); + break; + } else { + l.index = i; + } + } + } + }, + + createOverlay: function(element, pos) { + element.css('display', 'block'); + var ov = new ol.Overlay({ + position: pos, + element: element, + positioning: 'center-left' + }); + + return ov; + } + }; +}]); + +angular.module('openlayers-directive').factory('olMapDefaults', ["$q", "olHelpers", function($q, olHelpers) { + + var base64icon = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAApCAYAAADAk4LOAAAGmklEQVRYw' + + '7VXeUyTZxjvNnfELFuyIzOabermMZEeQC/OclkO49CpOHXOLJl/CAURuYbQi3KLgEhbrhZ1aDwmaoGq' + + 'KII6odATmH/scDFbdC7LvFqOCc+e95s2VG50X/LLm/f4/Z7neY/ne18aANCmAr5E/xZf1uDOkTcGcWR' + + '6hl9247tT5U7Y6SNvWsKT63P58qbfeLJG8M5qcgTknrvvrdDbsT7Ml+tv82X6vVxJE33aRmgSyYtcWV' + + 'MqX97Yv2JvW39UhRE2HuyBL+t+gK1116ly06EeWFNlAmHxlQE0OMiV6mQCScusKRlhS3QLeVJdl1+23' + + 'h5dY4FNB3thrbYboqptEFlphTC1hSpJnbRvxP4NWgsE5Jyz86QNNi/5qSUTGuFk1gu54tN9wuK2wc3o' + + '+Wc13RCmsoBwEqzGcZsxsvCSy/9wJKf7UWf1mEY8JWfewc67UUoDbDjQC+FqK4QqLVMGGR9d2wurKzq' + + 'Bk3nqIT/9zLxRRjgZ9bqQgub+DdoeCC03Q8j+0QhFhBHR/eP3U/zCln7Uu+hihJ1+bBNffLIvmkyP0g' + + 'pBZWYXhKussK6mBz5HT6M1Nqpcp+mBCPXosYQfrekGvrjewd59/GvKCE7TbK/04/ZV5QZYVWmDwH1mF' + + '3xa2Q3ra3DBC5vBT1oP7PTj4C0+CcL8c7C2CtejqhuCnuIQHaKHzvcRfZpnylFfXsYJx3pNLwhKzRAw' + + 'AhEqG0SpusBHfAKkxw3w4627MPhoCH798z7s0ZnBJ/MEJbZSbXPhER2ih7p2ok/zSj2cEJDd4CAe+5W' + + 'YnBCgR2uruyEw6zRoW6/DWJ/OeAP8pd/BGtzOZKpG8oke0SX6GMmRk6GFlyAc59K32OTEinILRJRcha' + + 'h8HQwND8N435Z9Z0FY1EqtxUg+0SO6RJ/mmXz4VuS+DpxXC3gXmZwIL7dBSH4zKE50wESf8qwVgrP1E' + + 'IlTO5JP9Igu0aexdh28F1lmAEGJGfh7jE6ElyM5Rw/FDcYJjWhbeiBYoYNIpc2FT/SILivp0F1ipDWk' + + '4BIEo2VuodEJUifhbiltnNBIXPUFCMpthtAyqws/BPlEF/VbaIxErdxPphsU7rcCp8DohC+GvBIPJS/' + + 'tW2jtvTmmAeuNO8BNOYQeG8G/2OzCJ3q+soYB5i6NhMaKr17FSal7GIHheuV3uSCY8qYVuEm1cOzqdW' + + 'r7ku/R0BDoTT+DT+ohCM6/CCvKLKO4RI+dXPeAuaMqksaKrZ7L3FE5FIFbkIceeOZ2OcHO6wIhTkNo0' + + 'ffgjRGxEqogXHYUPHfWAC/lADpwGcLRY3aeK4/oRGCKYcZXPVoeX/kelVYY8dUGf8V5EBRbgJXT5QIP' + + 'hP9ePJi428JKOiEYhYXFBqou2Guh+p/mEB1/RfMw6rY7cxcjTrneI1FrDyuzUSRm9miwEJx8E/gUmql' + + 'yvHGkneiwErR21F3tNOK5Tf0yXaT+O7DgCvALTUBXdM4YhC/IawPU+2PduqMvuaR6eoxSwUk75ggqsY' + + 'J7VicsnwGIkZBSXKOUww73WGXyqP+J2/b9c+gi1YAg/xpwck3gJuucNrh5JvDPvQr0WFXf0piyt8f8/' + + 'WI0hV4pRxxkQZdJDfDJNOAmM0Ag8jyT6hz0WGXWuP94Yh2jcfjmXAGvHCMslRimDHYuHuDsy2QtHuIa' + + 'vznhbYURq5R57KpzBBRZKPJi8eQg48h4j8SDdowifdIrEVdU+gbO6QNvRRt4ZBthUaZhUnjlYObNagV' + + '3keoeru3rU7rcuceqU1mJBxy+BWZYlNEBH+0eH4vRiB+OYybU2hnblYlTvkHinM4m54YnxSyaZYSF6R' + + '3jwgP7udKLGIX6r/lbNa9N6y5MFynjWDtrHd75ZvTYAPO/6RgF0k76mQla3FGq7dO+cH8sKn0Vo7nDl' + + 'lwAhqwLPkxrHwWmHJOo+AKJ4rab5OgrM7rVu8eWb2Pu0Dh4eDgXoOfvp7Y7QeqknRmvcTBEyq9m/HQQ' + + 'SCSz6LHq3z0yzsNySRfMS253wl2KyRDbcZPcfJKjZmSEOjcxyi+Y8dUOtsIEH6R2wNykdqrkYJ0RV92' + + 'H0W58pkfQk7cKevsLK10Py8SdMGfXNXATY+pPbyJR/ET6n9nIfztNtZYRV9XniQu9IA2vOVgy4ir7GC' + + 'LVmmd+zjkH0eAF9Po6K61pmCXHxU5rHMYd1ftc3owjwRSVRzLjKvqZEty6cRUD7jGqiOdu5HG6MdHjN' + + 'cNYGqfDm5YRzLBBCCDl/2bk8a8gdbqcfwECu62Fg/HrggAAAABJRU5ErkJggg=='; + + var _getDefaults = function() { + return { + view: { + projection: 'EPSG:3857', + minZoom: undefined, + maxZoom: undefined, + rotation: 0, + extent: undefined + }, + center: { + lat: 0, + lon: 0, + zoom: 1, + autodiscover: false, + bounds: [], + centerUrlHash: false, + projection: 'EPSG:4326' + }, + styles: { + path: { + stroke: { + color: 'blue', + width: 8 + } + }, + marker: { + image: new ol.style.Icon({ + anchor: [0.5, 1], + anchorXUnits: 'fraction', + anchorYUnits: 'fraction', + opacity: 0.90, + src: base64icon + }) + } + }, + events: { + map: [], + markers: [], + layers: [] + }, + controls: { + attribution: true, + rotate: false, + zoom: true + }, + interactions: { + mouseWheelZoom: false + }, + renderer: 'canvas' + }; + }; + + var isDefined = olHelpers.isDefined; + var defaults = {}; + + // Get the _defaults dictionary, and override the properties defined by the user + return { + getDefaults: function(scope) { + if (!isDefined(scope)) { + for (var i in defaults) { + return defaults[i]; + } + } + return defaults[scope.$id]; + }, + + setDefaults: function(scope) { + var userDefaults = scope.defaults; + var scopeId = scope.$id; + var newDefaults = _getDefaults(); + + if (isDefined(userDefaults)) { + + if (isDefined(userDefaults.layers)) { + newDefaults.layers = angular.copy(userDefaults.layers); + } + + if (isDefined(userDefaults.controls)) { + newDefaults.controls = angular.copy(userDefaults.controls); + } + + if (isDefined(userDefaults.events)) { + newDefaults.events = angular.copy(userDefaults.events); + } + + if (isDefined(userDefaults.interactions)) { + newDefaults.interactions = angular.copy(userDefaults.interactions); + } + + if (isDefined(userDefaults.renderer)) { + newDefaults.renderer = userDefaults.renderer; + } + + if (isDefined(userDefaults.view)) { + newDefaults.view.maxZoom = userDefaults.view.maxZoom || newDefaults.view.maxZoom; + newDefaults.view.minZoom = userDefaults.view.minZoom || newDefaults.view.minZoom; + newDefaults.view.projection = userDefaults.view.projection || newDefaults.view.projection; + newDefaults.view.extent = userDefaults.view.extent || newDefaults.view.extent; + } + + if (isDefined(userDefaults.styles)) { + newDefaults.styles = angular.extend(newDefaults.styles, userDefaults.styles); + } + + } + + defaults[scopeId] = newDefaults; + return newDefaults; + } + }; +}]); + +})); \ No newline at end of file diff --git a/dist/angular-openlayers-directive.min.js b/dist/angular-openlayers-directive.min.js new file mode 100644 index 00000000..a2536ee2 --- /dev/null +++ b/dist/angular-openlayers-directive.min.js @@ -0,0 +1,32 @@ +/**! + * The MIT License + * + * Copyright (c) 2013 the angular-openlayers-directive Team, http://tombatossals.github.io/angular-openlayers-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-google-maps + * https://github.com/tombatossals/angular-openlayers-directive + * + * @authors https://github.com/tombatossals/angular-openlayers-directive/graphs/contributors + */ + +/*! angular-openlayers-directive 06-11-2015 */ +!function(a,b){"function"==typeof define&&define.amd?define(["ol"],function(c){return a.angularOpenlayersDirective=b(c)}):a.angularOpenlayersDirective=b(a.ol)}(this,function(a){angular.module("openlayers-directive",["ngSanitize"]).directive("openlayers",["$log","$q","$compile","olHelpers","olMapDefaults","olData",function(b,c,d,e,f,g){return{restrict:"EA",transclude:!0,replace:!0,scope:{center:"=olCenter",defaults:"=olDefaults",view:"=olView",events:"=olEvents"},template:'
',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p});if(!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d){if("pixel"===g.view.projection)return void i.setCenter(c.coord);var e=a.proj.transform(d,g.view.projection,c.projection);(e[1]!==c.lat||e[0]!==c.lon)&&p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}}),f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i))}else d=j(c,f),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i))}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)}),e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope();i.getMap().then(function(b){var d=e.getControlClasses,i=d();return a.$on("$destroy",function(){b.removeControl(f)}),h(a.properties)&&h(a.properties.control)?(f=a.properties.control,void b.addControl(f)):void(c.name&&(h(a.properties)&&(g=a.properties),f=new i[c.name](g),b.addControl(f)))})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return e.on("pointerdown",j),e.on("pointerup",j),e.on("pointerdrag",j),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e)}),k(c.properties)?void c.$watch("properties",function(d){if(e.getViewport().removeEventListener("mousemove",d.handleInteraction),e.getViewport().removeEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",d.handleTapInteraction),e.getViewport().removeEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",d.removeAllOverlays),d.handleInteraction=function(b){if(!d.label.show){var f=!1,g=e.getEventPixel(b),i=e.forEachFeatureAtPixel(g,function(a){return a}),j=!1;i===r&&(j=!0,f=!0,k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),!d.onClick||"click"!==b.type&&"touchend"!==b.type||c.$apply(function(){d.onClick.call(r,b,d)}),e.getTarget().style.cursor="pointer"),!f&&p&&(j=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),j&&b.preventDefault()}},d.handleTapInteraction=function(){function a(){c=!0,b&&clearTimeout(b),b=setTimeout(function(){c=!1,b=null},500)}var b,c=!1;return e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",a),function(){c||(d.handleInteraction.apply(null,arguments),a())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||d.onClick)&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q","olHelpers",function(a,b,c){var d=c.obtainEffectiveMapId,e={},f=function(a,b){var c=d(a,b);a[c].resolvedDefer=!0},g=function(a,c){var e,f=d(a,c);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},h=function(a,b){var c,e=d(a,b);return c=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:g(a,b)};this.setMap=function(a,b){var c=g(e,b);c.resolve(a),f(e,b)},this.getMap=function(a){var b=h(e,a);return b.promise}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function x(a,b){var c;if(b?c=a[b]:(b="style",c=a),"style"===b&&a instanceof Function)return a;if(!(c instanceof Object))return c;var d;if("[object Object]"===Object.prototype.toString.call(c)){d={};var e=l[b];if(e&&c instanceof e)return c;Object.getOwnPropertyNames(c).forEach(function(a,f,g){var h=l[a];return e&&h&&h.prototype instanceof l[b]?(console.assert(1===g.length,"Extra parameters for "+b),d=x(c,a),m(d,h)):(d[a]=x(c,a),void("text"!==a&&"string"!=typeof d[a]&&(d[a]=m(d[a],l[a]))))})}else d=c;return m(d,l[b])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"TileVector":return"Vector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");var i="http://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,l=window.devicePixelRatio;l>1&&(i=i.replace(".png","@2x.png")),g=new a.source.XYZ({url:i,attributions:s(b),tilePixelRatio:l>1?2:1,wrapX:"undefined"===b.wrapX?1:b.wrapX});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,attributions:s(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:b.params,wrapX:"undefined"===b.wrapX?1:b.wrapX});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var m={crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:b.params,attributions:s(b),wrapX:"undefined"===b.wrapX?1:b.wrapX};b.url&&(m.url=b.url),b.urls&&(m.urls=b.urls),g=new a.source.TileWMS(m);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var n={projection:f,layer:b.layer,attributions:s(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),wrapX:"undefined"===b.wrapX?1:b.wrapX};e(b.url)&&(n.url=b.url),e(b.urls)&&(n.urls=b.urls),g=new a.source.WMTS(n);break;case"OSM":g=new a.source.OSM({attributions:s(b),wrapX:"undefined"===b.wrapX?1:b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var o={key:b.key,attributions:s(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:"undefined"===b.wrapX?1:b.wrapX};b.maxZoom&&(o.maxZoom=b.maxZoom),g=new a.source.BingMaps(o);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:s(b),layer:b.layer,wrapX:"undefined"===b.wrapX?1:b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var p="http://services.arcgisonline.com/ArcGIS/rest/services/",r=p+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:s(b),url:r,wrapX:"undefined"===b.wrapX?1:b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url,wrapX:"undefined"===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var t=f;e(b.geojson.projection)&&(t=b.geojson.projection);var u=new a.format.GeoJSON,v=u.readFeatures(b.geojson.object,{featureProjection:t});g.addFeatures(v)}break;case"JSONP":if(!b.url)return void c.error("[AngularJS - Openlayers] - You need an url properly configured to add a JSONP layer.");e(b.url)&&(g=new a.source.Vector({format:new a.format.GeoJSON,loader:function(){var a=b.url+"&outputFormat=text/javascript&format_options=callback:JSON_CALLBACK";d.jsonp(a,{cache:b.cache}).success(function(a){g.addFeatures(g.readFeatures(a))}).error(function(a){c(a)})},wrapX:"undefined"===b.wrapX?1:b.wrapX}));break;case"TopoJSON":if(!b.topojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a topojson property to add a TopoJSON layer.");g=b.url?new a.source.Vector({format:new a.format.TopoJSON,url:b.url,wrapX:"undefined"===b.wrapX?1:b.wrapX}):new a.source.Vector(angular.extend(b.topojson,{format:new a.format.TopoJSON,wrapX:"undefined"===b.wrapX?1:b.wrapX}));break;case"TileJSON":g=new a.source.TileJSON({url:b.url,attributions:s(b),crossOrigin:"anonymous",wrapX:"undefined"===b.wrapX?1:b.wrapX});break;case"TileVector":b.url&&b.format||c.error("[AngularJS - Openlayers] - TileVector Layer needs valid url and format properties"),g=new a.source.TileVector({url:b.url,projection:f,attributions:s(b),format:b.format,tileGrid:new a.tilegrid.createXYZ({maxZoom:b.maxZoom||19}),wrapX:"undefined"===b.wrapX?1:b.wrapX});break;case"TileTMS":b.url&&b.tileGrid||c.error("[AngularJS - Openlayers] - TileTMS Layer needs valid url and tileGrid properties"),g=new a.source.TileImage({url:b.url,maxExtent:b.maxExtent,attributions:s(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=a[2];if(0>d||0>e)return"";var f=b.url+c+"/"+d+"/"+e+".png";return f},wrapX:"undefined"===b.wrapX?1:b.wrapX});break;case"TileImage":g=new a.source.TileImage({url:b.url,attributions:s(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=-a[2]-1,f=b.url.replace("{z}",c.toString()).replace("{x}",d.toString()).replace("{y}",e.toString());return f},wrapX:"undefined"===b.wrapX?1:b.wrapX});break;case"KML":var w=b.extractStyles||!1;g=new a.source.Vector({url:b.url,format:new a.format.KML,radius:b.radius,extractStyles:w,wrapX:"undefined"===b.wrapX?1:b.wrapX});break;case"Stamen":if(!b.layer||!q(b.layer))return void c.error("[AngularJS - Openlayers] - You need a valid Stamen layer.");g=new a.source.Stamen({layer:b.layer,wrapX:"undefined"===b.wrapX?1:b.wrapX});break;case"ImageStatic":if(!b.url||!angular.isArray(b.imageSize)||2!==b.imageSize.length)return void c.error("[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.");g=new a.source.ImageStatic({url:b.url,attributions:s(b),imageSize:b.imageSize,projection:f,imageExtent:f.getExtent(),imageLoadFunction:b.imageLoadFunction,wrapX:"undefined"===b.wrapX?1:b.wrapX});break;case"XYZ":b.url||c.error("[AngularJS - Openlayers] - XYZ Layer needs valid url and params properties"),g=new a.source.XYZ({url:b.url,attributions:s(b),minZoom:b.minZoom,maxZoom:b.maxZoom,wrapX:"undefined"===b.wrapX?1:b.wrapX})}return g||c.warn('[AngularJS - Openlayers] - No source could be found for type "'+b.type+'"'),g},s=function(b){var c=[];return e(b.attribution)&&c.unshift(new a.Attribution({html:b.attribution})),c},t=function(b){var c=new a.layer.Group;return c.set("name",b),c},u=function(b,c){var d;return angular.forEach(b,function(b){return b instanceof a.layer.Group&&b.get("name")===c?void(d=b):void 0}),d},v=function(a,b){for(var c,d=0;d',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p});if(!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d){if("pixel"===g.view.projection)return void i.setCenter(c.coord);var e=a.proj.transform(d,g.view.projection,c.projection);(e[1]!==c.lat||e[0]!==c.lon)&&p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}}),f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i))}else d=j(c,f),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i))}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)}),e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope();i.getMap().then(function(b){var d=e.getControlClasses,i=d();return a.$on("$destroy",function(){b.removeControl(f)}),h(a.properties)&&h(a.properties.control)?(f=a.properties.control,void b.addControl(f)):void(c.name&&(h(a.properties)&&(g=a.properties),f=new i[c.name](g),b.addControl(f)))})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return e.on("pointerdown",j),e.on("pointerup",j),e.on("pointerdrag",j),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e)}),k(c.properties)?void c.$watch("properties",function(d){if(e.getViewport().removeEventListener("mousemove",d.handleInteraction),e.getViewport().removeEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",d.handleTapInteraction),e.getViewport().removeEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",d.removeAllOverlays),d.handleInteraction=function(b){if(!d.label.show){var f=!1,g=e.getEventPixel(b),i=e.forEachFeatureAtPixel(g,function(a){return a}),j=!1;i===r&&(j=!0,f=!0,k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),!d.onClick||"click"!==b.type&&"touchend"!==b.type||c.$apply(function(){d.onClick.call(r,b,d)}),e.getTarget().style.cursor="pointer"),!f&&p&&(j=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),j&&b.preventDefault()}},d.handleTapInteraction=function(){function a(){c=!0,b&&clearTimeout(b),b=setTimeout(function(){c=!1,b=null},500)}var b,c=!1;return e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",a),function(){c||(d.handleInteraction.apply(null,arguments),a())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||d.onClick)&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q","olHelpers",function(a,b,c){var d=c.obtainEffectiveMapId,e={},f=function(a,b){var c=d(a,b);a[c].resolvedDefer=!0},g=function(a,c){var e,f=d(a,c);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},h=function(a,b){var c,e=d(a,b);return c=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:g(a,b)};this.setMap=function(a,b){var c=g(e,b);c.resolve(a),f(e,b)},this.getMap=function(a){var b=h(e,a);return b.promise}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function x(a,b){var c;if(b?c=a[b]:(b="style",c=a),"style"===b&&a instanceof Function)return a;if(!(c instanceof Object))return c;var d;if("[object Object]"===Object.prototype.toString.call(c)){d={};var e=l[b];if(e&&c instanceof e)return c;Object.getOwnPropertyNames(c).forEach(function(a,f,g){var h=l[a];return e&&h&&h.prototype instanceof l[b]?(console.assert(1===g.length,"Extra parameters for "+b),d=x(c,a),m(d,h)):(d[a]=x(c,a),void("text"!==a&&"string"!=typeof d[a]&&(d[a]=m(d[a],l[a]))))})}else d=c;return m(d,l[b])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"TileVector":return"Vector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");var i="http://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,l=window.devicePixelRatio;l>1&&(i=i.replace(".png","@2x.png")),g=new a.source.XYZ({url:i,attributions:s(b),tilePixelRatio:l>1?2:1,wrapX:"undefined"===b.wrapX?1:b.wrapX});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,attributions:s(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:b.params,wrapX:"undefined"===b.wrapX?1:b.wrapX});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var m={crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:b.params,attributions:s(b),wrapX:"undefined"===b.wrapX?1:b.wrapX};b.url&&(m.url=b.url),b.urls&&(m.urls=b.urls),g=new a.source.TileWMS(m);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var n={projection:f,layer:b.layer,attributions:s(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),wrapX:"undefined"===b.wrapX?1:b.wrapX};e(b.url)&&(n.url=b.url),e(b.urls)&&(n.urls=b.urls),g=new a.source.WMTS(n);break;case"OSM":g=new a.source.OSM({attributions:s(b),wrapX:"undefined"===b.wrapX?1:b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var o={key:b.key,attributions:s(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:"undefined"===b.wrapX?1:b.wrapX};b.maxZoom&&(o.maxZoom=b.maxZoom),g=new a.source.BingMaps(o);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:s(b),layer:b.layer,wrapX:"undefined"===b.wrapX?1:b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var p="http://services.arcgisonline.com/ArcGIS/rest/services/",r=p+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:s(b),url:r,wrapX:"undefined"===b.wrapX?1:b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url,wrapX:"undefined"===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var t=f;e(b.geojson.projection)&&(t=b.geojson.projection);var u=new a.format.GeoJSON,v=u.readFeatures(b.geojson.object,{featureProjection:t});g.addFeatures(v)}break;case"JSONP":if(!b.url)return void c.error("[AngularJS - Openlayers] - You need an url properly configured to add a JSONP layer.");e(b.url)&&(g=new a.source.Vector({format:new a.format.GeoJSON,loader:function(){var a=b.url+"&outputFormat=text/javascript&format_options=callback:JSON_CALLBACK";d.jsonp(a,{cache:b.cache}).success(function(a){g.addFeatures(g.readFeatures(a))}).error(function(a){c(a)})},wrapX:"undefined"===b.wrapX?1:b.wrapX}));break;case"TopoJSON":if(!b.topojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a topojson property to add a TopoJSON layer.");g=b.url?new a.source.Vector({format:new a.format.TopoJSON,url:b.url,wrapX:"undefined"===b.wrapX?1:b.wrapX}):new a.source.Vector(angular.extend(b.topojson,{format:new a.format.TopoJSON,wrapX:"undefined"===b.wrapX?1:b.wrapX}));break;case"TileJSON":g=new a.source.TileJSON({url:b.url,attributions:s(b),crossOrigin:"anonymous",wrapX:"undefined"===b.wrapX?1:b.wrapX});break;case"TileVector":b.url&&b.format||c.error("[AngularJS - Openlayers] - TileVector Layer needs valid url and format properties"),g=new a.source.TileVector({url:b.url,projection:f,attributions:s(b),format:b.format,tileGrid:new a.tilegrid.createXYZ({maxZoom:b.maxZoom||19}),wrapX:"undefined"===b.wrapX?1:b.wrapX});break;case"TileTMS":b.url&&b.tileGrid||c.error("[AngularJS - Openlayers] - TileTMS Layer needs valid url and tileGrid properties"),g=new a.source.TileImage({url:b.url,maxExtent:b.maxExtent,attributions:s(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=a[2];if(0>d||0>e)return"";var f=b.url+c+"/"+d+"/"+e+".png";return f},wrapX:"undefined"===b.wrapX?1:b.wrapX});break;case"TileImage":g=new a.source.TileImage({url:b.url,attributions:s(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=-a[2]-1,f=b.url.replace("{z}",c.toString()).replace("{x}",d.toString()).replace("{y}",e.toString());return f},wrapX:"undefined"===b.wrapX?1:b.wrapX});break;case"KML":var w=b.extractStyles||!1;g=new a.source.Vector({url:b.url,format:new a.format.KML,radius:b.radius,extractStyles:w,wrapX:"undefined"===b.wrapX?1:b.wrapX});break;case"Stamen":if(!b.layer||!q(b.layer))return void c.error("[AngularJS - Openlayers] - You need a valid Stamen layer.");g=new a.source.Stamen({layer:b.layer,wrapX:"undefined"===b.wrapX?1:b.wrapX});break;case"ImageStatic":if(!b.url||!angular.isArray(b.imageSize)||2!==b.imageSize.length)return void c.error("[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.");g=new a.source.ImageStatic({url:b.url,attributions:s(b),imageSize:b.imageSize,projection:f,imageExtent:f.getExtent(),imageLoadFunction:b.imageLoadFunction,wrapX:"undefined"===b.wrapX?1:b.wrapX});break;case"XYZ":b.url||c.error("[AngularJS - Openlayers] - XYZ Layer needs valid url and params properties"),g=new a.source.XYZ({url:b.url,attributions:s(b),minZoom:b.minZoom,maxZoom:b.maxZoom,wrapX:"undefined"===b.wrapX?1:b.wrapX})}return g||c.warn('[AngularJS - Openlayers] - No source could be found for type "'+b.type+'"'),g},s=function(b){var c=[];return e(b.attribution)&&c.unshift(new a.Attribution({html:b.attribution})),c},t=function(b){var c=new a.layer.Group;return c.set("name",b),c},u=function(b,c){var d;return angular.forEach(b,function(b){return b instanceof a.layer.Group&&b.get("name")===c?void(d=b):void 0}),d},v=function(a,b){for(var c,d=0;d', + controller: function($scope) { + var _map = $q.defer(); + $scope.getMap = function() { + return _map.promise; + }; + + $scope.setMap = function(map) { + _map.resolve(map); + }; + + this.getOpenlayersScope = function() { + return $scope; + }; + }, + link: function(scope, element, attrs) { + var isDefined = olHelpers.isDefined; + var createLayer = olHelpers.createLayer; + var setMapEvents = olHelpers.setMapEvents; + var setViewEvents = olHelpers.setViewEvents; + var createView = olHelpers.createView; + var defaults = olMapDefaults.setDefaults(scope); + + // Set width and height if they are defined + if (isDefined(attrs.width)) { + if (isNaN(attrs.width)) { + element.css('width', attrs.width); + } else { + element.css('width', attrs.width + 'px'); + } + } + + if (isDefined(attrs.height)) { + if (isNaN(attrs.height)) { + element.css('height', attrs.height); + } else { + element.css('height', attrs.height + 'px'); + } + } + + if (isDefined(attrs.lat)) { + defaults.center.lat = parseFloat(attrs.lat); + } + + if (isDefined(attrs.lon)) { + defaults.center.lon = parseFloat(attrs.lon); + } + + if (isDefined(attrs.zoom)) { + defaults.center.zoom = parseFloat(attrs.zoom); + } + + var controls = ol.control.defaults(defaults.controls); + var interactions = ol.interaction.defaults(defaults.interactions); + var view = createView(defaults.view); + + // Create the Openlayers Map Object with the options + var map = new ol.Map({ + target: element[0], + controls: controls, + interactions: interactions, + renderer: defaults.renderer, + view: view + }); + + // If no layer is defined, set the default tileLayer + if (!attrs.customLayers) { + var l = { + type: 'Tile', + source: { + type: 'OSM' + } + }; + var layer = createLayer(l, view.getProjection(), 'default'); + map.addLayer(layer); + map.set('default', true); + } + + if (!isDefined(attrs.olCenter)) { + var c = ol.proj.transform([defaults.center.lon, + defaults.center.lat + ], + defaults.center.projection, view.getProjection() + ); + view.setCenter(c); + view.setZoom(defaults.center.zoom); + } + + // Set the Default events for the map + setMapEvents(defaults.events, map, scope); + + //Set the Default events for the map view + setViewEvents(defaults.events, map, scope); + + // Resolve the map object to the promises + scope.setMap(map); + olData.setMap(map, attrs.id); + + } + }; + }); + +angular.module('openlayers-directive').directive('olCenter', function($log, $location, olMapDefaults, olHelpers) { + + return { + restrict: 'A', + scope: false, + replace: false, + require: 'openlayers', + + link: function(scope, element, attrs, controller) { + var safeApply = olHelpers.safeApply; + var isValidCenter = olHelpers.isValidCenter; + var isDefined = olHelpers.isDefined; + var isArray = olHelpers.isArray; + var isNumber = olHelpers.isNumber; + var isSameCenterOnMap = olHelpers.isSameCenterOnMap; + var setCenter = olHelpers.setCenter; + var setZoom = olHelpers.setZoom; + var olScope = controller.getOpenlayersScope(); + + olScope.getMap().then(function(map) { + var defaults = olMapDefaults.getDefaults(olScope); + var view = map.getView(); + var center = olScope.center; + + if (attrs.olCenter.search('-') !== -1) { + $log.error('[AngularJS - Openlayers] The "center" variable can\'t use ' + + 'a "-" on his key name: "' + attrs.center + '".'); + setCenter(view, defaults.view.projection, defaults.center, map); + return; + } + + if (!isDefined(center)) { + center = {}; + } + + if (!isValidCenter(center)) { + $log.warn('[AngularJS - Openlayers] invalid \'center\''); + center.lat = defaults.center.lat; + center.lon = defaults.center.lon; + center.zoom = defaults.center.zoom; + center.projection = defaults.center.projection; + } + + if (!center.projection) { + if (defaults.view.projection !== 'pixel') { + center.projection = defaults.center.projection; + } else { + center.projection = 'pixel'; + } + } + + if (!isNumber(center.zoom)) { + center.zoom = 1; + } + + setCenter(view, defaults.view.projection, center, map); + view.setZoom(center.zoom); + + var centerUrlHash; + if (center.centerUrlHash === true) { + var extractCenterFromUrl = function() { + var search = $location.search(); + var centerParam; + if (isDefined(search.c)) { + var cParam = search.c.split(':'); + if (cParam.length === 3) { + centerParam = { + lat: parseFloat(cParam[0]), + lon: parseFloat(cParam[1]), + zoom: parseInt(cParam[2], 10) + }; + } + } + return centerParam; + }; + centerUrlHash = extractCenterFromUrl(); + + olScope.$on('$locationChangeSuccess', function() { + var urlCenter = extractCenterFromUrl(); + if (urlCenter && !isSameCenterOnMap(urlCenter, map)) { + safeApply(olScope, function(scope) { + scope.center.lat = urlCenter.lat; + scope.center.lon = urlCenter.lon; + scope.center.zoom = urlCenter.zoom; + }); + } + }); + } + + var geolocation; + olScope.$watchCollection('center', function(center) { + + if (!center) { + return; + } + + if (!center.projection) { + center.projection = defaults.center.projection; + } + + if (center.autodiscover) { + if (!geolocation) { + geolocation = new ol.Geolocation({ + projection: ol.proj.get(center.projection) + }); + + geolocation.on('change', function() { + if (center.autodiscover) { + var location = geolocation.getPosition(); + safeApply(olScope, function(scope) { + scope.center.lat = location[1]; + scope.center.lon = location[0]; + scope.center.zoom = 12; + scope.center.autodiscover = false; + geolocation.setTracking(false); + }); + } + }); + } + geolocation.setTracking(true); + return; + } + + if (!isValidCenter(center)) { + $log.warn('[AngularJS - Openlayers] invalid \'center\''); + center = defaults.center; + } + + var viewCenter = view.getCenter(); + if (viewCenter) { + if (defaults.view.projection === 'pixel') { + view.setCenter(center.coord); + return; + } + var actualCenter = ol.proj.transform(viewCenter, defaults.view.projection, center.projection); + if (!(actualCenter[1] === center.lat && actualCenter[0] === center.lon)) { + setCenter(view, defaults.view.projection, center, map); + } + } + + if (view.getZoom() !== center.zoom) { + setZoom(view, center.zoom, map); + } + }); + + map.on('moveend', function() { + safeApply(olScope, function(scope) { + + if (!isDefined(scope.center)) { + return; + } + + var center = map.getView().getCenter(); + scope.center.zoom = view.getZoom(); + + if (defaults.view.projection === 'pixel') { + scope.center.coord = center; + return; + } + + if (scope.center) { + var proj = ol.proj.transform(center, defaults.view.projection, scope.center.projection); + scope.center.lat = proj[1]; + scope.center.lon = proj[0]; + + // Notify the controller about a change in the center position + olHelpers.notifyCenterUrlHashChanged(olScope, scope.center, $location.search()); + + // Calculate the bounds if needed + if (isArray(scope.center.bounds)) { + var extent = view.calculateExtent(map.getSize()); + var centerProjection = scope.center.projection; + var viewProjection = defaults.view.projection; + scope.center.bounds = ol.proj.transformExtent(extent, viewProjection, centerProjection); + } + } + }); + }); + + }); + } + }; +}); + +angular.module('openlayers-directive').directive('olLayer', function($log, $q, olMapDefaults, olHelpers) { + + return { + restrict: 'E', + scope: { + properties: '=olLayerProperties' + }, + replace: false, + require: '^openlayers', + link: function(scope, element, attrs, controller) { + var isDefined = olHelpers.isDefined; + var equals = olHelpers.equals; + var olScope = controller.getOpenlayersScope(); + var createLayer = olHelpers.createLayer; + var setVectorLayerEvents = olHelpers.setVectorLayerEvents; + var detectLayerType = olHelpers.detectLayerType; + var createStyle = olHelpers.createStyle; + var isBoolean = olHelpers.isBoolean; + var addLayerBeforeMarkers = olHelpers.addLayerBeforeMarkers; + var isNumber = olHelpers.isNumber; + var insertLayer = olHelpers.insertLayer; + var removeLayer = olHelpers.removeLayer; + var addLayerToGroup = olHelpers.addLayerToGroup; + var removeLayerFromGroup = olHelpers.removeLayerFromGroup; + var getGroup = olHelpers.getGroup; + + olScope.getMap().then(function(map) { + var projection = map.getView().getProjection(); + var defaults = olMapDefaults.setDefaults(olScope); + var layerCollection = map.getLayers(); + var olLayer; + + scope.$on('$destroy', function() { + if (scope.properties.group) { + removeLayerFromGroup(layerCollection, olLayer, scope.properties.group); + } else { + removeLayer(layerCollection, olLayer.index); + } + + map.removeLayer(olLayer); + }); + + if (!isDefined(scope.properties)) { + if (isDefined(attrs.sourceType) && isDefined(attrs.sourceUrl)) { + var l = { + source: { + url: attrs.sourceUrl, + type: attrs.sourceType + } + }; + + olLayer = createLayer(l, projection, attrs.layerName); + if (detectLayerType(l) === 'Vector') { + setVectorLayerEvents(defaults.events, map, scope, attrs.name); + } + addLayerBeforeMarkers(layerCollection, olLayer); + } + return; + } + + scope.$watch('properties', function(properties, oldProperties) { + if (!isDefined(properties.source) || !isDefined(properties.source.type)) { + return; + } + + if (!isDefined(properties.visible)) { + properties.visible = true; + return; + } + + if (!isDefined(properties.opacity)) { + properties.opacity = 1; + return; + } + + var style; + var group; + var collection; + if (!isDefined(olLayer)) { + olLayer = createLayer(properties, projection); + if (isDefined(properties.group)) { + addLayerToGroup(layerCollection, olLayer, properties.group); + } else if (isDefined(properties.index)) { + insertLayer(layerCollection, properties.index, olLayer); + } else { + addLayerBeforeMarkers(layerCollection, olLayer); + } + + if (detectLayerType(properties) === 'Vector') { + setVectorLayerEvents(defaults.events, map, scope, properties.name); + } + + if (isBoolean(properties.visible)) { + olLayer.setVisible(properties.visible); + } + + if (properties.opacity) { + olLayer.setOpacity(properties.opacity); + } + + if (angular.isArray(properties.extent)) { + olLayer.setExtent(properties.extent); + } + + if (properties.style) { + if (!angular.isFunction(properties.style)) { + style = createStyle(properties.style); + } else { + style = properties.style; + } + // not every layer has a setStyle method + if (olLayer.setStyle && angular.isFunction(olLayer.setStyle)) { + olLayer.setStyle(style); + } + } + + } else { + var isNewLayer = (function(olLayer) { + // this function can be used to verify whether a new layer instance has + // been created. This is needed in order to re-assign styles, opacity + // etc... + return function(layer) { + return layer !== olLayer; + }; + })(olLayer); + + // set source properties + if (isDefined(oldProperties) && !equals(properties.source, oldProperties.source)) { + var idx = olLayer.index; + collection = layerCollection; + group = olLayer.get('group'); + + if (group) { + collection = getGroup(layerCollection, group).getLayers(); + } + + collection.removeAt(idx); + + olLayer = createLayer(properties, projection); + olLayer.set('group', group); + + if (isDefined(olLayer)) { + insertLayer(collection, idx, olLayer); + + if (detectLayerType(properties) === 'Vector') { + setVectorLayerEvents(defaults.events, map, scope, properties.name); + } + } + } + + // set opacity + if (isDefined(oldProperties) && + properties.opacity !== oldProperties.opacity || isNewLayer(olLayer)) { + if (isNumber(properties.opacity) || isNumber(parseFloat(properties.opacity))) { + olLayer.setOpacity(properties.opacity); + } + } + + // set index + if (isDefined(properties.index) && properties.index !== olLayer.index) { + collection = layerCollection; + group = olLayer.get('group'); + + if (group) { + collection = getGroup(layerCollection, group).getLayers(); + } + + removeLayer(collection, olLayer.index); + insertLayer(collection, properties.index, olLayer); + } + + // set group + if (isDefined(properties.group) && properties.group !== oldProperties.group) { + removeLayerFromGroup(layerCollection, olLayer, oldProperties.group); + addLayerToGroup(layerCollection, olLayer, properties.group); + } + + // set visibility + if (isDefined(oldProperties) && + isBoolean(properties.visible) && + properties.visible !== oldProperties.visible || isNewLayer(olLayer)) { + olLayer.setVisible(properties.visible); + } + + // set style + if (isDefined(properties.style) && + !equals(properties.style, oldProperties.style) || isNewLayer(olLayer)) { + if (!angular.isFunction(properties.style)) { + style = createStyle(properties.style); + } else { + style = properties.style; + } + // not every layer has a setStyle method + if (olLayer.setStyle && angular.isFunction(olLayer.setStyle)) { + olLayer.setStyle(style); + } + } + } + }, true); + }); + } + }; +}); + +angular.module('openlayers-directive').directive('olPath', function($log, $q, olMapDefaults, olHelpers) { + + return { + restrict: 'E', + scope: { + properties: '=olGeomProperties' + }, + require: '^openlayers', + replace: true, + template: '', + + link: function(scope, element, attrs, controller) { + var isDefined = olHelpers.isDefined; + var createFeature = olHelpers.createFeature; + var createOverlay = olHelpers.createOverlay; + var createVectorLayer = olHelpers.createVectorLayer; + var insertLayer = olHelpers.insertLayer; + var removeLayer = olHelpers.removeLayer; + var olScope = controller.getOpenlayersScope(); + + olScope.getMap().then(function(map) { + var mapDefaults = olMapDefaults.getDefaults(olScope); + var viewProjection = mapDefaults.view.projection; + + var layer = createVectorLayer(); + var layerCollection = map.getLayers(); + + insertLayer(layerCollection, layerCollection.getLength(), layer); + + scope.$on('$destroy', function() { + removeLayer(layerCollection, layer.index); + }); + + if (isDefined(attrs.coords)) { + var proj = attrs.proj || 'EPSG:4326'; + var coords = JSON.parse(attrs.coords); + var data = { + type: 'Polygon', + coords: coords, + projection: proj, + style: mapDefaults.styles.path + }; + var feature = createFeature(data, viewProjection); + layer.getSource().addFeature(feature); + + if (attrs.message) { + scope.message = attrs.message; + var extent = feature.getGeometry().getExtent(); + var label = createOverlay(element, extent); + map.addOverlay(label); + } + return; + } + }); + } + }; +}); + +angular.module('openlayers-directive').directive('olView', function($log, $q, olData, olMapDefaults, olHelpers) { + return { + restrict: 'A', + scope: false, + replace: false, + require: 'openlayers', + link: function(scope, element, attrs, controller) { + var olScope = controller.getOpenlayersScope(); + var isNumber = olHelpers.isNumber; + var safeApply = olHelpers.safeApply; + var createView = olHelpers.createView; + + olScope.getMap().then(function(map) { + var defaults = olMapDefaults.getDefaults(olScope); + var view = olScope.view; + + if (!view.projection) { + view.projection = defaults.view.projection; + } + + if (!view.maxZoom) { + view.maxZoom = defaults.view.maxZoom; + } + + if (!view.minZoom) { + view.minZoom = defaults.view.minZoom; + } + + if (!view.rotation) { + view.rotation = defaults.view.rotation; + } + + var mapView = createView(view); + map.setView(mapView); + + olScope.$watchCollection('view', function(view) { + if (isNumber(view.rotation)) { + mapView.setRotation(view.rotation); + } + }); + + mapView.on('change:rotation', function() { + safeApply(olScope, function(scope) { + scope.view.rotation = map.getView().getRotation(); + }); + }); + + }); + } + }; +}); + +angular.module('openlayers-directive').directive('olControl', function($log, $q, olData, olMapDefaults, olHelpers) { + + return { + restrict: 'E', + scope: { + properties: '=olControlProperties' + }, + replace: false, + require: '^openlayers', + link: function(scope, element, attrs, controller) { + var isDefined = olHelpers.isDefined; + var olScope = controller.getOpenlayersScope(); + var olControl; + var olControlOps; + + olScope.getMap().then(function(map) { + var getControlClasses = olHelpers.getControlClasses; + var controlClasses = getControlClasses(); + + scope.$on('$destroy', function() { + map.removeControl(olControl); + }); + + if (!isDefined(scope.properties) || !isDefined(scope.properties.control)) { + if (attrs.name) { + if (isDefined(scope.properties)) { + olControlOps = scope.properties; + } + olControl = new controlClasses[attrs.name](olControlOps); + map.addControl(olControl); + } + return; + } + + olControl = scope.properties.control; + map.addControl(olControl); + }); + } + }; +}); + +angular.module('openlayers-directive').directive('olMarker', function($log, $q, olMapDefaults, olHelpers) { + + var getMarkerDefaults = function() { + return { + projection: 'EPSG:4326', + lat: 0, + lon: 0, + coord: [], + show: true, + showOnMouseOver: false, + showOnMouseClick: false, + keepOneOverlayVisible: false + }; + }; + + var markerLayerManager = (function() { + var mapDict = []; + + function getMapIndex(map) { + return mapDict.map(function(record) { + return record.map; + }).indexOf(map); + } + + return { + getInst: function getMarkerLayerInst(scope, map) { + var mapIndex = getMapIndex(map); + + if (mapIndex === -1) { + var markerLayer = olHelpers.createVectorLayer(); + markerLayer.set('markers', true); + map.addLayer(markerLayer); + mapDict.push({ + map: map, + markerLayer: markerLayer, + instScopes: [] + }); + mapIndex = mapDict.length - 1; + } + + mapDict[mapIndex].instScopes.push(scope); + + return mapDict[mapIndex].markerLayer; + }, + deregisterScope: function deregisterScope(scope, map) { + var mapIndex = getMapIndex(map); + if (mapIndex === -1) { + throw Error('This map has no markers'); + } + + var scopes = mapDict[mapIndex].instScopes; + var scopeIndex = scopes.indexOf(scope); + if (scopeIndex === -1) { + throw Error('Scope wan\'t registered'); + } + + scopes.splice(scopeIndex, 1); + + if (!scopes.length) { + map.removeLayer(mapDict[mapIndex].markerLayer); + delete mapDict[mapIndex]; + } + } + }; + })(); + return { + restrict: 'E', + scope: { + lat: '=lat', + lon: '=lon', + label: '=label', + properties: '=olMarkerProperties', + style: '=olStyle' + }, + transclude: true, + require: '^openlayers', + replace: true, + template: + '', + + link: function(scope, element, attrs, controller) { + var isDefined = olHelpers.isDefined; + var olScope = controller.getOpenlayersScope(); + var createFeature = olHelpers.createFeature; + var createOverlay = olHelpers.createOverlay; + + var hasTranscluded = element.find('ng-transclude').children().length > 0; + + olScope.getMap().then(function(map) { + var markerLayer = markerLayerManager.getInst(scope, map); + var data = getMarkerDefaults(); + + var mapDefaults = olMapDefaults.getDefaults(olScope); + var viewProjection = mapDefaults.view.projection; + var label; + var pos; + var marker; + + // This function handles dragging a marker + var pickOffset = null; + var pickProperties = null; + function handleDrag(evt) { + var coord = evt.coordinate; + var proj = map.getView().getProjection().getCode(); + if (proj === 'pixel') { + coord = coord.map(function(v) { + return parseInt(v, 10); + }); + } else { + coord = ol.proj.transform(coord, proj, 'EPSG:4326'); + } + + if (evt.type === 'pointerdown') { + // Get feature under mouse if any + var feature = map.forEachFeatureAtPixel(evt.pixel, function(feature) { + return feature; + }); + // Get associated marker properties + pickProperties = (feature ? feature.get('marker') : null); + if (!pickProperties || !pickProperties.draggable) { + pickProperties = null; + return; + } + map.getTarget().style.cursor = 'pointer'; + if (proj === 'pixel') { + pickOffset = [coord[0] - pickProperties.coord[0], coord[1] - pickProperties.coord[1]]; + } else { + pickOffset = [coord[0] - pickProperties.lon, coord[1] - pickProperties.lat]; + } + evt.preventDefault(); + } else if (pickOffset && pickProperties) { + if (evt.type === 'pointerup') { + map.getTarget().style.cursor = ''; + pickOffset = null; + pickProperties = null; + evt.preventDefault(); + } else if (evt.type === 'pointerdrag') { + evt.preventDefault(); + scope.$apply(function() { + // Add current delta to marker initial position + if (proj === 'pixel') { + pickProperties.coord[0] = coord[0] - pickOffset[0]; + pickProperties.coord[1] = coord[1] - pickOffset[1]; + } else { + pickProperties.lon = coord[0] - pickOffset[0]; + pickProperties.lat = coord[1] - pickOffset[1]; + } + }); + } + } + } + + // Setup generic handlers for marker drag + map.on('pointerdown', handleDrag); + map.on('pointerup', handleDrag); + map.on('pointerdrag', handleDrag); + + scope.$on('$destroy', function() { + markerLayer.getSource().removeFeature(marker); + if (isDefined(label)) { + map.removeOverlay(label); + } + markerLayerManager.deregisterScope(scope, map); + }); + + if (!isDefined(scope.properties)) { + data.lat = scope.lat ? scope.lat : data.lat; + data.lon = scope.lon ? scope.lon : data.lon; + data.message = attrs.message; + data.style = scope.style ? scope.style : mapDefaults.styles.marker; + + marker = createFeature(data, viewProjection); + if (!isDefined(marker)) { + $log.error('[AngularJS - Openlayers] Received invalid data on ' + + 'the marker.'); + } + // Add a link between the feature and the marker properties + marker.set('marker', scope); + markerLayer.getSource().addFeature(marker); + + if (data.message || hasTranscluded) { + scope.message = attrs.message; + pos = ol.proj.transform([data.lon, data.lat], data.projection, + viewProjection); + label = createOverlay(element, pos); + map.addOverlay(label); + } + return; + } + + scope.$watch('properties', function(properties) { + + // Remove previous listeners if any + map.getViewport().removeEventListener('mousemove', properties.handleInteraction); + map.getViewport().removeEventListener('click', properties.handleTapInteraction); + map.getViewport().querySelector('canvas.ol-unselectable').removeEventListener( + 'touchend', properties.handleTapInteraction); + map.getViewport().removeEventListener('mousemove', properties.showAtLeastOneOverlay); + map.getViewport().removeEventListener('click', properties.removeAllOverlays); + + // This function handles popup on mouse over/click + properties.handleInteraction = function(evt) { + if (properties.label.show) { + return; + } + var found = false; + var pixel = map.getEventPixel(evt); + var feature = map.forEachFeatureAtPixel(pixel, function(feature) { + return feature; + }); + + var actionTaken = false; + if (feature === marker) { + actionTaken = true; + found = true; + if (!isDefined(label)) { + if (data.projection === 'pixel') { + pos = properties.coord; + } else { + pos = ol.proj.transform([properties.lon, properties.lat], + data.projection, viewProjection); + } + label = createOverlay(element, pos); + map.addOverlay(label); + } + + if (properties.onClick && (evt.type === 'click' || evt.type === 'touchend')) { + scope.$apply(function() { + properties.onClick.call(marker, evt, properties); + }); + } + map.getTarget().style.cursor = 'pointer'; + } + + if (!found && label) { + actionTaken = true; + map.removeOverlay(label); + label = undefined; + map.getTarget().style.cursor = ''; + } + + if (actionTaken) { + evt.preventDefault(); + } + }; + + // Made to filter out click/tap events if both are being triggered on this platform + properties.handleTapInteraction = (function() { + var cooldownActive = false; + var prevTimeout; + + // Sets the cooldown flag to filter out any subsequent events within 500 ms + function activateCooldown() { + cooldownActive = true; + if (prevTimeout) { + clearTimeout(prevTimeout); + } + prevTimeout = setTimeout(function() { + cooldownActive = false; + prevTimeout = null; + }, 500); + } + + // Preventing from 'touchend' to be considered a tap, if fired immediately after 'touchmove' + map.getViewport().querySelector('canvas.ol-unselectable').addEventListener( + 'touchmove', activateCooldown); + + return function() { + if (!cooldownActive) { + properties.handleInteraction.apply(null, arguments); + activateCooldown(); + } + }; + })(); + + properties.showAtLeastOneOverlay = function(evt) { + if (properties.label.show) { + return; + } + var found = false; + var pixel = map.getEventPixel(evt); + var feature = map.forEachFeatureAtPixel(pixel, function(feature) { + return feature; + }); + + var actionTaken = false; + if (feature === marker) { + actionTaken = true; + found = true; + if (!isDefined(label)) { + if (data.projection === 'pixel') { + pos = data.coord; + } else { + pos = ol.proj.transform([data.lon, data.lat], + data.projection, viewProjection); + } + label = createOverlay(element, pos); + angular.forEach(map.getOverlays(), function(value) { + map.removeOverlay(value); + }); + map.addOverlay(label); + } + map.getTarget().style.cursor = 'pointer'; + } + + if (!found && label) { + actionTaken = true; + label = undefined; + map.getTarget().style.cursor = ''; + } + + if (actionTaken) { + evt.preventDefault(); + } + }; + + properties.removeAllOverlays = function(evt) { + angular.forEach(map.getOverlays(), function(value) { + map.removeOverlay(value); + }); + evt.preventDefault(); + }; + + if (!isDefined(marker)) { + data.projection = properties.projection ? properties.projection : + data.projection; + data.coord = properties.coord ? properties.coord : data.coord; + data.lat = properties.lat ? properties.lat : data.lat; + data.lon = properties.lon ? properties.lon : data.lon; + + if (isDefined(properties.style)) { + data.style = properties.style; + } else { + data.style = mapDefaults.styles.marker; + } + + marker = createFeature(data, viewProjection); + if (!isDefined(marker)) { + $log.error('[AngularJS - Openlayers] Received invalid data on ' + + 'the marker.'); + } + // Add a link between the feature and the marker properties + marker.set('marker', properties); + markerLayer.getSource().addFeature(marker); + } else { + var requestedPosition; + if (properties.projection === 'pixel') { + requestedPosition = properties.coord; + } else { + requestedPosition = ol.proj.transform([properties.lon, properties.lat], data.projection, + map.getView().getProjection()); + } + + if (!angular.equals(marker.getGeometry().getCoordinates(), requestedPosition)) { + var geometry = new ol.geom.Point(requestedPosition); + marker.setGeometry(geometry); + } + } + + if (isDefined(label)) { + map.removeOverlay(label); + } + + if (!isDefined(properties.label)) { + return; + } + + scope.message = properties.label.message; + if (!hasTranscluded && (!isDefined(scope.message) || scope.message.length === 0)) { + return; + } + + if (properties.label && properties.label.show === true) { + if (data.projection === 'pixel') { + pos = data.coord; + } else { + pos = ol.proj.transform([properties.lon, properties.lat], data.projection, + viewProjection); + } + label = createOverlay(element, pos); + map.addOverlay(label); + } + + if (label && properties.label && properties.label.show === false) { + map.removeOverlay(label); + label = undefined; + } + + // Then setup new ones according to properties + if (properties.label && properties.label.show === false && + properties.label.showOnMouseOver) { + map.getViewport().addEventListener('mousemove', properties.handleInteraction); + } + + if ((properties.label && properties.label.show === false && + properties.label.showOnMouseClick) || + properties.onClick) { + map.getViewport().addEventListener('click', properties.handleTapInteraction); + map.getViewport().querySelector('canvas.ol-unselectable').addEventListener( + 'touchend', properties.handleTapInteraction); + } + + if ((properties.label && properties.label.show === false && + properties.label.keepOneOverlayVisible)) { + map.getViewport().addEventListener('mousemove', properties.showAtLeastOneOverlay); + map.getViewport().addEventListener('click', properties.removeAllOverlays); + } + }, true); + }); + } + }; +}); + +angular.module('openlayers-directive').service('olData', function($log, $q, olHelpers) { + + var obtainEffectiveMapId = olHelpers.obtainEffectiveMapId; + + var maps = {}; + + var setResolvedDefer = function(d, mapId) { + var id = obtainEffectiveMapId(d, mapId); + d[id].resolvedDefer = true; + }; + + var getUnresolvedDefer = function(d, mapId) { + var id = obtainEffectiveMapId(d, mapId); + var defer; + + if (!angular.isDefined(d[id]) || d[id].resolvedDefer === true) { + defer = $q.defer(); + d[id] = { + defer: defer, + resolvedDefer: false + }; + } else { + defer = d[id].defer; + } + return defer; + }; + + var getDefer = function(d, mapId) { + var id = obtainEffectiveMapId(d, mapId); + var defer; + + if (!angular.isDefined(d[id]) || d[id].resolvedDefer === false) { + defer = getUnresolvedDefer(d, mapId); + } else { + defer = d[id].defer; + } + return defer; + }; + + this.setMap = function(olMap, scopeId) { + var defer = getUnresolvedDefer(maps, scopeId); + defer.resolve(olMap); + setResolvedDefer(maps, scopeId); + }; + + this.getMap = function(scopeId) { + var defer = getDefer(maps, scopeId); + return defer.promise; + }; + +}); + +angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $http) { + + var isDefined = function(value) { + return angular.isDefined(value); + }; + + var isDefinedAndNotNull = function(value) { + return angular.isDefined(value) && value !== null; + }; + + var setEvent = function(map, eventType, scope) { + map.on(eventType, function(event) { + var coord = event.coordinate; + var proj = map.getView().getProjection().getCode(); + if (proj === 'pixel') { + coord = coord.map(function(v) { + return parseInt(v, 10); + }); + } + scope.$emit('openlayers.map.' + eventType, { + 'coord': coord, + 'projection': proj, + 'event': event + }); + }); + }; + + var bingImagerySets = [ + 'Road', + 'Aerial', + 'AerialWithLabels', + 'collinsBart', + 'ordnanceSurvey' + ]; + + var getControlClasses = function() { + return { + attribution: ol.control.Attribution, + fullscreen: ol.control.FullScreen, + mouseposition: ol.control.MousePosition, + rotate: ol.control.Rotate, + scaleline: ol.control.ScaleLine, + zoom: ol.control.Zoom, + zoomslider: ol.control.ZoomSlider, + zoomtoextent: ol.control.ZoomToExtent + }; + }; + + var mapQuestLayers = ['osm', 'sat', 'hyb']; + + var esriBaseLayers = ['World_Imagery', 'World_Street_Map', 'World_Topo_Map', + 'World_Physical_Map', 'World_Terrain_Base', + 'Ocean_Basemap', 'NatGeo_World_Map']; + + var styleMap = { + 'style': ol.style.Style, + 'fill': ol.style.Fill, + 'stroke': ol.style.Stroke, + 'circle': ol.style.Circle, + 'icon': ol.style.Icon, + 'image': ol.style.Image, + 'regularshape': ol.style.RegularShape, + 'text': ol.style.Text + }; + + var optionalFactory = function(style, Constructor) { + if (Constructor && style instanceof Constructor) { + return style; + } else if (Constructor) { + return new Constructor(style); + } else { + return style; + } + }; + + //Parse the style tree calling the appropriate constructors. + //The keys in styleMap can be used and the OpenLayers constructors can be + //used directly. + var createStyle = function recursiveStyle(data, styleName) { + var style; + if (!styleName) { + styleName = 'style'; + style = data; + } else { + style = data[styleName]; + } + //Instead of defining one style for the layer, we've been given a style function + //to apply to each feature. + if (styleName === 'style' && data instanceof Function) { + return data; + } + + if (!(style instanceof Object)) { + return style; + } + + var styleObject; + if (Object.prototype.toString.call(style) === '[object Object]') { + styleObject = {}; + var styleConstructor = styleMap[styleName]; + if (styleConstructor && style instanceof styleConstructor) { + return style; + } + Object.getOwnPropertyNames(style).forEach(function(val, idx, array) { + //Consider the case + //image: { + // circle: { + // fill: { + // color: 'red' + // } + // } + // + //An ol.style.Circle is an instance of ol.style.Image, so we do not want to construct + //an Image and then construct a Circle. We assume that if we have an instanceof + //relationship, that the JSON parent has exactly one child. + //We check to see if an inheritance relationship exists. + //If it does, then for the parent we create an instance of the child. + var valConstructor = styleMap[val]; + if (styleConstructor && valConstructor && + valConstructor.prototype instanceof styleMap[styleName]) { + console.assert(array.length === 1, 'Extra parameters for ' + styleName); + styleObject = recursiveStyle(style, val); + return optionalFactory(styleObject, valConstructor); + } else { + styleObject[val] = recursiveStyle(style, val); + + // if the value is 'text' and it contains a String, then it should be interpreted + // as such, 'cause the text style might effectively contain a text to display + if (val !== 'text' && typeof styleObject[val] !== 'string') { + styleObject[val] = optionalFactory(styleObject[val], styleMap[val]); + } + } + }); + } else { + styleObject = style; + } + return optionalFactory(styleObject, styleMap[styleName]); + }; + + var detectLayerType = function(layer) { + if (layer.type) { + return layer.type; + } else { + switch (layer.source.type) { + case 'ImageWMS': + return 'Image'; + case 'ImageStatic': + return 'Image'; + case 'GeoJSON': + case 'JSONP': + case 'TopoJSON': + case 'KML': + case 'TileVector': + return 'Vector'; + default: + return 'Tile'; + } + } + }; + + var createProjection = function(view) { + var oProjection; + + switch (view.projection) { + case 'pixel': + if (!isDefined(view.extent)) { + $log.error('[AngularJS - Openlayers] - You must provide the extent of the image ' + + 'if using pixel projection'); + return; + } + oProjection = new ol.proj.Projection({ + code: 'pixel', + units: 'pixels', + extent: view.extent + }); + break; + default: + oProjection = new ol.proj.get(view.projection); + break; + } + + return oProjection; + }; + + var isValidStamenLayer = function(layer) { + return ['watercolor', 'terrain', 'toner'].indexOf(layer) !== -1; + }; + + var createSource = function(source, projection) { + var oSource; + + switch (source.type) { + case 'MapBox': + if (!source.mapId || !source.accessToken) { + $log.error('[AngularJS - Openlayers] - MapBox layer requires the map id and the access token'); + return; + } + var url = 'http://api.tiles.mapbox.com/v4/' + source.mapId + '/{z}/{x}/{y}.png?access_token=' + + source.accessToken; + + var pixelRatio = window.devicePixelRatio; + + if (pixelRatio > 1) { + url = url.replace('.png', '@2x.png'); + } + + oSource = new ol.source.XYZ({ + url: url, + attributions: createAttribution(source), + tilePixelRatio: pixelRatio > 1 ? 2 : 1, + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + }); + break; + case 'ImageWMS': + if (!source.url || !source.params) { + $log.error('[AngularJS - Openlayers] - ImageWMS Layer needs ' + + 'valid server url and params properties'); + } + oSource = new ol.source.ImageWMS({ + url: source.url, + attributions: createAttribution(source), + crossOrigin: (typeof source.crossOrigin === 'undefined') ? 'anonymous' : source.crossOrigin, + params: source.params, + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + }); + break; + + case 'TileWMS': + if ((!source.url && !source.urls) || !source.params) { + $log.error('[AngularJS - Openlayers] - TileWMS Layer needs ' + + 'valid url (or urls) and params properties'); + } + + var wmsConfiguration = { + crossOrigin: (typeof source.crossOrigin === 'undefined') ? 'anonymous' : source.crossOrigin, + params: source.params, + attributions: createAttribution(source), + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + }; + + if (source.url) { + wmsConfiguration.url = source.url; + } + + if (source.urls) { + wmsConfiguration.urls = source.urls; + } + + oSource = new ol.source.TileWMS(wmsConfiguration); + break; + + case 'WMTS': + if ((!source.url && !source.urls) || !source.tileGrid) { + $log.error('[AngularJS - Openlayers] - WMTS Layer needs valid url ' + + '(or urls) and tileGrid properties'); + } + + var wmtsConfiguration = { + projection: projection, + layer: source.layer, + attributions: createAttribution(source), + matrixSet: (source.matrixSet === 'undefined') ? projection : source.matrixSet, + format: (source.format === 'undefined') ? 'image/jpeg' : source.format, + requestEncoding: (source.requestEncoding === 'undefined') ? + 'KVP' : source.requestEncoding, + tileGrid: new ol.tilegrid.WMTS({ + origin: source.tileGrid.origin, + resolutions: source.tileGrid.resolutions, + matrixIds: source.tileGrid.matrixIds + }), + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + }; + + if (isDefined(source.url)) { + wmtsConfiguration.url = source.url; + } + + if (isDefined(source.urls)) { + wmtsConfiguration.urls = source.urls; + } + + oSource = new ol.source.WMTS(wmtsConfiguration); + break; + + case 'OSM': + oSource = new ol.source.OSM({ + attributions: createAttribution(source), + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + }); + + if (source.url) { + oSource.setUrl(source.url); + } + + break; + case 'BingMaps': + if (!source.key) { + $log.error('[AngularJS - Openlayers] - You need an API key to show the Bing Maps.'); + return; + } + + var bingConfiguration = { + key: source.key, + attributions: createAttribution(source), + imagerySet: source.imagerySet ? source.imagerySet : bingImagerySets[0], + culture: source.culture, + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + }; + + if (source.maxZoom) { + bingConfiguration.maxZoom = source.maxZoom; + } + + oSource = new ol.source.BingMaps(bingConfiguration); + break; + + case 'MapQuest': + if (!source.layer || mapQuestLayers.indexOf(source.layer) === -1) { + $log.error('[AngularJS - Openlayers] - MapQuest layers needs a valid \'layer\' property.'); + return; + } + + oSource = new ol.source.MapQuest({ + attributions: createAttribution(source), + layer: source.layer, + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + }); + + break; + + case 'EsriBaseMaps': + if (!source.layer || esriBaseLayers.indexOf(source.layer) === -1) { + $log.error('[AngularJS - Openlayers] - ESRI layers needs a valid \'layer\' property.'); + return; + } + + var _urlBase = 'http://services.arcgisonline.com/ArcGIS/rest/services/'; + var _url = _urlBase + source.layer + '/MapServer/tile/{z}/{y}/{x}'; + + oSource = new ol.source.XYZ({ + attributions: createAttribution(source), + url: _url, + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + }); + + break; + + case 'GeoJSON': + if (!(source.geojson || source.url)) { + $log.error('[AngularJS - Openlayers] - You need a geojson ' + + 'property to add a GeoJSON layer.'); + return; + } + + if (isDefined(source.url)) { + oSource = new ol.source.Vector({ + format: new ol.format.GeoJSON(), + url: source.url, + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + }); + } else { + oSource = new ol.source.Vector(); + + var projectionToUse = projection; + if (isDefined(source.geojson.projection)) { + projectionToUse = source.geojson.projection; + } + + var geojsonFormat = new ol.format.GeoJSON(); + var features = geojsonFormat.readFeatures( + source.geojson.object, { featureProjection: projectionToUse }); + + oSource.addFeatures(features); + } + + break; + case 'JSONP': + if (!(source.url)) { + $log.error('[AngularJS - Openlayers] - You need an url properly configured to add a JSONP layer.'); + return; + } + + if (isDefined(source.url)) { + oSource = new ol.source.Vector({ + format: new ol.format.GeoJSON(), + loader: function(/*extent, resolution, projection*/) { + var url = source.url + + '&outputFormat=text/javascript&format_options=callback:JSON_CALLBACK'; + $http.jsonp(url, { cache: source.cache}).success(function(response) { + oSource.addFeatures(oSource.readFeatures(response)); + }).error(function(response) { + $log(response); + }); + }, + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + }); + } + break; + case 'TopoJSON': + if (!(source.topojson || source.url)) { + $log.error('[AngularJS - Openlayers] - You need a topojson ' + + 'property to add a TopoJSON layer.'); + return; + } + + if (source.url) { + oSource = new ol.source.Vector({ + format: new ol.format.TopoJSON(), + url: source.url, + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + }); + } else { + oSource = new ol.source.Vector(angular.extend(source.topojson, { + format: new ol.format.TopoJSON(), + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + })); + } + break; + case 'TileJSON': + oSource = new ol.source.TileJSON({ + url: source.url, + attributions: createAttribution(source), + crossOrigin: 'anonymous', + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + }); + break; + + case 'TileVector': + if (!source.url || !source.format) { + $log.error('[AngularJS - Openlayers] - TileVector Layer needs valid url and format properties'); + } + oSource = new ol.source.TileVector({ + url: source.url, + projection: projection, + attributions: createAttribution(source), + format: source.format, + tileGrid: new ol.tilegrid.createXYZ({ + maxZoom: source.maxZoom || 19 + }), + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + }); + break; + + case 'TileTMS': + if (!source.url || !source.tileGrid) { + $log.error('[AngularJS - Openlayers] - TileTMS Layer needs valid url and tileGrid properties'); + } + oSource = new ol.source.TileImage({ + url: source.url, + maxExtent: source.maxExtent, + attributions: createAttribution(source), + tileGrid: new ol.tilegrid.TileGrid({ + origin: source.tileGrid.origin, + resolutions: source.tileGrid.resolutions + }), + tileUrlFunction: function(tileCoord) { + + var z = tileCoord[0]; + var x = tileCoord[1]; + var y = tileCoord[2]; //(1 << z) - tileCoord[2] - 1; + + if (x < 0 || y < 0) { + return ''; + } + + var url = source.url + z + '/' + x + '/' + y + '.png'; + + return url; + }, + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + }); + break; + case 'TileImage': + oSource = new ol.source.TileImage({ + url: source.url, + attributions: createAttribution(source), + tileGrid: new ol.tilegrid.TileGrid({ + origin: source.tileGrid.origin, // top left corner of the pixel projection's extent + resolutions: source.tileGrid.resolutions + }), + tileUrlFunction: function(tileCoord/*, pixelRatio, projection*/) { + var z = tileCoord[0]; + var x = tileCoord[1]; + var y = -tileCoord[2] - 1; + var url = source.url + .replace('{z}', z.toString()) + .replace('{x}', x.toString()) + .replace('{y}', y.toString()); + return url; + }, + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + }); + break; + case 'KML': + var extractStyles = source.extractStyles || false; + oSource = new ol.source.Vector({ + url: source.url, + format: new ol.format.KML(), + radius: source.radius, + extractStyles: extractStyles, + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + }); + break; + case 'Stamen': + if (!source.layer || !isValidStamenLayer(source.layer)) { + $log.error('[AngularJS - Openlayers] - You need a valid Stamen layer.'); + return; + } + oSource = new ol.source.Stamen({ + layer: source.layer, + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + }); + break; + case 'ImageStatic': + if (!source.url || !angular.isArray(source.imageSize) || source.imageSize.length !== 2) { + $log.error('[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.'); + return; + } + + oSource = new ol.source.ImageStatic({ + url: source.url, + attributions: createAttribution(source), + imageSize: source.imageSize, + projection: projection, + imageExtent: projection.getExtent(), + imageLoadFunction: source.imageLoadFunction, + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + }); + break; + case 'XYZ': + if (!source.url) { + $log.error('[AngularJS - Openlayers] - XYZ Layer needs valid url and params properties'); + } + oSource = new ol.source.XYZ({ + url: source.url, + attributions: createAttribution(source), + minZoom: source.minZoom, + maxZoom: source.maxZoom, + wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + }); + break; + } + + // log a warning when no source could be created for the given type + if (!oSource) { + $log.warn('[AngularJS - Openlayers] - No source could be found for type "' + source.type + '"'); + } + + return oSource; + }; + + var createAttribution = function(source) { + var attributions = []; + if (isDefined(source.attribution)) { + attributions.unshift(new ol.Attribution({html: source.attribution})); + } + return attributions; + }; + + var createGroup = function(name) { + var olGroup = new ol.layer.Group(); + olGroup.set('name', name); + + return olGroup; + }; + + var getGroup = function(layers, name) { + var layer; + + angular.forEach(layers, function(l) { + if (l instanceof ol.layer.Group && l.get('name') === name) { + layer = l; + return; + } + }); + + return layer; + }; + + var addLayerBeforeMarkers = function(layers, layer) { + var markersIndex; + for (var i = 0; i < layers.getLength(); i++) { + var l = layers.item(i); + + if (l.get('markers')) { + markersIndex = i; + break; + } + } + + if (isDefined(markersIndex)) { + var markers = layers.item(markersIndex); + layer.index = markersIndex; + layers.setAt(markersIndex, layer); + markers.index = layers.getLength(); + layers.push(markers); + } else { + layer.index = layers.getLength(); + layers.push(layer); + } + + }; + + var removeLayer = function(layers, index) { + layers.removeAt(index); + for (var i = index; i < layers.getLength(); i++) { + var l = layers.item(i); + if (l === null) { + layers.insertAt(i, null); + break; + } else { + l.index = i; + } + } + }; + + return { + // Determine if a reference is defined + isDefined: isDefined, + + // Determine if a reference is a number + isNumber: function(value) { + return angular.isNumber(value); + }, + + createView: function(view) { + var projection = createProjection(view); + + return new ol.View({ + projection: projection, + maxZoom: view.maxZoom, + minZoom: view.minZoom, + extent: view.extent + }); + }, + + // Determine if a reference is defined and not null + isDefinedAndNotNull: isDefinedAndNotNull, + + // Determine if a reference is a string + isString: function(value) { + return angular.isString(value); + }, + + // Determine if a reference is an array + isArray: function(value) { + return angular.isArray(value); + }, + + // Determine if a reference is an object + isObject: function(value) { + return angular.isObject(value); + }, + + // Determine if two objects have the same properties + equals: function(o1, o2) { + return angular.equals(o1, o2); + }, + + isValidCenter: function(center) { + return angular.isDefined(center) && + (typeof center.autodiscover === 'boolean' || + angular.isNumber(center.lat) && angular.isNumber(center.lon) || + (angular.isArray(center.coord) && center.coord.length === 2 && + angular.isNumber(center.coord[0]) && angular.isNumber(center.coord[1])) || + (angular.isArray(center.bounds) && center.bounds.length === 4 && + angular.isNumber(center.bounds[0]) && angular.isNumber(center.bounds[1]) && + angular.isNumber(center.bounds[1]) && angular.isNumber(center.bounds[2]))); + }, + + safeApply: function($scope, fn) { + var phase = $scope.$root.$$phase; + if (phase === '$apply' || phase === '$digest') { + $scope.$eval(fn); + } else { + $scope.$apply(fn); + } + }, + + isSameCenterOnMap: function(center, map) { + var urlProj = center.projection || 'EPSG:4326'; + var urlCenter = [center.lon, center.lat]; + var mapProj = map.getView().getProjection(); + var mapCenter = ol.proj.transform(map.getView().getCenter(), mapProj, urlProj); + var zoom = map.getView().getZoom(); + if (mapCenter[1].toFixed(4) === urlCenter[1].toFixed(4) && + mapCenter[0].toFixed(4) === urlCenter[0].toFixed(4) && + zoom === center.zoom) { + return true; + } + return false; + }, + + setCenter: function(view, projection, newCenter, map) { + + if (map && view.getCenter()) { + var pan = ol.animation.pan({ + duration: 150, + source: (view.getCenter()) + }); + map.beforeRender(pan); + } + + if (newCenter.projection === projection) { + view.setCenter([newCenter.lon, newCenter.lat]); + } else { + var coord = [newCenter.lon, newCenter.lat]; + view.setCenter(ol.proj.transform(coord, newCenter.projection, projection)); + } + }, + + setZoom: function(view, zoom, map) { + var z = ol.animation.zoom({ + duration: 150, + resolution: map.getView().getResolution() + }); + map.beforeRender(z); + view.setZoom(zoom); + }, + + isBoolean: function(value) { + return typeof value === 'boolean'; + }, + + obtainEffectiveMapId: function(d, mapId) { + var id; + var i; + if (!angular.isDefined(mapId)) { + if (Object.keys(d).length === 1) { + for (i in d) { + if (d.hasOwnProperty(i)) { + id = i; + } + } + } else if (Object.keys(d).length === 0) { + id = 'main'; + } else { + $log.error('[AngularJS - Openlayers] - You have more than 1 map on the DOM, ' + + 'you must provide the map ID to the olData.getXXX call'); + } + } else { + id = mapId; + } + return id; + }, + + createStyle: createStyle, + + setMapEvents: function(events, map, scope) { + if (isDefined(events) && angular.isArray(events.map)) { + for (var i in events.map) { + var event = events.map[i]; + setEvent(map, event, scope); + } + } + }, + + setVectorLayerEvents: function(events, map, scope, layerName) { + if (isDefined(events) && angular.isArray(events.layers)) { + angular.forEach(events.layers, function(eventType) { + angular.element(map.getViewport()).on(eventType, function(evt) { + var pixel = map.getEventPixel(evt); + var feature = map.forEachFeatureAtPixel(pixel, function(feature, olLayer) { + // only return the feature if it is in this layer (based on the name) + return (isDefinedAndNotNull(olLayer) && olLayer.get('name') === layerName) ? feature : null; + }); + if (isDefinedAndNotNull(feature)) { + scope.$emit('openlayers.layers.' + layerName + '.' + eventType, feature, evt); + } + }); + }); + } + }, + + setViewEvents: function(events, map, scope) { + if (isDefined(events) && angular.isArray(events.view)) { + var view = map.getView(); + angular.forEach(events.view, function(eventType) { + view.on(eventType, function(event) { + scope.$emit('openlayers.view.' + eventType, view, event); + }); + }); + } + }, + + detectLayerType: detectLayerType, + + createLayer: function(layer, projection, name) { + var oLayer; + var type = detectLayerType(layer); + var oSource = createSource(layer.source, projection); + if (!oSource) { + return; + } + + // Manage clustering + if ((type === 'Vector') && layer.clustering) { + oSource = new ol.source.Cluster({ + source: oSource, + distance: layer.clusteringDistance, + }); + } + + switch (type) { + case 'Image': + oLayer = new ol.layer.Image({ source: oSource }); + break; + case 'Tile': + oLayer = new ol.layer.Tile({ source: oSource }); + break; + case 'Heatmap': + oLayer = new ol.layer.Heatmap({ source: oSource }); + break; + case 'Vector': + oLayer = new ol.layer.Vector({ source: oSource }); + break; + } + + // set a layer name if given + if (isDefined(name)) { + oLayer.set('name', name); + } else if (isDefined(layer.name)) { + oLayer.set('name', layer.name); + } + + return oLayer; + }, + + createVectorLayer: function() { + return new ol.layer.Vector({ + source: new ol.source.Vector() + }); + }, + + notifyCenterUrlHashChanged: function(scope, center, search) { + if (center.centerUrlHash) { + var centerUrlHash = center.lat.toFixed(4) + ':' + center.lon.toFixed(4) + ':' + center.zoom; + if (!isDefined(search.c) || search.c !== centerUrlHash) { + scope.$emit('centerUrlHash', centerUrlHash); + } + } + }, + + getControlClasses: getControlClasses, + + detectControls: function(controls) { + var actualControls = {}; + var controlClasses = getControlClasses(); + + controls.forEach(function(control) { + for (var i in controlClasses) { + if (control instanceof controlClasses[i]) { + actualControls[i] = control; + } + } + }); + + return actualControls; + }, + + createFeature: function(data, viewProjection) { + var geometry; + + switch (data.type) { + case 'Polygon': + geometry = new ol.geom.Polygon(data.coords); + break; + default: + if (isDefined(data.coord) && data.projection === 'pixel') { + geometry = new ol.geom.Point(data.coord); + } else { + geometry = new ol.geom.Point([data.lon, data.lat]); + } + break; + } + + if (isDefined(data.projection) && data.projection !== 'pixel') { + geometry = geometry.transform(data.projection, viewProjection); + } + + var feature = new ol.Feature({ + geometry: geometry + }); + + if (isDefined(data.style)) { + var style = createStyle(data.style); + feature.setStyle(style); + } + return feature; + }, + + addLayerBeforeMarkers: addLayerBeforeMarkers, + + getGroup: getGroup, + + addLayerToGroup: function(layers, layer, name) { + var groupLayer = getGroup(layers, name); + + if (!isDefined(groupLayer)) { + groupLayer = createGroup(name); + addLayerBeforeMarkers(layers,groupLayer); + } + + layer.set('group', name); + addLayerBeforeMarkers(groupLayer.getLayers(), layer); + }, + + removeLayerFromGroup: function(layers, layer, name) { + var groupLayer = getGroup(layers, name); + layer.set('group'); + removeLayer(groupLayer.getLayers(), layer.index); + }, + + removeLayer: removeLayer, + + insertLayer: function(layers, index, layer) { + if (layers.getLength() < index) { + while (layers.getLength() < index) { + layers.push(null); + } + layer.index = index; + layers.push(layer); + } else { + layer.index = index; + layers.insertAt(layer.index, layer); + for (var i = index + 1; i < layers.getLength(); i++) { + var l = layers.item(i); + if (l === null) { + layers.removeAt(i); + break; + } else { + l.index = i; + } + } + } + }, + + createOverlay: function(element, pos) { + element.css('display', 'block'); + var ov = new ol.Overlay({ + position: pos, + element: element, + positioning: 'center-left' + }); + + return ov; + } + }; +}); + +angular.module('openlayers-directive').factory('olMapDefaults', function($q, olHelpers) { + + var base64icon = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAApCAYAAADAk4LOAAAGmklEQVRYw' + + '7VXeUyTZxjvNnfELFuyIzOabermMZEeQC/OclkO49CpOHXOLJl/CAURuYbQi3KLgEhbrhZ1aDwmaoGq' + + 'KII6odATmH/scDFbdC7LvFqOCc+e95s2VG50X/LLm/f4/Z7neY/ne18aANCmAr5E/xZf1uDOkTcGcWR' + + '6hl9247tT5U7Y6SNvWsKT63P58qbfeLJG8M5qcgTknrvvrdDbsT7Ml+tv82X6vVxJE33aRmgSyYtcWV' + + 'MqX97Yv2JvW39UhRE2HuyBL+t+gK1116ly06EeWFNlAmHxlQE0OMiV6mQCScusKRlhS3QLeVJdl1+23' + + 'h5dY4FNB3thrbYboqptEFlphTC1hSpJnbRvxP4NWgsE5Jyz86QNNi/5qSUTGuFk1gu54tN9wuK2wc3o' + + '+Wc13RCmsoBwEqzGcZsxsvCSy/9wJKf7UWf1mEY8JWfewc67UUoDbDjQC+FqK4QqLVMGGR9d2wurKzq' + + 'Bk3nqIT/9zLxRRjgZ9bqQgub+DdoeCC03Q8j+0QhFhBHR/eP3U/zCln7Uu+hihJ1+bBNffLIvmkyP0g' + + 'pBZWYXhKussK6mBz5HT6M1Nqpcp+mBCPXosYQfrekGvrjewd59/GvKCE7TbK/04/ZV5QZYVWmDwH1mF' + + '3xa2Q3ra3DBC5vBT1oP7PTj4C0+CcL8c7C2CtejqhuCnuIQHaKHzvcRfZpnylFfXsYJx3pNLwhKzRAw' + + 'AhEqG0SpusBHfAKkxw3w4627MPhoCH798z7s0ZnBJ/MEJbZSbXPhER2ih7p2ok/zSj2cEJDd4CAe+5W' + + 'YnBCgR2uruyEw6zRoW6/DWJ/OeAP8pd/BGtzOZKpG8oke0SX6GMmRk6GFlyAc59K32OTEinILRJRcha' + + 'h8HQwND8N435Z9Z0FY1EqtxUg+0SO6RJ/mmXz4VuS+DpxXC3gXmZwIL7dBSH4zKE50wESf8qwVgrP1E' + + 'IlTO5JP9Igu0aexdh28F1lmAEGJGfh7jE6ElyM5Rw/FDcYJjWhbeiBYoYNIpc2FT/SILivp0F1ipDWk' + + '4BIEo2VuodEJUifhbiltnNBIXPUFCMpthtAyqws/BPlEF/VbaIxErdxPphsU7rcCp8DohC+GvBIPJS/' + + 'tW2jtvTmmAeuNO8BNOYQeG8G/2OzCJ3q+soYB5i6NhMaKr17FSal7GIHheuV3uSCY8qYVuEm1cOzqdW' + + 'r7ku/R0BDoTT+DT+ohCM6/CCvKLKO4RI+dXPeAuaMqksaKrZ7L3FE5FIFbkIceeOZ2OcHO6wIhTkNo0' + + 'ffgjRGxEqogXHYUPHfWAC/lADpwGcLRY3aeK4/oRGCKYcZXPVoeX/kelVYY8dUGf8V5EBRbgJXT5QIP' + + 'hP9ePJi428JKOiEYhYXFBqou2Guh+p/mEB1/RfMw6rY7cxcjTrneI1FrDyuzUSRm9miwEJx8E/gUmql' + + 'yvHGkneiwErR21F3tNOK5Tf0yXaT+O7DgCvALTUBXdM4YhC/IawPU+2PduqMvuaR6eoxSwUk75ggqsY' + + 'J7VicsnwGIkZBSXKOUww73WGXyqP+J2/b9c+gi1YAg/xpwck3gJuucNrh5JvDPvQr0WFXf0piyt8f8/' + + 'WI0hV4pRxxkQZdJDfDJNOAmM0Ag8jyT6hz0WGXWuP94Yh2jcfjmXAGvHCMslRimDHYuHuDsy2QtHuIa' + + 'vznhbYURq5R57KpzBBRZKPJi8eQg48h4j8SDdowifdIrEVdU+gbO6QNvRRt4ZBthUaZhUnjlYObNagV' + + '3keoeru3rU7rcuceqU1mJBxy+BWZYlNEBH+0eH4vRiB+OYybU2hnblYlTvkHinM4m54YnxSyaZYSF6R' + + '3jwgP7udKLGIX6r/lbNa9N6y5MFynjWDtrHd75ZvTYAPO/6RgF0k76mQla3FGq7dO+cH8sKn0Vo7nDl' + + 'lwAhqwLPkxrHwWmHJOo+AKJ4rab5OgrM7rVu8eWb2Pu0Dh4eDgXoOfvp7Y7QeqknRmvcTBEyq9m/HQQ' + + 'SCSz6LHq3z0yzsNySRfMS253wl2KyRDbcZPcfJKjZmSEOjcxyi+Y8dUOtsIEH6R2wNykdqrkYJ0RV92' + + 'H0W58pkfQk7cKevsLK10Py8SdMGfXNXATY+pPbyJR/ET6n9nIfztNtZYRV9XniQu9IA2vOVgy4ir7GC' + + 'LVmmd+zjkH0eAF9Po6K61pmCXHxU5rHMYd1ftc3owjwRSVRzLjKvqZEty6cRUD7jGqiOdu5HG6MdHjN' + + 'cNYGqfDm5YRzLBBCCDl/2bk8a8gdbqcfwECu62Fg/HrggAAAABJRU5ErkJggg=='; + + var _getDefaults = function() { + return { + view: { + projection: 'EPSG:3857', + minZoom: undefined, + maxZoom: undefined, + rotation: 0, + extent: undefined + }, + center: { + lat: 0, + lon: 0, + zoom: 1, + autodiscover: false, + bounds: [], + centerUrlHash: false, + projection: 'EPSG:4326' + }, + styles: { + path: { + stroke: { + color: 'blue', + width: 8 + } + }, + marker: { + image: new ol.style.Icon({ + anchor: [0.5, 1], + anchorXUnits: 'fraction', + anchorYUnits: 'fraction', + opacity: 0.90, + src: base64icon + }) + } + }, + events: { + map: [], + markers: [], + layers: [] + }, + controls: { + attribution: true, + rotate: false, + zoom: true + }, + interactions: { + mouseWheelZoom: false + }, + renderer: 'canvas' + }; + }; + + var isDefined = olHelpers.isDefined; + var defaults = {}; + + // Get the _defaults dictionary, and override the properties defined by the user + return { + getDefaults: function(scope) { + if (!isDefined(scope)) { + for (var i in defaults) { + return defaults[i]; + } + } + return defaults[scope.$id]; + }, + + setDefaults: function(scope) { + var userDefaults = scope.defaults; + var scopeId = scope.$id; + var newDefaults = _getDefaults(); + + if (isDefined(userDefaults)) { + + if (isDefined(userDefaults.layers)) { + newDefaults.layers = angular.copy(userDefaults.layers); + } + + if (isDefined(userDefaults.controls)) { + newDefaults.controls = angular.copy(userDefaults.controls); + } + + if (isDefined(userDefaults.events)) { + newDefaults.events = angular.copy(userDefaults.events); + } + + if (isDefined(userDefaults.interactions)) { + newDefaults.interactions = angular.copy(userDefaults.interactions); + } + + if (isDefined(userDefaults.renderer)) { + newDefaults.renderer = userDefaults.renderer; + } + + if (isDefined(userDefaults.view)) { + newDefaults.view.maxZoom = userDefaults.view.maxZoom || newDefaults.view.maxZoom; + newDefaults.view.minZoom = userDefaults.view.minZoom || newDefaults.view.minZoom; + newDefaults.view.projection = userDefaults.view.projection || newDefaults.view.projection; + newDefaults.view.extent = userDefaults.view.extent || newDefaults.view.extent; + } + + if (isDefined(userDefaults.styles)) { + newDefaults.styles = angular.extend(newDefaults.styles, userDefaults.styles); + } + + } + + defaults[scopeId] = newDefaults; + return newDefaults; + } + }; +}); + +})); \ No newline at end of file From 241e1272800e420aa5182cde4e81299bb12ea565 Mon Sep 17 00:00:00 2001 From: Tirumala Dilip Kumar Date: Fri, 6 Nov 2015 16:09:11 +0530 Subject: [PATCH 07/53] update 'undefined' to undefined in olHelpers.js --- dist/angular-openlayers-directive.js | 40 +++++++++---------- dist/angular-openlayers-directive.min.js | 4 +- ...ular-openlayers-directive.min.no-header.js | 4 +- dist/angular-openlayers-directive.pre.js | 40 +++++++++---------- src/services/olHelpers.js | 40 +++++++++---------- 5 files changed, 64 insertions(+), 64 deletions(-) diff --git a/dist/angular-openlayers-directive.js b/dist/angular-openlayers-directive.js index 94615a23..aea4b269 100644 --- a/dist/angular-openlayers-directive.js +++ b/dist/angular-openlayers-directive.js @@ -1340,7 +1340,7 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt url: url, attributions: createAttribution(source), tilePixelRatio: pixelRatio > 1 ? 2 : 1, - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }); break; case 'ImageWMS': @@ -1353,7 +1353,7 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt attributions: createAttribution(source), crossOrigin: (typeof source.crossOrigin === 'undefined') ? 'anonymous' : source.crossOrigin, params: source.params, - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }); break; @@ -1367,7 +1367,7 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt crossOrigin: (typeof source.crossOrigin === 'undefined') ? 'anonymous' : source.crossOrigin, params: source.params, attributions: createAttribution(source), - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }; if (source.url) { @@ -1400,7 +1400,7 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt resolutions: source.tileGrid.resolutions, matrixIds: source.tileGrid.matrixIds }), - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }; if (isDefined(source.url)) { @@ -1417,7 +1417,7 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt case 'OSM': oSource = new ol.source.OSM({ attributions: createAttribution(source), - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }); if (source.url) { @@ -1436,7 +1436,7 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt attributions: createAttribution(source), imagerySet: source.imagerySet ? source.imagerySet : bingImagerySets[0], culture: source.culture, - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }; if (source.maxZoom) { @@ -1455,7 +1455,7 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt oSource = new ol.source.MapQuest({ attributions: createAttribution(source), layer: source.layer, - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }); break; @@ -1472,7 +1472,7 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt oSource = new ol.source.XYZ({ attributions: createAttribution(source), url: _url, - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }); break; @@ -1488,7 +1488,7 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt oSource = new ol.source.Vector({ format: new ol.format.GeoJSON(), url: source.url, - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }); } else { oSource = new ol.source.Vector(); @@ -1524,7 +1524,7 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt $log(response); }); }, - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }); } break; @@ -1539,12 +1539,12 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt oSource = new ol.source.Vector({ format: new ol.format.TopoJSON(), url: source.url, - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }); } else { oSource = new ol.source.Vector(angular.extend(source.topojson, { format: new ol.format.TopoJSON(), - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX })); } break; @@ -1553,7 +1553,7 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt url: source.url, attributions: createAttribution(source), crossOrigin: 'anonymous', - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }); break; @@ -1569,7 +1569,7 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt tileGrid: new ol.tilegrid.createXYZ({ maxZoom: source.maxZoom || 19 }), - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }); break; @@ -1599,7 +1599,7 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt return url; }, - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }); break; case 'TileImage': @@ -1620,7 +1620,7 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt .replace('{y}', y.toString()); return url; }, - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }); break; case 'KML': @@ -1630,7 +1630,7 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt format: new ol.format.KML(), radius: source.radius, extractStyles: extractStyles, - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }); break; case 'Stamen': @@ -1640,7 +1640,7 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt } oSource = new ol.source.Stamen({ layer: source.layer, - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }); break; case 'ImageStatic': @@ -1656,7 +1656,7 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt projection: projection, imageExtent: projection.getExtent(), imageLoadFunction: source.imageLoadFunction, - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }); break; case 'XYZ': @@ -1668,7 +1668,7 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt attributions: createAttribution(source), minZoom: source.minZoom, maxZoom: source.maxZoom, - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }); break; } diff --git a/dist/angular-openlayers-directive.min.js b/dist/angular-openlayers-directive.min.js index a2536ee2..1f238470 100644 --- a/dist/angular-openlayers-directive.min.js +++ b/dist/angular-openlayers-directive.min.js @@ -28,5 +28,5 @@ */ /*! angular-openlayers-directive 06-11-2015 */ -!function(a,b){"function"==typeof define&&define.amd?define(["ol"],function(c){return a.angularOpenlayersDirective=b(c)}):a.angularOpenlayersDirective=b(a.ol)}(this,function(a){angular.module("openlayers-directive",["ngSanitize"]).directive("openlayers",["$log","$q","$compile","olHelpers","olMapDefaults","olData",function(b,c,d,e,f,g){return{restrict:"EA",transclude:!0,replace:!0,scope:{center:"=olCenter",defaults:"=olDefaults",view:"=olView",events:"=olEvents"},template:'
',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p});if(!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d){if("pixel"===g.view.projection)return void i.setCenter(c.coord);var e=a.proj.transform(d,g.view.projection,c.projection);(e[1]!==c.lat||e[0]!==c.lon)&&p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}}),f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i))}else d=j(c,f),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i))}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)}),e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope();i.getMap().then(function(b){var d=e.getControlClasses,i=d();return a.$on("$destroy",function(){b.removeControl(f)}),h(a.properties)&&h(a.properties.control)?(f=a.properties.control,void b.addControl(f)):void(c.name&&(h(a.properties)&&(g=a.properties),f=new i[c.name](g),b.addControl(f)))})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return e.on("pointerdown",j),e.on("pointerup",j),e.on("pointerdrag",j),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e)}),k(c.properties)?void c.$watch("properties",function(d){if(e.getViewport().removeEventListener("mousemove",d.handleInteraction),e.getViewport().removeEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",d.handleTapInteraction),e.getViewport().removeEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",d.removeAllOverlays),d.handleInteraction=function(b){if(!d.label.show){var f=!1,g=e.getEventPixel(b),i=e.forEachFeatureAtPixel(g,function(a){return a}),j=!1;i===r&&(j=!0,f=!0,k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),!d.onClick||"click"!==b.type&&"touchend"!==b.type||c.$apply(function(){d.onClick.call(r,b,d)}),e.getTarget().style.cursor="pointer"),!f&&p&&(j=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),j&&b.preventDefault()}},d.handleTapInteraction=function(){function a(){c=!0,b&&clearTimeout(b),b=setTimeout(function(){c=!1,b=null},500)}var b,c=!1;return e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",a),function(){c||(d.handleInteraction.apply(null,arguments),a())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||d.onClick)&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q","olHelpers",function(a,b,c){var d=c.obtainEffectiveMapId,e={},f=function(a,b){var c=d(a,b);a[c].resolvedDefer=!0},g=function(a,c){var e,f=d(a,c);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},h=function(a,b){var c,e=d(a,b);return c=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:g(a,b)};this.setMap=function(a,b){var c=g(e,b);c.resolve(a),f(e,b)},this.getMap=function(a){var b=h(e,a);return b.promise}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function x(a,b){var c;if(b?c=a[b]:(b="style",c=a),"style"===b&&a instanceof Function)return a;if(!(c instanceof Object))return c;var d;if("[object Object]"===Object.prototype.toString.call(c)){d={};var e=l[b];if(e&&c instanceof e)return c;Object.getOwnPropertyNames(c).forEach(function(a,f,g){var h=l[a];return e&&h&&h.prototype instanceof l[b]?(console.assert(1===g.length,"Extra parameters for "+b),d=x(c,a),m(d,h)):(d[a]=x(c,a),void("text"!==a&&"string"!=typeof d[a]&&(d[a]=m(d[a],l[a]))))})}else d=c;return m(d,l[b])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"TileVector":return"Vector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");var i="http://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,l=window.devicePixelRatio;l>1&&(i=i.replace(".png","@2x.png")),g=new a.source.XYZ({url:i,attributions:s(b),tilePixelRatio:l>1?2:1,wrapX:"undefined"===b.wrapX?1:b.wrapX});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,attributions:s(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:b.params,wrapX:"undefined"===b.wrapX?1:b.wrapX});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var m={crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:b.params,attributions:s(b),wrapX:"undefined"===b.wrapX?1:b.wrapX};b.url&&(m.url=b.url),b.urls&&(m.urls=b.urls),g=new a.source.TileWMS(m);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var n={projection:f,layer:b.layer,attributions:s(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),wrapX:"undefined"===b.wrapX?1:b.wrapX};e(b.url)&&(n.url=b.url),e(b.urls)&&(n.urls=b.urls),g=new a.source.WMTS(n);break;case"OSM":g=new a.source.OSM({attributions:s(b),wrapX:"undefined"===b.wrapX?1:b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var o={key:b.key,attributions:s(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:"undefined"===b.wrapX?1:b.wrapX};b.maxZoom&&(o.maxZoom=b.maxZoom),g=new a.source.BingMaps(o);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:s(b),layer:b.layer,wrapX:"undefined"===b.wrapX?1:b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var p="http://services.arcgisonline.com/ArcGIS/rest/services/",r=p+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:s(b),url:r,wrapX:"undefined"===b.wrapX?1:b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url,wrapX:"undefined"===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var t=f;e(b.geojson.projection)&&(t=b.geojson.projection);var u=new a.format.GeoJSON,v=u.readFeatures(b.geojson.object,{featureProjection:t});g.addFeatures(v)}break;case"JSONP":if(!b.url)return void c.error("[AngularJS - Openlayers] - You need an url properly configured to add a JSONP layer.");e(b.url)&&(g=new a.source.Vector({format:new a.format.GeoJSON,loader:function(){var a=b.url+"&outputFormat=text/javascript&format_options=callback:JSON_CALLBACK";d.jsonp(a,{cache:b.cache}).success(function(a){g.addFeatures(g.readFeatures(a))}).error(function(a){c(a)})},wrapX:"undefined"===b.wrapX?1:b.wrapX}));break;case"TopoJSON":if(!b.topojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a topojson property to add a TopoJSON layer.");g=b.url?new a.source.Vector({format:new a.format.TopoJSON,url:b.url,wrapX:"undefined"===b.wrapX?1:b.wrapX}):new a.source.Vector(angular.extend(b.topojson,{format:new a.format.TopoJSON,wrapX:"undefined"===b.wrapX?1:b.wrapX}));break;case"TileJSON":g=new a.source.TileJSON({url:b.url,attributions:s(b),crossOrigin:"anonymous",wrapX:"undefined"===b.wrapX?1:b.wrapX});break;case"TileVector":b.url&&b.format||c.error("[AngularJS - Openlayers] - TileVector Layer needs valid url and format properties"),g=new a.source.TileVector({url:b.url,projection:f,attributions:s(b),format:b.format,tileGrid:new a.tilegrid.createXYZ({maxZoom:b.maxZoom||19}),wrapX:"undefined"===b.wrapX?1:b.wrapX});break;case"TileTMS":b.url&&b.tileGrid||c.error("[AngularJS - Openlayers] - TileTMS Layer needs valid url and tileGrid properties"),g=new a.source.TileImage({url:b.url,maxExtent:b.maxExtent,attributions:s(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=a[2];if(0>d||0>e)return"";var f=b.url+c+"/"+d+"/"+e+".png";return f},wrapX:"undefined"===b.wrapX?1:b.wrapX});break;case"TileImage":g=new a.source.TileImage({url:b.url,attributions:s(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=-a[2]-1,f=b.url.replace("{z}",c.toString()).replace("{x}",d.toString()).replace("{y}",e.toString());return f},wrapX:"undefined"===b.wrapX?1:b.wrapX});break;case"KML":var w=b.extractStyles||!1;g=new a.source.Vector({url:b.url,format:new a.format.KML,radius:b.radius,extractStyles:w,wrapX:"undefined"===b.wrapX?1:b.wrapX});break;case"Stamen":if(!b.layer||!q(b.layer))return void c.error("[AngularJS - Openlayers] - You need a valid Stamen layer.");g=new a.source.Stamen({layer:b.layer,wrapX:"undefined"===b.wrapX?1:b.wrapX});break;case"ImageStatic":if(!b.url||!angular.isArray(b.imageSize)||2!==b.imageSize.length)return void c.error("[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.");g=new a.source.ImageStatic({url:b.url,attributions:s(b),imageSize:b.imageSize,projection:f,imageExtent:f.getExtent(),imageLoadFunction:b.imageLoadFunction,wrapX:"undefined"===b.wrapX?1:b.wrapX});break;case"XYZ":b.url||c.error("[AngularJS - Openlayers] - XYZ Layer needs valid url and params properties"),g=new a.source.XYZ({url:b.url,attributions:s(b),minZoom:b.minZoom,maxZoom:b.maxZoom,wrapX:"undefined"===b.wrapX?1:b.wrapX})}return g||c.warn('[AngularJS - Openlayers] - No source could be found for type "'+b.type+'"'),g},s=function(b){var c=[];return e(b.attribution)&&c.unshift(new a.Attribution({html:b.attribution})),c},t=function(b){var c=new a.layer.Group;return c.set("name",b),c},u=function(b,c){var d;return angular.forEach(b,function(b){return b instanceof a.layer.Group&&b.get("name")===c?void(d=b):void 0}),d},v=function(a,b){for(var c,d=0;d',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p});if(!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d){if("pixel"===g.view.projection)return void i.setCenter(c.coord);var e=a.proj.transform(d,g.view.projection,c.projection);(e[1]!==c.lat||e[0]!==c.lon)&&p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}}),f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i))}else d=j(c,f),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i))}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)}),e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope();i.getMap().then(function(b){var d=e.getControlClasses,i=d();return a.$on("$destroy",function(){b.removeControl(f)}),h(a.properties)&&h(a.properties.control)?(f=a.properties.control,void b.addControl(f)):void(c.name&&(h(a.properties)&&(g=a.properties),f=new i[c.name](g),b.addControl(f)))})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return e.on("pointerdown",j),e.on("pointerup",j),e.on("pointerdrag",j),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e)}),k(c.properties)?void c.$watch("properties",function(d){if(e.getViewport().removeEventListener("mousemove",d.handleInteraction),e.getViewport().removeEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",d.handleTapInteraction),e.getViewport().removeEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",d.removeAllOverlays),d.handleInteraction=function(b){if(!d.label.show){var f=!1,g=e.getEventPixel(b),i=e.forEachFeatureAtPixel(g,function(a){return a}),j=!1;i===r&&(j=!0,f=!0,k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),!d.onClick||"click"!==b.type&&"touchend"!==b.type||c.$apply(function(){d.onClick.call(r,b,d)}),e.getTarget().style.cursor="pointer"),!f&&p&&(j=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),j&&b.preventDefault()}},d.handleTapInteraction=function(){function a(){c=!0,b&&clearTimeout(b),b=setTimeout(function(){c=!1,b=null},500)}var b,c=!1;return e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",a),function(){c||(d.handleInteraction.apply(null,arguments),a())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||d.onClick)&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q","olHelpers",function(a,b,c){var d=c.obtainEffectiveMapId,e={},f=function(a,b){var c=d(a,b);a[c].resolvedDefer=!0},g=function(a,c){var e,f=d(a,c);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},h=function(a,b){var c,e=d(a,b);return c=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:g(a,b)};this.setMap=function(a,b){var c=g(e,b);c.resolve(a),f(e,b)},this.getMap=function(a){var b=h(e,a);return b.promise}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function x(a,b){var c;if(b?c=a[b]:(b="style",c=a),"style"===b&&a instanceof Function)return a;if(!(c instanceof Object))return c;var d;if("[object Object]"===Object.prototype.toString.call(c)){d={};var e=l[b];if(e&&c instanceof e)return c;Object.getOwnPropertyNames(c).forEach(function(a,f,g){var h=l[a];return e&&h&&h.prototype instanceof l[b]?(console.assert(1===g.length,"Extra parameters for "+b),d=x(c,a),m(d,h)):(d[a]=x(c,a),void("text"!==a&&"string"!=typeof d[a]&&(d[a]=m(d[a],l[a]))))})}else d=c;return m(d,l[b])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"TileVector":return"Vector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");var i="http://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,l=window.devicePixelRatio;l>1&&(i=i.replace(".png","@2x.png")),g=new a.source.XYZ({url:i,attributions:s(b),tilePixelRatio:l>1?2:1,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,attributions:s(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:b.params,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var m={crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:b.params,attributions:s(b),wrapX:void 0===b.wrapX?1:b.wrapX};b.url&&(m.url=b.url),b.urls&&(m.urls=b.urls),g=new a.source.TileWMS(m);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var n={projection:f,layer:b.layer,attributions:s(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),wrapX:void 0===b.wrapX?1:b.wrapX};e(b.url)&&(n.url=b.url),e(b.urls)&&(n.urls=b.urls),g=new a.source.WMTS(n);break;case"OSM":g=new a.source.OSM({attributions:s(b),wrapX:void 0===b.wrapX?1:b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var o={key:b.key,attributions:s(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX?1:b.wrapX};b.maxZoom&&(o.maxZoom=b.maxZoom),g=new a.source.BingMaps(o);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:s(b),layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var p="http://services.arcgisonline.com/ArcGIS/rest/services/",r=p+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:s(b),url:r,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var t=f;e(b.geojson.projection)&&(t=b.geojson.projection);var u=new a.format.GeoJSON,v=u.readFeatures(b.geojson.object,{featureProjection:t});g.addFeatures(v)}break;case"JSONP":if(!b.url)return void c.error("[AngularJS - Openlayers] - You need an url properly configured to add a JSONP layer.");e(b.url)&&(g=new a.source.Vector({format:new a.format.GeoJSON,loader:function(){var a=b.url+"&outputFormat=text/javascript&format_options=callback:JSON_CALLBACK";d.jsonp(a,{cache:b.cache}).success(function(a){g.addFeatures(g.readFeatures(a))}).error(function(a){c(a)})},wrapX:void 0===b.wrapX?1:b.wrapX}));break;case"TopoJSON":if(!b.topojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a topojson property to add a TopoJSON layer.");g=b.url?new a.source.Vector({format:new a.format.TopoJSON,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX}):new a.source.Vector(angular.extend(b.topojson,{format:new a.format.TopoJSON,wrapX:void 0===b.wrapX?1:b.wrapX}));break;case"TileJSON":g=new a.source.TileJSON({url:b.url,attributions:s(b),crossOrigin:"anonymous",wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileVector":b.url&&b.format||c.error("[AngularJS - Openlayers] - TileVector Layer needs valid url and format properties"),g=new a.source.TileVector({url:b.url,projection:f,attributions:s(b),format:b.format,tileGrid:new a.tilegrid.createXYZ({maxZoom:b.maxZoom||19}),wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileTMS":b.url&&b.tileGrid||c.error("[AngularJS - Openlayers] - TileTMS Layer needs valid url and tileGrid properties"),g=new a.source.TileImage({url:b.url,maxExtent:b.maxExtent,attributions:s(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=a[2];if(0>d||0>e)return"";var f=b.url+c+"/"+d+"/"+e+".png";return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileImage":g=new a.source.TileImage({url:b.url,attributions:s(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=-a[2]-1,f=b.url.replace("{z}",c.toString()).replace("{x}",d.toString()).replace("{y}",e.toString());return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"KML":var w=b.extractStyles||!1;g=new a.source.Vector({url:b.url,format:new a.format.KML,radius:b.radius,extractStyles:w,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"Stamen":if(!b.layer||!q(b.layer))return void c.error("[AngularJS - Openlayers] - You need a valid Stamen layer.");g=new a.source.Stamen({layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageStatic":if(!b.url||!angular.isArray(b.imageSize)||2!==b.imageSize.length)return void c.error("[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.");g=new a.source.ImageStatic({url:b.url,attributions:s(b),imageSize:b.imageSize,projection:f,imageExtent:f.getExtent(),imageLoadFunction:b.imageLoadFunction,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"XYZ":b.url||c.error("[AngularJS - Openlayers] - XYZ Layer needs valid url and params properties"),g=new a.source.XYZ({url:b.url,attributions:s(b),minZoom:b.minZoom,maxZoom:b.maxZoom,wrapX:void 0===b.wrapX?1:b.wrapX})}return g||c.warn('[AngularJS - Openlayers] - No source could be found for type "'+b.type+'"'),g},s=function(b){var c=[];return e(b.attribution)&&c.unshift(new a.Attribution({html:b.attribution})),c},t=function(b){var c=new a.layer.Group;return c.set("name",b),c},u=function(b,c){var d;return angular.forEach(b,function(b){return b instanceof a.layer.Group&&b.get("name")===c?void(d=b):void 0}),d},v=function(a,b){for(var c,d=0;d',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p});if(!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d){if("pixel"===g.view.projection)return void i.setCenter(c.coord);var e=a.proj.transform(d,g.view.projection,c.projection);(e[1]!==c.lat||e[0]!==c.lon)&&p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}}),f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i))}else d=j(c,f),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i))}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)}),e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope();i.getMap().then(function(b){var d=e.getControlClasses,i=d();return a.$on("$destroy",function(){b.removeControl(f)}),h(a.properties)&&h(a.properties.control)?(f=a.properties.control,void b.addControl(f)):void(c.name&&(h(a.properties)&&(g=a.properties),f=new i[c.name](g),b.addControl(f)))})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return e.on("pointerdown",j),e.on("pointerup",j),e.on("pointerdrag",j),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e)}),k(c.properties)?void c.$watch("properties",function(d){if(e.getViewport().removeEventListener("mousemove",d.handleInteraction),e.getViewport().removeEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",d.handleTapInteraction),e.getViewport().removeEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",d.removeAllOverlays),d.handleInteraction=function(b){if(!d.label.show){var f=!1,g=e.getEventPixel(b),i=e.forEachFeatureAtPixel(g,function(a){return a}),j=!1;i===r&&(j=!0,f=!0,k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),!d.onClick||"click"!==b.type&&"touchend"!==b.type||c.$apply(function(){d.onClick.call(r,b,d)}),e.getTarget().style.cursor="pointer"),!f&&p&&(j=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),j&&b.preventDefault()}},d.handleTapInteraction=function(){function a(){c=!0,b&&clearTimeout(b),b=setTimeout(function(){c=!1,b=null},500)}var b,c=!1;return e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",a),function(){c||(d.handleInteraction.apply(null,arguments),a())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||d.onClick)&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q","olHelpers",function(a,b,c){var d=c.obtainEffectiveMapId,e={},f=function(a,b){var c=d(a,b);a[c].resolvedDefer=!0},g=function(a,c){var e,f=d(a,c);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},h=function(a,b){var c,e=d(a,b);return c=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:g(a,b)};this.setMap=function(a,b){var c=g(e,b);c.resolve(a),f(e,b)},this.getMap=function(a){var b=h(e,a);return b.promise}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function x(a,b){var c;if(b?c=a[b]:(b="style",c=a),"style"===b&&a instanceof Function)return a;if(!(c instanceof Object))return c;var d;if("[object Object]"===Object.prototype.toString.call(c)){d={};var e=l[b];if(e&&c instanceof e)return c;Object.getOwnPropertyNames(c).forEach(function(a,f,g){var h=l[a];return e&&h&&h.prototype instanceof l[b]?(console.assert(1===g.length,"Extra parameters for "+b),d=x(c,a),m(d,h)):(d[a]=x(c,a),void("text"!==a&&"string"!=typeof d[a]&&(d[a]=m(d[a],l[a]))))})}else d=c;return m(d,l[b])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"TileVector":return"Vector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");var i="http://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,l=window.devicePixelRatio;l>1&&(i=i.replace(".png","@2x.png")),g=new a.source.XYZ({url:i,attributions:s(b),tilePixelRatio:l>1?2:1,wrapX:"undefined"===b.wrapX?1:b.wrapX});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,attributions:s(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:b.params,wrapX:"undefined"===b.wrapX?1:b.wrapX});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var m={crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:b.params,attributions:s(b),wrapX:"undefined"===b.wrapX?1:b.wrapX};b.url&&(m.url=b.url),b.urls&&(m.urls=b.urls),g=new a.source.TileWMS(m);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var n={projection:f,layer:b.layer,attributions:s(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),wrapX:"undefined"===b.wrapX?1:b.wrapX};e(b.url)&&(n.url=b.url),e(b.urls)&&(n.urls=b.urls),g=new a.source.WMTS(n);break;case"OSM":g=new a.source.OSM({attributions:s(b),wrapX:"undefined"===b.wrapX?1:b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var o={key:b.key,attributions:s(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:"undefined"===b.wrapX?1:b.wrapX};b.maxZoom&&(o.maxZoom=b.maxZoom),g=new a.source.BingMaps(o);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:s(b),layer:b.layer,wrapX:"undefined"===b.wrapX?1:b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var p="http://services.arcgisonline.com/ArcGIS/rest/services/",r=p+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:s(b),url:r,wrapX:"undefined"===b.wrapX?1:b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url,wrapX:"undefined"===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var t=f;e(b.geojson.projection)&&(t=b.geojson.projection);var u=new a.format.GeoJSON,v=u.readFeatures(b.geojson.object,{featureProjection:t});g.addFeatures(v)}break;case"JSONP":if(!b.url)return void c.error("[AngularJS - Openlayers] - You need an url properly configured to add a JSONP layer.");e(b.url)&&(g=new a.source.Vector({format:new a.format.GeoJSON,loader:function(){var a=b.url+"&outputFormat=text/javascript&format_options=callback:JSON_CALLBACK";d.jsonp(a,{cache:b.cache}).success(function(a){g.addFeatures(g.readFeatures(a))}).error(function(a){c(a)})},wrapX:"undefined"===b.wrapX?1:b.wrapX}));break;case"TopoJSON":if(!b.topojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a topojson property to add a TopoJSON layer.");g=b.url?new a.source.Vector({format:new a.format.TopoJSON,url:b.url,wrapX:"undefined"===b.wrapX?1:b.wrapX}):new a.source.Vector(angular.extend(b.topojson,{format:new a.format.TopoJSON,wrapX:"undefined"===b.wrapX?1:b.wrapX}));break;case"TileJSON":g=new a.source.TileJSON({url:b.url,attributions:s(b),crossOrigin:"anonymous",wrapX:"undefined"===b.wrapX?1:b.wrapX});break;case"TileVector":b.url&&b.format||c.error("[AngularJS - Openlayers] - TileVector Layer needs valid url and format properties"),g=new a.source.TileVector({url:b.url,projection:f,attributions:s(b),format:b.format,tileGrid:new a.tilegrid.createXYZ({maxZoom:b.maxZoom||19}),wrapX:"undefined"===b.wrapX?1:b.wrapX});break;case"TileTMS":b.url&&b.tileGrid||c.error("[AngularJS - Openlayers] - TileTMS Layer needs valid url and tileGrid properties"),g=new a.source.TileImage({url:b.url,maxExtent:b.maxExtent,attributions:s(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=a[2];if(0>d||0>e)return"";var f=b.url+c+"/"+d+"/"+e+".png";return f},wrapX:"undefined"===b.wrapX?1:b.wrapX});break;case"TileImage":g=new a.source.TileImage({url:b.url,attributions:s(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=-a[2]-1,f=b.url.replace("{z}",c.toString()).replace("{x}",d.toString()).replace("{y}",e.toString());return f},wrapX:"undefined"===b.wrapX?1:b.wrapX});break;case"KML":var w=b.extractStyles||!1;g=new a.source.Vector({url:b.url,format:new a.format.KML,radius:b.radius,extractStyles:w,wrapX:"undefined"===b.wrapX?1:b.wrapX});break;case"Stamen":if(!b.layer||!q(b.layer))return void c.error("[AngularJS - Openlayers] - You need a valid Stamen layer.");g=new a.source.Stamen({layer:b.layer,wrapX:"undefined"===b.wrapX?1:b.wrapX});break;case"ImageStatic":if(!b.url||!angular.isArray(b.imageSize)||2!==b.imageSize.length)return void c.error("[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.");g=new a.source.ImageStatic({url:b.url,attributions:s(b),imageSize:b.imageSize,projection:f,imageExtent:f.getExtent(),imageLoadFunction:b.imageLoadFunction,wrapX:"undefined"===b.wrapX?1:b.wrapX});break;case"XYZ":b.url||c.error("[AngularJS - Openlayers] - XYZ Layer needs valid url and params properties"),g=new a.source.XYZ({url:b.url,attributions:s(b),minZoom:b.minZoom,maxZoom:b.maxZoom,wrapX:"undefined"===b.wrapX?1:b.wrapX})}return g||c.warn('[AngularJS - Openlayers] - No source could be found for type "'+b.type+'"'),g},s=function(b){var c=[];return e(b.attribution)&&c.unshift(new a.Attribution({html:b.attribution})),c},t=function(b){var c=new a.layer.Group;return c.set("name",b),c},u=function(b,c){var d;return angular.forEach(b,function(b){return b instanceof a.layer.Group&&b.get("name")===c?void(d=b):void 0}),d},v=function(a,b){for(var c,d=0;d',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p});if(!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d){if("pixel"===g.view.projection)return void i.setCenter(c.coord);var e=a.proj.transform(d,g.view.projection,c.projection);(e[1]!==c.lat||e[0]!==c.lon)&&p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}}),f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i))}else d=j(c,f),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i))}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)}),e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope();i.getMap().then(function(b){var d=e.getControlClasses,i=d();return a.$on("$destroy",function(){b.removeControl(f)}),h(a.properties)&&h(a.properties.control)?(f=a.properties.control,void b.addControl(f)):void(c.name&&(h(a.properties)&&(g=a.properties),f=new i[c.name](g),b.addControl(f)))})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return e.on("pointerdown",j),e.on("pointerup",j),e.on("pointerdrag",j),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e)}),k(c.properties)?void c.$watch("properties",function(d){if(e.getViewport().removeEventListener("mousemove",d.handleInteraction),e.getViewport().removeEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",d.handleTapInteraction),e.getViewport().removeEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",d.removeAllOverlays),d.handleInteraction=function(b){if(!d.label.show){var f=!1,g=e.getEventPixel(b),i=e.forEachFeatureAtPixel(g,function(a){return a}),j=!1;i===r&&(j=!0,f=!0,k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),!d.onClick||"click"!==b.type&&"touchend"!==b.type||c.$apply(function(){d.onClick.call(r,b,d)}),e.getTarget().style.cursor="pointer"),!f&&p&&(j=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),j&&b.preventDefault()}},d.handleTapInteraction=function(){function a(){c=!0,b&&clearTimeout(b),b=setTimeout(function(){c=!1,b=null},500)}var b,c=!1;return e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",a),function(){c||(d.handleInteraction.apply(null,arguments),a())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||d.onClick)&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q","olHelpers",function(a,b,c){var d=c.obtainEffectiveMapId,e={},f=function(a,b){var c=d(a,b);a[c].resolvedDefer=!0},g=function(a,c){var e,f=d(a,c);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},h=function(a,b){var c,e=d(a,b);return c=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:g(a,b)};this.setMap=function(a,b){var c=g(e,b);c.resolve(a),f(e,b)},this.getMap=function(a){var b=h(e,a);return b.promise}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function x(a,b){var c;if(b?c=a[b]:(b="style",c=a),"style"===b&&a instanceof Function)return a;if(!(c instanceof Object))return c;var d;if("[object Object]"===Object.prototype.toString.call(c)){d={};var e=l[b];if(e&&c instanceof e)return c;Object.getOwnPropertyNames(c).forEach(function(a,f,g){var h=l[a];return e&&h&&h.prototype instanceof l[b]?(console.assert(1===g.length,"Extra parameters for "+b),d=x(c,a),m(d,h)):(d[a]=x(c,a),void("text"!==a&&"string"!=typeof d[a]&&(d[a]=m(d[a],l[a]))))})}else d=c;return m(d,l[b])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"TileVector":return"Vector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");var i="http://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,l=window.devicePixelRatio;l>1&&(i=i.replace(".png","@2x.png")),g=new a.source.XYZ({url:i,attributions:s(b),tilePixelRatio:l>1?2:1,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,attributions:s(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:b.params,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var m={crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:b.params,attributions:s(b),wrapX:void 0===b.wrapX?1:b.wrapX};b.url&&(m.url=b.url),b.urls&&(m.urls=b.urls),g=new a.source.TileWMS(m);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var n={projection:f,layer:b.layer,attributions:s(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),wrapX:void 0===b.wrapX?1:b.wrapX};e(b.url)&&(n.url=b.url),e(b.urls)&&(n.urls=b.urls),g=new a.source.WMTS(n);break;case"OSM":g=new a.source.OSM({attributions:s(b),wrapX:void 0===b.wrapX?1:b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var o={key:b.key,attributions:s(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX?1:b.wrapX};b.maxZoom&&(o.maxZoom=b.maxZoom),g=new a.source.BingMaps(o);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:s(b),layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var p="http://services.arcgisonline.com/ArcGIS/rest/services/",r=p+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:s(b),url:r,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var t=f;e(b.geojson.projection)&&(t=b.geojson.projection);var u=new a.format.GeoJSON,v=u.readFeatures(b.geojson.object,{featureProjection:t});g.addFeatures(v)}break;case"JSONP":if(!b.url)return void c.error("[AngularJS - Openlayers] - You need an url properly configured to add a JSONP layer.");e(b.url)&&(g=new a.source.Vector({format:new a.format.GeoJSON,loader:function(){var a=b.url+"&outputFormat=text/javascript&format_options=callback:JSON_CALLBACK";d.jsonp(a,{cache:b.cache}).success(function(a){g.addFeatures(g.readFeatures(a))}).error(function(a){c(a)})},wrapX:void 0===b.wrapX?1:b.wrapX}));break;case"TopoJSON":if(!b.topojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a topojson property to add a TopoJSON layer.");g=b.url?new a.source.Vector({format:new a.format.TopoJSON,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX}):new a.source.Vector(angular.extend(b.topojson,{format:new a.format.TopoJSON,wrapX:void 0===b.wrapX?1:b.wrapX}));break;case"TileJSON":g=new a.source.TileJSON({url:b.url,attributions:s(b),crossOrigin:"anonymous",wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileVector":b.url&&b.format||c.error("[AngularJS - Openlayers] - TileVector Layer needs valid url and format properties"),g=new a.source.TileVector({url:b.url,projection:f,attributions:s(b),format:b.format,tileGrid:new a.tilegrid.createXYZ({maxZoom:b.maxZoom||19}),wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileTMS":b.url&&b.tileGrid||c.error("[AngularJS - Openlayers] - TileTMS Layer needs valid url and tileGrid properties"),g=new a.source.TileImage({url:b.url,maxExtent:b.maxExtent,attributions:s(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=a[2];if(0>d||0>e)return"";var f=b.url+c+"/"+d+"/"+e+".png";return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileImage":g=new a.source.TileImage({url:b.url,attributions:s(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=-a[2]-1,f=b.url.replace("{z}",c.toString()).replace("{x}",d.toString()).replace("{y}",e.toString());return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"KML":var w=b.extractStyles||!1;g=new a.source.Vector({url:b.url,format:new a.format.KML,radius:b.radius,extractStyles:w,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"Stamen":if(!b.layer||!q(b.layer))return void c.error("[AngularJS - Openlayers] - You need a valid Stamen layer.");g=new a.source.Stamen({layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageStatic":if(!b.url||!angular.isArray(b.imageSize)||2!==b.imageSize.length)return void c.error("[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.");g=new a.source.ImageStatic({url:b.url,attributions:s(b),imageSize:b.imageSize,projection:f,imageExtent:f.getExtent(),imageLoadFunction:b.imageLoadFunction,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"XYZ":b.url||c.error("[AngularJS - Openlayers] - XYZ Layer needs valid url and params properties"),g=new a.source.XYZ({url:b.url,attributions:s(b),minZoom:b.minZoom,maxZoom:b.maxZoom,wrapX:void 0===b.wrapX?1:b.wrapX})}return g||c.warn('[AngularJS - Openlayers] - No source could be found for type "'+b.type+'"'),g},s=function(b){var c=[];return e(b.attribution)&&c.unshift(new a.Attribution({html:b.attribution})),c},t=function(b){var c=new a.layer.Group;return c.set("name",b),c},u=function(b,c){var d;return angular.forEach(b,function(b){return b instanceof a.layer.Group&&b.get("name")===c?void(d=b):void 0}),d},v=function(a,b){for(var c,d=0;d 1 ? 2 : 1, - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }); break; case 'ImageWMS': @@ -1353,7 +1353,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ attributions: createAttribution(source), crossOrigin: (typeof source.crossOrigin === 'undefined') ? 'anonymous' : source.crossOrigin, params: source.params, - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }); break; @@ -1367,7 +1367,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ crossOrigin: (typeof source.crossOrigin === 'undefined') ? 'anonymous' : source.crossOrigin, params: source.params, attributions: createAttribution(source), - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }; if (source.url) { @@ -1400,7 +1400,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ resolutions: source.tileGrid.resolutions, matrixIds: source.tileGrid.matrixIds }), - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }; if (isDefined(source.url)) { @@ -1417,7 +1417,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ case 'OSM': oSource = new ol.source.OSM({ attributions: createAttribution(source), - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }); if (source.url) { @@ -1436,7 +1436,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ attributions: createAttribution(source), imagerySet: source.imagerySet ? source.imagerySet : bingImagerySets[0], culture: source.culture, - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }; if (source.maxZoom) { @@ -1455,7 +1455,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ oSource = new ol.source.MapQuest({ attributions: createAttribution(source), layer: source.layer, - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }); break; @@ -1472,7 +1472,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ oSource = new ol.source.XYZ({ attributions: createAttribution(source), url: _url, - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }); break; @@ -1488,7 +1488,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ oSource = new ol.source.Vector({ format: new ol.format.GeoJSON(), url: source.url, - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }); } else { oSource = new ol.source.Vector(); @@ -1524,7 +1524,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ $log(response); }); }, - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }); } break; @@ -1539,12 +1539,12 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ oSource = new ol.source.Vector({ format: new ol.format.TopoJSON(), url: source.url, - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }); } else { oSource = new ol.source.Vector(angular.extend(source.topojson, { format: new ol.format.TopoJSON(), - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX })); } break; @@ -1553,7 +1553,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ url: source.url, attributions: createAttribution(source), crossOrigin: 'anonymous', - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }); break; @@ -1569,7 +1569,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ tileGrid: new ol.tilegrid.createXYZ({ maxZoom: source.maxZoom || 19 }), - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }); break; @@ -1599,7 +1599,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ return url; }, - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }); break; case 'TileImage': @@ -1620,7 +1620,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ .replace('{y}', y.toString()); return url; }, - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }); break; case 'KML': @@ -1630,7 +1630,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ format: new ol.format.KML(), radius: source.radius, extractStyles: extractStyles, - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }); break; case 'Stamen': @@ -1640,7 +1640,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ } oSource = new ol.source.Stamen({ layer: source.layer, - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }); break; case 'ImageStatic': @@ -1656,7 +1656,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ projection: projection, imageExtent: projection.getExtent(), imageLoadFunction: source.imageLoadFunction, - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }); break; case 'XYZ': @@ -1668,7 +1668,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ attributions: createAttribution(source), minZoom: source.minZoom, maxZoom: source.maxZoom, - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }); break; } diff --git a/src/services/olHelpers.js b/src/services/olHelpers.js index a7767a80..f499c4a9 100644 --- a/src/services/olHelpers.js +++ b/src/services/olHelpers.js @@ -208,7 +208,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ url: url, attributions: createAttribution(source), tilePixelRatio: pixelRatio > 1 ? 2 : 1, - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }); break; case 'ImageWMS': @@ -221,7 +221,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ attributions: createAttribution(source), crossOrigin: (typeof source.crossOrigin === 'undefined') ? 'anonymous' : source.crossOrigin, params: source.params, - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }); break; @@ -235,7 +235,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ crossOrigin: (typeof source.crossOrigin === 'undefined') ? 'anonymous' : source.crossOrigin, params: source.params, attributions: createAttribution(source), - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }; if (source.url) { @@ -268,7 +268,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ resolutions: source.tileGrid.resolutions, matrixIds: source.tileGrid.matrixIds }), - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }; if (isDefined(source.url)) { @@ -285,7 +285,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ case 'OSM': oSource = new ol.source.OSM({ attributions: createAttribution(source), - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }); if (source.url) { @@ -304,7 +304,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ attributions: createAttribution(source), imagerySet: source.imagerySet ? source.imagerySet : bingImagerySets[0], culture: source.culture, - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }; if (source.maxZoom) { @@ -323,7 +323,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ oSource = new ol.source.MapQuest({ attributions: createAttribution(source), layer: source.layer, - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }); break; @@ -340,7 +340,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ oSource = new ol.source.XYZ({ attributions: createAttribution(source), url: _url, - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }); break; @@ -356,7 +356,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ oSource = new ol.source.Vector({ format: new ol.format.GeoJSON(), url: source.url, - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }); } else { oSource = new ol.source.Vector(); @@ -392,7 +392,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ $log(response); }); }, - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }); } break; @@ -407,12 +407,12 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ oSource = new ol.source.Vector({ format: new ol.format.TopoJSON(), url: source.url, - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }); } else { oSource = new ol.source.Vector(angular.extend(source.topojson, { format: new ol.format.TopoJSON(), - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX })); } break; @@ -421,7 +421,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ url: source.url, attributions: createAttribution(source), crossOrigin: 'anonymous', - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }); break; @@ -437,7 +437,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ tileGrid: new ol.tilegrid.createXYZ({ maxZoom: source.maxZoom || 19 }), - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }); break; @@ -467,7 +467,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ return url; }, - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }); break; case 'TileImage': @@ -488,7 +488,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ .replace('{y}', y.toString()); return url; }, - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }); break; case 'KML': @@ -498,7 +498,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ format: new ol.format.KML(), radius: source.radius, extractStyles: extractStyles, - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }); break; case 'Stamen': @@ -508,7 +508,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ } oSource = new ol.source.Stamen({ layer: source.layer, - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }); break; case 'ImageStatic': @@ -524,7 +524,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ projection: projection, imageExtent: projection.getExtent(), imageLoadFunction: source.imageLoadFunction, - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }); break; case 'XYZ': @@ -536,7 +536,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ attributions: createAttribution(source), minZoom: source.minZoom, maxZoom: source.maxZoom, - wrapX: (source.wrapX === 'undefined') ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }); break; } From 994da429059feb247f5f8dde646a021b393c81dc Mon Sep 17 00:00:00 2001 From: Tirumala Dilip Kumar Date: Fri, 6 Nov 2015 18:38:27 +0530 Subject: [PATCH 08/53] dist/angular opne layers css file --- dist/angular-openlayers-directive.css | 58 +++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 dist/angular-openlayers-directive.css diff --git a/dist/angular-openlayers-directive.css b/dist/angular-openlayers-directive.css new file mode 100644 index 00000000..fd9933e0 --- /dev/null +++ b/dist/angular-openlayers-directive.css @@ -0,0 +1,58 @@ +.popup-label { + background-color: #fff; + border: 2px #444 solid; + border-radius: 7px; + -webkit-box-shadow: 4px 4px 5px 0px rgba(50, 50, 50, 0.75); + -moz-box-shadow: 4px 4px 5px 0px rgba(50, 50, 50, 0.75); + box-shadow: 4px 4px 5px 0px rgba(50, 50, 50, 0.75); + color: #111; + font: 12px/20px "Helvetica Neue", Arial, Helvetica, sans-serif; + font-weight: bold; + padding: 3px 6px; + position: absolute; + white-space: nowrap; + top: -35px; + left: 20px; + display: none; +} + +.popup-label img { + vertical-align: middle; +} + +.popup-label.marker:before { + border-top: 6px solid transparent; + border-bottom: 6px solid transparent; + content: ""; + border-right: 6px solid black; + border-right-color: inherit; + position: absolute; + left: -8px; + top: 5px; +} + +.angular-openlayers-map:-moz-full-screen { + height: 100%; +} +.angular-openlayers-map:-webkit-full-screen { + height: 100%; +} +.angular-openlayers-map:full-screen { + height: 100%; +} + +.angular-openlayers-map:not(-moz-full-screen) { + height: 400px; +} + +.angular-openlayers-map:not(-webkit-full-screen) { + height: 400px; +} + +.angular-openlayers-map:not(full-screen) { + height: 400px; +} +.ol-full-screen { + position: absolute; + top: 50%; +} From 5414ff6828ff908b86401c5dd401421c0841183d Mon Sep 17 00:00:00 2001 From: Clay Anderson Date: Wed, 16 Dec 2015 16:09:08 -0700 Subject: [PATCH 09/53] Include version --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 4fcacac7..35f115b1 100644 --- a/package.json +++ b/package.json @@ -60,5 +60,6 @@ "postpublish": "publish-latest", "semantic-release": "semantic-release pre && npm publish && semantic-release post" }, - "main": "dist/angular-openlayers-directive" + "main": "dist/angular-openlayers-directive", + "version": "0.0.0" } From 4fc3c3d7c3debbb9a901779b09d6ec713f0c23d1 Mon Sep 17 00:00:00 2001 From: Clay Anderson Date: Mon, 4 Jan 2016 10:32:58 -0700 Subject: [PATCH 10/53] Added dist files --- dist/angular-openlayers-directive.css | 58 + dist/angular-openlayers-directive.js | 2258 +++++++++++++++++ ...ular-openlayers-directive.min.no-header.js | 3 + dist/angular-openlayers-directive.pre.js | 2258 +++++++++++++++++ node_modules/.bin/grunt-open | 15 + 5 files changed, 4592 insertions(+) create mode 100644 dist/angular-openlayers-directive.css create mode 100644 dist/angular-openlayers-directive.js create mode 100644 dist/angular-openlayers-directive.min.no-header.js create mode 100644 dist/angular-openlayers-directive.pre.js create mode 100644 node_modules/.bin/grunt-open diff --git a/dist/angular-openlayers-directive.css b/dist/angular-openlayers-directive.css new file mode 100644 index 00000000..fd9933e0 --- /dev/null +++ b/dist/angular-openlayers-directive.css @@ -0,0 +1,58 @@ +.popup-label { + background-color: #fff; + border: 2px #444 solid; + border-radius: 7px; + -webkit-box-shadow: 4px 4px 5px 0px rgba(50, 50, 50, 0.75); + -moz-box-shadow: 4px 4px 5px 0px rgba(50, 50, 50, 0.75); + box-shadow: 4px 4px 5px 0px rgba(50, 50, 50, 0.75); + color: #111; + font: 12px/20px "Helvetica Neue", Arial, Helvetica, sans-serif; + font-weight: bold; + padding: 3px 6px; + position: absolute; + white-space: nowrap; + top: -35px; + left: 20px; + display: none; +} + +.popup-label img { + vertical-align: middle; +} + +.popup-label.marker:before { + border-top: 6px solid transparent; + border-bottom: 6px solid transparent; + content: ""; + border-right: 6px solid black; + border-right-color: inherit; + position: absolute; + left: -8px; + top: 5px; +} + +.angular-openlayers-map:-moz-full-screen { + height: 100%; +} +.angular-openlayers-map:-webkit-full-screen { + height: 100%; +} +.angular-openlayers-map:full-screen { + height: 100%; +} + +.angular-openlayers-map:not(-moz-full-screen) { + height: 400px; +} + +.angular-openlayers-map:not(-webkit-full-screen) { + height: 400px; +} + +.angular-openlayers-map:not(full-screen) { + height: 400px; +} +.ol-full-screen { + position: absolute; + top: 50%; +} diff --git a/dist/angular-openlayers-directive.js b/dist/angular-openlayers-directive.js new file mode 100644 index 00000000..12e1f154 --- /dev/null +++ b/dist/angular-openlayers-directive.js @@ -0,0 +1,2258 @@ +(function (root, factory) { + if (typeof require === 'function' && typeof exports === 'object') { + // CommonJS + var ol = require('openlayers'); + exports.angularOpenlayersDirective = factory(ol); + } else if (typeof define === 'function' && define.amd) { + // AMD. + define(['ol'], function (ol) { + return root.angularOpenlayersDirective = factory(ol); + }); + } else { + // Browser globals + root.angularOpenlayersDirective = factory(root.ol); + } +}(this, function (ol) { +angular.module('openlayers-directive', ['ngSanitize']).directive('openlayers', ["$log", "$q", "$compile", "olHelpers", "olMapDefaults", "olData", function($log, $q, $compile, olHelpers, + olMapDefaults, olData) { + return { + restrict: 'EA', + transclude: true, + replace: true, + scope: { + center: '=olCenter', + defaults: '=olDefaults', + view: '=olView', + events: '=olEvents' + }, + template: '
', + controller: ["$scope", function($scope) { + var _map = $q.defer(); + $scope.getMap = function() { + return _map.promise; + }; + + $scope.setMap = function(map) { + _map.resolve(map); + }; + + this.getOpenlayersScope = function() { + return $scope; + }; + }], + link: function(scope, element, attrs) { + var isDefined = olHelpers.isDefined; + var createLayer = olHelpers.createLayer; + var setMapEvents = olHelpers.setMapEvents; + var setViewEvents = olHelpers.setViewEvents; + var createView = olHelpers.createView; + var defaults = olMapDefaults.setDefaults(scope); + + // Set width and height if they are defined + if (isDefined(attrs.width)) { + if (isNaN(attrs.width)) { + element.css('width', attrs.width); + } else { + element.css('width', attrs.width + 'px'); + } + } + + if (isDefined(attrs.height)) { + if (isNaN(attrs.height)) { + element.css('height', attrs.height); + } else { + element.css('height', attrs.height + 'px'); + } + } + + if (isDefined(attrs.lat)) { + defaults.center.lat = parseFloat(attrs.lat); + } + + if (isDefined(attrs.lon)) { + defaults.center.lon = parseFloat(attrs.lon); + } + + if (isDefined(attrs.zoom)) { + defaults.center.zoom = parseFloat(attrs.zoom); + } + + var controls = ol.control.defaults(defaults.controls); + var interactions = ol.interaction.defaults(defaults.interactions); + var view = createView(defaults.view); + + // Create the Openlayers Map Object with the options + var map = new ol.Map({ + target: element[0], + controls: controls, + interactions: interactions, + renderer: defaults.renderer, + view: view + }); + + // If no layer is defined, set the default tileLayer + if (!attrs.customLayers) { + var l = { + type: 'Tile', + source: { + type: 'OSM' + } + }; + var layer = createLayer(l, view.getProjection(), 'default'); + map.addLayer(layer); + map.set('default', true); + } + + if (!isDefined(attrs.olCenter)) { + var c = ol.proj.transform([defaults.center.lon, + defaults.center.lat + ], + defaults.center.projection, view.getProjection() + ); + view.setCenter(c); + view.setZoom(defaults.center.zoom); + } + + // Set the Default events for the map + setMapEvents(defaults.events, map, scope); + + //Set the Default events for the map view + setViewEvents(defaults.events, map, scope); + + // Resolve the map object to the promises + scope.setMap(map); + olData.setMap(map, attrs.id); + + } + }; + }]); + +angular.module('openlayers-directive').directive('olCenter', ["$log", "$location", "olMapDefaults", "olHelpers", function($log, $location, olMapDefaults, olHelpers) { + + return { + restrict: 'A', + scope: false, + replace: false, + require: 'openlayers', + + link: function(scope, element, attrs, controller) { + var safeApply = olHelpers.safeApply; + var isValidCenter = olHelpers.isValidCenter; + var isDefined = olHelpers.isDefined; + var isArray = olHelpers.isArray; + var isNumber = olHelpers.isNumber; + var isSameCenterOnMap = olHelpers.isSameCenterOnMap; + var setCenter = olHelpers.setCenter; + var setZoom = olHelpers.setZoom; + var olScope = controller.getOpenlayersScope(); + + olScope.getMap().then(function(map) { + var defaults = olMapDefaults.getDefaults(olScope); + var view = map.getView(); + var center = olScope.center; + + if (attrs.olCenter.search('-') !== -1) { + $log.error('[AngularJS - Openlayers] The "center" variable can\'t use ' + + 'a "-" on his key name: "' + attrs.center + '".'); + setCenter(view, defaults.view.projection, defaults.center, map); + return; + } + + if (!isDefined(center)) { + center = {}; + } + + if (!isValidCenter(center)) { + $log.warn('[AngularJS - Openlayers] invalid \'center\''); + center.lat = defaults.center.lat; + center.lon = defaults.center.lon; + center.zoom = defaults.center.zoom; + center.projection = defaults.center.projection; + } + + if (!center.projection) { + if (defaults.view.projection !== 'pixel') { + center.projection = defaults.center.projection; + } else { + center.projection = 'pixel'; + } + } + + if (!isNumber(center.zoom)) { + center.zoom = 1; + } + + setCenter(view, defaults.view.projection, center, map); + view.setZoom(center.zoom); + + var centerUrlHash; + if (center.centerUrlHash === true) { + var extractCenterFromUrl = function() { + var search = $location.search(); + var centerParam; + if (isDefined(search.c)) { + var cParam = search.c.split(':'); + if (cParam.length === 3) { + centerParam = { + lat: parseFloat(cParam[0]), + lon: parseFloat(cParam[1]), + zoom: parseInt(cParam[2], 10) + }; + } + } + return centerParam; + }; + centerUrlHash = extractCenterFromUrl(); + + olScope.$on('$locationChangeSuccess', function() { + var urlCenter = extractCenterFromUrl(); + if (urlCenter && !isSameCenterOnMap(urlCenter, map)) { + safeApply(olScope, function(scope) { + scope.center.lat = urlCenter.lat; + scope.center.lon = urlCenter.lon; + scope.center.zoom = urlCenter.zoom; + }); + } + }); + } + + var geolocation; + olScope.$watchCollection('center', function(center) { + + if (!center) { + return; + } + + if (!center.projection) { + center.projection = defaults.center.projection; + } + + if (center.autodiscover) { + if (!geolocation) { + geolocation = new ol.Geolocation({ + projection: ol.proj.get(center.projection) + }); + + geolocation.on('change', function() { + if (center.autodiscover) { + var location = geolocation.getPosition(); + safeApply(olScope, function(scope) { + scope.center.lat = location[1]; + scope.center.lon = location[0]; + scope.center.zoom = 12; + scope.center.autodiscover = false; + geolocation.setTracking(false); + }); + } + }); + } + geolocation.setTracking(true); + return; + } + + if (!isValidCenter(center)) { + $log.warn('[AngularJS - Openlayers] invalid \'center\''); + center = defaults.center; + } + + var viewCenter = view.getCenter(); + if (viewCenter) { + if (defaults.view.projection === 'pixel') { + view.setCenter(center.coord); + return; + } + var actualCenter = ol.proj.transform(viewCenter, defaults.view.projection, center.projection); + if (!(actualCenter[1] === center.lat && actualCenter[0] === center.lon)) { + setCenter(view, defaults.view.projection, center, map); + } + } + + if (view.getZoom() !== center.zoom) { + setZoom(view, center.zoom, map); + } + }); + + map.on('moveend', function() { + safeApply(olScope, function(scope) { + + if (!isDefined(scope.center)) { + return; + } + + var center = map.getView().getCenter(); + scope.center.zoom = view.getZoom(); + + if (defaults.view.projection === 'pixel') { + scope.center.coord = center; + return; + } + + if (scope.center) { + var proj = ol.proj.transform(center, defaults.view.projection, scope.center.projection); + scope.center.lat = proj[1]; + scope.center.lon = proj[0]; + + // Notify the controller about a change in the center position + olHelpers.notifyCenterUrlHashChanged(olScope, scope.center, $location.search()); + + // Calculate the bounds if needed + if (isArray(scope.center.bounds)) { + var extent = view.calculateExtent(map.getSize()); + var centerProjection = scope.center.projection; + var viewProjection = defaults.view.projection; + scope.center.bounds = ol.proj.transformExtent(extent, viewProjection, centerProjection); + } + } + }); + }); + + }); + } + }; +}]); + +angular.module('openlayers-directive').directive('olLayer', ["$log", "$q", "olMapDefaults", "olHelpers", function($log, $q, olMapDefaults, olHelpers) { + + return { + restrict: 'E', + scope: { + properties: '=olLayerProperties' + }, + replace: false, + require: '^openlayers', + link: function(scope, element, attrs, controller) { + var isDefined = olHelpers.isDefined; + var equals = olHelpers.equals; + var olScope = controller.getOpenlayersScope(); + var createLayer = olHelpers.createLayer; + var setVectorLayerEvents = olHelpers.setVectorLayerEvents; + var detectLayerType = olHelpers.detectLayerType; + var createStyle = olHelpers.createStyle; + var isBoolean = olHelpers.isBoolean; + var addLayerBeforeMarkers = olHelpers.addLayerBeforeMarkers; + var isNumber = olHelpers.isNumber; + var insertLayer = olHelpers.insertLayer; + var removeLayer = olHelpers.removeLayer; + var addLayerToGroup = olHelpers.addLayerToGroup; + var removeLayerFromGroup = olHelpers.removeLayerFromGroup; + var getGroup = olHelpers.getGroup; + + olScope.getMap().then(function(map) { + var projection = map.getView().getProjection(); + var defaults = olMapDefaults.setDefaults(olScope); + var layerCollection = map.getLayers(); + var olLayer; + + scope.$on('$destroy', function() { + if (scope.properties.group) { + removeLayerFromGroup(layerCollection, olLayer, scope.properties.group); + } else { + removeLayer(layerCollection, olLayer.index); + } + + map.removeLayer(olLayer); + }); + + if (!isDefined(scope.properties)) { + if (isDefined(attrs.sourceType) && isDefined(attrs.sourceUrl)) { + var l = { + source: { + url: attrs.sourceUrl, + type: attrs.sourceType + } + }; + + olLayer = createLayer(l, projection, attrs.layerName); + if (detectLayerType(l) === 'Vector') { + setVectorLayerEvents(defaults.events, map, scope, attrs.name); + } + addLayerBeforeMarkers(layerCollection, olLayer); + } + return; + } + + scope.$watch('properties', function(properties, oldProperties) { + if (!isDefined(properties.source) || !isDefined(properties.source.type)) { + return; + } + + if (!isDefined(properties.visible)) { + properties.visible = true; + return; + } + + if (!isDefined(properties.opacity)) { + properties.opacity = 1; + return; + } + + var style; + var group; + var collection; + if (!isDefined(olLayer)) { + olLayer = createLayer(properties, projection); + if (isDefined(properties.group)) { + addLayerToGroup(layerCollection, olLayer, properties.group); + } else if (isDefined(properties.index)) { + insertLayer(layerCollection, properties.index, olLayer); + } else { + addLayerBeforeMarkers(layerCollection, olLayer); + } + + if (detectLayerType(properties) === 'Vector') { + setVectorLayerEvents(defaults.events, map, scope, properties.name); + } + + if (isBoolean(properties.visible)) { + olLayer.setVisible(properties.visible); + } + + if (properties.opacity) { + olLayer.setOpacity(properties.opacity); + } + + if (angular.isArray(properties.extent)) { + olLayer.setExtent(properties.extent); + } + + if (properties.style) { + if (!angular.isFunction(properties.style)) { + style = createStyle(properties.style); + } else { + style = properties.style; + } + // not every layer has a setStyle method + if (olLayer.setStyle && angular.isFunction(olLayer.setStyle)) { + olLayer.setStyle(style); + } + } + + if (properties.minResolution) { + olLayer.setMinResolution(properties.minResolution); + } + + if (properties.maxResolution) { + olLayer.setMaxResolution(properties.maxResolution); + } + + } else { + var isNewLayer = (function(olLayer) { + // this function can be used to verify whether a new layer instance has + // been created. This is needed in order to re-assign styles, opacity + // etc... + return function(layer) { + return layer !== olLayer; + }; + })(olLayer); + + // set source properties + if (isDefined(oldProperties) && !equals(properties.source, oldProperties.source)) { + var idx = olLayer.index; + collection = layerCollection; + group = olLayer.get('group'); + + if (group) { + collection = getGroup(layerCollection, group).getLayers(); + } + + collection.removeAt(idx); + + olLayer = createLayer(properties, projection); + olLayer.set('group', group); + + if (isDefined(olLayer)) { + insertLayer(collection, idx, olLayer); + + if (detectLayerType(properties) === 'Vector') { + setVectorLayerEvents(defaults.events, map, scope, properties.name); + } + } + } + + // set opacity + if (isDefined(oldProperties) && + properties.opacity !== oldProperties.opacity || isNewLayer(olLayer)) { + if (isNumber(properties.opacity) || isNumber(parseFloat(properties.opacity))) { + olLayer.setOpacity(properties.opacity); + } + } + + // set index + if (isDefined(properties.index) && properties.index !== olLayer.index) { + collection = layerCollection; + group = olLayer.get('group'); + + if (group) { + collection = getGroup(layerCollection, group).getLayers(); + } + + removeLayer(collection, olLayer.index); + insertLayer(collection, properties.index, olLayer); + } + + // set group + if (isDefined(properties.group) && properties.group !== oldProperties.group) { + removeLayerFromGroup(layerCollection, olLayer, oldProperties.group); + addLayerToGroup(layerCollection, olLayer, properties.group); + } + + // set visibility + if (isDefined(oldProperties) && + isBoolean(properties.visible) && + properties.visible !== oldProperties.visible || isNewLayer(olLayer)) { + olLayer.setVisible(properties.visible); + } + + // set style + if (isDefined(properties.style) && + !equals(properties.style, oldProperties.style) || isNewLayer(olLayer)) { + if (!angular.isFunction(properties.style)) { + style = createStyle(properties.style); + } else { + style = properties.style; + } + // not every layer has a setStyle method + if (olLayer.setStyle && angular.isFunction(olLayer.setStyle)) { + olLayer.setStyle(style); + } + } + + //set min resolution + if (!equals(properties.minResolution, oldProperties.minResolution) || isNewLayer(olLayer)) { + if (isDefined(properties.minResolution)) { + olLayer.setMinResolution(properties.minResolution); + } + } + + //set max resolution + if (!equals(properties.maxResolution, oldProperties.maxResolution) || isNewLayer(olLayer)) { + if (isDefined(properties.maxResolution)) { + olLayer.setMaxResolution(properties.maxResolution); + } + } + } + }, true); + }); + } + }; +}]); + +angular.module('openlayers-directive').directive('olPath', ["$log", "$q", "olMapDefaults", "olHelpers", function($log, $q, olMapDefaults, olHelpers) { + + return { + restrict: 'E', + scope: { + properties: '=olGeomProperties' + }, + require: '^openlayers', + replace: true, + template: '', + + link: function(scope, element, attrs, controller) { + var isDefined = olHelpers.isDefined; + var createFeature = olHelpers.createFeature; + var createOverlay = olHelpers.createOverlay; + var createVectorLayer = olHelpers.createVectorLayer; + var insertLayer = olHelpers.insertLayer; + var removeLayer = olHelpers.removeLayer; + var olScope = controller.getOpenlayersScope(); + + olScope.getMap().then(function(map) { + var mapDefaults = olMapDefaults.getDefaults(olScope); + var viewProjection = mapDefaults.view.projection; + + var layer = createVectorLayer(); + var layerCollection = map.getLayers(); + + insertLayer(layerCollection, layerCollection.getLength(), layer); + + scope.$on('$destroy', function() { + removeLayer(layerCollection, layer.index); + }); + + if (isDefined(attrs.coords)) { + var proj = attrs.proj || 'EPSG:4326'; + var coords = JSON.parse(attrs.coords); + var data = { + type: 'Polygon', + coords: coords, + projection: proj, + style: mapDefaults.styles.path + }; + var feature = createFeature(data, viewProjection); + layer.getSource().addFeature(feature); + + if (attrs.message) { + scope.message = attrs.message; + var extent = feature.getGeometry().getExtent(); + var label = createOverlay(element, extent); + map.addOverlay(label); + } + return; + } + }); + } + }; +}]); + +angular.module('openlayers-directive').directive('olView', ["$log", "$q", "olData", "olMapDefaults", "olHelpers", function($log, $q, olData, olMapDefaults, olHelpers) { + return { + restrict: 'A', + scope: false, + replace: false, + require: 'openlayers', + link: function(scope, element, attrs, controller) { + var olScope = controller.getOpenlayersScope(); + var isNumber = olHelpers.isNumber; + var safeApply = olHelpers.safeApply; + var createView = olHelpers.createView; + + olScope.getMap().then(function(map) { + var defaults = olMapDefaults.getDefaults(olScope); + var view = olScope.view; + + if (!view.projection) { + view.projection = defaults.view.projection; + } + + if (!view.maxZoom) { + view.maxZoom = defaults.view.maxZoom; + } + + if (!view.minZoom) { + view.minZoom = defaults.view.minZoom; + } + + if (!view.rotation) { + view.rotation = defaults.view.rotation; + } + + var mapView = createView(view); + map.setView(mapView); + + olScope.$watchCollection('view', function(view) { + if (isNumber(view.rotation)) { + mapView.setRotation(view.rotation); + } + }); + + mapView.on('change:rotation', function() { + safeApply(olScope, function(scope) { + scope.view.rotation = map.getView().getRotation(); + }); + }); + + }); + } + }; +}]); + +angular.module('openlayers-directive').directive('olControl', ["$log", "$q", "olData", "olMapDefaults", "olHelpers", function($log, $q, olData, olMapDefaults, olHelpers) { + + return { + restrict: 'E', + scope: { + properties: '=olControlProperties' + }, + replace: false, + require: '^openlayers', + link: function(scope, element, attrs, controller) { + var isDefined = olHelpers.isDefined; + var olScope = controller.getOpenlayersScope(); + var olControl; + var olControlOps; + + olScope.getMap().then(function(map) { + var getControlClasses = olHelpers.getControlClasses; + var controlClasses = getControlClasses(); + + scope.$on('$destroy', function() { + map.removeControl(olControl); + }); + + if (!isDefined(scope.properties) || !isDefined(scope.properties.control)) { + if (attrs.name) { + if (isDefined(scope.properties)) { + olControlOps = scope.properties; + } + olControl = new controlClasses[attrs.name](olControlOps); + map.addControl(olControl); + } + return; + } + + olControl = scope.properties.control; + map.addControl(olControl); + }); + } + }; +}]); + +angular.module('openlayers-directive').directive('olMarker', ["$log", "$q", "olMapDefaults", "olHelpers", function($log, $q, olMapDefaults, olHelpers) { + + var getMarkerDefaults = function() { + return { + projection: 'EPSG:4326', + lat: 0, + lon: 0, + coord: [], + show: true, + showOnMouseOver: false, + showOnMouseClick: false, + keepOneOverlayVisible: false + }; + }; + + var markerLayerManager = (function() { + var mapDict = []; + + function getMapIndex(map) { + return mapDict.map(function(record) { + return record.map; + }).indexOf(map); + } + + return { + getInst: function getMarkerLayerInst(scope, map) { + var mapIndex = getMapIndex(map); + + if (mapIndex === -1) { + var markerLayer = olHelpers.createVectorLayer(); + markerLayer.set('markers', true); + map.addLayer(markerLayer); + mapDict.push({ + map: map, + markerLayer: markerLayer, + instScopes: [] + }); + mapIndex = mapDict.length - 1; + } + + mapDict[mapIndex].instScopes.push(scope); + + return mapDict[mapIndex].markerLayer; + }, + deregisterScope: function deregisterScope(scope, map) { + var mapIndex = getMapIndex(map); + if (mapIndex === -1) { + throw Error('This map has no markers'); + } + + var scopes = mapDict[mapIndex].instScopes; + var scopeIndex = scopes.indexOf(scope); + if (scopeIndex === -1) { + throw Error('Scope wan\'t registered'); + } + + scopes.splice(scopeIndex, 1); + + if (!scopes.length) { + map.removeLayer(mapDict[mapIndex].markerLayer); + delete mapDict[mapIndex]; + } + } + }; + })(); + return { + restrict: 'E', + scope: { + lat: '=lat', + lon: '=lon', + label: '=label', + properties: '=olMarkerProperties', + style: '=olStyle' + }, + transclude: true, + require: '^openlayers', + replace: true, + template: + '', + + link: function(scope, element, attrs, controller) { + var isDefined = olHelpers.isDefined; + var olScope = controller.getOpenlayersScope(); + var createFeature = olHelpers.createFeature; + var createOverlay = olHelpers.createOverlay; + + var hasTranscluded = element.find('ng-transclude').children().length > 0; + + olScope.getMap().then(function(map) { + var markerLayer = markerLayerManager.getInst(scope, map); + var data = getMarkerDefaults(); + + var mapDefaults = olMapDefaults.getDefaults(olScope); + var viewProjection = mapDefaults.view.projection; + var label; + var pos; + var marker; + + // This function handles dragging a marker + var pickOffset = null; + var pickProperties = null; + function handleDrag(evt) { + var coord = evt.coordinate; + var proj = map.getView().getProjection().getCode(); + if (proj === 'pixel') { + coord = coord.map(function(v) { + return parseInt(v, 10); + }); + } else { + coord = ol.proj.transform(coord, proj, 'EPSG:4326'); + } + + if (evt.type === 'pointerdown') { + // Get feature under mouse if any + var feature = map.forEachFeatureAtPixel(evt.pixel, function(feature) { + return feature; + }); + // Get associated marker properties + pickProperties = (feature ? feature.get('marker') : null); + if (!pickProperties || !pickProperties.draggable) { + pickProperties = null; + return; + } + map.getTarget().style.cursor = 'pointer'; + if (proj === 'pixel') { + pickOffset = [coord[0] - pickProperties.coord[0], coord[1] - pickProperties.coord[1]]; + } else { + pickOffset = [coord[0] - pickProperties.lon, coord[1] - pickProperties.lat]; + } + evt.preventDefault(); + } else if (pickOffset && pickProperties) { + if (evt.type === 'pointerup') { + map.getTarget().style.cursor = ''; + pickOffset = null; + pickProperties = null; + evt.preventDefault(); + } else if (evt.type === 'pointerdrag') { + evt.preventDefault(); + scope.$apply(function() { + // Add current delta to marker initial position + if (proj === 'pixel') { + pickProperties.coord[0] = coord[0] - pickOffset[0]; + pickProperties.coord[1] = coord[1] - pickOffset[1]; + } else { + pickProperties.lon = coord[0] - pickOffset[0]; + pickProperties.lat = coord[1] - pickOffset[1]; + } + }); + } + } + } + + // Setup generic handlers for marker drag + map.on('pointerdown', handleDrag); + map.on('pointerup', handleDrag); + map.on('pointerdrag', handleDrag); + + scope.$on('$destroy', function() { + markerLayer.getSource().removeFeature(marker); + if (isDefined(label)) { + map.removeOverlay(label); + } + markerLayerManager.deregisterScope(scope, map); + }); + + if (!isDefined(scope.properties)) { + data.lat = scope.lat ? scope.lat : data.lat; + data.lon = scope.lon ? scope.lon : data.lon; + data.message = attrs.message; + data.style = scope.style ? scope.style : mapDefaults.styles.marker; + + marker = createFeature(data, viewProjection); + if (!isDefined(marker)) { + $log.error('[AngularJS - Openlayers] Received invalid data on ' + + 'the marker.'); + } + // Add a link between the feature and the marker properties + marker.set('marker', scope); + markerLayer.getSource().addFeature(marker); + + if (data.message || hasTranscluded) { + scope.message = attrs.message; + pos = ol.proj.transform([data.lon, data.lat], data.projection, + viewProjection); + label = createOverlay(element, pos); + map.addOverlay(label); + } + return; + } + + scope.$watch('properties', function(properties) { + + // Remove previous listeners if any + map.getViewport().removeEventListener('mousemove', properties.handleInteraction); + map.getViewport().removeEventListener('click', properties.handleTapInteraction); + map.getViewport().querySelector('canvas.ol-unselectable').removeEventListener( + 'touchend', properties.handleTapInteraction); + map.getViewport().removeEventListener('mousemove', properties.showAtLeastOneOverlay); + map.getViewport().removeEventListener('click', properties.removeAllOverlays); + + // This function handles popup on mouse over/click + properties.handleInteraction = function(evt) { + if (properties.label.show) { + return; + } + var found = false; + var pixel = map.getEventPixel(evt); + var feature = map.forEachFeatureAtPixel(pixel, function(feature) { + return feature; + }); + + var actionTaken = false; + if (feature === marker) { + actionTaken = true; + found = true; + if (!isDefined(label)) { + if (data.projection === 'pixel') { + pos = properties.coord; + } else { + pos = ol.proj.transform([properties.lon, properties.lat], + data.projection, viewProjection); + } + label = createOverlay(element, pos); + map.addOverlay(label); + } + + if (properties.onClick && (evt.type === 'click' || evt.type === 'touchend')) { + scope.$apply(function() { + properties.onClick.call(marker, evt, properties); + }); + } + map.getTarget().style.cursor = 'pointer'; + } + + if (!found && label) { + actionTaken = true; + map.removeOverlay(label); + label = undefined; + map.getTarget().style.cursor = ''; + } + + if (actionTaken) { + evt.preventDefault(); + } + }; + + // Made to filter out click/tap events if both are being triggered on this platform + properties.handleTapInteraction = (function() { + var cooldownActive = false; + var prevTimeout; + + // Sets the cooldown flag to filter out any subsequent events within 500 ms + function activateCooldown() { + cooldownActive = true; + if (prevTimeout) { + clearTimeout(prevTimeout); + } + prevTimeout = setTimeout(function() { + cooldownActive = false; + prevTimeout = null; + }, 500); + } + + // Preventing from 'touchend' to be considered a tap, if fired immediately after 'touchmove' + map.getViewport().querySelector('canvas.ol-unselectable').addEventListener( + 'touchmove', activateCooldown); + + return function() { + if (!cooldownActive) { + properties.handleInteraction.apply(null, arguments); + activateCooldown(); + } + }; + })(); + + properties.showAtLeastOneOverlay = function(evt) { + if (properties.label.show) { + return; + } + var found = false; + var pixel = map.getEventPixel(evt); + var feature = map.forEachFeatureAtPixel(pixel, function(feature) { + return feature; + }); + + var actionTaken = false; + if (feature === marker) { + actionTaken = true; + found = true; + if (!isDefined(label)) { + if (data.projection === 'pixel') { + pos = data.coord; + } else { + pos = ol.proj.transform([data.lon, data.lat], + data.projection, viewProjection); + } + label = createOverlay(element, pos); + angular.forEach(map.getOverlays(), function(value) { + map.removeOverlay(value); + }); + map.addOverlay(label); + } + map.getTarget().style.cursor = 'pointer'; + } + + if (!found && label) { + actionTaken = true; + label = undefined; + map.getTarget().style.cursor = ''; + } + + if (actionTaken) { + evt.preventDefault(); + } + }; + + properties.removeAllOverlays = function(evt) { + angular.forEach(map.getOverlays(), function(value) { + map.removeOverlay(value); + }); + evt.preventDefault(); + }; + + if (!isDefined(marker)) { + data.projection = properties.projection ? properties.projection : + data.projection; + data.coord = properties.coord ? properties.coord : data.coord; + data.lat = properties.lat ? properties.lat : data.lat; + data.lon = properties.lon ? properties.lon : data.lon; + + if (isDefined(properties.style)) { + data.style = properties.style; + } else { + data.style = mapDefaults.styles.marker; + } + + marker = createFeature(data, viewProjection); + if (!isDefined(marker)) { + $log.error('[AngularJS - Openlayers] Received invalid data on ' + + 'the marker.'); + } + // Add a link between the feature and the marker properties + marker.set('marker', properties); + markerLayer.getSource().addFeature(marker); + } else { + var requestedPosition; + if (properties.projection === 'pixel') { + requestedPosition = properties.coord; + } else { + requestedPosition = ol.proj.transform([properties.lon, properties.lat], data.projection, + map.getView().getProjection()); + } + + if (!angular.equals(marker.getGeometry().getCoordinates(), requestedPosition)) { + var geometry = new ol.geom.Point(requestedPosition); + marker.setGeometry(geometry); + } + } + + if (isDefined(label)) { + map.removeOverlay(label); + } + + if (!isDefined(properties.label)) { + return; + } + + scope.message = properties.label.message; + if (!hasTranscluded && (!isDefined(scope.message) || scope.message.length === 0)) { + return; + } + + if (properties.label && properties.label.show === true) { + if (data.projection === 'pixel') { + pos = data.coord; + } else { + pos = ol.proj.transform([properties.lon, properties.lat], data.projection, + viewProjection); + } + label = createOverlay(element, pos); + map.addOverlay(label); + } + + if (label && properties.label && properties.label.show === false) { + map.removeOverlay(label); + label = undefined; + } + + // Then setup new ones according to properties + if (properties.label && properties.label.show === false && + properties.label.showOnMouseOver) { + map.getViewport().addEventListener('mousemove', properties.handleInteraction); + } + + if ((properties.label && properties.label.show === false && + properties.label.showOnMouseClick) || + properties.onClick) { + map.getViewport().addEventListener('click', properties.handleTapInteraction); + map.getViewport().querySelector('canvas.ol-unselectable').addEventListener( + 'touchend', properties.handleTapInteraction); + } + + if ((properties.label && properties.label.show === false && + properties.label.keepOneOverlayVisible)) { + map.getViewport().addEventListener('mousemove', properties.showAtLeastOneOverlay); + map.getViewport().addEventListener('click', properties.removeAllOverlays); + } + }, true); + }); + } + }; +}]); + +angular.module('openlayers-directive').service('olData', ["$log", "$q", function($log, $q) { + + var maps = {}; + + var setResolvedDefer = function(d, mapId) { + var id = obtainEffectiveMapId(d, mapId); + d[id].resolvedDefer = true; + }; + + var getUnresolvedDefer = function(d, mapId) { + var id = obtainEffectiveMapId(d, mapId); + var defer; + + if (!angular.isDefined(d[id]) || d[id].resolvedDefer === true) { + defer = $q.defer(); + d[id] = { + defer: defer, + resolvedDefer: false + }; + } else { + defer = d[id].defer; + } + return defer; + }; + + var getDefer = function(d, mapId) { + var id = obtainEffectiveMapId(d, mapId); + var defer; + + if (!angular.isDefined(d[id]) || d[id].resolvedDefer === false) { + defer = getUnresolvedDefer(d, mapId); + } else { + defer = d[id].defer; + } + return defer; + }; + + this.setMap = function(olMap, scopeId) { + var defer = getUnresolvedDefer(maps, scopeId); + defer.resolve(olMap); + setResolvedDefer(maps, scopeId); + }; + + this.getMap = function(scopeId) { + var defer = getDefer(maps, scopeId); + return defer.promise; + }; + + function obtainEffectiveMapId(d, mapId) { + var id; + var i; + if (!angular.isDefined(mapId)) { + if (Object.keys(d).length === 1) { + for (i in d) { + if (d.hasOwnProperty(i)) { + id = i; + } + } + } else if (Object.keys(d).length === 0) { + id = 'main'; + } else { + $log.error('[AngularJS - Openlayers] - You have more than 1 map on the DOM, ' + + 'you must provide the map ID to the olData.getXXX call'); + } + } else { + id = mapId; + } + return id; + } + +}]); + +angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$http", function($q, $log, $http) { + + var isDefined = function(value) { + return angular.isDefined(value); + }; + + var isDefinedAndNotNull = function(value) { + return angular.isDefined(value) && value !== null; + }; + + var setEvent = function(map, eventType, scope) { + map.on(eventType, function(event) { + var coord = event.coordinate; + var proj = map.getView().getProjection().getCode(); + if (proj === 'pixel') { + coord = coord.map(function(v) { + return parseInt(v, 10); + }); + } + scope.$emit('openlayers.map.' + eventType, { + 'coord': coord, + 'projection': proj, + 'event': event + }); + }); + }; + + var bingImagerySets = [ + 'Road', + 'Aerial', + 'AerialWithLabels', + 'collinsBart', + 'ordnanceSurvey' + ]; + + var getControlClasses = function() { + return { + attribution: ol.control.Attribution, + fullscreen: ol.control.FullScreen, + mouseposition: ol.control.MousePosition, + overviewmap: ol.control.OverviewMap, + rotate: ol.control.Rotate, + scaleline: ol.control.ScaleLine, + zoom: ol.control.Zoom, + zoomslider: ol.control.ZoomSlider, + zoomtoextent: ol.control.ZoomToExtent + }; + }; + + var mapQuestLayers = ['osm', 'sat', 'hyb']; + + var esriBaseLayers = ['World_Imagery', 'World_Street_Map', 'World_Topo_Map', + 'World_Physical_Map', 'World_Terrain_Base', + 'Ocean_Basemap', 'NatGeo_World_Map']; + + var styleMap = { + 'style': ol.style.Style, + 'fill': ol.style.Fill, + 'stroke': ol.style.Stroke, + 'circle': ol.style.Circle, + 'icon': ol.style.Icon, + 'image': ol.style.Image, + 'regularshape': ol.style.RegularShape, + 'text': ol.style.Text + }; + + var optionalFactory = function(style, Constructor) { + if (Constructor && style instanceof Constructor) { + return style; + } else if (Constructor) { + return new Constructor(style); + } else { + return style; + } + }; + + //Parse the style tree calling the appropriate constructors. + //The keys in styleMap can be used and the OpenLayers constructors can be + //used directly. + var createStyle = function recursiveStyle(data, styleName) { + var style; + if (!styleName) { + styleName = 'style'; + style = data; + } else { + style = data[styleName]; + } + //Instead of defining one style for the layer, we've been given a style function + //to apply to each feature. + if (styleName === 'style' && data instanceof Function) { + return data; + } + + if (!(style instanceof Object)) { + return style; + } + + var styleObject; + if (Object.prototype.toString.call(style) === '[object Object]') { + styleObject = {}; + var styleConstructor = styleMap[styleName]; + if (styleConstructor && style instanceof styleConstructor) { + return style; + } + Object.getOwnPropertyNames(style).forEach(function(val, idx, array) { + //Consider the case + //image: { + // circle: { + // fill: { + // color: 'red' + // } + // } + // + //An ol.style.Circle is an instance of ol.style.Image, so we do not want to construct + //an Image and then construct a Circle. We assume that if we have an instanceof + //relationship, that the JSON parent has exactly one child. + //We check to see if an inheritance relationship exists. + //If it does, then for the parent we create an instance of the child. + var valConstructor = styleMap[val]; + if (styleConstructor && valConstructor && + valConstructor.prototype instanceof styleMap[styleName]) { + console.assert(array.length === 1, 'Extra parameters for ' + styleName); + styleObject = recursiveStyle(style, val); + return optionalFactory(styleObject, valConstructor); + } else { + styleObject[val] = recursiveStyle(style, val); + + // if the value is 'text' and it contains a String, then it should be interpreted + // as such, 'cause the text style might effectively contain a text to display + if (val !== 'text' && typeof styleObject[val] !== 'string') { + styleObject[val] = optionalFactory(styleObject[val], styleMap[val]); + } + } + }); + } else { + styleObject = style; + } + return optionalFactory(styleObject, styleMap[styleName]); + }; + + var detectLayerType = function(layer) { + if (layer.type) { + return layer.type; + } else { + switch (layer.source.type) { + case 'ImageWMS': + return 'Image'; + case 'ImageStatic': + return 'Image'; + case 'GeoJSON': + case 'JSONP': + case 'TopoJSON': + case 'KML': + case 'TileVector': + return 'Vector'; + default: + return 'Tile'; + } + } + }; + + var createProjection = function(view) { + var oProjection; + + switch (view.projection) { + case 'pixel': + if (!isDefined(view.extent)) { + $log.error('[AngularJS - Openlayers] - You must provide the extent of the image ' + + 'if using pixel projection'); + return; + } + oProjection = new ol.proj.Projection({ + code: 'pixel', + units: 'pixels', + extent: view.extent + }); + break; + default: + oProjection = new ol.proj.get(view.projection); + break; + } + + return oProjection; + }; + + var isValidStamenLayer = function(layer) { + return ['watercolor', 'terrain', 'toner'].indexOf(layer) !== -1; + }; + + var createSource = function(source, projection) { + var oSource; + + switch (source.type) { + case 'MapBox': + if (!source.mapId || !source.accessToken) { + $log.error('[AngularJS - Openlayers] - MapBox layer requires the map id and the access token'); + return; + } + var url = 'http://api.tiles.mapbox.com/v4/' + source.mapId + '/{z}/{x}/{y}.png?access_token=' + + source.accessToken; + + var pixelRatio = window.devicePixelRatio; + + if (pixelRatio > 1) { + url = url.replace('.png', '@2x.png'); + } + + oSource = new ol.source.XYZ({ + url: url, + attributions: createAttribution(source), + tilePixelRatio: pixelRatio > 1 ? 2 : 1 + }); + break; + case 'ImageWMS': + if (!source.url || !source.params) { + $log.error('[AngularJS - Openlayers] - ImageWMS Layer needs ' + + 'valid server url and params properties'); + } + oSource = new ol.source.ImageWMS({ + url: source.url, + attributions: createAttribution(source), + crossOrigin: (typeof source.crossOrigin === 'undefined') ? 'anonymous' : source.crossOrigin, + params: source.params + }); + break; + + case 'TileWMS': + if ((!source.url && !source.urls) || !source.params) { + $log.error('[AngularJS - Openlayers] - TileWMS Layer needs ' + + 'valid url (or urls) and params properties'); + } + + var wmsConfiguration = { + crossOrigin: (typeof source.crossOrigin === 'undefined') ? 'anonymous' : source.crossOrigin, + params: source.params, + attributions: createAttribution(source) + }; + + if (source.serverType) { + wmsConfiguration.serverType = source.serverType; + } + + if (source.url) { + wmsConfiguration.url = source.url; + } + + if (source.urls) { + wmsConfiguration.urls = source.urls; + } + + oSource = new ol.source.TileWMS(wmsConfiguration); + break; + + case 'WMTS': + if ((!source.url && !source.urls) || !source.tileGrid) { + $log.error('[AngularJS - Openlayers] - WMTS Layer needs valid url ' + + '(or urls) and tileGrid properties'); + } + + var wmtsConfiguration = { + projection: projection, + layer: source.layer, + attributions: createAttribution(source), + matrixSet: (source.matrixSet === 'undefined') ? projection : source.matrixSet, + format: (source.format === 'undefined') ? 'image/jpeg' : source.format, + requestEncoding: (source.requestEncoding === 'undefined') ? + 'KVP' : source.requestEncoding, + tileGrid: new ol.tilegrid.WMTS({ + origin: source.tileGrid.origin, + resolutions: source.tileGrid.resolutions, + matrixIds: source.tileGrid.matrixIds + }) + }; + + if (isDefined(source.url)) { + wmtsConfiguration.url = source.url; + } + + if (isDefined(source.urls)) { + wmtsConfiguration.urls = source.urls; + } + + oSource = new ol.source.WMTS(wmtsConfiguration); + break; + + case 'OSM': + oSource = new ol.source.OSM({ + attributions: createAttribution(source) + }); + + if (source.url) { + oSource.setUrl(source.url); + } + + break; + case 'BingMaps': + if (!source.key) { + $log.error('[AngularJS - Openlayers] - You need an API key to show the Bing Maps.'); + return; + } + + var bingConfiguration = { + key: source.key, + attributions: createAttribution(source), + imagerySet: source.imagerySet ? source.imagerySet : bingImagerySets[0], + culture: source.culture + }; + + if (source.maxZoom) { + bingConfiguration.maxZoom = source.maxZoom; + } + + oSource = new ol.source.BingMaps(bingConfiguration); + break; + + case 'MapQuest': + if (!source.layer || mapQuestLayers.indexOf(source.layer) === -1) { + $log.error('[AngularJS - Openlayers] - MapQuest layers needs a valid \'layer\' property.'); + return; + } + + oSource = new ol.source.MapQuest({ + attributions: createAttribution(source), + layer: source.layer + }); + + break; + + case 'EsriBaseMaps': + if (!source.layer || esriBaseLayers.indexOf(source.layer) === -1) { + $log.error('[AngularJS - Openlayers] - ESRI layers needs a valid \'layer\' property.'); + return; + } + + var _urlBase = 'http://services.arcgisonline.com/ArcGIS/rest/services/'; + var _url = _urlBase + source.layer + '/MapServer/tile/{z}/{y}/{x}'; + + oSource = new ol.source.XYZ({ + attributions: createAttribution(source), + url: _url + }); + + break; + + case 'GeoJSON': + if (!(source.geojson || source.url)) { + $log.error('[AngularJS - Openlayers] - You need a geojson ' + + 'property to add a GeoJSON layer.'); + return; + } + + if (isDefined(source.url)) { + oSource = new ol.source.Vector({ + format: new ol.format.GeoJSON(), + url: source.url + }); + } else { + oSource = new ol.source.Vector(); + + var projectionToUse = projection; + if (isDefined(source.geojson.projection)) { + projectionToUse = source.geojson.projection; + } + + var geojsonFormat = new ol.format.GeoJSON(); + var features = geojsonFormat.readFeatures( + source.geojson.object, { featureProjection: projectionToUse }); + + oSource.addFeatures(features); + } + + break; + case 'JSONP': + if (!(source.url)) { + $log.error('[AngularJS - Openlayers] - You need an url properly configured to add a JSONP layer.'); + return; + } + + if (isDefined(source.url)) { + oSource = new ol.source.Vector({ + format: new ol.format.GeoJSON(), + loader: function(/*extent, resolution, projection*/) { + var url = source.url + + '&outputFormat=text/javascript&format_options=callback:JSON_CALLBACK'; + $http.jsonp(url, { cache: source.cache}).success(function(response) { + oSource.addFeatures(oSource.readFeatures(response)); + }).error(function(response) { + $log(response); + }); + } + }); + } + break; + case 'TopoJSON': + if (!(source.topojson || source.url)) { + $log.error('[AngularJS - Openlayers] - You need a topojson ' + + 'property to add a TopoJSON layer.'); + return; + } + + if (source.url) { + oSource = new ol.source.Vector({ + format: new ol.format.TopoJSON(), + url: source.url + }); + } else { + oSource = new ol.source.Vector(angular.extend(source.topojson, { + format: new ol.format.TopoJSON() + })); + } + break; + case 'TileJSON': + oSource = new ol.source.TileJSON({ + url: source.url, + attributions: createAttribution(source), + crossOrigin: 'anonymous' + }); + break; + + case 'TileVector': + if (!source.url || !source.format) { + $log.error('[AngularJS - Openlayers] - TileVector Layer needs valid url and format properties'); + } + oSource = new ol.source.TileVector({ + url: source.url, + projection: projection, + attributions: createAttribution(source), + format: source.format, + tileGrid: new ol.tilegrid.createXYZ({ + maxZoom: source.maxZoom || 19 + }) + }); + break; + + case 'TileTMS': + if (!source.url || !source.tileGrid) { + $log.error('[AngularJS - Openlayers] - TileTMS Layer needs valid url and tileGrid properties'); + } + oSource = new ol.source.TileImage({ + url: source.url, + maxExtent: source.maxExtent, + attributions: createAttribution(source), + tileGrid: new ol.tilegrid.TileGrid({ + origin: source.tileGrid.origin, + resolutions: source.tileGrid.resolutions + }), + tileUrlFunction: function(tileCoord) { + + var z = tileCoord[0]; + var x = tileCoord[1]; + var y = tileCoord[2]; //(1 << z) - tileCoord[2] - 1; + + if (x < 0 || y < 0) { + return ''; + } + + var url = source.url + z + '/' + x + '/' + y + '.png'; + + return url; + } + }); + break; + case 'TileImage': + oSource = new ol.source.TileImage({ + url: source.url, + attributions: createAttribution(source), + tileGrid: new ol.tilegrid.TileGrid({ + origin: source.tileGrid.origin, // top left corner of the pixel projection's extent + resolutions: source.tileGrid.resolutions + }), + tileUrlFunction: function(tileCoord/*, pixelRatio, projection*/) { + var z = tileCoord[0]; + var x = tileCoord[1]; + var y = -tileCoord[2] - 1; + var url = source.url + .replace('{z}', z.toString()) + .replace('{x}', x.toString()) + .replace('{y}', y.toString()); + return url; + } + }); + break; + case 'KML': + var extractStyles = source.extractStyles || false; + oSource = new ol.source.Vector({ + url: source.url, + format: new ol.format.KML(), + radius: source.radius, + extractStyles: extractStyles + }); + break; + case 'Stamen': + if (!source.layer || !isValidStamenLayer(source.layer)) { + $log.error('[AngularJS - Openlayers] - You need a valid Stamen layer.'); + return; + } + oSource = new ol.source.Stamen({ + layer: source.layer + }); + break; + case 'ImageStatic': + if (!source.url || !angular.isArray(source.imageSize) || source.imageSize.length !== 2) { + $log.error('[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.'); + return; + } + + oSource = new ol.source.ImageStatic({ + url: source.url, + attributions: createAttribution(source), + imageSize: source.imageSize, + projection: projection, + imageExtent: projection.getExtent(), + imageLoadFunction: source.imageLoadFunction + }); + break; + case 'XYZ': + if (!source.url) { + $log.error('[AngularJS - Openlayers] - XYZ Layer needs valid url and params properties'); + } + oSource = new ol.source.XYZ({ + url: source.url, + attributions: createAttribution(source), + minZoom: source.minZoom, + maxZoom: source.maxZoom + }); + break; + } + + // log a warning when no source could be created for the given type + if (!oSource) { + $log.warn('[AngularJS - Openlayers] - No source could be found for type "' + source.type + '"'); + } + + return oSource; + }; + + var createAttribution = function(source) { + var attributions = []; + if (isDefined(source.attribution)) { + attributions.unshift(new ol.Attribution({html: source.attribution})); + } + return attributions; + }; + + var createGroup = function(name) { + var olGroup = new ol.layer.Group(); + olGroup.set('name', name); + + return olGroup; + }; + + var getGroup = function(layers, name) { + var layer; + + angular.forEach(layers, function(l) { + if (l instanceof ol.layer.Group && l.get('name') === name) { + layer = l; + return; + } + }); + + return layer; + }; + + var addLayerBeforeMarkers = function(layers, layer) { + var markersIndex; + for (var i = 0; i < layers.getLength(); i++) { + var l = layers.item(i); + + if (l.get('markers')) { + markersIndex = i; + break; + } + } + + if (isDefined(markersIndex)) { + var markers = layers.item(markersIndex); + layer.index = markersIndex; + layers.setAt(markersIndex, layer); + markers.index = layers.getLength(); + layers.push(markers); + } else { + layer.index = layers.getLength(); + layers.push(layer); + } + + }; + + var removeLayer = function(layers, index) { + layers.removeAt(index); + for (var i = index; i < layers.getLength(); i++) { + var l = layers.item(i); + if (l === null) { + layers.insertAt(i, null); + break; + } else { + l.index = i; + } + } + }; + + return { + // Determine if a reference is defined + isDefined: isDefined, + + // Determine if a reference is a number + isNumber: function(value) { + return angular.isNumber(value); + }, + + createView: function(view) { + var projection = createProjection(view); + + var viewConfig = { + projection: projection, + maxZoom: view.maxZoom, + minZoom: view.minZoom + }; + + if (view.center) { + viewConfig.center = view.center; + } + if (view.extent) { + viewConfig.extent = view.extent; + } + if (view.zoom) { + viewConfig.zoom = view.zoom; + } + + return new ol.View(viewConfig); + }, + + // Determine if a reference is defined and not null + isDefinedAndNotNull: isDefinedAndNotNull, + + // Determine if a reference is a string + isString: function(value) { + return angular.isString(value); + }, + + // Determine if a reference is an array + isArray: function(value) { + return angular.isArray(value); + }, + + // Determine if a reference is an object + isObject: function(value) { + return angular.isObject(value); + }, + + // Determine if two objects have the same properties + equals: function(o1, o2) { + return angular.equals(o1, o2); + }, + + isValidCenter: function(center) { + return angular.isDefined(center) && + (typeof center.autodiscover === 'boolean' || + angular.isNumber(center.lat) && angular.isNumber(center.lon) || + (angular.isArray(center.coord) && center.coord.length === 2 && + angular.isNumber(center.coord[0]) && angular.isNumber(center.coord[1])) || + (angular.isArray(center.bounds) && center.bounds.length === 4 && + angular.isNumber(center.bounds[0]) && angular.isNumber(center.bounds[1]) && + angular.isNumber(center.bounds[1]) && angular.isNumber(center.bounds[2]))); + }, + + safeApply: function($scope, fn) { + var phase = $scope.$root.$$phase; + if (phase === '$apply' || phase === '$digest') { + $scope.$eval(fn); + } else { + $scope.$apply(fn); + } + }, + + isSameCenterOnMap: function(center, map) { + var urlProj = center.projection || 'EPSG:4326'; + var urlCenter = [center.lon, center.lat]; + var mapProj = map.getView().getProjection(); + var mapCenter = ol.proj.transform(map.getView().getCenter(), mapProj, urlProj); + var zoom = map.getView().getZoom(); + if (mapCenter[1].toFixed(4) === urlCenter[1].toFixed(4) && + mapCenter[0].toFixed(4) === urlCenter[0].toFixed(4) && + zoom === center.zoom) { + return true; + } + return false; + }, + + setCenter: function(view, projection, newCenter, map) { + + if (map && view.getCenter()) { + var pan = ol.animation.pan({ + duration: 150, + source: (view.getCenter()) + }); + map.beforeRender(pan); + } + + if (newCenter.projection === projection) { + view.setCenter([newCenter.lon, newCenter.lat]); + } else { + var coord = [newCenter.lon, newCenter.lat]; + view.setCenter(ol.proj.transform(coord, newCenter.projection, projection)); + } + }, + + setZoom: function(view, zoom, map) { + var z = ol.animation.zoom({ + duration: 150, + resolution: map.getView().getResolution() + }); + map.beforeRender(z); + view.setZoom(zoom); + }, + + isBoolean: function(value) { + return typeof value === 'boolean'; + }, + + createStyle: createStyle, + + setMapEvents: function(events, map, scope) { + if (isDefined(events) && angular.isArray(events.map)) { + for (var i in events.map) { + var event = events.map[i]; + setEvent(map, event, scope); + } + } + }, + + setVectorLayerEvents: function(events, map, scope, layerName) { + if (isDefined(events) && angular.isArray(events.layers)) { + angular.forEach(events.layers, function(eventType) { + angular.element(map.getViewport()).on(eventType, function(evt) { + var pixel = map.getEventPixel(evt); + var feature = map.forEachFeatureAtPixel(pixel, function(feature, olLayer) { + // only return the feature if it is in this layer (based on the name) + return (isDefinedAndNotNull(olLayer) && olLayer.get('name') === layerName) ? feature : null; + }); + if (isDefinedAndNotNull(feature)) { + scope.$emit('openlayers.layers.' + layerName + '.' + eventType, feature, evt); + } + }); + }); + } + }, + + setViewEvents: function(events, map, scope) { + if (isDefined(events) && angular.isArray(events.view)) { + var view = map.getView(); + angular.forEach(events.view, function(eventType) { + view.on(eventType, function(event) { + scope.$emit('openlayers.view.' + eventType, view, event); + }); + }); + } + }, + + detectLayerType: detectLayerType, + + createLayer: function(layer, projection, name) { + var oLayer; + var type = detectLayerType(layer); + var oSource = createSource(layer.source, projection); + if (!oSource) { + return; + } + + // Manage clustering + if ((type === 'Vector') && layer.clustering) { + oSource = new ol.source.Cluster({ + source: oSource, + distance: layer.clusteringDistance + }); + } + + switch (type) { + case 'Image': + oLayer = new ol.layer.Image({ source: oSource }); + break; + case 'Tile': + oLayer = new ol.layer.Tile({ source: oSource }); + break; + case 'Heatmap': + oLayer = new ol.layer.Heatmap({ source: oSource }); + break; + case 'Vector': + oLayer = new ol.layer.Vector({ source: oSource }); + break; + } + + // set a layer name if given + if (isDefined(name)) { + oLayer.set('name', name); + } else if (isDefined(layer.name)) { + oLayer.set('name', layer.name); + } + + // set custom layer properties if given + if (isDefined(layer.customAttributes)) { + for (var key in layer.customAttributes) { + oLayer.set(key, layer.customAttributes[key]); + } + } + + return oLayer; + }, + + createVectorLayer: function() { + return new ol.layer.Vector({ + source: new ol.source.Vector() + }); + }, + + notifyCenterUrlHashChanged: function(scope, center, search) { + if (center.centerUrlHash) { + var centerUrlHash = center.lat.toFixed(4) + ':' + center.lon.toFixed(4) + ':' + center.zoom; + if (!isDefined(search.c) || search.c !== centerUrlHash) { + scope.$emit('centerUrlHash', centerUrlHash); + } + } + }, + + getControlClasses: getControlClasses, + + detectControls: function(controls) { + var actualControls = {}; + var controlClasses = getControlClasses(); + + controls.forEach(function(control) { + for (var i in controlClasses) { + if (control instanceof controlClasses[i]) { + actualControls[i] = control; + } + } + }); + + return actualControls; + }, + + createFeature: function(data, viewProjection) { + var geometry; + + switch (data.type) { + case 'Polygon': + geometry = new ol.geom.Polygon(data.coords); + break; + default: + if (isDefined(data.coord) && data.projection === 'pixel') { + geometry = new ol.geom.Point(data.coord); + } else { + geometry = new ol.geom.Point([data.lon, data.lat]); + } + break; + } + + if (isDefined(data.projection) && data.projection !== 'pixel') { + geometry = geometry.transform(data.projection, viewProjection); + } + + var feature = new ol.Feature({ + geometry: geometry + }); + + if (isDefined(data.style)) { + var style = createStyle(data.style); + feature.setStyle(style); + } + return feature; + }, + + addLayerBeforeMarkers: addLayerBeforeMarkers, + + getGroup: getGroup, + + addLayerToGroup: function(layers, layer, name) { + var groupLayer = getGroup(layers, name); + + if (!isDefined(groupLayer)) { + groupLayer = createGroup(name); + addLayerBeforeMarkers(layers,groupLayer); + } + + layer.set('group', name); + addLayerBeforeMarkers(groupLayer.getLayers(), layer); + }, + + removeLayerFromGroup: function(layers, layer, name) { + var groupLayer = getGroup(layers, name); + layer.set('group'); + removeLayer(groupLayer.getLayers(), layer.index); + }, + + removeLayer: removeLayer, + + insertLayer: function(layers, index, layer) { + if (layers.getLength() < index) { + // fill up with "null layers" till we get to the desired index + while (layers.getLength() < index) { + var nullLayer = new ol.layer.Image(); + nullLayer.index = layers.getLength(); // add index which will be equal to the length in this case + layers.push(nullLayer); + } + layer.index = index; + layers.push(layer); + } else { + layer.index = index; + layers.insertAt(layer.index, layer); + for (var i = index + 1; i < layers.getLength(); i++) { + var l = layers.item(i); + if (l === null) { + layers.removeAt(i); + break; + } else { + l.index = i; + } + } + } + }, + + createOverlay: function(element, pos) { + element.css('display', 'block'); + var ov = new ol.Overlay({ + position: pos, + element: element, + positioning: 'center-left' + }); + + return ov; + } + }; +}]); + +angular.module('openlayers-directive').factory('olMapDefaults', ["$q", "olHelpers", function($q, olHelpers) { + + var base64icon = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAApCAYAAADAk4LOAAAGmklEQVRYw' + + '7VXeUyTZxjvNnfELFuyIzOabermMZEeQC/OclkO49CpOHXOLJl/CAURuYbQi3KLgEhbrhZ1aDwmaoGq' + + 'KII6odATmH/scDFbdC7LvFqOCc+e95s2VG50X/LLm/f4/Z7neY/ne18aANCmAr5E/xZf1uDOkTcGcWR' + + '6hl9247tT5U7Y6SNvWsKT63P58qbfeLJG8M5qcgTknrvvrdDbsT7Ml+tv82X6vVxJE33aRmgSyYtcWV' + + 'MqX97Yv2JvW39UhRE2HuyBL+t+gK1116ly06EeWFNlAmHxlQE0OMiV6mQCScusKRlhS3QLeVJdl1+23' + + 'h5dY4FNB3thrbYboqptEFlphTC1hSpJnbRvxP4NWgsE5Jyz86QNNi/5qSUTGuFk1gu54tN9wuK2wc3o' + + '+Wc13RCmsoBwEqzGcZsxsvCSy/9wJKf7UWf1mEY8JWfewc67UUoDbDjQC+FqK4QqLVMGGR9d2wurKzq' + + 'Bk3nqIT/9zLxRRjgZ9bqQgub+DdoeCC03Q8j+0QhFhBHR/eP3U/zCln7Uu+hihJ1+bBNffLIvmkyP0g' + + 'pBZWYXhKussK6mBz5HT6M1Nqpcp+mBCPXosYQfrekGvrjewd59/GvKCE7TbK/04/ZV5QZYVWmDwH1mF' + + '3xa2Q3ra3DBC5vBT1oP7PTj4C0+CcL8c7C2CtejqhuCnuIQHaKHzvcRfZpnylFfXsYJx3pNLwhKzRAw' + + 'AhEqG0SpusBHfAKkxw3w4627MPhoCH798z7s0ZnBJ/MEJbZSbXPhER2ih7p2ok/zSj2cEJDd4CAe+5W' + + 'YnBCgR2uruyEw6zRoW6/DWJ/OeAP8pd/BGtzOZKpG8oke0SX6GMmRk6GFlyAc59K32OTEinILRJRcha' + + 'h8HQwND8N435Z9Z0FY1EqtxUg+0SO6RJ/mmXz4VuS+DpxXC3gXmZwIL7dBSH4zKE50wESf8qwVgrP1E' + + 'IlTO5JP9Igu0aexdh28F1lmAEGJGfh7jE6ElyM5Rw/FDcYJjWhbeiBYoYNIpc2FT/SILivp0F1ipDWk' + + '4BIEo2VuodEJUifhbiltnNBIXPUFCMpthtAyqws/BPlEF/VbaIxErdxPphsU7rcCp8DohC+GvBIPJS/' + + 'tW2jtvTmmAeuNO8BNOYQeG8G/2OzCJ3q+soYB5i6NhMaKr17FSal7GIHheuV3uSCY8qYVuEm1cOzqdW' + + 'r7ku/R0BDoTT+DT+ohCM6/CCvKLKO4RI+dXPeAuaMqksaKrZ7L3FE5FIFbkIceeOZ2OcHO6wIhTkNo0' + + 'ffgjRGxEqogXHYUPHfWAC/lADpwGcLRY3aeK4/oRGCKYcZXPVoeX/kelVYY8dUGf8V5EBRbgJXT5QIP' + + 'hP9ePJi428JKOiEYhYXFBqou2Guh+p/mEB1/RfMw6rY7cxcjTrneI1FrDyuzUSRm9miwEJx8E/gUmql' + + 'yvHGkneiwErR21F3tNOK5Tf0yXaT+O7DgCvALTUBXdM4YhC/IawPU+2PduqMvuaR6eoxSwUk75ggqsY' + + 'J7VicsnwGIkZBSXKOUww73WGXyqP+J2/b9c+gi1YAg/xpwck3gJuucNrh5JvDPvQr0WFXf0piyt8f8/' + + 'WI0hV4pRxxkQZdJDfDJNOAmM0Ag8jyT6hz0WGXWuP94Yh2jcfjmXAGvHCMslRimDHYuHuDsy2QtHuIa' + + 'vznhbYURq5R57KpzBBRZKPJi8eQg48h4j8SDdowifdIrEVdU+gbO6QNvRRt4ZBthUaZhUnjlYObNagV' + + '3keoeru3rU7rcuceqU1mJBxy+BWZYlNEBH+0eH4vRiB+OYybU2hnblYlTvkHinM4m54YnxSyaZYSF6R' + + '3jwgP7udKLGIX6r/lbNa9N6y5MFynjWDtrHd75ZvTYAPO/6RgF0k76mQla3FGq7dO+cH8sKn0Vo7nDl' + + 'lwAhqwLPkxrHwWmHJOo+AKJ4rab5OgrM7rVu8eWb2Pu0Dh4eDgXoOfvp7Y7QeqknRmvcTBEyq9m/HQQ' + + 'SCSz6LHq3z0yzsNySRfMS253wl2KyRDbcZPcfJKjZmSEOjcxyi+Y8dUOtsIEH6R2wNykdqrkYJ0RV92' + + 'H0W58pkfQk7cKevsLK10Py8SdMGfXNXATY+pPbyJR/ET6n9nIfztNtZYRV9XniQu9IA2vOVgy4ir7GC' + + 'LVmmd+zjkH0eAF9Po6K61pmCXHxU5rHMYd1ftc3owjwRSVRzLjKvqZEty6cRUD7jGqiOdu5HG6MdHjN' + + 'cNYGqfDm5YRzLBBCCDl/2bk8a8gdbqcfwECu62Fg/HrggAAAABJRU5ErkJggg=='; + + var _getDefaults = function() { + return { + view: { + projection: 'EPSG:3857', + minZoom: undefined, + maxZoom: undefined, + rotation: 0, + extent: undefined + }, + center: { + lat: 0, + lon: 0, + zoom: 1, + autodiscover: false, + bounds: [], + centerUrlHash: false, + projection: 'EPSG:4326' + }, + styles: { + path: { + stroke: { + color: 'blue', + width: 8 + } + }, + marker: { + image: new ol.style.Icon({ + anchor: [0.5, 1], + anchorXUnits: 'fraction', + anchorYUnits: 'fraction', + opacity: 0.90, + src: base64icon + }) + } + }, + events: { + map: [], + markers: [], + layers: [] + }, + controls: { + attribution: true, + rotate: false, + zoom: true + }, + interactions: { + mouseWheelZoom: false + }, + renderer: 'canvas' + }; + }; + + var isDefined = olHelpers.isDefined; + var defaults = {}; + + // Get the _defaults dictionary, and override the properties defined by the user + return { + getDefaults: function(scope) { + if (!isDefined(scope)) { + for (var i in defaults) { + return defaults[i]; + } + } + return defaults[scope.$id]; + }, + + setDefaults: function(scope) { + var userDefaults = scope.defaults; + var scopeId = scope.$id; + var newDefaults = _getDefaults(); + + if (isDefined(userDefaults)) { + + if (isDefined(userDefaults.layers)) { + newDefaults.layers = angular.copy(userDefaults.layers); + } + + if (isDefined(userDefaults.controls)) { + newDefaults.controls = angular.copy(userDefaults.controls); + } + + if (isDefined(userDefaults.events)) { + newDefaults.events = angular.copy(userDefaults.events); + } + + if (isDefined(userDefaults.interactions)) { + newDefaults.interactions = angular.copy(userDefaults.interactions); + } + + if (isDefined(userDefaults.renderer)) { + newDefaults.renderer = userDefaults.renderer; + } + + if (isDefined(userDefaults.view)) { + newDefaults.view.maxZoom = userDefaults.view.maxZoom || newDefaults.view.maxZoom; + newDefaults.view.minZoom = userDefaults.view.minZoom || newDefaults.view.minZoom; + newDefaults.view.projection = userDefaults.view.projection || newDefaults.view.projection; + newDefaults.view.extent = userDefaults.view.extent || newDefaults.view.extent; + } + + if (isDefined(userDefaults.styles)) { + newDefaults.styles = angular.extend(newDefaults.styles, userDefaults.styles); + } + + } + + defaults[scopeId] = newDefaults; + return newDefaults; + } + }; +}]); + +})); \ No newline at end of file diff --git a/dist/angular-openlayers-directive.min.no-header.js b/dist/angular-openlayers-directive.min.no-header.js new file mode 100644 index 00000000..b4537459 --- /dev/null +++ b/dist/angular-openlayers-directive.min.no-header.js @@ -0,0 +1,3 @@ +/*! angular-openlayers-directive 04-01-2016 */ +!function(a,b){if("function"==typeof require&&"object"==typeof exports){var c=require("openlayers");exports.angularOpenlayersDirective=b(c)}else"function"==typeof define&&define.amd?define(["ol"],function(c){return a.angularOpenlayersDirective=b(c)}):a.angularOpenlayersDirective=b(a.ol)}(this,function(a){angular.module("openlayers-directive",["ngSanitize"]).directive("openlayers",["$log","$q","$compile","olHelpers","olMapDefaults","olData",function(b,c,d,e,f,g){return{restrict:"EA",transclude:!0,replace:!0,scope:{center:"=olCenter",defaults:"=olDefaults",view:"=olView",events:"=olEvents"},template:'
',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p});if(!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d){if("pixel"===g.view.projection)return void i.setCenter(c.coord);var e=a.proj.transform(d,g.view.projection,c.projection);(e[1]!==c.lat||e[0]!==c.lon)&&p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}}),f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),(!h(c.minResolution,e.minResolution)||z(d))&&g(c.minResolution)&&d.setMinResolution(c.minResolution),(!h(c.maxResolution,e.maxResolution)||z(d))&&g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)}),e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope();i.getMap().then(function(b){var d=e.getControlClasses,i=d();return a.$on("$destroy",function(){b.removeControl(f)}),h(a.properties)&&h(a.properties.control)?(f=a.properties.control,void b.addControl(f)):void(c.name&&(h(a.properties)&&(g=a.properties),f=new i[c.name](g),b.addControl(f)))})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return e.on("pointerdown",j),e.on("pointerup",j),e.on("pointerdrag",j),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e)}),k(c.properties)?void c.$watch("properties",function(d){if(e.getViewport().removeEventListener("mousemove",d.handleInteraction),e.getViewport().removeEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",d.handleTapInteraction),e.getViewport().removeEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",d.removeAllOverlays),d.handleInteraction=function(b){if(!d.label.show){var f=!1,g=e.getEventPixel(b),i=e.forEachFeatureAtPixel(g,function(a){return a}),j=!1;i===r&&(j=!0,f=!0,k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),!d.onClick||"click"!==b.type&&"touchend"!==b.type||c.$apply(function(){d.onClick.call(r,b,d)}),e.getTarget().style.cursor="pointer"),!f&&p&&(j=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),j&&b.preventDefault()}},d.handleTapInteraction=function(){function a(){c=!0,b&&clearTimeout(b),b=setTimeout(function(){c=!1,b=null},500)}var b,c=!1;return e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",a),function(){c||(d.handleInteraction.apply(null,arguments),a())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||d.onClick)&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){var d=c(a,b);a[d].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d,e=c(a,b);return d=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:f(a,b)};this.setMap=function(a,b){var c=f(d,b);c.resolve(a),e(d,b)},this.getMap=function(a){var b=g(d,a);return b.promise}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function x(a,b){var c;if(b?c=a[b]:(b="style",c=a),"style"===b&&a instanceof Function)return a;if(!(c instanceof Object))return c;var d;if("[object Object]"===Object.prototype.toString.call(c)){d={};var e=l[b];if(e&&c instanceof e)return c;Object.getOwnPropertyNames(c).forEach(function(a,f,g){var h=l[a];return e&&h&&h.prototype instanceof l[b]?(console.assert(1===g.length,"Extra parameters for "+b),d=x(c,a),m(d,h)):(d[a]=x(c,a),void("text"!==a&&"string"!=typeof d[a]&&(d[a]=m(d[a],l[a]))))})}else d=c;return m(d,l[b])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"TileVector":return"Vector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");var i="http://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,l=window.devicePixelRatio;l>1&&(i=i.replace(".png","@2x.png")),g=new a.source.XYZ({url:i,attributions:s(b),tilePixelRatio:l>1?2:1});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,attributions:s(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:b.params});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var m={crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:b.params,attributions:s(b)};b.serverType&&(m.serverType=b.serverType),b.url&&(m.url=b.url),b.urls&&(m.urls=b.urls),g=new a.source.TileWMS(m);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var n={projection:f,layer:b.layer,attributions:s(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds})};e(b.url)&&(n.url=b.url),e(b.urls)&&(n.urls=b.urls),g=new a.source.WMTS(n);break;case"OSM":g=new a.source.OSM({attributions:s(b)}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var o={key:b.key,attributions:s(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture};b.maxZoom&&(o.maxZoom=b.maxZoom),g=new a.source.BingMaps(o);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:s(b),layer:b.layer});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var p="http://services.arcgisonline.com/ArcGIS/rest/services/",r=p+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:s(b),url:r});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url});else{g=new a.source.Vector;var t=f;e(b.geojson.projection)&&(t=b.geojson.projection);var u=new a.format.GeoJSON,v=u.readFeatures(b.geojson.object,{featureProjection:t});g.addFeatures(v)}break;case"JSONP":if(!b.url)return void c.error("[AngularJS - Openlayers] - You need an url properly configured to add a JSONP layer.");e(b.url)&&(g=new a.source.Vector({format:new a.format.GeoJSON,loader:function(){var a=b.url+"&outputFormat=text/javascript&format_options=callback:JSON_CALLBACK";d.jsonp(a,{cache:b.cache}).success(function(a){g.addFeatures(g.readFeatures(a))}).error(function(a){c(a)})}}));break;case"TopoJSON":if(!b.topojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a topojson property to add a TopoJSON layer.");g=b.url?new a.source.Vector({format:new a.format.TopoJSON,url:b.url}):new a.source.Vector(angular.extend(b.topojson,{format:new a.format.TopoJSON}));break;case"TileJSON":g=new a.source.TileJSON({url:b.url,attributions:s(b),crossOrigin:"anonymous"});break;case"TileVector":b.url&&b.format||c.error("[AngularJS - Openlayers] - TileVector Layer needs valid url and format properties"),g=new a.source.TileVector({url:b.url,projection:f,attributions:s(b),format:b.format,tileGrid:new a.tilegrid.createXYZ({maxZoom:b.maxZoom||19})});break;case"TileTMS":b.url&&b.tileGrid||c.error("[AngularJS - Openlayers] - TileTMS Layer needs valid url and tileGrid properties"),g=new a.source.TileImage({url:b.url,maxExtent:b.maxExtent,attributions:s(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=a[2];if(0>d||0>e)return"";var f=b.url+c+"/"+d+"/"+e+".png";return f}});break;case"TileImage":g=new a.source.TileImage({url:b.url,attributions:s(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=-a[2]-1,f=b.url.replace("{z}",c.toString()).replace("{x}",d.toString()).replace("{y}",e.toString());return f}});break;case"KML":var w=b.extractStyles||!1;g=new a.source.Vector({url:b.url,format:new a.format.KML,radius:b.radius,extractStyles:w});break;case"Stamen":if(!b.layer||!q(b.layer))return void c.error("[AngularJS - Openlayers] - You need a valid Stamen layer.");g=new a.source.Stamen({layer:b.layer});break;case"ImageStatic":if(!b.url||!angular.isArray(b.imageSize)||2!==b.imageSize.length)return void c.error("[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.");g=new a.source.ImageStatic({url:b.url,attributions:s(b),imageSize:b.imageSize,projection:f,imageExtent:f.getExtent(),imageLoadFunction:b.imageLoadFunction});break;case"XYZ":b.url||c.error("[AngularJS - Openlayers] - XYZ Layer needs valid url and params properties"),g=new a.source.XYZ({url:b.url,attributions:s(b),minZoom:b.minZoom,maxZoom:b.maxZoom})}return g||c.warn('[AngularJS - Openlayers] - No source could be found for type "'+b.type+'"'),g},s=function(b){var c=[];return e(b.attribution)&&c.unshift(new a.Attribution({html:b.attribution})),c},t=function(b){var c=new a.layer.Group;return c.set("name",b),c},u=function(b,c){var d;return angular.forEach(b,function(b){return b instanceof a.layer.Group&&b.get("name")===c?void(d=b):void 0}),d},v=function(a,b){for(var c,d=0;d', + controller: function($scope) { + var _map = $q.defer(); + $scope.getMap = function() { + return _map.promise; + }; + + $scope.setMap = function(map) { + _map.resolve(map); + }; + + this.getOpenlayersScope = function() { + return $scope; + }; + }, + link: function(scope, element, attrs) { + var isDefined = olHelpers.isDefined; + var createLayer = olHelpers.createLayer; + var setMapEvents = olHelpers.setMapEvents; + var setViewEvents = olHelpers.setViewEvents; + var createView = olHelpers.createView; + var defaults = olMapDefaults.setDefaults(scope); + + // Set width and height if they are defined + if (isDefined(attrs.width)) { + if (isNaN(attrs.width)) { + element.css('width', attrs.width); + } else { + element.css('width', attrs.width + 'px'); + } + } + + if (isDefined(attrs.height)) { + if (isNaN(attrs.height)) { + element.css('height', attrs.height); + } else { + element.css('height', attrs.height + 'px'); + } + } + + if (isDefined(attrs.lat)) { + defaults.center.lat = parseFloat(attrs.lat); + } + + if (isDefined(attrs.lon)) { + defaults.center.lon = parseFloat(attrs.lon); + } + + if (isDefined(attrs.zoom)) { + defaults.center.zoom = parseFloat(attrs.zoom); + } + + var controls = ol.control.defaults(defaults.controls); + var interactions = ol.interaction.defaults(defaults.interactions); + var view = createView(defaults.view); + + // Create the Openlayers Map Object with the options + var map = new ol.Map({ + target: element[0], + controls: controls, + interactions: interactions, + renderer: defaults.renderer, + view: view + }); + + // If no layer is defined, set the default tileLayer + if (!attrs.customLayers) { + var l = { + type: 'Tile', + source: { + type: 'OSM' + } + }; + var layer = createLayer(l, view.getProjection(), 'default'); + map.addLayer(layer); + map.set('default', true); + } + + if (!isDefined(attrs.olCenter)) { + var c = ol.proj.transform([defaults.center.lon, + defaults.center.lat + ], + defaults.center.projection, view.getProjection() + ); + view.setCenter(c); + view.setZoom(defaults.center.zoom); + } + + // Set the Default events for the map + setMapEvents(defaults.events, map, scope); + + //Set the Default events for the map view + setViewEvents(defaults.events, map, scope); + + // Resolve the map object to the promises + scope.setMap(map); + olData.setMap(map, attrs.id); + + } + }; + }); + +angular.module('openlayers-directive').directive('olCenter', function($log, $location, olMapDefaults, olHelpers) { + + return { + restrict: 'A', + scope: false, + replace: false, + require: 'openlayers', + + link: function(scope, element, attrs, controller) { + var safeApply = olHelpers.safeApply; + var isValidCenter = olHelpers.isValidCenter; + var isDefined = olHelpers.isDefined; + var isArray = olHelpers.isArray; + var isNumber = olHelpers.isNumber; + var isSameCenterOnMap = olHelpers.isSameCenterOnMap; + var setCenter = olHelpers.setCenter; + var setZoom = olHelpers.setZoom; + var olScope = controller.getOpenlayersScope(); + + olScope.getMap().then(function(map) { + var defaults = olMapDefaults.getDefaults(olScope); + var view = map.getView(); + var center = olScope.center; + + if (attrs.olCenter.search('-') !== -1) { + $log.error('[AngularJS - Openlayers] The "center" variable can\'t use ' + + 'a "-" on his key name: "' + attrs.center + '".'); + setCenter(view, defaults.view.projection, defaults.center, map); + return; + } + + if (!isDefined(center)) { + center = {}; + } + + if (!isValidCenter(center)) { + $log.warn('[AngularJS - Openlayers] invalid \'center\''); + center.lat = defaults.center.lat; + center.lon = defaults.center.lon; + center.zoom = defaults.center.zoom; + center.projection = defaults.center.projection; + } + + if (!center.projection) { + if (defaults.view.projection !== 'pixel') { + center.projection = defaults.center.projection; + } else { + center.projection = 'pixel'; + } + } + + if (!isNumber(center.zoom)) { + center.zoom = 1; + } + + setCenter(view, defaults.view.projection, center, map); + view.setZoom(center.zoom); + + var centerUrlHash; + if (center.centerUrlHash === true) { + var extractCenterFromUrl = function() { + var search = $location.search(); + var centerParam; + if (isDefined(search.c)) { + var cParam = search.c.split(':'); + if (cParam.length === 3) { + centerParam = { + lat: parseFloat(cParam[0]), + lon: parseFloat(cParam[1]), + zoom: parseInt(cParam[2], 10) + }; + } + } + return centerParam; + }; + centerUrlHash = extractCenterFromUrl(); + + olScope.$on('$locationChangeSuccess', function() { + var urlCenter = extractCenterFromUrl(); + if (urlCenter && !isSameCenterOnMap(urlCenter, map)) { + safeApply(olScope, function(scope) { + scope.center.lat = urlCenter.lat; + scope.center.lon = urlCenter.lon; + scope.center.zoom = urlCenter.zoom; + }); + } + }); + } + + var geolocation; + olScope.$watchCollection('center', function(center) { + + if (!center) { + return; + } + + if (!center.projection) { + center.projection = defaults.center.projection; + } + + if (center.autodiscover) { + if (!geolocation) { + geolocation = new ol.Geolocation({ + projection: ol.proj.get(center.projection) + }); + + geolocation.on('change', function() { + if (center.autodiscover) { + var location = geolocation.getPosition(); + safeApply(olScope, function(scope) { + scope.center.lat = location[1]; + scope.center.lon = location[0]; + scope.center.zoom = 12; + scope.center.autodiscover = false; + geolocation.setTracking(false); + }); + } + }); + } + geolocation.setTracking(true); + return; + } + + if (!isValidCenter(center)) { + $log.warn('[AngularJS - Openlayers] invalid \'center\''); + center = defaults.center; + } + + var viewCenter = view.getCenter(); + if (viewCenter) { + if (defaults.view.projection === 'pixel') { + view.setCenter(center.coord); + return; + } + var actualCenter = ol.proj.transform(viewCenter, defaults.view.projection, center.projection); + if (!(actualCenter[1] === center.lat && actualCenter[0] === center.lon)) { + setCenter(view, defaults.view.projection, center, map); + } + } + + if (view.getZoom() !== center.zoom) { + setZoom(view, center.zoom, map); + } + }); + + map.on('moveend', function() { + safeApply(olScope, function(scope) { + + if (!isDefined(scope.center)) { + return; + } + + var center = map.getView().getCenter(); + scope.center.zoom = view.getZoom(); + + if (defaults.view.projection === 'pixel') { + scope.center.coord = center; + return; + } + + if (scope.center) { + var proj = ol.proj.transform(center, defaults.view.projection, scope.center.projection); + scope.center.lat = proj[1]; + scope.center.lon = proj[0]; + + // Notify the controller about a change in the center position + olHelpers.notifyCenterUrlHashChanged(olScope, scope.center, $location.search()); + + // Calculate the bounds if needed + if (isArray(scope.center.bounds)) { + var extent = view.calculateExtent(map.getSize()); + var centerProjection = scope.center.projection; + var viewProjection = defaults.view.projection; + scope.center.bounds = ol.proj.transformExtent(extent, viewProjection, centerProjection); + } + } + }); + }); + + }); + } + }; +}); + +angular.module('openlayers-directive').directive('olLayer', function($log, $q, olMapDefaults, olHelpers) { + + return { + restrict: 'E', + scope: { + properties: '=olLayerProperties' + }, + replace: false, + require: '^openlayers', + link: function(scope, element, attrs, controller) { + var isDefined = olHelpers.isDefined; + var equals = olHelpers.equals; + var olScope = controller.getOpenlayersScope(); + var createLayer = olHelpers.createLayer; + var setVectorLayerEvents = olHelpers.setVectorLayerEvents; + var detectLayerType = olHelpers.detectLayerType; + var createStyle = olHelpers.createStyle; + var isBoolean = olHelpers.isBoolean; + var addLayerBeforeMarkers = olHelpers.addLayerBeforeMarkers; + var isNumber = olHelpers.isNumber; + var insertLayer = olHelpers.insertLayer; + var removeLayer = olHelpers.removeLayer; + var addLayerToGroup = olHelpers.addLayerToGroup; + var removeLayerFromGroup = olHelpers.removeLayerFromGroup; + var getGroup = olHelpers.getGroup; + + olScope.getMap().then(function(map) { + var projection = map.getView().getProjection(); + var defaults = olMapDefaults.setDefaults(olScope); + var layerCollection = map.getLayers(); + var olLayer; + + scope.$on('$destroy', function() { + if (scope.properties.group) { + removeLayerFromGroup(layerCollection, olLayer, scope.properties.group); + } else { + removeLayer(layerCollection, olLayer.index); + } + + map.removeLayer(olLayer); + }); + + if (!isDefined(scope.properties)) { + if (isDefined(attrs.sourceType) && isDefined(attrs.sourceUrl)) { + var l = { + source: { + url: attrs.sourceUrl, + type: attrs.sourceType + } + }; + + olLayer = createLayer(l, projection, attrs.layerName); + if (detectLayerType(l) === 'Vector') { + setVectorLayerEvents(defaults.events, map, scope, attrs.name); + } + addLayerBeforeMarkers(layerCollection, olLayer); + } + return; + } + + scope.$watch('properties', function(properties, oldProperties) { + if (!isDefined(properties.source) || !isDefined(properties.source.type)) { + return; + } + + if (!isDefined(properties.visible)) { + properties.visible = true; + return; + } + + if (!isDefined(properties.opacity)) { + properties.opacity = 1; + return; + } + + var style; + var group; + var collection; + if (!isDefined(olLayer)) { + olLayer = createLayer(properties, projection); + if (isDefined(properties.group)) { + addLayerToGroup(layerCollection, olLayer, properties.group); + } else if (isDefined(properties.index)) { + insertLayer(layerCollection, properties.index, olLayer); + } else { + addLayerBeforeMarkers(layerCollection, olLayer); + } + + if (detectLayerType(properties) === 'Vector') { + setVectorLayerEvents(defaults.events, map, scope, properties.name); + } + + if (isBoolean(properties.visible)) { + olLayer.setVisible(properties.visible); + } + + if (properties.opacity) { + olLayer.setOpacity(properties.opacity); + } + + if (angular.isArray(properties.extent)) { + olLayer.setExtent(properties.extent); + } + + if (properties.style) { + if (!angular.isFunction(properties.style)) { + style = createStyle(properties.style); + } else { + style = properties.style; + } + // not every layer has a setStyle method + if (olLayer.setStyle && angular.isFunction(olLayer.setStyle)) { + olLayer.setStyle(style); + } + } + + if (properties.minResolution) { + olLayer.setMinResolution(properties.minResolution); + } + + if (properties.maxResolution) { + olLayer.setMaxResolution(properties.maxResolution); + } + + } else { + var isNewLayer = (function(olLayer) { + // this function can be used to verify whether a new layer instance has + // been created. This is needed in order to re-assign styles, opacity + // etc... + return function(layer) { + return layer !== olLayer; + }; + })(olLayer); + + // set source properties + if (isDefined(oldProperties) && !equals(properties.source, oldProperties.source)) { + var idx = olLayer.index; + collection = layerCollection; + group = olLayer.get('group'); + + if (group) { + collection = getGroup(layerCollection, group).getLayers(); + } + + collection.removeAt(idx); + + olLayer = createLayer(properties, projection); + olLayer.set('group', group); + + if (isDefined(olLayer)) { + insertLayer(collection, idx, olLayer); + + if (detectLayerType(properties) === 'Vector') { + setVectorLayerEvents(defaults.events, map, scope, properties.name); + } + } + } + + // set opacity + if (isDefined(oldProperties) && + properties.opacity !== oldProperties.opacity || isNewLayer(olLayer)) { + if (isNumber(properties.opacity) || isNumber(parseFloat(properties.opacity))) { + olLayer.setOpacity(properties.opacity); + } + } + + // set index + if (isDefined(properties.index) && properties.index !== olLayer.index) { + collection = layerCollection; + group = olLayer.get('group'); + + if (group) { + collection = getGroup(layerCollection, group).getLayers(); + } + + removeLayer(collection, olLayer.index); + insertLayer(collection, properties.index, olLayer); + } + + // set group + if (isDefined(properties.group) && properties.group !== oldProperties.group) { + removeLayerFromGroup(layerCollection, olLayer, oldProperties.group); + addLayerToGroup(layerCollection, olLayer, properties.group); + } + + // set visibility + if (isDefined(oldProperties) && + isBoolean(properties.visible) && + properties.visible !== oldProperties.visible || isNewLayer(olLayer)) { + olLayer.setVisible(properties.visible); + } + + // set style + if (isDefined(properties.style) && + !equals(properties.style, oldProperties.style) || isNewLayer(olLayer)) { + if (!angular.isFunction(properties.style)) { + style = createStyle(properties.style); + } else { + style = properties.style; + } + // not every layer has a setStyle method + if (olLayer.setStyle && angular.isFunction(olLayer.setStyle)) { + olLayer.setStyle(style); + } + } + + //set min resolution + if (!equals(properties.minResolution, oldProperties.minResolution) || isNewLayer(olLayer)) { + if (isDefined(properties.minResolution)) { + olLayer.setMinResolution(properties.minResolution); + } + } + + //set max resolution + if (!equals(properties.maxResolution, oldProperties.maxResolution) || isNewLayer(olLayer)) { + if (isDefined(properties.maxResolution)) { + olLayer.setMaxResolution(properties.maxResolution); + } + } + } + }, true); + }); + } + }; +}); + +angular.module('openlayers-directive').directive('olPath', function($log, $q, olMapDefaults, olHelpers) { + + return { + restrict: 'E', + scope: { + properties: '=olGeomProperties' + }, + require: '^openlayers', + replace: true, + template: '', + + link: function(scope, element, attrs, controller) { + var isDefined = olHelpers.isDefined; + var createFeature = olHelpers.createFeature; + var createOverlay = olHelpers.createOverlay; + var createVectorLayer = olHelpers.createVectorLayer; + var insertLayer = olHelpers.insertLayer; + var removeLayer = olHelpers.removeLayer; + var olScope = controller.getOpenlayersScope(); + + olScope.getMap().then(function(map) { + var mapDefaults = olMapDefaults.getDefaults(olScope); + var viewProjection = mapDefaults.view.projection; + + var layer = createVectorLayer(); + var layerCollection = map.getLayers(); + + insertLayer(layerCollection, layerCollection.getLength(), layer); + + scope.$on('$destroy', function() { + removeLayer(layerCollection, layer.index); + }); + + if (isDefined(attrs.coords)) { + var proj = attrs.proj || 'EPSG:4326'; + var coords = JSON.parse(attrs.coords); + var data = { + type: 'Polygon', + coords: coords, + projection: proj, + style: mapDefaults.styles.path + }; + var feature = createFeature(data, viewProjection); + layer.getSource().addFeature(feature); + + if (attrs.message) { + scope.message = attrs.message; + var extent = feature.getGeometry().getExtent(); + var label = createOverlay(element, extent); + map.addOverlay(label); + } + return; + } + }); + } + }; +}); + +angular.module('openlayers-directive').directive('olView', function($log, $q, olData, olMapDefaults, olHelpers) { + return { + restrict: 'A', + scope: false, + replace: false, + require: 'openlayers', + link: function(scope, element, attrs, controller) { + var olScope = controller.getOpenlayersScope(); + var isNumber = olHelpers.isNumber; + var safeApply = olHelpers.safeApply; + var createView = olHelpers.createView; + + olScope.getMap().then(function(map) { + var defaults = olMapDefaults.getDefaults(olScope); + var view = olScope.view; + + if (!view.projection) { + view.projection = defaults.view.projection; + } + + if (!view.maxZoom) { + view.maxZoom = defaults.view.maxZoom; + } + + if (!view.minZoom) { + view.minZoom = defaults.view.minZoom; + } + + if (!view.rotation) { + view.rotation = defaults.view.rotation; + } + + var mapView = createView(view); + map.setView(mapView); + + olScope.$watchCollection('view', function(view) { + if (isNumber(view.rotation)) { + mapView.setRotation(view.rotation); + } + }); + + mapView.on('change:rotation', function() { + safeApply(olScope, function(scope) { + scope.view.rotation = map.getView().getRotation(); + }); + }); + + }); + } + }; +}); + +angular.module('openlayers-directive').directive('olControl', function($log, $q, olData, olMapDefaults, olHelpers) { + + return { + restrict: 'E', + scope: { + properties: '=olControlProperties' + }, + replace: false, + require: '^openlayers', + link: function(scope, element, attrs, controller) { + var isDefined = olHelpers.isDefined; + var olScope = controller.getOpenlayersScope(); + var olControl; + var olControlOps; + + olScope.getMap().then(function(map) { + var getControlClasses = olHelpers.getControlClasses; + var controlClasses = getControlClasses(); + + scope.$on('$destroy', function() { + map.removeControl(olControl); + }); + + if (!isDefined(scope.properties) || !isDefined(scope.properties.control)) { + if (attrs.name) { + if (isDefined(scope.properties)) { + olControlOps = scope.properties; + } + olControl = new controlClasses[attrs.name](olControlOps); + map.addControl(olControl); + } + return; + } + + olControl = scope.properties.control; + map.addControl(olControl); + }); + } + }; +}); + +angular.module('openlayers-directive').directive('olMarker', function($log, $q, olMapDefaults, olHelpers) { + + var getMarkerDefaults = function() { + return { + projection: 'EPSG:4326', + lat: 0, + lon: 0, + coord: [], + show: true, + showOnMouseOver: false, + showOnMouseClick: false, + keepOneOverlayVisible: false + }; + }; + + var markerLayerManager = (function() { + var mapDict = []; + + function getMapIndex(map) { + return mapDict.map(function(record) { + return record.map; + }).indexOf(map); + } + + return { + getInst: function getMarkerLayerInst(scope, map) { + var mapIndex = getMapIndex(map); + + if (mapIndex === -1) { + var markerLayer = olHelpers.createVectorLayer(); + markerLayer.set('markers', true); + map.addLayer(markerLayer); + mapDict.push({ + map: map, + markerLayer: markerLayer, + instScopes: [] + }); + mapIndex = mapDict.length - 1; + } + + mapDict[mapIndex].instScopes.push(scope); + + return mapDict[mapIndex].markerLayer; + }, + deregisterScope: function deregisterScope(scope, map) { + var mapIndex = getMapIndex(map); + if (mapIndex === -1) { + throw Error('This map has no markers'); + } + + var scopes = mapDict[mapIndex].instScopes; + var scopeIndex = scopes.indexOf(scope); + if (scopeIndex === -1) { + throw Error('Scope wan\'t registered'); + } + + scopes.splice(scopeIndex, 1); + + if (!scopes.length) { + map.removeLayer(mapDict[mapIndex].markerLayer); + delete mapDict[mapIndex]; + } + } + }; + })(); + return { + restrict: 'E', + scope: { + lat: '=lat', + lon: '=lon', + label: '=label', + properties: '=olMarkerProperties', + style: '=olStyle' + }, + transclude: true, + require: '^openlayers', + replace: true, + template: + '', + + link: function(scope, element, attrs, controller) { + var isDefined = olHelpers.isDefined; + var olScope = controller.getOpenlayersScope(); + var createFeature = olHelpers.createFeature; + var createOverlay = olHelpers.createOverlay; + + var hasTranscluded = element.find('ng-transclude').children().length > 0; + + olScope.getMap().then(function(map) { + var markerLayer = markerLayerManager.getInst(scope, map); + var data = getMarkerDefaults(); + + var mapDefaults = olMapDefaults.getDefaults(olScope); + var viewProjection = mapDefaults.view.projection; + var label; + var pos; + var marker; + + // This function handles dragging a marker + var pickOffset = null; + var pickProperties = null; + function handleDrag(evt) { + var coord = evt.coordinate; + var proj = map.getView().getProjection().getCode(); + if (proj === 'pixel') { + coord = coord.map(function(v) { + return parseInt(v, 10); + }); + } else { + coord = ol.proj.transform(coord, proj, 'EPSG:4326'); + } + + if (evt.type === 'pointerdown') { + // Get feature under mouse if any + var feature = map.forEachFeatureAtPixel(evt.pixel, function(feature) { + return feature; + }); + // Get associated marker properties + pickProperties = (feature ? feature.get('marker') : null); + if (!pickProperties || !pickProperties.draggable) { + pickProperties = null; + return; + } + map.getTarget().style.cursor = 'pointer'; + if (proj === 'pixel') { + pickOffset = [coord[0] - pickProperties.coord[0], coord[1] - pickProperties.coord[1]]; + } else { + pickOffset = [coord[0] - pickProperties.lon, coord[1] - pickProperties.lat]; + } + evt.preventDefault(); + } else if (pickOffset && pickProperties) { + if (evt.type === 'pointerup') { + map.getTarget().style.cursor = ''; + pickOffset = null; + pickProperties = null; + evt.preventDefault(); + } else if (evt.type === 'pointerdrag') { + evt.preventDefault(); + scope.$apply(function() { + // Add current delta to marker initial position + if (proj === 'pixel') { + pickProperties.coord[0] = coord[0] - pickOffset[0]; + pickProperties.coord[1] = coord[1] - pickOffset[1]; + } else { + pickProperties.lon = coord[0] - pickOffset[0]; + pickProperties.lat = coord[1] - pickOffset[1]; + } + }); + } + } + } + + // Setup generic handlers for marker drag + map.on('pointerdown', handleDrag); + map.on('pointerup', handleDrag); + map.on('pointerdrag', handleDrag); + + scope.$on('$destroy', function() { + markerLayer.getSource().removeFeature(marker); + if (isDefined(label)) { + map.removeOverlay(label); + } + markerLayerManager.deregisterScope(scope, map); + }); + + if (!isDefined(scope.properties)) { + data.lat = scope.lat ? scope.lat : data.lat; + data.lon = scope.lon ? scope.lon : data.lon; + data.message = attrs.message; + data.style = scope.style ? scope.style : mapDefaults.styles.marker; + + marker = createFeature(data, viewProjection); + if (!isDefined(marker)) { + $log.error('[AngularJS - Openlayers] Received invalid data on ' + + 'the marker.'); + } + // Add a link between the feature and the marker properties + marker.set('marker', scope); + markerLayer.getSource().addFeature(marker); + + if (data.message || hasTranscluded) { + scope.message = attrs.message; + pos = ol.proj.transform([data.lon, data.lat], data.projection, + viewProjection); + label = createOverlay(element, pos); + map.addOverlay(label); + } + return; + } + + scope.$watch('properties', function(properties) { + + // Remove previous listeners if any + map.getViewport().removeEventListener('mousemove', properties.handleInteraction); + map.getViewport().removeEventListener('click', properties.handleTapInteraction); + map.getViewport().querySelector('canvas.ol-unselectable').removeEventListener( + 'touchend', properties.handleTapInteraction); + map.getViewport().removeEventListener('mousemove', properties.showAtLeastOneOverlay); + map.getViewport().removeEventListener('click', properties.removeAllOverlays); + + // This function handles popup on mouse over/click + properties.handleInteraction = function(evt) { + if (properties.label.show) { + return; + } + var found = false; + var pixel = map.getEventPixel(evt); + var feature = map.forEachFeatureAtPixel(pixel, function(feature) { + return feature; + }); + + var actionTaken = false; + if (feature === marker) { + actionTaken = true; + found = true; + if (!isDefined(label)) { + if (data.projection === 'pixel') { + pos = properties.coord; + } else { + pos = ol.proj.transform([properties.lon, properties.lat], + data.projection, viewProjection); + } + label = createOverlay(element, pos); + map.addOverlay(label); + } + + if (properties.onClick && (evt.type === 'click' || evt.type === 'touchend')) { + scope.$apply(function() { + properties.onClick.call(marker, evt, properties); + }); + } + map.getTarget().style.cursor = 'pointer'; + } + + if (!found && label) { + actionTaken = true; + map.removeOverlay(label); + label = undefined; + map.getTarget().style.cursor = ''; + } + + if (actionTaken) { + evt.preventDefault(); + } + }; + + // Made to filter out click/tap events if both are being triggered on this platform + properties.handleTapInteraction = (function() { + var cooldownActive = false; + var prevTimeout; + + // Sets the cooldown flag to filter out any subsequent events within 500 ms + function activateCooldown() { + cooldownActive = true; + if (prevTimeout) { + clearTimeout(prevTimeout); + } + prevTimeout = setTimeout(function() { + cooldownActive = false; + prevTimeout = null; + }, 500); + } + + // Preventing from 'touchend' to be considered a tap, if fired immediately after 'touchmove' + map.getViewport().querySelector('canvas.ol-unselectable').addEventListener( + 'touchmove', activateCooldown); + + return function() { + if (!cooldownActive) { + properties.handleInteraction.apply(null, arguments); + activateCooldown(); + } + }; + })(); + + properties.showAtLeastOneOverlay = function(evt) { + if (properties.label.show) { + return; + } + var found = false; + var pixel = map.getEventPixel(evt); + var feature = map.forEachFeatureAtPixel(pixel, function(feature) { + return feature; + }); + + var actionTaken = false; + if (feature === marker) { + actionTaken = true; + found = true; + if (!isDefined(label)) { + if (data.projection === 'pixel') { + pos = data.coord; + } else { + pos = ol.proj.transform([data.lon, data.lat], + data.projection, viewProjection); + } + label = createOverlay(element, pos); + angular.forEach(map.getOverlays(), function(value) { + map.removeOverlay(value); + }); + map.addOverlay(label); + } + map.getTarget().style.cursor = 'pointer'; + } + + if (!found && label) { + actionTaken = true; + label = undefined; + map.getTarget().style.cursor = ''; + } + + if (actionTaken) { + evt.preventDefault(); + } + }; + + properties.removeAllOverlays = function(evt) { + angular.forEach(map.getOverlays(), function(value) { + map.removeOverlay(value); + }); + evt.preventDefault(); + }; + + if (!isDefined(marker)) { + data.projection = properties.projection ? properties.projection : + data.projection; + data.coord = properties.coord ? properties.coord : data.coord; + data.lat = properties.lat ? properties.lat : data.lat; + data.lon = properties.lon ? properties.lon : data.lon; + + if (isDefined(properties.style)) { + data.style = properties.style; + } else { + data.style = mapDefaults.styles.marker; + } + + marker = createFeature(data, viewProjection); + if (!isDefined(marker)) { + $log.error('[AngularJS - Openlayers] Received invalid data on ' + + 'the marker.'); + } + // Add a link between the feature and the marker properties + marker.set('marker', properties); + markerLayer.getSource().addFeature(marker); + } else { + var requestedPosition; + if (properties.projection === 'pixel') { + requestedPosition = properties.coord; + } else { + requestedPosition = ol.proj.transform([properties.lon, properties.lat], data.projection, + map.getView().getProjection()); + } + + if (!angular.equals(marker.getGeometry().getCoordinates(), requestedPosition)) { + var geometry = new ol.geom.Point(requestedPosition); + marker.setGeometry(geometry); + } + } + + if (isDefined(label)) { + map.removeOverlay(label); + } + + if (!isDefined(properties.label)) { + return; + } + + scope.message = properties.label.message; + if (!hasTranscluded && (!isDefined(scope.message) || scope.message.length === 0)) { + return; + } + + if (properties.label && properties.label.show === true) { + if (data.projection === 'pixel') { + pos = data.coord; + } else { + pos = ol.proj.transform([properties.lon, properties.lat], data.projection, + viewProjection); + } + label = createOverlay(element, pos); + map.addOverlay(label); + } + + if (label && properties.label && properties.label.show === false) { + map.removeOverlay(label); + label = undefined; + } + + // Then setup new ones according to properties + if (properties.label && properties.label.show === false && + properties.label.showOnMouseOver) { + map.getViewport().addEventListener('mousemove', properties.handleInteraction); + } + + if ((properties.label && properties.label.show === false && + properties.label.showOnMouseClick) || + properties.onClick) { + map.getViewport().addEventListener('click', properties.handleTapInteraction); + map.getViewport().querySelector('canvas.ol-unselectable').addEventListener( + 'touchend', properties.handleTapInteraction); + } + + if ((properties.label && properties.label.show === false && + properties.label.keepOneOverlayVisible)) { + map.getViewport().addEventListener('mousemove', properties.showAtLeastOneOverlay); + map.getViewport().addEventListener('click', properties.removeAllOverlays); + } + }, true); + }); + } + }; +}); + +angular.module('openlayers-directive').service('olData', function($log, $q) { + + var maps = {}; + + var setResolvedDefer = function(d, mapId) { + var id = obtainEffectiveMapId(d, mapId); + d[id].resolvedDefer = true; + }; + + var getUnresolvedDefer = function(d, mapId) { + var id = obtainEffectiveMapId(d, mapId); + var defer; + + if (!angular.isDefined(d[id]) || d[id].resolvedDefer === true) { + defer = $q.defer(); + d[id] = { + defer: defer, + resolvedDefer: false + }; + } else { + defer = d[id].defer; + } + return defer; + }; + + var getDefer = function(d, mapId) { + var id = obtainEffectiveMapId(d, mapId); + var defer; + + if (!angular.isDefined(d[id]) || d[id].resolvedDefer === false) { + defer = getUnresolvedDefer(d, mapId); + } else { + defer = d[id].defer; + } + return defer; + }; + + this.setMap = function(olMap, scopeId) { + var defer = getUnresolvedDefer(maps, scopeId); + defer.resolve(olMap); + setResolvedDefer(maps, scopeId); + }; + + this.getMap = function(scopeId) { + var defer = getDefer(maps, scopeId); + return defer.promise; + }; + + function obtainEffectiveMapId(d, mapId) { + var id; + var i; + if (!angular.isDefined(mapId)) { + if (Object.keys(d).length === 1) { + for (i in d) { + if (d.hasOwnProperty(i)) { + id = i; + } + } + } else if (Object.keys(d).length === 0) { + id = 'main'; + } else { + $log.error('[AngularJS - Openlayers] - You have more than 1 map on the DOM, ' + + 'you must provide the map ID to the olData.getXXX call'); + } + } else { + id = mapId; + } + return id; + } + +}); + +angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $http) { + + var isDefined = function(value) { + return angular.isDefined(value); + }; + + var isDefinedAndNotNull = function(value) { + return angular.isDefined(value) && value !== null; + }; + + var setEvent = function(map, eventType, scope) { + map.on(eventType, function(event) { + var coord = event.coordinate; + var proj = map.getView().getProjection().getCode(); + if (proj === 'pixel') { + coord = coord.map(function(v) { + return parseInt(v, 10); + }); + } + scope.$emit('openlayers.map.' + eventType, { + 'coord': coord, + 'projection': proj, + 'event': event + }); + }); + }; + + var bingImagerySets = [ + 'Road', + 'Aerial', + 'AerialWithLabels', + 'collinsBart', + 'ordnanceSurvey' + ]; + + var getControlClasses = function() { + return { + attribution: ol.control.Attribution, + fullscreen: ol.control.FullScreen, + mouseposition: ol.control.MousePosition, + overviewmap: ol.control.OverviewMap, + rotate: ol.control.Rotate, + scaleline: ol.control.ScaleLine, + zoom: ol.control.Zoom, + zoomslider: ol.control.ZoomSlider, + zoomtoextent: ol.control.ZoomToExtent + }; + }; + + var mapQuestLayers = ['osm', 'sat', 'hyb']; + + var esriBaseLayers = ['World_Imagery', 'World_Street_Map', 'World_Topo_Map', + 'World_Physical_Map', 'World_Terrain_Base', + 'Ocean_Basemap', 'NatGeo_World_Map']; + + var styleMap = { + 'style': ol.style.Style, + 'fill': ol.style.Fill, + 'stroke': ol.style.Stroke, + 'circle': ol.style.Circle, + 'icon': ol.style.Icon, + 'image': ol.style.Image, + 'regularshape': ol.style.RegularShape, + 'text': ol.style.Text + }; + + var optionalFactory = function(style, Constructor) { + if (Constructor && style instanceof Constructor) { + return style; + } else if (Constructor) { + return new Constructor(style); + } else { + return style; + } + }; + + //Parse the style tree calling the appropriate constructors. + //The keys in styleMap can be used and the OpenLayers constructors can be + //used directly. + var createStyle = function recursiveStyle(data, styleName) { + var style; + if (!styleName) { + styleName = 'style'; + style = data; + } else { + style = data[styleName]; + } + //Instead of defining one style for the layer, we've been given a style function + //to apply to each feature. + if (styleName === 'style' && data instanceof Function) { + return data; + } + + if (!(style instanceof Object)) { + return style; + } + + var styleObject; + if (Object.prototype.toString.call(style) === '[object Object]') { + styleObject = {}; + var styleConstructor = styleMap[styleName]; + if (styleConstructor && style instanceof styleConstructor) { + return style; + } + Object.getOwnPropertyNames(style).forEach(function(val, idx, array) { + //Consider the case + //image: { + // circle: { + // fill: { + // color: 'red' + // } + // } + // + //An ol.style.Circle is an instance of ol.style.Image, so we do not want to construct + //an Image and then construct a Circle. We assume that if we have an instanceof + //relationship, that the JSON parent has exactly one child. + //We check to see if an inheritance relationship exists. + //If it does, then for the parent we create an instance of the child. + var valConstructor = styleMap[val]; + if (styleConstructor && valConstructor && + valConstructor.prototype instanceof styleMap[styleName]) { + console.assert(array.length === 1, 'Extra parameters for ' + styleName); + styleObject = recursiveStyle(style, val); + return optionalFactory(styleObject, valConstructor); + } else { + styleObject[val] = recursiveStyle(style, val); + + // if the value is 'text' and it contains a String, then it should be interpreted + // as such, 'cause the text style might effectively contain a text to display + if (val !== 'text' && typeof styleObject[val] !== 'string') { + styleObject[val] = optionalFactory(styleObject[val], styleMap[val]); + } + } + }); + } else { + styleObject = style; + } + return optionalFactory(styleObject, styleMap[styleName]); + }; + + var detectLayerType = function(layer) { + if (layer.type) { + return layer.type; + } else { + switch (layer.source.type) { + case 'ImageWMS': + return 'Image'; + case 'ImageStatic': + return 'Image'; + case 'GeoJSON': + case 'JSONP': + case 'TopoJSON': + case 'KML': + case 'TileVector': + return 'Vector'; + default: + return 'Tile'; + } + } + }; + + var createProjection = function(view) { + var oProjection; + + switch (view.projection) { + case 'pixel': + if (!isDefined(view.extent)) { + $log.error('[AngularJS - Openlayers] - You must provide the extent of the image ' + + 'if using pixel projection'); + return; + } + oProjection = new ol.proj.Projection({ + code: 'pixel', + units: 'pixels', + extent: view.extent + }); + break; + default: + oProjection = new ol.proj.get(view.projection); + break; + } + + return oProjection; + }; + + var isValidStamenLayer = function(layer) { + return ['watercolor', 'terrain', 'toner'].indexOf(layer) !== -1; + }; + + var createSource = function(source, projection) { + var oSource; + + switch (source.type) { + case 'MapBox': + if (!source.mapId || !source.accessToken) { + $log.error('[AngularJS - Openlayers] - MapBox layer requires the map id and the access token'); + return; + } + var url = 'http://api.tiles.mapbox.com/v4/' + source.mapId + '/{z}/{x}/{y}.png?access_token=' + + source.accessToken; + + var pixelRatio = window.devicePixelRatio; + + if (pixelRatio > 1) { + url = url.replace('.png', '@2x.png'); + } + + oSource = new ol.source.XYZ({ + url: url, + attributions: createAttribution(source), + tilePixelRatio: pixelRatio > 1 ? 2 : 1 + }); + break; + case 'ImageWMS': + if (!source.url || !source.params) { + $log.error('[AngularJS - Openlayers] - ImageWMS Layer needs ' + + 'valid server url and params properties'); + } + oSource = new ol.source.ImageWMS({ + url: source.url, + attributions: createAttribution(source), + crossOrigin: (typeof source.crossOrigin === 'undefined') ? 'anonymous' : source.crossOrigin, + params: source.params + }); + break; + + case 'TileWMS': + if ((!source.url && !source.urls) || !source.params) { + $log.error('[AngularJS - Openlayers] - TileWMS Layer needs ' + + 'valid url (or urls) and params properties'); + } + + var wmsConfiguration = { + crossOrigin: (typeof source.crossOrigin === 'undefined') ? 'anonymous' : source.crossOrigin, + params: source.params, + attributions: createAttribution(source) + }; + + if (source.serverType) { + wmsConfiguration.serverType = source.serverType; + } + + if (source.url) { + wmsConfiguration.url = source.url; + } + + if (source.urls) { + wmsConfiguration.urls = source.urls; + } + + oSource = new ol.source.TileWMS(wmsConfiguration); + break; + + case 'WMTS': + if ((!source.url && !source.urls) || !source.tileGrid) { + $log.error('[AngularJS - Openlayers] - WMTS Layer needs valid url ' + + '(or urls) and tileGrid properties'); + } + + var wmtsConfiguration = { + projection: projection, + layer: source.layer, + attributions: createAttribution(source), + matrixSet: (source.matrixSet === 'undefined') ? projection : source.matrixSet, + format: (source.format === 'undefined') ? 'image/jpeg' : source.format, + requestEncoding: (source.requestEncoding === 'undefined') ? + 'KVP' : source.requestEncoding, + tileGrid: new ol.tilegrid.WMTS({ + origin: source.tileGrid.origin, + resolutions: source.tileGrid.resolutions, + matrixIds: source.tileGrid.matrixIds + }) + }; + + if (isDefined(source.url)) { + wmtsConfiguration.url = source.url; + } + + if (isDefined(source.urls)) { + wmtsConfiguration.urls = source.urls; + } + + oSource = new ol.source.WMTS(wmtsConfiguration); + break; + + case 'OSM': + oSource = new ol.source.OSM({ + attributions: createAttribution(source) + }); + + if (source.url) { + oSource.setUrl(source.url); + } + + break; + case 'BingMaps': + if (!source.key) { + $log.error('[AngularJS - Openlayers] - You need an API key to show the Bing Maps.'); + return; + } + + var bingConfiguration = { + key: source.key, + attributions: createAttribution(source), + imagerySet: source.imagerySet ? source.imagerySet : bingImagerySets[0], + culture: source.culture + }; + + if (source.maxZoom) { + bingConfiguration.maxZoom = source.maxZoom; + } + + oSource = new ol.source.BingMaps(bingConfiguration); + break; + + case 'MapQuest': + if (!source.layer || mapQuestLayers.indexOf(source.layer) === -1) { + $log.error('[AngularJS - Openlayers] - MapQuest layers needs a valid \'layer\' property.'); + return; + } + + oSource = new ol.source.MapQuest({ + attributions: createAttribution(source), + layer: source.layer + }); + + break; + + case 'EsriBaseMaps': + if (!source.layer || esriBaseLayers.indexOf(source.layer) === -1) { + $log.error('[AngularJS - Openlayers] - ESRI layers needs a valid \'layer\' property.'); + return; + } + + var _urlBase = 'http://services.arcgisonline.com/ArcGIS/rest/services/'; + var _url = _urlBase + source.layer + '/MapServer/tile/{z}/{y}/{x}'; + + oSource = new ol.source.XYZ({ + attributions: createAttribution(source), + url: _url + }); + + break; + + case 'GeoJSON': + if (!(source.geojson || source.url)) { + $log.error('[AngularJS - Openlayers] - You need a geojson ' + + 'property to add a GeoJSON layer.'); + return; + } + + if (isDefined(source.url)) { + oSource = new ol.source.Vector({ + format: new ol.format.GeoJSON(), + url: source.url + }); + } else { + oSource = new ol.source.Vector(); + + var projectionToUse = projection; + if (isDefined(source.geojson.projection)) { + projectionToUse = source.geojson.projection; + } + + var geojsonFormat = new ol.format.GeoJSON(); + var features = geojsonFormat.readFeatures( + source.geojson.object, { featureProjection: projectionToUse }); + + oSource.addFeatures(features); + } + + break; + case 'JSONP': + if (!(source.url)) { + $log.error('[AngularJS - Openlayers] - You need an url properly configured to add a JSONP layer.'); + return; + } + + if (isDefined(source.url)) { + oSource = new ol.source.Vector({ + format: new ol.format.GeoJSON(), + loader: function(/*extent, resolution, projection*/) { + var url = source.url + + '&outputFormat=text/javascript&format_options=callback:JSON_CALLBACK'; + $http.jsonp(url, { cache: source.cache}).success(function(response) { + oSource.addFeatures(oSource.readFeatures(response)); + }).error(function(response) { + $log(response); + }); + } + }); + } + break; + case 'TopoJSON': + if (!(source.topojson || source.url)) { + $log.error('[AngularJS - Openlayers] - You need a topojson ' + + 'property to add a TopoJSON layer.'); + return; + } + + if (source.url) { + oSource = new ol.source.Vector({ + format: new ol.format.TopoJSON(), + url: source.url + }); + } else { + oSource = new ol.source.Vector(angular.extend(source.topojson, { + format: new ol.format.TopoJSON() + })); + } + break; + case 'TileJSON': + oSource = new ol.source.TileJSON({ + url: source.url, + attributions: createAttribution(source), + crossOrigin: 'anonymous' + }); + break; + + case 'TileVector': + if (!source.url || !source.format) { + $log.error('[AngularJS - Openlayers] - TileVector Layer needs valid url and format properties'); + } + oSource = new ol.source.TileVector({ + url: source.url, + projection: projection, + attributions: createAttribution(source), + format: source.format, + tileGrid: new ol.tilegrid.createXYZ({ + maxZoom: source.maxZoom || 19 + }) + }); + break; + + case 'TileTMS': + if (!source.url || !source.tileGrid) { + $log.error('[AngularJS - Openlayers] - TileTMS Layer needs valid url and tileGrid properties'); + } + oSource = new ol.source.TileImage({ + url: source.url, + maxExtent: source.maxExtent, + attributions: createAttribution(source), + tileGrid: new ol.tilegrid.TileGrid({ + origin: source.tileGrid.origin, + resolutions: source.tileGrid.resolutions + }), + tileUrlFunction: function(tileCoord) { + + var z = tileCoord[0]; + var x = tileCoord[1]; + var y = tileCoord[2]; //(1 << z) - tileCoord[2] - 1; + + if (x < 0 || y < 0) { + return ''; + } + + var url = source.url + z + '/' + x + '/' + y + '.png'; + + return url; + } + }); + break; + case 'TileImage': + oSource = new ol.source.TileImage({ + url: source.url, + attributions: createAttribution(source), + tileGrid: new ol.tilegrid.TileGrid({ + origin: source.tileGrid.origin, // top left corner of the pixel projection's extent + resolutions: source.tileGrid.resolutions + }), + tileUrlFunction: function(tileCoord/*, pixelRatio, projection*/) { + var z = tileCoord[0]; + var x = tileCoord[1]; + var y = -tileCoord[2] - 1; + var url = source.url + .replace('{z}', z.toString()) + .replace('{x}', x.toString()) + .replace('{y}', y.toString()); + return url; + } + }); + break; + case 'KML': + var extractStyles = source.extractStyles || false; + oSource = new ol.source.Vector({ + url: source.url, + format: new ol.format.KML(), + radius: source.radius, + extractStyles: extractStyles + }); + break; + case 'Stamen': + if (!source.layer || !isValidStamenLayer(source.layer)) { + $log.error('[AngularJS - Openlayers] - You need a valid Stamen layer.'); + return; + } + oSource = new ol.source.Stamen({ + layer: source.layer + }); + break; + case 'ImageStatic': + if (!source.url || !angular.isArray(source.imageSize) || source.imageSize.length !== 2) { + $log.error('[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.'); + return; + } + + oSource = new ol.source.ImageStatic({ + url: source.url, + attributions: createAttribution(source), + imageSize: source.imageSize, + projection: projection, + imageExtent: projection.getExtent(), + imageLoadFunction: source.imageLoadFunction + }); + break; + case 'XYZ': + if (!source.url) { + $log.error('[AngularJS - Openlayers] - XYZ Layer needs valid url and params properties'); + } + oSource = new ol.source.XYZ({ + url: source.url, + attributions: createAttribution(source), + minZoom: source.minZoom, + maxZoom: source.maxZoom + }); + break; + } + + // log a warning when no source could be created for the given type + if (!oSource) { + $log.warn('[AngularJS - Openlayers] - No source could be found for type "' + source.type + '"'); + } + + return oSource; + }; + + var createAttribution = function(source) { + var attributions = []; + if (isDefined(source.attribution)) { + attributions.unshift(new ol.Attribution({html: source.attribution})); + } + return attributions; + }; + + var createGroup = function(name) { + var olGroup = new ol.layer.Group(); + olGroup.set('name', name); + + return olGroup; + }; + + var getGroup = function(layers, name) { + var layer; + + angular.forEach(layers, function(l) { + if (l instanceof ol.layer.Group && l.get('name') === name) { + layer = l; + return; + } + }); + + return layer; + }; + + var addLayerBeforeMarkers = function(layers, layer) { + var markersIndex; + for (var i = 0; i < layers.getLength(); i++) { + var l = layers.item(i); + + if (l.get('markers')) { + markersIndex = i; + break; + } + } + + if (isDefined(markersIndex)) { + var markers = layers.item(markersIndex); + layer.index = markersIndex; + layers.setAt(markersIndex, layer); + markers.index = layers.getLength(); + layers.push(markers); + } else { + layer.index = layers.getLength(); + layers.push(layer); + } + + }; + + var removeLayer = function(layers, index) { + layers.removeAt(index); + for (var i = index; i < layers.getLength(); i++) { + var l = layers.item(i); + if (l === null) { + layers.insertAt(i, null); + break; + } else { + l.index = i; + } + } + }; + + return { + // Determine if a reference is defined + isDefined: isDefined, + + // Determine if a reference is a number + isNumber: function(value) { + return angular.isNumber(value); + }, + + createView: function(view) { + var projection = createProjection(view); + + var viewConfig = { + projection: projection, + maxZoom: view.maxZoom, + minZoom: view.minZoom + }; + + if (view.center) { + viewConfig.center = view.center; + } + if (view.extent) { + viewConfig.extent = view.extent; + } + if (view.zoom) { + viewConfig.zoom = view.zoom; + } + + return new ol.View(viewConfig); + }, + + // Determine if a reference is defined and not null + isDefinedAndNotNull: isDefinedAndNotNull, + + // Determine if a reference is a string + isString: function(value) { + return angular.isString(value); + }, + + // Determine if a reference is an array + isArray: function(value) { + return angular.isArray(value); + }, + + // Determine if a reference is an object + isObject: function(value) { + return angular.isObject(value); + }, + + // Determine if two objects have the same properties + equals: function(o1, o2) { + return angular.equals(o1, o2); + }, + + isValidCenter: function(center) { + return angular.isDefined(center) && + (typeof center.autodiscover === 'boolean' || + angular.isNumber(center.lat) && angular.isNumber(center.lon) || + (angular.isArray(center.coord) && center.coord.length === 2 && + angular.isNumber(center.coord[0]) && angular.isNumber(center.coord[1])) || + (angular.isArray(center.bounds) && center.bounds.length === 4 && + angular.isNumber(center.bounds[0]) && angular.isNumber(center.bounds[1]) && + angular.isNumber(center.bounds[1]) && angular.isNumber(center.bounds[2]))); + }, + + safeApply: function($scope, fn) { + var phase = $scope.$root.$$phase; + if (phase === '$apply' || phase === '$digest') { + $scope.$eval(fn); + } else { + $scope.$apply(fn); + } + }, + + isSameCenterOnMap: function(center, map) { + var urlProj = center.projection || 'EPSG:4326'; + var urlCenter = [center.lon, center.lat]; + var mapProj = map.getView().getProjection(); + var mapCenter = ol.proj.transform(map.getView().getCenter(), mapProj, urlProj); + var zoom = map.getView().getZoom(); + if (mapCenter[1].toFixed(4) === urlCenter[1].toFixed(4) && + mapCenter[0].toFixed(4) === urlCenter[0].toFixed(4) && + zoom === center.zoom) { + return true; + } + return false; + }, + + setCenter: function(view, projection, newCenter, map) { + + if (map && view.getCenter()) { + var pan = ol.animation.pan({ + duration: 150, + source: (view.getCenter()) + }); + map.beforeRender(pan); + } + + if (newCenter.projection === projection) { + view.setCenter([newCenter.lon, newCenter.lat]); + } else { + var coord = [newCenter.lon, newCenter.lat]; + view.setCenter(ol.proj.transform(coord, newCenter.projection, projection)); + } + }, + + setZoom: function(view, zoom, map) { + var z = ol.animation.zoom({ + duration: 150, + resolution: map.getView().getResolution() + }); + map.beforeRender(z); + view.setZoom(zoom); + }, + + isBoolean: function(value) { + return typeof value === 'boolean'; + }, + + createStyle: createStyle, + + setMapEvents: function(events, map, scope) { + if (isDefined(events) && angular.isArray(events.map)) { + for (var i in events.map) { + var event = events.map[i]; + setEvent(map, event, scope); + } + } + }, + + setVectorLayerEvents: function(events, map, scope, layerName) { + if (isDefined(events) && angular.isArray(events.layers)) { + angular.forEach(events.layers, function(eventType) { + angular.element(map.getViewport()).on(eventType, function(evt) { + var pixel = map.getEventPixel(evt); + var feature = map.forEachFeatureAtPixel(pixel, function(feature, olLayer) { + // only return the feature if it is in this layer (based on the name) + return (isDefinedAndNotNull(olLayer) && olLayer.get('name') === layerName) ? feature : null; + }); + if (isDefinedAndNotNull(feature)) { + scope.$emit('openlayers.layers.' + layerName + '.' + eventType, feature, evt); + } + }); + }); + } + }, + + setViewEvents: function(events, map, scope) { + if (isDefined(events) && angular.isArray(events.view)) { + var view = map.getView(); + angular.forEach(events.view, function(eventType) { + view.on(eventType, function(event) { + scope.$emit('openlayers.view.' + eventType, view, event); + }); + }); + } + }, + + detectLayerType: detectLayerType, + + createLayer: function(layer, projection, name) { + var oLayer; + var type = detectLayerType(layer); + var oSource = createSource(layer.source, projection); + if (!oSource) { + return; + } + + // Manage clustering + if ((type === 'Vector') && layer.clustering) { + oSource = new ol.source.Cluster({ + source: oSource, + distance: layer.clusteringDistance + }); + } + + switch (type) { + case 'Image': + oLayer = new ol.layer.Image({ source: oSource }); + break; + case 'Tile': + oLayer = new ol.layer.Tile({ source: oSource }); + break; + case 'Heatmap': + oLayer = new ol.layer.Heatmap({ source: oSource }); + break; + case 'Vector': + oLayer = new ol.layer.Vector({ source: oSource }); + break; + } + + // set a layer name if given + if (isDefined(name)) { + oLayer.set('name', name); + } else if (isDefined(layer.name)) { + oLayer.set('name', layer.name); + } + + // set custom layer properties if given + if (isDefined(layer.customAttributes)) { + for (var key in layer.customAttributes) { + oLayer.set(key, layer.customAttributes[key]); + } + } + + return oLayer; + }, + + createVectorLayer: function() { + return new ol.layer.Vector({ + source: new ol.source.Vector() + }); + }, + + notifyCenterUrlHashChanged: function(scope, center, search) { + if (center.centerUrlHash) { + var centerUrlHash = center.lat.toFixed(4) + ':' + center.lon.toFixed(4) + ':' + center.zoom; + if (!isDefined(search.c) || search.c !== centerUrlHash) { + scope.$emit('centerUrlHash', centerUrlHash); + } + } + }, + + getControlClasses: getControlClasses, + + detectControls: function(controls) { + var actualControls = {}; + var controlClasses = getControlClasses(); + + controls.forEach(function(control) { + for (var i in controlClasses) { + if (control instanceof controlClasses[i]) { + actualControls[i] = control; + } + } + }); + + return actualControls; + }, + + createFeature: function(data, viewProjection) { + var geometry; + + switch (data.type) { + case 'Polygon': + geometry = new ol.geom.Polygon(data.coords); + break; + default: + if (isDefined(data.coord) && data.projection === 'pixel') { + geometry = new ol.geom.Point(data.coord); + } else { + geometry = new ol.geom.Point([data.lon, data.lat]); + } + break; + } + + if (isDefined(data.projection) && data.projection !== 'pixel') { + geometry = geometry.transform(data.projection, viewProjection); + } + + var feature = new ol.Feature({ + geometry: geometry + }); + + if (isDefined(data.style)) { + var style = createStyle(data.style); + feature.setStyle(style); + } + return feature; + }, + + addLayerBeforeMarkers: addLayerBeforeMarkers, + + getGroup: getGroup, + + addLayerToGroup: function(layers, layer, name) { + var groupLayer = getGroup(layers, name); + + if (!isDefined(groupLayer)) { + groupLayer = createGroup(name); + addLayerBeforeMarkers(layers,groupLayer); + } + + layer.set('group', name); + addLayerBeforeMarkers(groupLayer.getLayers(), layer); + }, + + removeLayerFromGroup: function(layers, layer, name) { + var groupLayer = getGroup(layers, name); + layer.set('group'); + removeLayer(groupLayer.getLayers(), layer.index); + }, + + removeLayer: removeLayer, + + insertLayer: function(layers, index, layer) { + if (layers.getLength() < index) { + // fill up with "null layers" till we get to the desired index + while (layers.getLength() < index) { + var nullLayer = new ol.layer.Image(); + nullLayer.index = layers.getLength(); // add index which will be equal to the length in this case + layers.push(nullLayer); + } + layer.index = index; + layers.push(layer); + } else { + layer.index = index; + layers.insertAt(layer.index, layer); + for (var i = index + 1; i < layers.getLength(); i++) { + var l = layers.item(i); + if (l === null) { + layers.removeAt(i); + break; + } else { + l.index = i; + } + } + } + }, + + createOverlay: function(element, pos) { + element.css('display', 'block'); + var ov = new ol.Overlay({ + position: pos, + element: element, + positioning: 'center-left' + }); + + return ov; + } + }; +}); + +angular.module('openlayers-directive').factory('olMapDefaults', function($q, olHelpers) { + + var base64icon = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAApCAYAAADAk4LOAAAGmklEQVRYw' + + '7VXeUyTZxjvNnfELFuyIzOabermMZEeQC/OclkO49CpOHXOLJl/CAURuYbQi3KLgEhbrhZ1aDwmaoGq' + + 'KII6odATmH/scDFbdC7LvFqOCc+e95s2VG50X/LLm/f4/Z7neY/ne18aANCmAr5E/xZf1uDOkTcGcWR' + + '6hl9247tT5U7Y6SNvWsKT63P58qbfeLJG8M5qcgTknrvvrdDbsT7Ml+tv82X6vVxJE33aRmgSyYtcWV' + + 'MqX97Yv2JvW39UhRE2HuyBL+t+gK1116ly06EeWFNlAmHxlQE0OMiV6mQCScusKRlhS3QLeVJdl1+23' + + 'h5dY4FNB3thrbYboqptEFlphTC1hSpJnbRvxP4NWgsE5Jyz86QNNi/5qSUTGuFk1gu54tN9wuK2wc3o' + + '+Wc13RCmsoBwEqzGcZsxsvCSy/9wJKf7UWf1mEY8JWfewc67UUoDbDjQC+FqK4QqLVMGGR9d2wurKzq' + + 'Bk3nqIT/9zLxRRjgZ9bqQgub+DdoeCC03Q8j+0QhFhBHR/eP3U/zCln7Uu+hihJ1+bBNffLIvmkyP0g' + + 'pBZWYXhKussK6mBz5HT6M1Nqpcp+mBCPXosYQfrekGvrjewd59/GvKCE7TbK/04/ZV5QZYVWmDwH1mF' + + '3xa2Q3ra3DBC5vBT1oP7PTj4C0+CcL8c7C2CtejqhuCnuIQHaKHzvcRfZpnylFfXsYJx3pNLwhKzRAw' + + 'AhEqG0SpusBHfAKkxw3w4627MPhoCH798z7s0ZnBJ/MEJbZSbXPhER2ih7p2ok/zSj2cEJDd4CAe+5W' + + 'YnBCgR2uruyEw6zRoW6/DWJ/OeAP8pd/BGtzOZKpG8oke0SX6GMmRk6GFlyAc59K32OTEinILRJRcha' + + 'h8HQwND8N435Z9Z0FY1EqtxUg+0SO6RJ/mmXz4VuS+DpxXC3gXmZwIL7dBSH4zKE50wESf8qwVgrP1E' + + 'IlTO5JP9Igu0aexdh28F1lmAEGJGfh7jE6ElyM5Rw/FDcYJjWhbeiBYoYNIpc2FT/SILivp0F1ipDWk' + + '4BIEo2VuodEJUifhbiltnNBIXPUFCMpthtAyqws/BPlEF/VbaIxErdxPphsU7rcCp8DohC+GvBIPJS/' + + 'tW2jtvTmmAeuNO8BNOYQeG8G/2OzCJ3q+soYB5i6NhMaKr17FSal7GIHheuV3uSCY8qYVuEm1cOzqdW' + + 'r7ku/R0BDoTT+DT+ohCM6/CCvKLKO4RI+dXPeAuaMqksaKrZ7L3FE5FIFbkIceeOZ2OcHO6wIhTkNo0' + + 'ffgjRGxEqogXHYUPHfWAC/lADpwGcLRY3aeK4/oRGCKYcZXPVoeX/kelVYY8dUGf8V5EBRbgJXT5QIP' + + 'hP9ePJi428JKOiEYhYXFBqou2Guh+p/mEB1/RfMw6rY7cxcjTrneI1FrDyuzUSRm9miwEJx8E/gUmql' + + 'yvHGkneiwErR21F3tNOK5Tf0yXaT+O7DgCvALTUBXdM4YhC/IawPU+2PduqMvuaR6eoxSwUk75ggqsY' + + 'J7VicsnwGIkZBSXKOUww73WGXyqP+J2/b9c+gi1YAg/xpwck3gJuucNrh5JvDPvQr0WFXf0piyt8f8/' + + 'WI0hV4pRxxkQZdJDfDJNOAmM0Ag8jyT6hz0WGXWuP94Yh2jcfjmXAGvHCMslRimDHYuHuDsy2QtHuIa' + + 'vznhbYURq5R57KpzBBRZKPJi8eQg48h4j8SDdowifdIrEVdU+gbO6QNvRRt4ZBthUaZhUnjlYObNagV' + + '3keoeru3rU7rcuceqU1mJBxy+BWZYlNEBH+0eH4vRiB+OYybU2hnblYlTvkHinM4m54YnxSyaZYSF6R' + + '3jwgP7udKLGIX6r/lbNa9N6y5MFynjWDtrHd75ZvTYAPO/6RgF0k76mQla3FGq7dO+cH8sKn0Vo7nDl' + + 'lwAhqwLPkxrHwWmHJOo+AKJ4rab5OgrM7rVu8eWb2Pu0Dh4eDgXoOfvp7Y7QeqknRmvcTBEyq9m/HQQ' + + 'SCSz6LHq3z0yzsNySRfMS253wl2KyRDbcZPcfJKjZmSEOjcxyi+Y8dUOtsIEH6R2wNykdqrkYJ0RV92' + + 'H0W58pkfQk7cKevsLK10Py8SdMGfXNXATY+pPbyJR/ET6n9nIfztNtZYRV9XniQu9IA2vOVgy4ir7GC' + + 'LVmmd+zjkH0eAF9Po6K61pmCXHxU5rHMYd1ftc3owjwRSVRzLjKvqZEty6cRUD7jGqiOdu5HG6MdHjN' + + 'cNYGqfDm5YRzLBBCCDl/2bk8a8gdbqcfwECu62Fg/HrggAAAABJRU5ErkJggg=='; + + var _getDefaults = function() { + return { + view: { + projection: 'EPSG:3857', + minZoom: undefined, + maxZoom: undefined, + rotation: 0, + extent: undefined + }, + center: { + lat: 0, + lon: 0, + zoom: 1, + autodiscover: false, + bounds: [], + centerUrlHash: false, + projection: 'EPSG:4326' + }, + styles: { + path: { + stroke: { + color: 'blue', + width: 8 + } + }, + marker: { + image: new ol.style.Icon({ + anchor: [0.5, 1], + anchorXUnits: 'fraction', + anchorYUnits: 'fraction', + opacity: 0.90, + src: base64icon + }) + } + }, + events: { + map: [], + markers: [], + layers: [] + }, + controls: { + attribution: true, + rotate: false, + zoom: true + }, + interactions: { + mouseWheelZoom: false + }, + renderer: 'canvas' + }; + }; + + var isDefined = olHelpers.isDefined; + var defaults = {}; + + // Get the _defaults dictionary, and override the properties defined by the user + return { + getDefaults: function(scope) { + if (!isDefined(scope)) { + for (var i in defaults) { + return defaults[i]; + } + } + return defaults[scope.$id]; + }, + + setDefaults: function(scope) { + var userDefaults = scope.defaults; + var scopeId = scope.$id; + var newDefaults = _getDefaults(); + + if (isDefined(userDefaults)) { + + if (isDefined(userDefaults.layers)) { + newDefaults.layers = angular.copy(userDefaults.layers); + } + + if (isDefined(userDefaults.controls)) { + newDefaults.controls = angular.copy(userDefaults.controls); + } + + if (isDefined(userDefaults.events)) { + newDefaults.events = angular.copy(userDefaults.events); + } + + if (isDefined(userDefaults.interactions)) { + newDefaults.interactions = angular.copy(userDefaults.interactions); + } + + if (isDefined(userDefaults.renderer)) { + newDefaults.renderer = userDefaults.renderer; + } + + if (isDefined(userDefaults.view)) { + newDefaults.view.maxZoom = userDefaults.view.maxZoom || newDefaults.view.maxZoom; + newDefaults.view.minZoom = userDefaults.view.minZoom || newDefaults.view.minZoom; + newDefaults.view.projection = userDefaults.view.projection || newDefaults.view.projection; + newDefaults.view.extent = userDefaults.view.extent || newDefaults.view.extent; + } + + if (isDefined(userDefaults.styles)) { + newDefaults.styles = angular.extend(newDefaults.styles, userDefaults.styles); + } + + } + + defaults[scopeId] = newDefaults; + return newDefaults; + } + }; +}); + +})); \ No newline at end of file diff --git a/node_modules/.bin/grunt-open b/node_modules/.bin/grunt-open new file mode 100644 index 00000000..b6035be1 --- /dev/null +++ b/node_modules/.bin/grunt-open @@ -0,0 +1,15 @@ +#!/bin/sh +basedir=`dirname "$0"` + +case `uname` in + *CYGWIN*) basedir=`cygpath -w "$basedir"`;; +esac + +if [ -x "$basedir/node" ]; then + "$basedir/node" "$basedir/../grunt-open/bin/grunt-open" "$@" + ret=$? +else + node "$basedir/../grunt-open/bin/grunt-open" "$@" + ret=$? +fi +exit $ret From d2d83dd455318420ce9d4760c986c377be99c54a Mon Sep 17 00:00:00 2001 From: Sathish Date: Tue, 12 Jan 2016 11:22:26 +0530 Subject: [PATCH 11/53] Upgrade it to Openlayers 12 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0f1a79ef..5c50ad5d 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "dependencies": { "angular": "~1.4.8", "angular-sanitize": "~1.4.8", - "openlayers": "~3.8" + "openlayers": "~3.12" }, "devDependencies": { "grunt": "~0.4.5", From faa71ca89034e0a2d2b751e0491a25b6ab0aab87 Mon Sep 17 00:00:00 2001 From: Sathish Date: Tue, 12 Jan 2016 22:41:45 +0530 Subject: [PATCH 12/53] enhanced commonjs compatibility --- grunt/concat.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/grunt/concat.js b/grunt/concat.js index 31e34c2f..75afa024 100644 --- a/grunt/concat.js +++ b/grunt/concat.js @@ -4,7 +4,8 @@ var banner = '(function (root, factory) {\n' + ' if (typeof require === \'function\' && typeof exports === \'object\') {\n' + ' // CommonJS\n' + ' var ol = require(\'openlayers\');\n' + - ' exports.angularOpenlayersDirective = factory(ol);\n' + + ' var ngSanitize = require(\'angular-sanitize\');\n' + + ' exports.angularOpenlayersDirective = factory(ol).name;\n' + ' } else if (typeof define === \'function\' && define.amd) {\n' + ' // AMD.\n' + ' define([\'ol\'], function (ol) {\n' + @@ -15,13 +16,15 @@ var banner = '(function (root, factory) {\n' + ' root.angularOpenlayersDirective = factory(root.ol);\n' + ' }\n' + '}(this, function (ol) {\n'; +var footer = 'return angular.module(\'openlayers-directive\')' + + '\n})); module.exports = function (grunt, options) { return { dist: { options: { banner: banner, - footer: '\n}));' + footer: footer }, src: [ 'src/directives/openlayers.js', From 27e894fd81565dc2771114811f3d0fd637e944ff Mon Sep 17 00:00:00 2001 From: Sathish Date: Tue, 12 Jan 2016 23:04:40 +0530 Subject: [PATCH 13/53] First build after commonjs code correction --- dist/angular-openlayers-directive.js | 5 +++-- dist/angular-openlayers-directive.min.js | 6 +++--- dist/angular-openlayers-directive.min.no-header.js | 6 +++--- dist/angular-openlayers-directive.pre.js | 5 +++-- grunt/concat.js | 2 +- 5 files changed, 13 insertions(+), 11 deletions(-) diff --git a/dist/angular-openlayers-directive.js b/dist/angular-openlayers-directive.js index fb973da7..e9640a97 100644 --- a/dist/angular-openlayers-directive.js +++ b/dist/angular-openlayers-directive.js @@ -2,7 +2,8 @@ if (typeof require === 'function' && typeof exports === 'object') { // CommonJS var ol = require('openlayers'); - exports.angularOpenlayersDirective = factory(ol); + var ngSanitize = require('angular-sanitize'); + exports.angularOpenlayersDirective = factory(ol).name; } else if (typeof define === 'function' && define.amd) { // AMD. define(['ol'], function (ol) { @@ -2274,5 +2275,5 @@ angular.module('openlayers-directive').factory('olMapDefaults', ["$q", "olHelper } }; }]); - +return angular.module('openlayers-directive') })); \ No newline at end of file diff --git a/dist/angular-openlayers-directive.min.js b/dist/angular-openlayers-directive.min.js index 1f238470..46be0c14 100644 --- a/dist/angular-openlayers-directive.min.js +++ b/dist/angular-openlayers-directive.min.js @@ -27,6 +27,6 @@ * @authors https://github.com/tombatossals/angular-openlayers-directive/graphs/contributors */ -/*! angular-openlayers-directive 06-11-2015 */ -!function(a,b){"function"==typeof define&&define.amd?define(["ol"],function(c){return a.angularOpenlayersDirective=b(c)}):a.angularOpenlayersDirective=b(a.ol)}(this,function(a){angular.module("openlayers-directive",["ngSanitize"]).directive("openlayers",["$log","$q","$compile","olHelpers","olMapDefaults","olData",function(b,c,d,e,f,g){return{restrict:"EA",transclude:!0,replace:!0,scope:{center:"=olCenter",defaults:"=olDefaults",view:"=olView",events:"=olEvents"},template:'
',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p});if(!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d){if("pixel"===g.view.projection)return void i.setCenter(c.coord);var e=a.proj.transform(d,g.view.projection,c.projection);(e[1]!==c.lat||e[0]!==c.lon)&&p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}}),f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i))}else d=j(c,f),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i))}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)}),e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope();i.getMap().then(function(b){var d=e.getControlClasses,i=d();return a.$on("$destroy",function(){b.removeControl(f)}),h(a.properties)&&h(a.properties.control)?(f=a.properties.control,void b.addControl(f)):void(c.name&&(h(a.properties)&&(g=a.properties),f=new i[c.name](g),b.addControl(f)))})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return e.on("pointerdown",j),e.on("pointerup",j),e.on("pointerdrag",j),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e)}),k(c.properties)?void c.$watch("properties",function(d){if(e.getViewport().removeEventListener("mousemove",d.handleInteraction),e.getViewport().removeEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",d.handleTapInteraction),e.getViewport().removeEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",d.removeAllOverlays),d.handleInteraction=function(b){if(!d.label.show){var f=!1,g=e.getEventPixel(b),i=e.forEachFeatureAtPixel(g,function(a){return a}),j=!1;i===r&&(j=!0,f=!0,k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),!d.onClick||"click"!==b.type&&"touchend"!==b.type||c.$apply(function(){d.onClick.call(r,b,d)}),e.getTarget().style.cursor="pointer"),!f&&p&&(j=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),j&&b.preventDefault()}},d.handleTapInteraction=function(){function a(){c=!0,b&&clearTimeout(b),b=setTimeout(function(){c=!1,b=null},500)}var b,c=!1;return e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",a),function(){c||(d.handleInteraction.apply(null,arguments),a())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||d.onClick)&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q","olHelpers",function(a,b,c){var d=c.obtainEffectiveMapId,e={},f=function(a,b){var c=d(a,b);a[c].resolvedDefer=!0},g=function(a,c){var e,f=d(a,c);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},h=function(a,b){var c,e=d(a,b);return c=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:g(a,b)};this.setMap=function(a,b){var c=g(e,b);c.resolve(a),f(e,b)},this.getMap=function(a){var b=h(e,a);return b.promise}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function x(a,b){var c;if(b?c=a[b]:(b="style",c=a),"style"===b&&a instanceof Function)return a;if(!(c instanceof Object))return c;var d;if("[object Object]"===Object.prototype.toString.call(c)){d={};var e=l[b];if(e&&c instanceof e)return c;Object.getOwnPropertyNames(c).forEach(function(a,f,g){var h=l[a];return e&&h&&h.prototype instanceof l[b]?(console.assert(1===g.length,"Extra parameters for "+b),d=x(c,a),m(d,h)):(d[a]=x(c,a),void("text"!==a&&"string"!=typeof d[a]&&(d[a]=m(d[a],l[a]))))})}else d=c;return m(d,l[b])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"TileVector":return"Vector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");var i="http://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,l=window.devicePixelRatio;l>1&&(i=i.replace(".png","@2x.png")),g=new a.source.XYZ({url:i,attributions:s(b),tilePixelRatio:l>1?2:1,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,attributions:s(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:b.params,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var m={crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:b.params,attributions:s(b),wrapX:void 0===b.wrapX?1:b.wrapX};b.url&&(m.url=b.url),b.urls&&(m.urls=b.urls),g=new a.source.TileWMS(m);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var n={projection:f,layer:b.layer,attributions:s(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),wrapX:void 0===b.wrapX?1:b.wrapX};e(b.url)&&(n.url=b.url),e(b.urls)&&(n.urls=b.urls),g=new a.source.WMTS(n);break;case"OSM":g=new a.source.OSM({attributions:s(b),wrapX:void 0===b.wrapX?1:b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var o={key:b.key,attributions:s(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX?1:b.wrapX};b.maxZoom&&(o.maxZoom=b.maxZoom),g=new a.source.BingMaps(o);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:s(b),layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var p="http://services.arcgisonline.com/ArcGIS/rest/services/",r=p+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:s(b),url:r,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var t=f;e(b.geojson.projection)&&(t=b.geojson.projection);var u=new a.format.GeoJSON,v=u.readFeatures(b.geojson.object,{featureProjection:t});g.addFeatures(v)}break;case"JSONP":if(!b.url)return void c.error("[AngularJS - Openlayers] - You need an url properly configured to add a JSONP layer.");e(b.url)&&(g=new a.source.Vector({format:new a.format.GeoJSON,loader:function(){var a=b.url+"&outputFormat=text/javascript&format_options=callback:JSON_CALLBACK";d.jsonp(a,{cache:b.cache}).success(function(a){g.addFeatures(g.readFeatures(a))}).error(function(a){c(a)})},wrapX:void 0===b.wrapX?1:b.wrapX}));break;case"TopoJSON":if(!b.topojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a topojson property to add a TopoJSON layer.");g=b.url?new a.source.Vector({format:new a.format.TopoJSON,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX}):new a.source.Vector(angular.extend(b.topojson,{format:new a.format.TopoJSON,wrapX:void 0===b.wrapX?1:b.wrapX}));break;case"TileJSON":g=new a.source.TileJSON({url:b.url,attributions:s(b),crossOrigin:"anonymous",wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileVector":b.url&&b.format||c.error("[AngularJS - Openlayers] - TileVector Layer needs valid url and format properties"),g=new a.source.TileVector({url:b.url,projection:f,attributions:s(b),format:b.format,tileGrid:new a.tilegrid.createXYZ({maxZoom:b.maxZoom||19}),wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileTMS":b.url&&b.tileGrid||c.error("[AngularJS - Openlayers] - TileTMS Layer needs valid url and tileGrid properties"),g=new a.source.TileImage({url:b.url,maxExtent:b.maxExtent,attributions:s(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=a[2];if(0>d||0>e)return"";var f=b.url+c+"/"+d+"/"+e+".png";return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileImage":g=new a.source.TileImage({url:b.url,attributions:s(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=-a[2]-1,f=b.url.replace("{z}",c.toString()).replace("{x}",d.toString()).replace("{y}",e.toString());return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"KML":var w=b.extractStyles||!1;g=new a.source.Vector({url:b.url,format:new a.format.KML,radius:b.radius,extractStyles:w,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"Stamen":if(!b.layer||!q(b.layer))return void c.error("[AngularJS - Openlayers] - You need a valid Stamen layer.");g=new a.source.Stamen({layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageStatic":if(!b.url||!angular.isArray(b.imageSize)||2!==b.imageSize.length)return void c.error("[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.");g=new a.source.ImageStatic({url:b.url,attributions:s(b),imageSize:b.imageSize,projection:f,imageExtent:f.getExtent(),imageLoadFunction:b.imageLoadFunction,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"XYZ":b.url||c.error("[AngularJS - Openlayers] - XYZ Layer needs valid url and params properties"),g=new a.source.XYZ({url:b.url,attributions:s(b),minZoom:b.minZoom,maxZoom:b.maxZoom,wrapX:void 0===b.wrapX?1:b.wrapX})}return g||c.warn('[AngularJS - Openlayers] - No source could be found for type "'+b.type+'"'),g},s=function(b){var c=[];return e(b.attribution)&&c.unshift(new a.Attribution({html:b.attribution})),c},t=function(b){var c=new a.layer.Group;return c.set("name",b),c},u=function(b,c){var d;return angular.forEach(b,function(b){return b instanceof a.layer.Group&&b.get("name")===c?void(d=b):void 0}),d},v=function(a,b){for(var c,d=0;d',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p});if(!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d){if("pixel"===g.view.projection)return void i.setCenter(c.coord);var e=a.proj.transform(d,g.view.projection,c.projection);(e[1]!==c.lat||e[0]!==c.lon)&&p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}}),f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),(!h(c.minResolution,e.minResolution)||z(d))&&g(c.minResolution)&&d.setMinResolution(c.minResolution),(!h(c.maxResolution,e.maxResolution)||z(d))&&g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)}),e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope();i.getMap().then(function(b){var d=e.getControlClasses,i=d();return a.$on("$destroy",function(){b.removeControl(f)}),h(a.properties)&&h(a.properties.control)?(f=a.properties.control,void b.addControl(f)):void(c.name&&(h(a.properties)&&(g=a.properties),f=new i[c.name](g),b.addControl(f)))})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return e.on("pointerdown",j),e.on("pointerup",j),e.on("pointerdrag",j),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e)}),k(c.properties)?void c.$watch("properties",function(d){if(e.getViewport().removeEventListener("mousemove",d.handleInteraction),e.getViewport().removeEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",d.handleTapInteraction),e.getViewport().removeEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",d.removeAllOverlays),d.handleInteraction=function(b){if(!d.label.show){var f=!1,g=e.getEventPixel(b),i=e.forEachFeatureAtPixel(g,function(a){return a}),j=!1;i===r&&(j=!0,f=!0,k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),!d.onClick||"click"!==b.type&&"touchend"!==b.type||c.$apply(function(){d.onClick.call(r,b,d)}),e.getTarget().style.cursor="pointer"),!f&&p&&(j=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),j&&b.preventDefault()}},d.handleTapInteraction=function(){function a(){c=!0,b&&clearTimeout(b),b=setTimeout(function(){c=!1,b=null},500)}var b,c=!1;return e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",a),function(){c||(d.handleInteraction.apply(null,arguments),a())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||d.onClick)&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){var d=c(a,b);a[d].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d,e=c(a,b);return d=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:f(a,b)};this.setMap=function(a,b){var c=f(d,b);c.resolve(a),e(d,b)},this.getMap=function(a){var b=g(d,a);return b.promise}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function x(a,b){var c;if(b?c=a[b]:(b="style",c=a),"style"===b&&a instanceof Function)return a;if(!(c instanceof Object))return c;var d;if("[object Object]"===Object.prototype.toString.call(c)){d={};var e=l[b];if(e&&c instanceof e)return c;Object.getOwnPropertyNames(c).forEach(function(a,f,g){var h=l[a];return e&&h&&h.prototype instanceof l[b]?(console.assert(1===g.length,"Extra parameters for "+b),d=x(c,a),m(d,h)):(d[a]=x(c,a),void("text"!==a&&"string"!=typeof d[a]&&(d[a]=m(d[a],l[a]))))})}else d=c;return m(d,l[b])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"TileVector":return"Vector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");var i="http://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,l=window.devicePixelRatio;l>1&&(i=i.replace(".png","@2x.png")),g=new a.source.XYZ({url:i,attributions:s(b),tilePixelRatio:l>1?2:1,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,attributions:s(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:b.params,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var m={crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:b.params,attributions:s(b),wrapX:void 0===b.wrapX?1:b.wrapX};b.serverType&&(m.serverType=b.serverType),b.url&&(m.url=b.url),b.urls&&(m.urls=b.urls),g=new a.source.TileWMS(m);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var n={projection:f,layer:b.layer,attributions:s(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),wrapX:void 0===b.wrapX?1:b.wrapX};e(b.url)&&(n.url=b.url),e(b.urls)&&(n.urls=b.urls),g=new a.source.WMTS(n);break;case"OSM":g=new a.source.OSM({attributions:s(b),wrapX:void 0===b.wrapX?1:b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var o={key:b.key,attributions:s(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX?1:b.wrapX};b.maxZoom&&(o.maxZoom=b.maxZoom),g=new a.source.BingMaps(o);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:s(b),layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var p="http://services.arcgisonline.com/ArcGIS/rest/services/",r=p+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:s(b),url:r,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var t=f;e(b.geojson.projection)&&(t=b.geojson.projection);var u=new a.format.GeoJSON,v=u.readFeatures(b.geojson.object,{featureProjection:t});g.addFeatures(v)}break;case"JSONP":if(!b.url)return void c.error("[AngularJS - Openlayers] - You need an url properly configured to add a JSONP layer.");e(b.url)&&(g=new a.source.Vector({format:new a.format.GeoJSON,loader:function(){var a=b.url+"&outputFormat=text/javascript&format_options=callback:JSON_CALLBACK";d.jsonp(a,{cache:b.cache}).success(function(a){g.addFeatures(g.readFeatures(a))}).error(function(a){c(a)})},wrapX:void 0===b.wrapX?1:b.wrapX}));break;case"TopoJSON":if(!b.topojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a topojson property to add a TopoJSON layer.");g=b.url?new a.source.Vector({format:new a.format.TopoJSON,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX}):new a.source.Vector(angular.extend(b.topojson,{format:new a.format.TopoJSON,wrapX:void 0===b.wrapX?1:b.wrapX}));break;case"TileJSON":g=new a.source.TileJSON({url:b.url,attributions:s(b),crossOrigin:"anonymous",wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileVector":b.url&&b.format||c.error("[AngularJS - Openlayers] - TileVector Layer needs valid url and format properties"),g=new a.source.TileVector({url:b.url,projection:f,attributions:s(b),format:b.format,tileGrid:new a.tilegrid.createXYZ({maxZoom:b.maxZoom||19}),wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileTMS":b.url&&b.tileGrid||c.error("[AngularJS - Openlayers] - TileTMS Layer needs valid url and tileGrid properties"),g=new a.source.TileImage({url:b.url,maxExtent:b.maxExtent,attributions:s(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=a[2];if(0>d||0>e)return"";var f=b.url+c+"/"+d+"/"+e+".png";return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileImage":g=new a.source.TileImage({url:b.url,attributions:s(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=-a[2]-1,f=b.url.replace("{z}",c.toString()).replace("{x}",d.toString()).replace("{y}",e.toString());return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"KML":var w=b.extractStyles||!1;g=new a.source.Vector({url:b.url,format:new a.format.KML,radius:b.radius,extractStyles:w,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"Stamen":if(!b.layer||!q(b.layer))return void c.error("[AngularJS - Openlayers] - You need a valid Stamen layer.");g=new a.source.Stamen({layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageStatic":if(!b.url||!angular.isArray(b.imageSize)||2!==b.imageSize.length)return void c.error("[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.");g=new a.source.ImageStatic({url:b.url,attributions:s(b),imageSize:b.imageSize,projection:f,imageExtent:f.getExtent(),imageLoadFunction:b.imageLoadFunction,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"XYZ":b.url||c.error("[AngularJS - Openlayers] - XYZ Layer needs valid url and params properties"),g=new a.source.XYZ({url:b.url,attributions:s(b),minZoom:b.minZoom,maxZoom:b.maxZoom,wrapX:void 0===b.wrapX?1:b.wrapX})}return g||c.warn('[AngularJS - Openlayers] - No source could be found for type "'+b.type+'"'),g},s=function(b){var c=[];return e(b.attribution)&&c.unshift(new a.Attribution({html:b.attribution})),c},t=function(b){var c=new a.layer.Group;return c.set("name",b),c},u=function(b,c){var d;return angular.forEach(b,function(b){return b instanceof a.layer.Group&&b.get("name")===c?void(d=b):void 0}),d},v=function(a,b){for(var c,d=0;d',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p});if(!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d){if("pixel"===g.view.projection)return void i.setCenter(c.coord);var e=a.proj.transform(d,g.view.projection,c.projection);(e[1]!==c.lat||e[0]!==c.lon)&&p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}}),f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),(!h(c.minResolution,e.minResolution)||z(d))&&g(c.minResolution)&&d.setMinResolution(c.minResolution),(!h(c.maxResolution,e.maxResolution)||z(d))&&g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)}),e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope();i.getMap().then(function(b){var d=e.getControlClasses,i=d();return a.$on("$destroy",function(){b.removeControl(f)}),h(a.properties)&&h(a.properties.control)?(f=a.properties.control,void b.addControl(f)):void(c.name&&(h(a.properties)&&(g=a.properties),f=new i[c.name](g),b.addControl(f)))})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return e.on("pointerdown",j),e.on("pointerup",j),e.on("pointerdrag",j),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e)}),k(c.properties)?void c.$watch("properties",function(d){if(e.getViewport().removeEventListener("mousemove",d.handleInteraction),e.getViewport().removeEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",d.handleTapInteraction),e.getViewport().removeEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",d.removeAllOverlays),d.handleInteraction=function(b){if(!d.label.show){var f=!1,g=e.getEventPixel(b),i=e.forEachFeatureAtPixel(g,function(a){return a}),j=!1;i===r&&(j=!0,f=!0,k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),!d.onClick||"click"!==b.type&&"touchend"!==b.type||c.$apply(function(){d.onClick.call(r,b,d)}),e.getTarget().style.cursor="pointer"),!f&&p&&(j=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),j&&b.preventDefault()}},d.handleTapInteraction=function(){function a(){c=!0,b&&clearTimeout(b),b=setTimeout(function(){c=!1,b=null},500)}var b,c=!1;return e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",a),function(){c||(d.handleInteraction.apply(null,arguments),a())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||d.onClick)&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){var d=c(a,b);a[d].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d,e=c(a,b);return d=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:f(a,b)};this.setMap=function(a,b){var c=f(d,b);c.resolve(a),e(d,b)},this.getMap=function(a){var b=g(d,a);return b.promise}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function x(a,b){var c;if(b?c=a[b]:(b="style",c=a),"style"===b&&a instanceof Function)return a;if(!(c instanceof Object))return c;var d;if("[object Object]"===Object.prototype.toString.call(c)){d={};var e=l[b];if(e&&c instanceof e)return c;Object.getOwnPropertyNames(c).forEach(function(a,f,g){var h=l[a];return e&&h&&h.prototype instanceof l[b]?(console.assert(1===g.length,"Extra parameters for "+b),d=x(c,a),m(d,h)):(d[a]=x(c,a),void("text"!==a&&"string"!=typeof d[a]&&(d[a]=m(d[a],l[a]))))})}else d=c;return m(d,l[b])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"TileVector":return"Vector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");var i="http://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,l=window.devicePixelRatio;l>1&&(i=i.replace(".png","@2x.png")),g=new a.source.XYZ({url:i,attributions:s(b),tilePixelRatio:l>1?2:1,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,attributions:s(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:b.params,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var m={crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:b.params,attributions:s(b),wrapX:void 0===b.wrapX?1:b.wrapX};b.serverType&&(m.serverType=b.serverType),b.url&&(m.url=b.url),b.urls&&(m.urls=b.urls),g=new a.source.TileWMS(m);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var n={projection:f,layer:b.layer,attributions:s(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),wrapX:void 0===b.wrapX?1:b.wrapX};e(b.url)&&(n.url=b.url),e(b.urls)&&(n.urls=b.urls),g=new a.source.WMTS(n);break;case"OSM":g=new a.source.OSM({attributions:s(b),wrapX:void 0===b.wrapX?1:b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var o={key:b.key,attributions:s(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX?1:b.wrapX};b.maxZoom&&(o.maxZoom=b.maxZoom),g=new a.source.BingMaps(o);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:s(b),layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var p="http://services.arcgisonline.com/ArcGIS/rest/services/",r=p+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:s(b),url:r,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var t=f;e(b.geojson.projection)&&(t=b.geojson.projection);var u=new a.format.GeoJSON,v=u.readFeatures(b.geojson.object,{featureProjection:t});g.addFeatures(v)}break;case"JSONP":if(!b.url)return void c.error("[AngularJS - Openlayers] - You need an url properly configured to add a JSONP layer.");e(b.url)&&(g=new a.source.Vector({format:new a.format.GeoJSON,loader:function(){var a=b.url+"&outputFormat=text/javascript&format_options=callback:JSON_CALLBACK";d.jsonp(a,{cache:b.cache}).success(function(a){g.addFeatures(g.readFeatures(a))}).error(function(a){c(a)})},wrapX:void 0===b.wrapX?1:b.wrapX}));break;case"TopoJSON":if(!b.topojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a topojson property to add a TopoJSON layer.");g=b.url?new a.source.Vector({format:new a.format.TopoJSON,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX}):new a.source.Vector(angular.extend(b.topojson,{format:new a.format.TopoJSON,wrapX:void 0===b.wrapX?1:b.wrapX}));break;case"TileJSON":g=new a.source.TileJSON({url:b.url,attributions:s(b),crossOrigin:"anonymous",wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileVector":b.url&&b.format||c.error("[AngularJS - Openlayers] - TileVector Layer needs valid url and format properties"),g=new a.source.TileVector({url:b.url,projection:f,attributions:s(b),format:b.format,tileGrid:new a.tilegrid.createXYZ({maxZoom:b.maxZoom||19}),wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileTMS":b.url&&b.tileGrid||c.error("[AngularJS - Openlayers] - TileTMS Layer needs valid url and tileGrid properties"),g=new a.source.TileImage({url:b.url,maxExtent:b.maxExtent,attributions:s(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=a[2];if(0>d||0>e)return"";var f=b.url+c+"/"+d+"/"+e+".png";return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileImage":g=new a.source.TileImage({url:b.url,attributions:s(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=-a[2]-1,f=b.url.replace("{z}",c.toString()).replace("{x}",d.toString()).replace("{y}",e.toString());return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"KML":var w=b.extractStyles||!1;g=new a.source.Vector({url:b.url,format:new a.format.KML,radius:b.radius,extractStyles:w,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"Stamen":if(!b.layer||!q(b.layer))return void c.error("[AngularJS - Openlayers] - You need a valid Stamen layer.");g=new a.source.Stamen({layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageStatic":if(!b.url||!angular.isArray(b.imageSize)||2!==b.imageSize.length)return void c.error("[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.");g=new a.source.ImageStatic({url:b.url,attributions:s(b),imageSize:b.imageSize,projection:f,imageExtent:f.getExtent(),imageLoadFunction:b.imageLoadFunction,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"XYZ":b.url||c.error("[AngularJS - Openlayers] - XYZ Layer needs valid url and params properties"),g=new a.source.XYZ({url:b.url,attributions:s(b),minZoom:b.minZoom,maxZoom:b.maxZoom,wrapX:void 0===b.wrapX?1:b.wrapX})}return g||c.warn('[AngularJS - Openlayers] - No source could be found for type "'+b.type+'"'),g},s=function(b){var c=[];return e(b.attribution)&&c.unshift(new a.Attribution({html:b.attribution})),c},t=function(b){var c=new a.layer.Group;return c.set("name",b),c},u=function(b,c){var d;return angular.forEach(b,function(b){return b instanceof a.layer.Group&&b.get("name")===c?void(d=b):void 0}),d},v=function(a,b){for(var c,d=0;d',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p});if(!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d){if("pixel"===g.view.projection)return void i.setCenter(c.coord);var e=a.proj.transform(d,g.view.projection,c.projection);(e[1]!==c.lat||e[0]!==c.lon)&&p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}}),f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),(!h(c.minResolution,e.minResolution)||z(d))&&g(c.minResolution)&&d.setMinResolution(c.minResolution),(!h(c.maxResolution,e.maxResolution)||z(d))&&g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)}),e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope();i.getMap().then(function(b){var d=e.getControlClasses,i=d();return a.$on("$destroy",function(){b.removeControl(f)}),h(a.properties)&&h(a.properties.control)?(f=a.properties.control,void b.addControl(f)):void(c.name&&(h(a.properties)&&(g=a.properties),f=new i[c.name](g),b.addControl(f)))})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return e.on("pointerdown",j),e.on("pointerup",j),e.on("pointerdrag",j),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e)}),k(c.properties)?void c.$watch("properties",function(d){if(e.getViewport().removeEventListener("mousemove",d.handleInteraction),e.getViewport().removeEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",d.handleTapInteraction),e.getViewport().removeEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",d.removeAllOverlays),d.handleInteraction=function(b){if(!d.label.show){var f=!1,g=e.getEventPixel(b),i=e.forEachFeatureAtPixel(g,function(a){return a}),j=!1;i===r&&(j=!0,f=!0,k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),!d.onClick||"click"!==b.type&&"touchend"!==b.type||c.$apply(function(){d.onClick.call(r,b,d)}),e.getTarget().style.cursor="pointer"),!f&&p&&(j=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),j&&b.preventDefault()}},d.handleTapInteraction=function(){function a(){c=!0,b&&clearTimeout(b),b=setTimeout(function(){c=!1,b=null},500)}var b,c=!1;return e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",a),function(){c||(d.handleInteraction.apply(null,arguments),a())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||d.onClick)&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){var d=c(a,b);a[d].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d,e=c(a,b);return d=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:f(a,b)};this.setMap=function(a,b){var c=f(d,b);c.resolve(a),e(d,b)},this.getMap=function(a){var b=g(d,a);return b.promise}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function x(a,b){var c;if(b?c=a[b]:(b="style",c=a),"style"===b&&a instanceof Function)return a;if(!(c instanceof Object))return c;var d;if("[object Object]"===Object.prototype.toString.call(c)){d={};var e=l[b];if(e&&c instanceof e)return c;Object.getOwnPropertyNames(c).forEach(function(a,f,g){var h=l[a];return e&&h&&h.prototype instanceof l[b]?(console.assert(1===g.length,"Extra parameters for "+b),d=x(c,a),m(d,h)):(d[a]=x(c,a),void("text"!==a&&"string"!=typeof d[a]&&(d[a]=m(d[a],l[a]))))})}else d=c;return m(d,l[b])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"TileVector":return"Vector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");var i="http://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,l=window.devicePixelRatio;l>1&&(i=i.replace(".png","@2x.png")),g=new a.source.XYZ({url:i,attributions:s(b),tilePixelRatio:l>1?2:1,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,attributions:s(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:b.params,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var m={crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:b.params,attributions:s(b),wrapX:void 0===b.wrapX?1:b.wrapX};b.serverType&&(m.serverType=b.serverType),b.url&&(m.url=b.url),b.urls&&(m.urls=b.urls),g=new a.source.TileWMS(m);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var n={projection:f,layer:b.layer,attributions:s(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),wrapX:void 0===b.wrapX?1:b.wrapX};e(b.url)&&(n.url=b.url),e(b.urls)&&(n.urls=b.urls),g=new a.source.WMTS(n);break;case"OSM":g=new a.source.OSM({attributions:s(b),wrapX:void 0===b.wrapX?1:b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var o={key:b.key,attributions:s(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX?1:b.wrapX};b.maxZoom&&(o.maxZoom=b.maxZoom),g=new a.source.BingMaps(o);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:s(b),layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var p="http://services.arcgisonline.com/ArcGIS/rest/services/",r=p+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:s(b),url:r,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var t=f;e(b.geojson.projection)&&(t=b.geojson.projection);var u=new a.format.GeoJSON,v=u.readFeatures(b.geojson.object,{featureProjection:t});g.addFeatures(v)}break;case"JSONP":if(!b.url)return void c.error("[AngularJS - Openlayers] - You need an url properly configured to add a JSONP layer.");e(b.url)&&(g=new a.source.Vector({format:new a.format.GeoJSON,loader:function(){var a=b.url+"&outputFormat=text/javascript&format_options=callback:JSON_CALLBACK";d.jsonp(a,{cache:b.cache}).success(function(a){g.addFeatures(g.readFeatures(a))}).error(function(a){c(a)})},wrapX:void 0===b.wrapX?1:b.wrapX}));break;case"TopoJSON":if(!b.topojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a topojson property to add a TopoJSON layer.");g=b.url?new a.source.Vector({format:new a.format.TopoJSON,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX}):new a.source.Vector(angular.extend(b.topojson,{format:new a.format.TopoJSON,wrapX:void 0===b.wrapX?1:b.wrapX}));break;case"TileJSON":g=new a.source.TileJSON({url:b.url,attributions:s(b),crossOrigin:"anonymous",wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileVector":b.url&&b.format||c.error("[AngularJS - Openlayers] - TileVector Layer needs valid url and format properties"),g=new a.source.TileVector({url:b.url,projection:f,attributions:s(b),format:b.format,tileGrid:new a.tilegrid.createXYZ({maxZoom:b.maxZoom||19}),wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileTMS":b.url&&b.tileGrid||c.error("[AngularJS - Openlayers] - TileTMS Layer needs valid url and tileGrid properties"),g=new a.source.TileImage({url:b.url,maxExtent:b.maxExtent,attributions:s(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=a[2];if(0>d||0>e)return"";var f=b.url+c+"/"+d+"/"+e+".png";return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileImage":g=new a.source.TileImage({url:b.url,attributions:s(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=-a[2]-1,f=b.url.replace("{z}",c.toString()).replace("{x}",d.toString()).replace("{y}",e.toString());return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"KML":var w=b.extractStyles||!1;g=new a.source.Vector({url:b.url,format:new a.format.KML,radius:b.radius,extractStyles:w,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"Stamen":if(!b.layer||!q(b.layer))return void c.error("[AngularJS - Openlayers] - You need a valid Stamen layer.");g=new a.source.Stamen({layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageStatic":if(!b.url||!angular.isArray(b.imageSize)||2!==b.imageSize.length)return void c.error("[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.");g=new a.source.ImageStatic({url:b.url,attributions:s(b),imageSize:b.imageSize,projection:f,imageExtent:f.getExtent(),imageLoadFunction:b.imageLoadFunction,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"XYZ":b.url||c.error("[AngularJS - Openlayers] - XYZ Layer needs valid url and params properties"),g=new a.source.XYZ({url:b.url,attributions:s(b),minZoom:b.minZoom,maxZoom:b.maxZoom,wrapX:void 0===b.wrapX?1:b.wrapX})}return g||c.warn('[AngularJS - Openlayers] - No source could be found for type "'+b.type+'"'),g},s=function(b){var c=[];return e(b.attribution)&&c.unshift(new a.Attribution({html:b.attribution})),c},t=function(b){var c=new a.layer.Group;return c.set("name",b),c},u=function(b,c){var d;return angular.forEach(b,function(b){return b instanceof a.layer.Group&&b.get("name")===c?void(d=b):void 0}),d},v=function(a,b){for(var c,d=0;d Date: Wed, 13 Jan 2016 10:52:58 +0530 Subject: [PATCH 14/53] modified to return the angular-openlayers-directive module instead of it's name --- dist/angular-openlayers-directive.js | 4 ++-- dist/angular-openlayers-directive.min.js | 4 ++-- dist/angular-openlayers-directive.min.no-header.js | 4 ++-- dist/angular-openlayers-directive.pre.js | 4 ++-- grunt/concat.js | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/dist/angular-openlayers-directive.js b/dist/angular-openlayers-directive.js index e9640a97..a13889e5 100644 --- a/dist/angular-openlayers-directive.js +++ b/dist/angular-openlayers-directive.js @@ -3,7 +3,7 @@ // CommonJS var ol = require('openlayers'); var ngSanitize = require('angular-sanitize'); - exports.angularOpenlayersDirective = factory(ol).name; + exports.angularOpenlayersDirective = factory(ol); } else if (typeof define === 'function' && define.amd) { // AMD. define(['ol'], function (ol) { @@ -2275,5 +2275,5 @@ angular.module('openlayers-directive').factory('olMapDefaults', ["$q", "olHelper } }; }]); -return angular.module('openlayers-directive') +return angular.module('openlayers-directive'); })); \ No newline at end of file diff --git a/dist/angular-openlayers-directive.min.js b/dist/angular-openlayers-directive.min.js index 46be0c14..1bfd054f 100644 --- a/dist/angular-openlayers-directive.min.js +++ b/dist/angular-openlayers-directive.min.js @@ -27,6 +27,6 @@ * @authors https://github.com/tombatossals/angular-openlayers-directive/graphs/contributors */ -/*! angular-openlayers-directive 12-01-2016 */ -!function(a,b){if("function"==typeof require&&"object"==typeof exports){var c=require("openlayers");require("angular-sanitize");exports.angularOpenlayersDirective=b(c).name}else"function"==typeof define&&define.amd?define(["ol"],function(c){return a.angularOpenlayersDirective=b(c)}):a.angularOpenlayersDirective=b(a.ol)}(this,function(a){return angular.module("openlayers-directive",["ngSanitize"]).directive("openlayers",["$log","$q","$compile","olHelpers","olMapDefaults","olData",function(b,c,d,e,f,g){return{restrict:"EA",transclude:!0,replace:!0,scope:{center:"=olCenter",defaults:"=olDefaults",view:"=olView",events:"=olEvents"},template:'
',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p});if(!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d){if("pixel"===g.view.projection)return void i.setCenter(c.coord);var e=a.proj.transform(d,g.view.projection,c.projection);(e[1]!==c.lat||e[0]!==c.lon)&&p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}}),f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),(!h(c.minResolution,e.minResolution)||z(d))&&g(c.minResolution)&&d.setMinResolution(c.minResolution),(!h(c.maxResolution,e.maxResolution)||z(d))&&g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)}),e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope();i.getMap().then(function(b){var d=e.getControlClasses,i=d();return a.$on("$destroy",function(){b.removeControl(f)}),h(a.properties)&&h(a.properties.control)?(f=a.properties.control,void b.addControl(f)):void(c.name&&(h(a.properties)&&(g=a.properties),f=new i[c.name](g),b.addControl(f)))})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return e.on("pointerdown",j),e.on("pointerup",j),e.on("pointerdrag",j),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e)}),k(c.properties)?void c.$watch("properties",function(d){if(e.getViewport().removeEventListener("mousemove",d.handleInteraction),e.getViewport().removeEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",d.handleTapInteraction),e.getViewport().removeEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",d.removeAllOverlays),d.handleInteraction=function(b){if(!d.label.show){var f=!1,g=e.getEventPixel(b),i=e.forEachFeatureAtPixel(g,function(a){return a}),j=!1;i===r&&(j=!0,f=!0,k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),!d.onClick||"click"!==b.type&&"touchend"!==b.type||c.$apply(function(){d.onClick.call(r,b,d)}),e.getTarget().style.cursor="pointer"),!f&&p&&(j=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),j&&b.preventDefault()}},d.handleTapInteraction=function(){function a(){c=!0,b&&clearTimeout(b),b=setTimeout(function(){c=!1,b=null},500)}var b,c=!1;return e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",a),function(){c||(d.handleInteraction.apply(null,arguments),a())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||d.onClick)&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){var d=c(a,b);a[d].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d,e=c(a,b);return d=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:f(a,b)};this.setMap=function(a,b){var c=f(d,b);c.resolve(a),e(d,b)},this.getMap=function(a){var b=g(d,a);return b.promise}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function x(a,b){var c;if(b?c=a[b]:(b="style",c=a),"style"===b&&a instanceof Function)return a;if(!(c instanceof Object))return c;var d;if("[object Object]"===Object.prototype.toString.call(c)){d={};var e=l[b];if(e&&c instanceof e)return c;Object.getOwnPropertyNames(c).forEach(function(a,f,g){var h=l[a];return e&&h&&h.prototype instanceof l[b]?(console.assert(1===g.length,"Extra parameters for "+b),d=x(c,a),m(d,h)):(d[a]=x(c,a),void("text"!==a&&"string"!=typeof d[a]&&(d[a]=m(d[a],l[a]))))})}else d=c;return m(d,l[b])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"TileVector":return"Vector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");var i="http://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,l=window.devicePixelRatio;l>1&&(i=i.replace(".png","@2x.png")),g=new a.source.XYZ({url:i,attributions:s(b),tilePixelRatio:l>1?2:1,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,attributions:s(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:b.params,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var m={crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:b.params,attributions:s(b),wrapX:void 0===b.wrapX?1:b.wrapX};b.serverType&&(m.serverType=b.serverType),b.url&&(m.url=b.url),b.urls&&(m.urls=b.urls),g=new a.source.TileWMS(m);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var n={projection:f,layer:b.layer,attributions:s(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),wrapX:void 0===b.wrapX?1:b.wrapX};e(b.url)&&(n.url=b.url),e(b.urls)&&(n.urls=b.urls),g=new a.source.WMTS(n);break;case"OSM":g=new a.source.OSM({attributions:s(b),wrapX:void 0===b.wrapX?1:b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var o={key:b.key,attributions:s(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX?1:b.wrapX};b.maxZoom&&(o.maxZoom=b.maxZoom),g=new a.source.BingMaps(o);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:s(b),layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var p="http://services.arcgisonline.com/ArcGIS/rest/services/",r=p+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:s(b),url:r,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var t=f;e(b.geojson.projection)&&(t=b.geojson.projection);var u=new a.format.GeoJSON,v=u.readFeatures(b.geojson.object,{featureProjection:t});g.addFeatures(v)}break;case"JSONP":if(!b.url)return void c.error("[AngularJS - Openlayers] - You need an url properly configured to add a JSONP layer.");e(b.url)&&(g=new a.source.Vector({format:new a.format.GeoJSON,loader:function(){var a=b.url+"&outputFormat=text/javascript&format_options=callback:JSON_CALLBACK";d.jsonp(a,{cache:b.cache}).success(function(a){g.addFeatures(g.readFeatures(a))}).error(function(a){c(a)})},wrapX:void 0===b.wrapX?1:b.wrapX}));break;case"TopoJSON":if(!b.topojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a topojson property to add a TopoJSON layer.");g=b.url?new a.source.Vector({format:new a.format.TopoJSON,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX}):new a.source.Vector(angular.extend(b.topojson,{format:new a.format.TopoJSON,wrapX:void 0===b.wrapX?1:b.wrapX}));break;case"TileJSON":g=new a.source.TileJSON({url:b.url,attributions:s(b),crossOrigin:"anonymous",wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileVector":b.url&&b.format||c.error("[AngularJS - Openlayers] - TileVector Layer needs valid url and format properties"),g=new a.source.TileVector({url:b.url,projection:f,attributions:s(b),format:b.format,tileGrid:new a.tilegrid.createXYZ({maxZoom:b.maxZoom||19}),wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileTMS":b.url&&b.tileGrid||c.error("[AngularJS - Openlayers] - TileTMS Layer needs valid url and tileGrid properties"),g=new a.source.TileImage({url:b.url,maxExtent:b.maxExtent,attributions:s(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=a[2];if(0>d||0>e)return"";var f=b.url+c+"/"+d+"/"+e+".png";return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileImage":g=new a.source.TileImage({url:b.url,attributions:s(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=-a[2]-1,f=b.url.replace("{z}",c.toString()).replace("{x}",d.toString()).replace("{y}",e.toString());return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"KML":var w=b.extractStyles||!1;g=new a.source.Vector({url:b.url,format:new a.format.KML,radius:b.radius,extractStyles:w,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"Stamen":if(!b.layer||!q(b.layer))return void c.error("[AngularJS - Openlayers] - You need a valid Stamen layer.");g=new a.source.Stamen({layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageStatic":if(!b.url||!angular.isArray(b.imageSize)||2!==b.imageSize.length)return void c.error("[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.");g=new a.source.ImageStatic({url:b.url,attributions:s(b),imageSize:b.imageSize,projection:f,imageExtent:f.getExtent(),imageLoadFunction:b.imageLoadFunction,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"XYZ":b.url||c.error("[AngularJS - Openlayers] - XYZ Layer needs valid url and params properties"),g=new a.source.XYZ({url:b.url,attributions:s(b),minZoom:b.minZoom,maxZoom:b.maxZoom,wrapX:void 0===b.wrapX?1:b.wrapX})}return g||c.warn('[AngularJS - Openlayers] - No source could be found for type "'+b.type+'"'),g},s=function(b){var c=[];return e(b.attribution)&&c.unshift(new a.Attribution({html:b.attribution})),c},t=function(b){var c=new a.layer.Group;return c.set("name",b),c},u=function(b,c){var d;return angular.forEach(b,function(b){return b instanceof a.layer.Group&&b.get("name")===c?void(d=b):void 0}),d},v=function(a,b){for(var c,d=0;d',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p});if(!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d){if("pixel"===g.view.projection)return void i.setCenter(c.coord);var e=a.proj.transform(d,g.view.projection,c.projection);(e[1]!==c.lat||e[0]!==c.lon)&&p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}}),f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),(!h(c.minResolution,e.minResolution)||z(d))&&g(c.minResolution)&&d.setMinResolution(c.minResolution),(!h(c.maxResolution,e.maxResolution)||z(d))&&g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)}),e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope();i.getMap().then(function(b){var d=e.getControlClasses,i=d();return a.$on("$destroy",function(){b.removeControl(f)}),h(a.properties)&&h(a.properties.control)?(f=a.properties.control,void b.addControl(f)):void(c.name&&(h(a.properties)&&(g=a.properties),f=new i[c.name](g),b.addControl(f)))})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return e.on("pointerdown",j),e.on("pointerup",j),e.on("pointerdrag",j),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e)}),k(c.properties)?void c.$watch("properties",function(d){if(e.getViewport().removeEventListener("mousemove",d.handleInteraction),e.getViewport().removeEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",d.handleTapInteraction),e.getViewport().removeEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",d.removeAllOverlays),d.handleInteraction=function(b){if(!d.label.show){var f=!1,g=e.getEventPixel(b),i=e.forEachFeatureAtPixel(g,function(a){return a}),j=!1;i===r&&(j=!0,f=!0,k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),!d.onClick||"click"!==b.type&&"touchend"!==b.type||c.$apply(function(){d.onClick.call(r,b,d)}),e.getTarget().style.cursor="pointer"),!f&&p&&(j=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),j&&b.preventDefault()}},d.handleTapInteraction=function(){function a(){c=!0,b&&clearTimeout(b),b=setTimeout(function(){c=!1,b=null},500)}var b,c=!1;return e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",a),function(){c||(d.handleInteraction.apply(null,arguments),a())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||d.onClick)&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){var d=c(a,b);a[d].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d,e=c(a,b);return d=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:f(a,b)};this.setMap=function(a,b){var c=f(d,b);c.resolve(a),e(d,b)},this.getMap=function(a){var b=g(d,a);return b.promise}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function x(a,b){var c;if(b?c=a[b]:(b="style",c=a),"style"===b&&a instanceof Function)return a;if(!(c instanceof Object))return c;var d;if("[object Object]"===Object.prototype.toString.call(c)){d={};var e=l[b];if(e&&c instanceof e)return c;Object.getOwnPropertyNames(c).forEach(function(a,f,g){var h=l[a];return e&&h&&h.prototype instanceof l[b]?(console.assert(1===g.length,"Extra parameters for "+b),d=x(c,a),m(d,h)):(d[a]=x(c,a),void("text"!==a&&"string"!=typeof d[a]&&(d[a]=m(d[a],l[a]))))})}else d=c;return m(d,l[b])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"TileVector":return"Vector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");var i="http://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,l=window.devicePixelRatio;l>1&&(i=i.replace(".png","@2x.png")),g=new a.source.XYZ({url:i,attributions:s(b),tilePixelRatio:l>1?2:1,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,attributions:s(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:b.params,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var m={crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:b.params,attributions:s(b),wrapX:void 0===b.wrapX?1:b.wrapX};b.serverType&&(m.serverType=b.serverType),b.url&&(m.url=b.url),b.urls&&(m.urls=b.urls),g=new a.source.TileWMS(m);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var n={projection:f,layer:b.layer,attributions:s(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),wrapX:void 0===b.wrapX?1:b.wrapX};e(b.url)&&(n.url=b.url),e(b.urls)&&(n.urls=b.urls),g=new a.source.WMTS(n);break;case"OSM":g=new a.source.OSM({attributions:s(b),wrapX:void 0===b.wrapX?1:b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var o={key:b.key,attributions:s(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX?1:b.wrapX};b.maxZoom&&(o.maxZoom=b.maxZoom),g=new a.source.BingMaps(o);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:s(b),layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var p="http://services.arcgisonline.com/ArcGIS/rest/services/",r=p+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:s(b),url:r,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var t=f;e(b.geojson.projection)&&(t=b.geojson.projection);var u=new a.format.GeoJSON,v=u.readFeatures(b.geojson.object,{featureProjection:t});g.addFeatures(v)}break;case"JSONP":if(!b.url)return void c.error("[AngularJS - Openlayers] - You need an url properly configured to add a JSONP layer.");e(b.url)&&(g=new a.source.Vector({format:new a.format.GeoJSON,loader:function(){var a=b.url+"&outputFormat=text/javascript&format_options=callback:JSON_CALLBACK";d.jsonp(a,{cache:b.cache}).success(function(a){g.addFeatures(g.readFeatures(a))}).error(function(a){c(a)})},wrapX:void 0===b.wrapX?1:b.wrapX}));break;case"TopoJSON":if(!b.topojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a topojson property to add a TopoJSON layer.");g=b.url?new a.source.Vector({format:new a.format.TopoJSON,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX}):new a.source.Vector(angular.extend(b.topojson,{format:new a.format.TopoJSON,wrapX:void 0===b.wrapX?1:b.wrapX}));break;case"TileJSON":g=new a.source.TileJSON({url:b.url,attributions:s(b),crossOrigin:"anonymous",wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileVector":b.url&&b.format||c.error("[AngularJS - Openlayers] - TileVector Layer needs valid url and format properties"),g=new a.source.TileVector({url:b.url,projection:f,attributions:s(b),format:b.format,tileGrid:new a.tilegrid.createXYZ({maxZoom:b.maxZoom||19}),wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileTMS":b.url&&b.tileGrid||c.error("[AngularJS - Openlayers] - TileTMS Layer needs valid url and tileGrid properties"),g=new a.source.TileImage({url:b.url,maxExtent:b.maxExtent,attributions:s(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=a[2];if(0>d||0>e)return"";var f=b.url+c+"/"+d+"/"+e+".png";return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileImage":g=new a.source.TileImage({url:b.url,attributions:s(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=-a[2]-1,f=b.url.replace("{z}",c.toString()).replace("{x}",d.toString()).replace("{y}",e.toString());return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"KML":var w=b.extractStyles||!1;g=new a.source.Vector({url:b.url,format:new a.format.KML,radius:b.radius,extractStyles:w,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"Stamen":if(!b.layer||!q(b.layer))return void c.error("[AngularJS - Openlayers] - You need a valid Stamen layer.");g=new a.source.Stamen({layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageStatic":if(!b.url||!angular.isArray(b.imageSize)||2!==b.imageSize.length)return void c.error("[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.");g=new a.source.ImageStatic({url:b.url,attributions:s(b),imageSize:b.imageSize,projection:f,imageExtent:f.getExtent(),imageLoadFunction:b.imageLoadFunction,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"XYZ":b.url||c.error("[AngularJS - Openlayers] - XYZ Layer needs valid url and params properties"),g=new a.source.XYZ({url:b.url,attributions:s(b),minZoom:b.minZoom,maxZoom:b.maxZoom,wrapX:void 0===b.wrapX?1:b.wrapX})}return g||c.warn('[AngularJS - Openlayers] - No source could be found for type "'+b.type+'"'),g},s=function(b){var c=[];return e(b.attribution)&&c.unshift(new a.Attribution({html:b.attribution})),c},t=function(b){var c=new a.layer.Group;return c.set("name",b),c},u=function(b,c){var d;return angular.forEach(b,function(b){return b instanceof a.layer.Group&&b.get("name")===c?void(d=b):void 0}),d},v=function(a,b){for(var c,d=0;d',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p});if(!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d){if("pixel"===g.view.projection)return void i.setCenter(c.coord);var e=a.proj.transform(d,g.view.projection,c.projection);(e[1]!==c.lat||e[0]!==c.lon)&&p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}}),f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),(!h(c.minResolution,e.minResolution)||z(d))&&g(c.minResolution)&&d.setMinResolution(c.minResolution),(!h(c.maxResolution,e.maxResolution)||z(d))&&g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)}),e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope();i.getMap().then(function(b){var d=e.getControlClasses,i=d();return a.$on("$destroy",function(){b.removeControl(f)}),h(a.properties)&&h(a.properties.control)?(f=a.properties.control,void b.addControl(f)):void(c.name&&(h(a.properties)&&(g=a.properties),f=new i[c.name](g),b.addControl(f)))})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return e.on("pointerdown",j),e.on("pointerup",j),e.on("pointerdrag",j),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e)}),k(c.properties)?void c.$watch("properties",function(d){if(e.getViewport().removeEventListener("mousemove",d.handleInteraction),e.getViewport().removeEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",d.handleTapInteraction),e.getViewport().removeEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",d.removeAllOverlays),d.handleInteraction=function(b){if(!d.label.show){var f=!1,g=e.getEventPixel(b),i=e.forEachFeatureAtPixel(g,function(a){return a}),j=!1;i===r&&(j=!0,f=!0,k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),!d.onClick||"click"!==b.type&&"touchend"!==b.type||c.$apply(function(){d.onClick.call(r,b,d)}),e.getTarget().style.cursor="pointer"),!f&&p&&(j=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),j&&b.preventDefault()}},d.handleTapInteraction=function(){function a(){c=!0,b&&clearTimeout(b),b=setTimeout(function(){c=!1,b=null},500)}var b,c=!1;return e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",a),function(){c||(d.handleInteraction.apply(null,arguments),a())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||d.onClick)&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){var d=c(a,b);a[d].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d,e=c(a,b);return d=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:f(a,b)};this.setMap=function(a,b){var c=f(d,b);c.resolve(a),e(d,b)},this.getMap=function(a){var b=g(d,a);return b.promise}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function x(a,b){var c;if(b?c=a[b]:(b="style",c=a),"style"===b&&a instanceof Function)return a;if(!(c instanceof Object))return c;var d;if("[object Object]"===Object.prototype.toString.call(c)){d={};var e=l[b];if(e&&c instanceof e)return c;Object.getOwnPropertyNames(c).forEach(function(a,f,g){var h=l[a];return e&&h&&h.prototype instanceof l[b]?(console.assert(1===g.length,"Extra parameters for "+b),d=x(c,a),m(d,h)):(d[a]=x(c,a),void("text"!==a&&"string"!=typeof d[a]&&(d[a]=m(d[a],l[a]))))})}else d=c;return m(d,l[b])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"TileVector":return"Vector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");var i="http://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,l=window.devicePixelRatio;l>1&&(i=i.replace(".png","@2x.png")),g=new a.source.XYZ({url:i,attributions:s(b),tilePixelRatio:l>1?2:1,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,attributions:s(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:b.params,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var m={crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:b.params,attributions:s(b),wrapX:void 0===b.wrapX?1:b.wrapX};b.serverType&&(m.serverType=b.serverType),b.url&&(m.url=b.url),b.urls&&(m.urls=b.urls),g=new a.source.TileWMS(m);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var n={projection:f,layer:b.layer,attributions:s(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),wrapX:void 0===b.wrapX?1:b.wrapX};e(b.url)&&(n.url=b.url),e(b.urls)&&(n.urls=b.urls),g=new a.source.WMTS(n);break;case"OSM":g=new a.source.OSM({attributions:s(b),wrapX:void 0===b.wrapX?1:b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var o={key:b.key,attributions:s(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX?1:b.wrapX};b.maxZoom&&(o.maxZoom=b.maxZoom),g=new a.source.BingMaps(o);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:s(b),layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var p="http://services.arcgisonline.com/ArcGIS/rest/services/",r=p+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:s(b),url:r,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var t=f;e(b.geojson.projection)&&(t=b.geojson.projection);var u=new a.format.GeoJSON,v=u.readFeatures(b.geojson.object,{featureProjection:t});g.addFeatures(v)}break;case"JSONP":if(!b.url)return void c.error("[AngularJS - Openlayers] - You need an url properly configured to add a JSONP layer.");e(b.url)&&(g=new a.source.Vector({format:new a.format.GeoJSON,loader:function(){var a=b.url+"&outputFormat=text/javascript&format_options=callback:JSON_CALLBACK";d.jsonp(a,{cache:b.cache}).success(function(a){g.addFeatures(g.readFeatures(a))}).error(function(a){c(a)})},wrapX:void 0===b.wrapX?1:b.wrapX}));break;case"TopoJSON":if(!b.topojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a topojson property to add a TopoJSON layer.");g=b.url?new a.source.Vector({format:new a.format.TopoJSON,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX}):new a.source.Vector(angular.extend(b.topojson,{format:new a.format.TopoJSON,wrapX:void 0===b.wrapX?1:b.wrapX}));break;case"TileJSON":g=new a.source.TileJSON({url:b.url,attributions:s(b),crossOrigin:"anonymous",wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileVector":b.url&&b.format||c.error("[AngularJS - Openlayers] - TileVector Layer needs valid url and format properties"),g=new a.source.TileVector({url:b.url,projection:f,attributions:s(b),format:b.format,tileGrid:new a.tilegrid.createXYZ({maxZoom:b.maxZoom||19}),wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileTMS":b.url&&b.tileGrid||c.error("[AngularJS - Openlayers] - TileTMS Layer needs valid url and tileGrid properties"),g=new a.source.TileImage({url:b.url,maxExtent:b.maxExtent,attributions:s(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=a[2];if(0>d||0>e)return"";var f=b.url+c+"/"+d+"/"+e+".png";return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileImage":g=new a.source.TileImage({url:b.url,attributions:s(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=-a[2]-1,f=b.url.replace("{z}",c.toString()).replace("{x}",d.toString()).replace("{y}",e.toString());return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"KML":var w=b.extractStyles||!1;g=new a.source.Vector({url:b.url,format:new a.format.KML,radius:b.radius,extractStyles:w,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"Stamen":if(!b.layer||!q(b.layer))return void c.error("[AngularJS - Openlayers] - You need a valid Stamen layer.");g=new a.source.Stamen({layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageStatic":if(!b.url||!angular.isArray(b.imageSize)||2!==b.imageSize.length)return void c.error("[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.");g=new a.source.ImageStatic({url:b.url,attributions:s(b),imageSize:b.imageSize,projection:f,imageExtent:f.getExtent(),imageLoadFunction:b.imageLoadFunction,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"XYZ":b.url||c.error("[AngularJS - Openlayers] - XYZ Layer needs valid url and params properties"),g=new a.source.XYZ({url:b.url,attributions:s(b),minZoom:b.minZoom,maxZoom:b.maxZoom,wrapX:void 0===b.wrapX?1:b.wrapX})}return g||c.warn('[AngularJS - Openlayers] - No source could be found for type "'+b.type+'"'),g},s=function(b){var c=[];return e(b.attribution)&&c.unshift(new a.Attribution({html:b.attribution})),c},t=function(b){var c=new a.layer.Group;return c.set("name",b),c},u=function(b,c){var d;return angular.forEach(b,function(b){return b instanceof a.layer.Group&&b.get("name")===c?void(d=b):void 0}),d},v=function(a,b){for(var c,d=0;d',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p});if(!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d){if("pixel"===g.view.projection)return void i.setCenter(c.coord);var e=a.proj.transform(d,g.view.projection,c.projection);(e[1]!==c.lat||e[0]!==c.lon)&&p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}}),f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),(!h(c.minResolution,e.minResolution)||z(d))&&g(c.minResolution)&&d.setMinResolution(c.minResolution),(!h(c.maxResolution,e.maxResolution)||z(d))&&g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)}),e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope();i.getMap().then(function(b){var d=e.getControlClasses,i=d();return a.$on("$destroy",function(){b.removeControl(f)}),h(a.properties)&&h(a.properties.control)?(f=a.properties.control,void b.addControl(f)):void(c.name&&(h(a.properties)&&(g=a.properties),f=new i[c.name](g),b.addControl(f)))})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return e.on("pointerdown",j),e.on("pointerup",j),e.on("pointerdrag",j),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e)}),k(c.properties)?void c.$watch("properties",function(d){if(e.getViewport().removeEventListener("mousemove",d.handleInteraction),e.getViewport().removeEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",d.handleTapInteraction),e.getViewport().removeEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",d.removeAllOverlays),d.handleInteraction=function(b){if(!d.label.show){var f=!1,g=e.getEventPixel(b),i=e.forEachFeatureAtPixel(g,function(a){return a}),j=!1;i===r&&(j=!0,f=!0,k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),!d.onClick||"click"!==b.type&&"touchend"!==b.type||c.$apply(function(){d.onClick.call(r,b,d)}),e.getTarget().style.cursor="pointer"),!f&&p&&(j=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),j&&b.preventDefault()}},d.handleTapInteraction=function(){function a(){c=!0,b&&clearTimeout(b),b=setTimeout(function(){c=!1,b=null},500)}var b,c=!1;return e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",a),function(){c||(d.handleInteraction.apply(null,arguments),a())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||d.onClick)&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){var d=c(a,b);a[d].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d,e=c(a,b);return d=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:f(a,b)};this.setMap=function(a,b){var c=f(d,b);c.resolve(a),e(d,b)},this.getMap=function(a){var b=g(d,a);return b.promise}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function x(a,b){var c;if(b?c=a[b]:(b="style",c=a),"style"===b&&a instanceof Function)return a;if(!(c instanceof Object))return c;var d;if("[object Object]"===Object.prototype.toString.call(c)){d={};var e=l[b];if(e&&c instanceof e)return c;Object.getOwnPropertyNames(c).forEach(function(a,f,g){var h=l[a];return e&&h&&h.prototype instanceof l[b]?(console.assert(1===g.length,"Extra parameters for "+b),d=x(c,a),m(d,h)):(d[a]=x(c,a),void("text"!==a&&"string"!=typeof d[a]&&(d[a]=m(d[a],l[a]))))})}else d=c;return m(d,l[b])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"TileVector":return"Vector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");var i="http://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,l=window.devicePixelRatio;l>1&&(i=i.replace(".png","@2x.png")),g=new a.source.XYZ({url:i,attributions:s(b),tilePixelRatio:l>1?2:1,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,attributions:s(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:b.params,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var m={crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:b.params,attributions:s(b),wrapX:void 0===b.wrapX?1:b.wrapX};b.serverType&&(m.serverType=b.serverType),b.url&&(m.url=b.url),b.urls&&(m.urls=b.urls),g=new a.source.TileWMS(m);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var n={projection:f,layer:b.layer,attributions:s(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),wrapX:void 0===b.wrapX?1:b.wrapX};e(b.url)&&(n.url=b.url),e(b.urls)&&(n.urls=b.urls),g=new a.source.WMTS(n);break;case"OSM":g=new a.source.OSM({attributions:s(b),wrapX:void 0===b.wrapX?1:b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var o={key:b.key,attributions:s(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX?1:b.wrapX};b.maxZoom&&(o.maxZoom=b.maxZoom),g=new a.source.BingMaps(o);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:s(b),layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var p="http://services.arcgisonline.com/ArcGIS/rest/services/",r=p+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:s(b),url:r,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var t=f;e(b.geojson.projection)&&(t=b.geojson.projection);var u=new a.format.GeoJSON,v=u.readFeatures(b.geojson.object,{featureProjection:t});g.addFeatures(v)}break;case"JSONP":if(!b.url)return void c.error("[AngularJS - Openlayers] - You need an url properly configured to add a JSONP layer.");e(b.url)&&(g=new a.source.Vector({format:new a.format.GeoJSON,loader:function(){var a=b.url+"&outputFormat=text/javascript&format_options=callback:JSON_CALLBACK";d.jsonp(a,{cache:b.cache}).success(function(a){g.addFeatures(g.readFeatures(a))}).error(function(a){c(a)})},wrapX:void 0===b.wrapX?1:b.wrapX}));break;case"TopoJSON":if(!b.topojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a topojson property to add a TopoJSON layer.");g=b.url?new a.source.Vector({format:new a.format.TopoJSON,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX}):new a.source.Vector(angular.extend(b.topojson,{format:new a.format.TopoJSON,wrapX:void 0===b.wrapX?1:b.wrapX}));break;case"TileJSON":g=new a.source.TileJSON({url:b.url,attributions:s(b),crossOrigin:"anonymous",wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileVector":b.url&&b.format||c.error("[AngularJS - Openlayers] - TileVector Layer needs valid url and format properties"),g=new a.source.TileVector({url:b.url,projection:f,attributions:s(b),format:b.format,tileGrid:new a.tilegrid.createXYZ({maxZoom:b.maxZoom||19}),wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileTMS":b.url&&b.tileGrid||c.error("[AngularJS - Openlayers] - TileTMS Layer needs valid url and tileGrid properties"),g=new a.source.TileImage({url:b.url,maxExtent:b.maxExtent,attributions:s(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=a[2];if(0>d||0>e)return"";var f=b.url+c+"/"+d+"/"+e+".png";return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileImage":g=new a.source.TileImage({url:b.url,attributions:s(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=-a[2]-1,f=b.url.replace("{z}",c.toString()).replace("{x}",d.toString()).replace("{y}",e.toString());return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"KML":var w=b.extractStyles||!1;g=new a.source.Vector({url:b.url,format:new a.format.KML,radius:b.radius,extractStyles:w,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"Stamen":if(!b.layer||!q(b.layer))return void c.error("[AngularJS - Openlayers] - You need a valid Stamen layer.");g=new a.source.Stamen({layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageStatic":if(!b.url||!angular.isArray(b.imageSize)||2!==b.imageSize.length)return void c.error("[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.");g=new a.source.ImageStatic({url:b.url,attributions:s(b),imageSize:b.imageSize,projection:f,imageExtent:f.getExtent(),imageLoadFunction:b.imageLoadFunction,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"XYZ":b.url||c.error("[AngularJS - Openlayers] - XYZ Layer needs valid url and params properties"),g=new a.source.XYZ({url:b.url,attributions:s(b),minZoom:b.minZoom,maxZoom:b.maxZoom,wrapX:void 0===b.wrapX?1:b.wrapX})}return g||c.warn('[AngularJS - Openlayers] - No source could be found for type "'+b.type+'"'),g},s=function(b){var c=[];return e(b.attribution)&&c.unshift(new a.Attribution({html:b.attribution})),c},t=function(b){var c=new a.layer.Group;return c.set("name",b),c},u=function(b,c){var d;return angular.forEach(b,function(b){return b instanceof a.layer.Group&&b.get("name")===c?void(d=b):void 0}),d},v=function(a,b){for(var c,d=0;d Date: Wed, 13 Jan 2016 17:49:00 +0530 Subject: [PATCH 15/53] WKT Geometry Format Support Included. --- src/services/olHelpers.js | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/services/olHelpers.js b/src/services/olHelpers.js index 1ee47e1e..26618a20 100644 --- a/src/services/olHelpers.js +++ b/src/services/olHelpers.js @@ -151,6 +151,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ case 'JSONP': case 'TopoJSON': case 'KML': + case 'WKT': case 'TileVector': return 'Vector'; default: @@ -369,6 +370,40 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ oSource.addFeatures(features); } + break; + case 'WKT': + if (!(source.wkt || source.url)) { + $log.error('[AngularJS - Openlayers] - You need a WKT ' + + 'property to add a GeoJSON layer.'); + return; + } + if (isDefined(source.url)) { + oSource = new ol.source.Vector({ + format: new ol.format.WKT(), + url: source.url, + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX + }); + } else { + oSource = new ol.source.Vector(); + + var projectionToUse = projection; + if (isDefined(source.wkt.projection)) { + projectionToUse = source.wkt.projection; + } + + var wktFormat = new ol.format.WKT(); + var features = []; + for(var k = 0; k< source.wkt.object.length; k++){ + var feature = wktFormat.readFeature( + source.wkt.object[k].data, {dataProjection: 'EPSG:4326',featureProjection: projectionToUse }); + if(source.wkt.object[k].properties){ + feature.properties = source.wkt.object[k].properties; + } + features.push(feature); + } + oSource.addFeatures(features); + } + break; case 'JSONP': if (!(source.url)) { From 1a169e73251fa94ba05a76d10e7d112085153b12 Mon Sep 17 00:00:00 2001 From: Sathish Kesavaperumal Date: Tue, 9 Feb 2016 18:56:16 +0530 Subject: [PATCH 16/53] Merged with master --- dist/angular-openlayers-directive.js | 62 ++++++++++++++----- dist/angular-openlayers-directive.min.js | 6 +- ...ular-openlayers-directive.min.no-header.js | 6 +- dist/angular-openlayers-directive.pre.js | 62 ++++++++++++++----- 4 files changed, 100 insertions(+), 36 deletions(-) diff --git a/dist/angular-openlayers-directive.js b/dist/angular-openlayers-directive.js index 00037fe2..8a390b0e 100644 --- a/dist/angular-openlayers-directive.js +++ b/dist/angular-openlayers-directive.js @@ -1369,6 +1369,7 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt var createSource = function(source, projection) { var oSource; + var geojsonFormat = new ol.format.GeoJSON(); // used in various switch stmnts below switch (source.type) { case 'MapBox': @@ -1551,9 +1552,11 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt projectionToUse = source.geojson.projection; } - var geojsonFormat = new ol.format.GeoJSON(); var features = geojsonFormat.readFeatures( - source.geojson.object, { featureProjection: projectionToUse }); + source.geojson.object, { + featureProjection: projectionToUse, + dataProjection: projectionToUse + }); oSource.addFeatures(features); } @@ -1600,18 +1603,21 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt } if (isDefined(source.url)) { - oSource = new ol.source.Vector({ - format: new ol.format.GeoJSON(), + oSource = new ol.source.ServerVector({ + format: geojsonFormat, loader: function(/*extent, resolution, projection*/) { var url = source.url + '&outputFormat=text/javascript&format_options=callback:JSON_CALLBACK'; - $http.jsonp(url, { cache: source.cache}).success(function(response) { - oSource.addFeatures(oSource.readFeatures(response)); - }).error(function(response) { - $log(response); - }); + $http.jsonp(url, { cache: source.cache}) + .success(function(response) { + oSource.addFeatures(geojsonFormat.readFeatures(response)); + }) + .error(function(response) { + $log(response); + }); }, - wrapX: (source.wrapX === undefined) ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX, + projection: projection }); } break; @@ -1862,6 +1868,9 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt if (view.zoom) { viewConfig.zoom = view.zoom; } + if (view.resolutions) { + viewConfig.resolutions = view.resolutions; + } return new ol.View(viewConfig); }, @@ -2011,18 +2020,40 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt }); } + var layerConfig = { source: oSource }; + + // ol.layer.Layer configuration options + if (isDefinedAndNotNull(layer.opacity)) { + layerConfig.opacity = layer.opacity; + } + if (isDefinedAndNotNull(layer.visible)) { + layerConfig.visible = layer.visible; + } + if (isDefinedAndNotNull(layer.extent)) { + layerConfig.extent = layer.extent; + } + if (isDefinedAndNotNull(layer.zIndex)) { + layerConfig.zIndex = layer.zIndex; + } + if (isDefinedAndNotNull(layer.minResolution)) { + layerConfig.minResolution = layer.minResolution; + } + if (isDefinedAndNotNull(layer.maxResolution)) { + layerConfig.maxResolution = layer.maxResolution; + } + switch (type) { case 'Image': - oLayer = new ol.layer.Image({ source: oSource }); + oLayer = new ol.layer.Image(layerConfig); break; case 'Tile': - oLayer = new ol.layer.Tile({ source: oSource }); + oLayer = new ol.layer.Tile(layerConfig); break; case 'Heatmap': - oLayer = new ol.layer.Heatmap({ source: oSource }); + oLayer = new ol.layer.Heatmap(layerConfig); break; case 'Vector': - oLayer = new ol.layer.Vector({ source: oSource }); + oLayer = new ol.layer.Vector(layerConfig); break; } @@ -2115,7 +2146,7 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt if (!isDefined(groupLayer)) { groupLayer = createGroup(name); - addLayerBeforeMarkers(layers,groupLayer); + addLayerBeforeMarkers(layers, groupLayer); } layer.set('group', name); @@ -2299,6 +2330,7 @@ angular.module('openlayers-directive').factory('olMapDefaults', ["$q", "olHelper newDefaults.view.minZoom = userDefaults.view.minZoom || newDefaults.view.minZoom; newDefaults.view.projection = userDefaults.view.projection || newDefaults.view.projection; newDefaults.view.extent = userDefaults.view.extent || newDefaults.view.extent; + newDefaults.view.resolutions = userDefaults.view.resolutions || newDefaults.view.resolutions; } if (isDefined(userDefaults.styles)) { diff --git a/dist/angular-openlayers-directive.min.js b/dist/angular-openlayers-directive.min.js index 7506abe9..c1b65cc8 100644 --- a/dist/angular-openlayers-directive.min.js +++ b/dist/angular-openlayers-directive.min.js @@ -27,6 +27,6 @@ * @authors https://github.com/tombatossals/angular-openlayers-directive/graphs/contributors */ -/*! angular-openlayers-directive 18-01-2016 */ -!function(a,b){if("function"==typeof require&&"object"==typeof exports){var c=require("openlayers");require("angular-sanitize");exports.angularOpenlayersDirective=b(c)}else"function"==typeof define&&define.amd?define(["ol"],function(c){return a.angularOpenlayersDirective=b(c)}):a.angularOpenlayersDirective=b(a.ol)}(this,function(a){return angular.module("openlayers-directive",["ngSanitize"]).directive("openlayers",["$log","$q","$compile","olHelpers","olMapDefaults","olData",function(b,c,d,e,f,g){return{restrict:"EA",transclude:!0,replace:!0,scope:{center:"=olCenter",defaults:"=olDefaults",view:"=olView",events:"=olEvents"},template:'
',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p});if(!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d){if("pixel"===g.view.projection)return void i.setCenter(c.coord);var e=a.proj.transform(d,g.view.projection,c.projection);(e[1]!==c.lat||e[0]!==c.lon)&&p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}}),f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),(!h(c.minResolution,e.minResolution)||z(d))&&g(c.minResolution)&&d.setMinResolution(c.minResolution),(!h(c.maxResolution,e.maxResolution)||z(d))&&g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)}),e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope();i.getMap().then(function(b){var d=e.getControlClasses,i=d();return a.$on("$destroy",function(){b.removeControl(f)}),h(a.properties)&&h(a.properties.control)?(f=a.properties.control,void b.addControl(f)):void(c.name&&(h(a.properties)&&(g=a.properties),f=new i[c.name](g),b.addControl(f)))})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return e.on("pointerdown",j),e.on("pointerup",j),e.on("pointerdrag",j),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e)}),k(c.properties)?void c.$watch("properties",function(d){if(e.getViewport().removeEventListener("mousemove",d.handleInteraction),e.getViewport().removeEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",d.handleTapInteraction),e.getViewport().removeEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",d.removeAllOverlays),d.handleInteraction=function(b){if(!d.label.show){var f=!1,g=e.getEventPixel(b),i=e.forEachFeatureAtPixel(g,function(a){return a}),j=!1;i===r&&(j=!0,f=!0,k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),!d.onClick||"click"!==b.type&&"touchend"!==b.type||c.$apply(function(){d.onClick.call(r,b,d)}),e.getTarget().style.cursor="pointer"),!f&&p&&(j=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),j&&b.preventDefault()}},d.handleTapInteraction=function(){function a(){c=!0,b&&clearTimeout(b),b=setTimeout(function(){c=!1,b=null},500)}var b,c=!1;return e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",a),function(){c||(d.handleInteraction.apply(null,arguments),a())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||d.onClick)&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){var d=c(a,b);a[d].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d,e=c(a,b);return d=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:f(a,b)};this.setMap=function(a,b){var c=f(d,b);c.resolve(a),e(d,b)},this.getMap=function(a){var b=g(d,a);return b.promise}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function x(a,b){var c;if(b?c=a[b]:(b="style",c=a),"style"===b&&a instanceof Function)return a;if(!(c instanceof Object))return c;var d;if("[object Object]"===Object.prototype.toString.call(c)){d={};var e=l[b];if(e&&c instanceof e)return c;Object.getOwnPropertyNames(c).forEach(function(a,f,g){var h=l[a];return e&&h&&h.prototype instanceof l[b]?(console.assert(1===g.length,"Extra parameters for "+b),d=x(c,a),m(d,h)):(d[a]=x(c,a),void("text"!==a&&"string"!=typeof d[a]&&(d[a]=m(d[a],l[a]))))})}else d=c;return m(d,l[b])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":case"TileVector":return"Vector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");var i="http://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,l=window.devicePixelRatio;l>1&&(i=i.replace(".png","@2x.png")),g=new a.source.XYZ({url:i,attributions:s(b),tilePixelRatio:l>1?2:1,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,attributions:s(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:b.params,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var m={crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:b.params,attributions:s(b),wrapX:void 0===b.wrapX?1:b.wrapX};b.serverType&&(m.serverType=b.serverType),b.url&&(m.url=b.url),b.urls&&(m.urls=b.urls),g=new a.source.TileWMS(m);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var n={projection:f,layer:b.layer,attributions:s(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),wrapX:void 0===b.wrapX?1:b.wrapX};e(b.url)&&(n.url=b.url),e(b.urls)&&(n.urls=b.urls),g=new a.source.WMTS(n);break;case"OSM":g=new a.source.OSM({attributions:s(b),wrapX:void 0===b.wrapX?1:b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var o={key:b.key,attributions:s(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX?1:b.wrapX};b.maxZoom&&(o.maxZoom=b.maxZoom),g=new a.source.BingMaps(o);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:s(b),layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var p="http://services.arcgisonline.com/ArcGIS/rest/services/",r=p+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:s(b),url:r,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var t=f;e(b.geojson.projection)&&(t=b.geojson.projection);var u=new a.format.GeoJSON,v=u.readFeatures(b.geojson.object,{featureProjection:t});g.addFeatures(v)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var w=f;e(b.wkt.projection)&&(w=b.wkt.projection);for(var x=new a.format.WKT,y=[],z=0;zd||0>e)return"";var f=b.url+c+"/"+d+"/"+e+".png";return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileImage":g=new a.source.TileImage({url:b.url,attributions:s(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=-a[2]-1,f=b.url.replace("{z}",c.toString()).replace("{x}",d.toString()).replace("{y}",e.toString());return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"KML":var B=b.extractStyles||!1;g=new a.source.Vector({url:b.url,format:new a.format.KML,radius:b.radius,extractStyles:B,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"Stamen":if(!b.layer||!q(b.layer))return void c.error("[AngularJS - Openlayers] - You need a valid Stamen layer.");g=new a.source.Stamen({layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageStatic":if(!b.url||!angular.isArray(b.imageSize)||2!==b.imageSize.length)return void c.error("[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.");g=new a.source.ImageStatic({url:b.url,attributions:s(b),imageSize:b.imageSize,projection:f,imageExtent:f.getExtent(),imageLoadFunction:b.imageLoadFunction,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"XYZ":b.url||b.tileUrlFunction||c.error("[AngularJS - Openlayers] - XYZ Layer needs valid url or tileUrlFunction properties"),g=new a.source.XYZ({url:b.url,attributions:s(b),minZoom:b.minZoom,maxZoom:b.maxZoom,wrapX:void 0===b.wrapX?1:b.wrapX,projection:b.projection,tileUrlFunction:b.tileUrlFunction})}return g||c.warn('[AngularJS - Openlayers] - No source could be found for type "'+b.type+'"'),g},s=function(b){var c=[];return e(b.attribution)&&c.unshift(new a.Attribution({html:b.attribution})),c},t=function(b){var c=new a.layer.Group;return c.set("name",b),c},u=function(b,c){var d;return angular.forEach(b,function(b){return b instanceof a.layer.Group&&b.get("name")===c?void(d=b):void 0}),d},v=function(a,b){for(var c,d=0;d',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p});if(!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d){if("pixel"===g.view.projection)return void i.setCenter(c.coord);var e=a.proj.transform(d,g.view.projection,c.projection);(e[1]!==c.lat||e[0]!==c.lon)&&p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}}),f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),(!h(c.minResolution,e.minResolution)||z(d))&&g(c.minResolution)&&d.setMinResolution(c.minResolution),(!h(c.maxResolution,e.maxResolution)||z(d))&&g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)}),e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope();i.getMap().then(function(b){var d=e.getControlClasses,i=d();return a.$on("$destroy",function(){b.removeControl(f)}),h(a.properties)&&h(a.properties.control)?(f=a.properties.control,void b.addControl(f)):void(c.name&&(h(a.properties)&&(g=a.properties),f=new i[c.name](g),b.addControl(f)))})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return e.on("pointerdown",j),e.on("pointerup",j),e.on("pointerdrag",j),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e)}),k(c.properties)?void c.$watch("properties",function(d){if(e.getViewport().removeEventListener("mousemove",d.handleInteraction),e.getViewport().removeEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",d.handleTapInteraction),e.getViewport().removeEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",d.removeAllOverlays),d.handleInteraction=function(b){if(!d.label.show){var f=!1,g=e.getEventPixel(b),i=e.forEachFeatureAtPixel(g,function(a){return a}),j=!1;i===r&&(j=!0,f=!0,k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),!d.onClick||"click"!==b.type&&"touchend"!==b.type||c.$apply(function(){d.onClick.call(r,b,d)}),e.getTarget().style.cursor="pointer"),!f&&p&&(j=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),j&&b.preventDefault()}},d.handleTapInteraction=function(){function a(){c=!0,b&&clearTimeout(b),b=setTimeout(function(){c=!1,b=null},500)}var b,c=!1;return e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",a),function(){c||(d.handleInteraction.apply(null,arguments),a())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||d.onClick)&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){var d=c(a,b);a[d].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d,e=c(a,b);return d=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:f(a,b)};this.setMap=function(a,b){var c=f(d,b);c.resolve(a),e(d,b)},this.getMap=function(a){var b=g(d,a);return b.promise}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function x(a,b){var c;if(b?c=a[b]:(b="style",c=a),"style"===b&&a instanceof Function)return a;if(!(c instanceof Object))return c;var d;if("[object Object]"===Object.prototype.toString.call(c)){d={};var e=l[b];if(e&&c instanceof e)return c;Object.getOwnPropertyNames(c).forEach(function(a,f,g){var h=l[a];return e&&h&&h.prototype instanceof l[b]?(console.assert(1===g.length,"Extra parameters for "+b),d=x(c,a),m(d,h)):(d[a]=x(c,a),void("text"!==a&&"string"!=typeof d[a]&&(d[a]=m(d[a],l[a]))))})}else d=c;return m(d,l[b])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":case"TileVector":return"Vector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g,i=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");var l="http://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,m=window.devicePixelRatio;m>1&&(l=l.replace(".png","@2x.png")),g=new a.source.XYZ({url:l,attributions:s(b),tilePixelRatio:m>1?2:1,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,attributions:s(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:b.params,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:b.params,attributions:s(b),wrapX:void 0===b.wrapX?1:b.wrapX};b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={projection:f,layer:b.layer,attributions:s(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),wrapX:void 0===b.wrapX?1:b.wrapX};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({attributions:s(b),wrapX:void 0===b.wrapX?1:b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,attributions:s(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX?1:b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:s(b),layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="http://services.arcgisonline.com/ArcGIS/rest/services/",t=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:s(b),url:t,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var u=f;e(b.geojson.projection)&&(u=b.geojson.projection);var v=i.readFeatures(b.geojson.object,{featureProjection:u,dataProjection:u});g.addFeatures(v)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var w=f;e(b.wkt.projection)&&(w=b.wkt.projection);for(var x=new a.format.WKT,y=[],z=0;zd||0>e)return"";var f=b.url+c+"/"+d+"/"+e+".png";return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileImage":g=new a.source.TileImage({url:b.url,attributions:s(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=-a[2]-1,f=b.url.replace("{z}",c.toString()).replace("{x}",d.toString()).replace("{y}",e.toString());return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"KML":var B=b.extractStyles||!1;g=new a.source.Vector({url:b.url,format:new a.format.KML,radius:b.radius,extractStyles:B,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"Stamen":if(!b.layer||!q(b.layer))return void c.error("[AngularJS - Openlayers] - You need a valid Stamen layer.");g=new a.source.Stamen({layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageStatic":if(!b.url||!angular.isArray(b.imageSize)||2!==b.imageSize.length)return void c.error("[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.");g=new a.source.ImageStatic({url:b.url,attributions:s(b),imageSize:b.imageSize,projection:f,imageExtent:f.getExtent(),imageLoadFunction:b.imageLoadFunction,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"XYZ":b.url||b.tileUrlFunction||c.error("[AngularJS - Openlayers] - XYZ Layer needs valid url or tileUrlFunction properties"),g=new a.source.XYZ({url:b.url,attributions:s(b),minZoom:b.minZoom,maxZoom:b.maxZoom,wrapX:void 0===b.wrapX?1:b.wrapX,projection:b.projection,tileUrlFunction:b.tileUrlFunction})}return g||c.warn('[AngularJS - Openlayers] - No source could be found for type "'+b.type+'"'),g},s=function(b){var c=[];return e(b.attribution)&&c.unshift(new a.Attribution({html:b.attribution})),c},t=function(b){var c=new a.layer.Group;return c.set("name",b),c},u=function(b,c){var d;return angular.forEach(b,function(b){return b instanceof a.layer.Group&&b.get("name")===c?void(d=b):void 0}),d},v=function(a,b){for(var c,d=0;d',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p});if(!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d){if("pixel"===g.view.projection)return void i.setCenter(c.coord);var e=a.proj.transform(d,g.view.projection,c.projection);(e[1]!==c.lat||e[0]!==c.lon)&&p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}}),f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),(!h(c.minResolution,e.minResolution)||z(d))&&g(c.minResolution)&&d.setMinResolution(c.minResolution),(!h(c.maxResolution,e.maxResolution)||z(d))&&g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)}),e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope();i.getMap().then(function(b){var d=e.getControlClasses,i=d();return a.$on("$destroy",function(){b.removeControl(f)}),h(a.properties)&&h(a.properties.control)?(f=a.properties.control,void b.addControl(f)):void(c.name&&(h(a.properties)&&(g=a.properties),f=new i[c.name](g),b.addControl(f)))})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return e.on("pointerdown",j),e.on("pointerup",j),e.on("pointerdrag",j),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e)}),k(c.properties)?void c.$watch("properties",function(d){if(e.getViewport().removeEventListener("mousemove",d.handleInteraction),e.getViewport().removeEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",d.handleTapInteraction),e.getViewport().removeEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",d.removeAllOverlays),d.handleInteraction=function(b){if(!d.label.show){var f=!1,g=e.getEventPixel(b),i=e.forEachFeatureAtPixel(g,function(a){return a}),j=!1;i===r&&(j=!0,f=!0,k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),!d.onClick||"click"!==b.type&&"touchend"!==b.type||c.$apply(function(){d.onClick.call(r,b,d)}),e.getTarget().style.cursor="pointer"),!f&&p&&(j=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),j&&b.preventDefault()}},d.handleTapInteraction=function(){function a(){c=!0,b&&clearTimeout(b),b=setTimeout(function(){c=!1,b=null},500)}var b,c=!1;return e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",a),function(){c||(d.handleInteraction.apply(null,arguments),a())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||d.onClick)&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){var d=c(a,b);a[d].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d,e=c(a,b);return d=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:f(a,b)};this.setMap=function(a,b){var c=f(d,b);c.resolve(a),e(d,b)},this.getMap=function(a){var b=g(d,a);return b.promise}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function x(a,b){var c;if(b?c=a[b]:(b="style",c=a),"style"===b&&a instanceof Function)return a;if(!(c instanceof Object))return c;var d;if("[object Object]"===Object.prototype.toString.call(c)){d={};var e=l[b];if(e&&c instanceof e)return c;Object.getOwnPropertyNames(c).forEach(function(a,f,g){var h=l[a];return e&&h&&h.prototype instanceof l[b]?(console.assert(1===g.length,"Extra parameters for "+b),d=x(c,a),m(d,h)):(d[a]=x(c,a),void("text"!==a&&"string"!=typeof d[a]&&(d[a]=m(d[a],l[a]))))})}else d=c;return m(d,l[b])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":case"TileVector":return"Vector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");var i="http://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,l=window.devicePixelRatio;l>1&&(i=i.replace(".png","@2x.png")),g=new a.source.XYZ({url:i,attributions:s(b),tilePixelRatio:l>1?2:1,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,attributions:s(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:b.params,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var m={crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:b.params,attributions:s(b),wrapX:void 0===b.wrapX?1:b.wrapX};b.serverType&&(m.serverType=b.serverType),b.url&&(m.url=b.url),b.urls&&(m.urls=b.urls),g=new a.source.TileWMS(m);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var n={projection:f,layer:b.layer,attributions:s(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),wrapX:void 0===b.wrapX?1:b.wrapX};e(b.url)&&(n.url=b.url),e(b.urls)&&(n.urls=b.urls),g=new a.source.WMTS(n);break;case"OSM":g=new a.source.OSM({attributions:s(b),wrapX:void 0===b.wrapX?1:b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var o={key:b.key,attributions:s(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX?1:b.wrapX};b.maxZoom&&(o.maxZoom=b.maxZoom),g=new a.source.BingMaps(o);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:s(b),layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var p="http://services.arcgisonline.com/ArcGIS/rest/services/",r=p+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:s(b),url:r,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var t=f;e(b.geojson.projection)&&(t=b.geojson.projection);var u=new a.format.GeoJSON,v=u.readFeatures(b.geojson.object,{featureProjection:t});g.addFeatures(v)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var w=f;e(b.wkt.projection)&&(w=b.wkt.projection);for(var x=new a.format.WKT,y=[],z=0;zd||0>e)return"";var f=b.url+c+"/"+d+"/"+e+".png";return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileImage":g=new a.source.TileImage({url:b.url,attributions:s(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=-a[2]-1,f=b.url.replace("{z}",c.toString()).replace("{x}",d.toString()).replace("{y}",e.toString());return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"KML":var B=b.extractStyles||!1;g=new a.source.Vector({url:b.url,format:new a.format.KML,radius:b.radius,extractStyles:B,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"Stamen":if(!b.layer||!q(b.layer))return void c.error("[AngularJS - Openlayers] - You need a valid Stamen layer.");g=new a.source.Stamen({layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageStatic":if(!b.url||!angular.isArray(b.imageSize)||2!==b.imageSize.length)return void c.error("[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.");g=new a.source.ImageStatic({url:b.url,attributions:s(b),imageSize:b.imageSize,projection:f,imageExtent:f.getExtent(),imageLoadFunction:b.imageLoadFunction,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"XYZ":b.url||b.tileUrlFunction||c.error("[AngularJS - Openlayers] - XYZ Layer needs valid url or tileUrlFunction properties"),g=new a.source.XYZ({url:b.url,attributions:s(b),minZoom:b.minZoom,maxZoom:b.maxZoom,wrapX:void 0===b.wrapX?1:b.wrapX,projection:b.projection,tileUrlFunction:b.tileUrlFunction})}return g||c.warn('[AngularJS - Openlayers] - No source could be found for type "'+b.type+'"'),g},s=function(b){var c=[];return e(b.attribution)&&c.unshift(new a.Attribution({html:b.attribution})),c},t=function(b){var c=new a.layer.Group;return c.set("name",b),c},u=function(b,c){var d;return angular.forEach(b,function(b){return b instanceof a.layer.Group&&b.get("name")===c?void(d=b):void 0}),d},v=function(a,b){for(var c,d=0;d',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p});if(!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d){if("pixel"===g.view.projection)return void i.setCenter(c.coord);var e=a.proj.transform(d,g.view.projection,c.projection);(e[1]!==c.lat||e[0]!==c.lon)&&p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}}),f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),(!h(c.minResolution,e.minResolution)||z(d))&&g(c.minResolution)&&d.setMinResolution(c.minResolution),(!h(c.maxResolution,e.maxResolution)||z(d))&&g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)}),e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope();i.getMap().then(function(b){var d=e.getControlClasses,i=d();return a.$on("$destroy",function(){b.removeControl(f)}),h(a.properties)&&h(a.properties.control)?(f=a.properties.control,void b.addControl(f)):void(c.name&&(h(a.properties)&&(g=a.properties),f=new i[c.name](g),b.addControl(f)))})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return e.on("pointerdown",j),e.on("pointerup",j),e.on("pointerdrag",j),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e)}),k(c.properties)?void c.$watch("properties",function(d){if(e.getViewport().removeEventListener("mousemove",d.handleInteraction),e.getViewport().removeEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",d.handleTapInteraction),e.getViewport().removeEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",d.removeAllOverlays),d.handleInteraction=function(b){if(!d.label.show){var f=!1,g=e.getEventPixel(b),i=e.forEachFeatureAtPixel(g,function(a){return a}),j=!1;i===r&&(j=!0,f=!0,k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),!d.onClick||"click"!==b.type&&"touchend"!==b.type||c.$apply(function(){d.onClick.call(r,b,d)}),e.getTarget().style.cursor="pointer"),!f&&p&&(j=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),j&&b.preventDefault()}},d.handleTapInteraction=function(){function a(){c=!0,b&&clearTimeout(b),b=setTimeout(function(){c=!1,b=null},500)}var b,c=!1;return e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",a),function(){c||(d.handleInteraction.apply(null,arguments),a())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||d.onClick)&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){var d=c(a,b);a[d].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d,e=c(a,b);return d=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:f(a,b)};this.setMap=function(a,b){var c=f(d,b);c.resolve(a),e(d,b)},this.getMap=function(a){var b=g(d,a);return b.promise}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function x(a,b){var c;if(b?c=a[b]:(b="style",c=a),"style"===b&&a instanceof Function)return a;if(!(c instanceof Object))return c;var d;if("[object Object]"===Object.prototype.toString.call(c)){d={};var e=l[b];if(e&&c instanceof e)return c;Object.getOwnPropertyNames(c).forEach(function(a,f,g){var h=l[a];return e&&h&&h.prototype instanceof l[b]?(console.assert(1===g.length,"Extra parameters for "+b),d=x(c,a),m(d,h)):(d[a]=x(c,a),void("text"!==a&&"string"!=typeof d[a]&&(d[a]=m(d[a],l[a]))))})}else d=c;return m(d,l[b])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":case"TileVector":return"Vector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g,i=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");var l="http://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,m=window.devicePixelRatio;m>1&&(l=l.replace(".png","@2x.png")),g=new a.source.XYZ({url:l,attributions:s(b),tilePixelRatio:m>1?2:1,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,attributions:s(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:b.params,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:b.params,attributions:s(b),wrapX:void 0===b.wrapX?1:b.wrapX};b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={projection:f,layer:b.layer,attributions:s(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),wrapX:void 0===b.wrapX?1:b.wrapX};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({attributions:s(b),wrapX:void 0===b.wrapX?1:b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,attributions:s(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX?1:b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:s(b),layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="http://services.arcgisonline.com/ArcGIS/rest/services/",t=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:s(b),url:t,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var u=f;e(b.geojson.projection)&&(u=b.geojson.projection);var v=i.readFeatures(b.geojson.object,{featureProjection:u,dataProjection:u});g.addFeatures(v)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var w=f;e(b.wkt.projection)&&(w=b.wkt.projection);for(var x=new a.format.WKT,y=[],z=0;zd||0>e)return"";var f=b.url+c+"/"+d+"/"+e+".png";return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileImage":g=new a.source.TileImage({url:b.url,attributions:s(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=-a[2]-1,f=b.url.replace("{z}",c.toString()).replace("{x}",d.toString()).replace("{y}",e.toString());return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"KML":var B=b.extractStyles||!1;g=new a.source.Vector({url:b.url,format:new a.format.KML,radius:b.radius,extractStyles:B,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"Stamen":if(!b.layer||!q(b.layer))return void c.error("[AngularJS - Openlayers] - You need a valid Stamen layer.");g=new a.source.Stamen({layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageStatic":if(!b.url||!angular.isArray(b.imageSize)||2!==b.imageSize.length)return void c.error("[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.");g=new a.source.ImageStatic({url:b.url,attributions:s(b),imageSize:b.imageSize,projection:f,imageExtent:f.getExtent(),imageLoadFunction:b.imageLoadFunction,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"XYZ":b.url||b.tileUrlFunction||c.error("[AngularJS - Openlayers] - XYZ Layer needs valid url or tileUrlFunction properties"),g=new a.source.XYZ({url:b.url,attributions:s(b),minZoom:b.minZoom,maxZoom:b.maxZoom,wrapX:void 0===b.wrapX?1:b.wrapX,projection:b.projection,tileUrlFunction:b.tileUrlFunction})}return g||c.warn('[AngularJS - Openlayers] - No source could be found for type "'+b.type+'"'),g},s=function(b){var c=[];return e(b.attribution)&&c.unshift(new a.Attribution({html:b.attribution})),c},t=function(b){var c=new a.layer.Group;return c.set("name",b),c},u=function(b,c){var d;return angular.forEach(b,function(b){return b instanceof a.layer.Group&&b.get("name")===c?void(d=b):void 0}),d},v=function(a,b){for(var c,d=0;d Date: Mon, 25 Apr 2016 12:59:39 -0600 Subject: [PATCH 17/53] unpin from angular 1.4.8 --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 5c50ad5d..de118b11 100644 --- a/package.json +++ b/package.json @@ -17,8 +17,8 @@ ], "license": "MIT", "dependencies": { - "angular": "~1.4.8", - "angular-sanitize": "~1.4.8", + "angular": "^1.4.8", + "angular-sanitize": "^1.4.8", "openlayers": "~3.12" }, "devDependencies": { From 84ef2fe4a9d003584e1c95302c53e460219ca2a4 Mon Sep 17 00:00:00 2001 From: Sathish Kesavaperumal Date: Fri, 13 May 2016 14:30:42 +0530 Subject: [PATCH 18/53] Updated openlayer to 3.14 version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index de118b11..45d61add 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "dependencies": { "angular": "^1.4.8", "angular-sanitize": "^1.4.8", - "openlayers": "~3.12" + "openlayers": "~3.14" }, "devDependencies": { "grunt": "~0.4.5", From 98eefb557761afde573857a6de8c14bf1339d1e0 Mon Sep 17 00:00:00 2001 From: sathishatnet Date: Wed, 15 Jun 2016 18:21:52 +0530 Subject: [PATCH 19/53] Update CONTRIBUTING.md --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 148a71c0..d1c889c0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -118,7 +118,7 @@ Once you have the development dependencies installed, we can use our predefined * **grunt test**. Executes the karma unitary tests and the protractor e2e tests, reporting the actual state of the project. * **grunt test:unit**. Executes only the karma unitary tests. * **grunt test:e2e**. Executes only the protractor e2e tests. -* **grunt coverage**. Generates a "coverage" folder with an [istanbul](https://github.com/gotwarlost/istanbul) report of wich part of the code is covered by the actual tests. +* **grunt coverage**. Generates a "coverage" folder with an [istanbul](https://github.com/gotwarlost/istanbul) report of which part of the code is covered by the actual tests. * **grunt**. The default task watches for project files changes and when a change is detected, tries to build the library file passing the jshint filter and the tests. Let's see an example: ``` From b319862dbe5ee3226c14ac06bc92351671ef5a97 Mon Sep 17 00:00:00 2001 From: Sathish Kesavaperumal Date: Tue, 19 Jul 2016 15:49:38 +0530 Subject: [PATCH 20/53] Added code to have different projection for TileWMS as optional --- dist/angular-openlayers-directive.js | 159 ++++++++++++++---- dist/angular-openlayers-directive.min.js | 6 +- ...ular-openlayers-directive.min.no-header.js | 6 +- dist/angular-openlayers-directive.pre.js | 159 ++++++++++++++---- src/services/olHelpers.js | 4 + 5 files changed, 260 insertions(+), 74 deletions(-) diff --git a/dist/angular-openlayers-directive.js b/dist/angular-openlayers-directive.js index 8a390b0e..3b18b24c 100644 --- a/dist/angular-openlayers-directive.js +++ b/dist/angular-openlayers-directive.js @@ -88,7 +88,13 @@ angular.module('openlayers-directive', ['ngSanitize']).directive('openlayers', [ controls: controls, interactions: interactions, renderer: defaults.renderer, - view: view + view: view, + loadTilesWhileAnimating: defaults.loadTilesWhileAnimating, + loadTilesWhileInteracting: defaults.loadTilesWhileInteracting + }); + + scope.$on('$destroy', function() { + olData.resetMap(attrs.id); }); // If no layer is defined, set the default tileLayer @@ -258,13 +264,14 @@ angular.module('openlayers-directive').directive('olCenter', ["$log", "$location var viewCenter = view.getCenter(); if (viewCenter) { - if (defaults.view.projection === 'pixel') { + if (defaults.view.projection === 'pixel' || center.projection === 'pixel') { view.setCenter(center.coord); - return; - } - var actualCenter = ol.proj.transform(viewCenter, defaults.view.projection, center.projection); - if (!(actualCenter[1] === center.lat && actualCenter[0] === center.lon)) { - setCenter(view, defaults.view.projection, center, map); + } else { + var actualCenter = + ol.proj.transform(viewCenter, defaults.view.projection, center.projection); + if (!(actualCenter[1] === center.lat && actualCenter[0] === center.lon)) { + setCenter(view, defaults.view.projection, center, map); + } } } @@ -283,7 +290,7 @@ angular.module('openlayers-directive').directive('olCenter', ["$log", "$location var center = map.getView().getCenter(); scope.center.zoom = view.getZoom(); - if (defaults.view.projection === 'pixel') { + if (defaults.view.projection === 'pixel' || scope.center.projection === 'pixel') { scope.center.coord = center; return; } @@ -317,7 +324,8 @@ angular.module('openlayers-directive').directive('olLayer', ["$log", "$q", "olMa return { restrict: 'E', scope: { - properties: '=olLayerProperties' + properties: '=olLayerProperties', + onLayerCreated: '&' }, replace: false, require: '^openlayers', @@ -363,7 +371,7 @@ angular.module('openlayers-directive').directive('olLayer', ["$log", "$q", "olMa } }; - olLayer = createLayer(l, projection, attrs.layerName); + olLayer = createLayer(l, projection, attrs.layerName, scope.onLayerCreated); if (detectLayerType(l) === 'Vector') { setVectorLayerEvents(defaults.events, map, scope, attrs.name); } @@ -391,7 +399,7 @@ angular.module('openlayers-directive').directive('olLayer', ["$log", "$q", "olMa var group; var collection; if (!isDefined(olLayer)) { - olLayer = createLayer(properties, projection); + olLayer = createLayer(properties, projection, scope.onLayerCreated); if (isDefined(properties.group)) { addLayerToGroup(layerCollection, olLayer, properties.group); } else if (isDefined(properties.index)) { @@ -458,7 +466,7 @@ angular.module('openlayers-directive').directive('olLayer', ["$log", "$q", "olMa collection.removeAt(idx); - olLayer = createLayer(properties, projection); + olLayer = createLayer(properties, projection, scope.onLayerCreated); olLayer.set('group', group); if (isDefined(olLayer)) { @@ -543,7 +551,8 @@ angular.module('openlayers-directive').directive('olPath', ["$log", "$q", "olMap return { restrict: 'E', scope: { - properties: '=olGeomProperties' + properties: '=olGeomProperties', + style: '=olStyle' }, require: '^openlayers', replace: true, @@ -578,7 +587,7 @@ angular.module('openlayers-directive').directive('olPath', ["$log", "$q", "olMap type: 'Polygon', coords: coords, projection: proj, - style: mapDefaults.styles.path + style: scope.style ? scope.style : mapDefaults.styles.path }; var feature = createFeature(data, viewProjection); layer.getSource().addFeature(feature); @@ -894,7 +903,12 @@ angular.module('openlayers-directive').directive('olMarker', ["$log", "$q", "olM // This function handles popup on mouse over/click properties.handleInteraction = function(evt) { - if (properties.label.show) { + var ngClick = false; + if (attrs.hasOwnProperty('ngClick')) { + ngClick = true; + } + + if (properties.label.show && !ngClick) { return; } var found = false; @@ -907,6 +921,12 @@ angular.module('openlayers-directive').directive('olMarker', ["$log", "$q", "olM if (feature === marker) { actionTaken = true; found = true; + if (ngClick && (evt.type === 'click' || evt.type === 'touchend')) { + element.triggerHandler('click'); + evt.preventDefault(); + evt.stopPropagation(); + return; + } if (!isDefined(label)) { if (data.projection === 'pixel') { pos = properties.coord; @@ -917,12 +937,6 @@ angular.module('openlayers-directive').directive('olMarker', ["$log", "$q", "olM label = createOverlay(element, pos); map.addOverlay(label); } - - if (properties.onClick && (evt.type === 'click' || evt.type === 'touchend')) { - scope.$apply(function() { - properties.onClick.call(marker, evt, properties); - }); - } map.getTarget().style.cursor = 'pointer'; } @@ -1088,7 +1102,7 @@ angular.module('openlayers-directive').directive('olMarker', ["$log", "$q", "olM if ((properties.label && properties.label.show === false && properties.label.showOnMouseClick) || - properties.onClick) { + attrs.hasOwnProperty('ngClick')) { map.getViewport().addEventListener('click', properties.handleTapInteraction); map.getViewport().querySelector('canvas.ol-unselectable').addEventListener( 'touchend', properties.handleTapInteraction); @@ -1175,6 +1189,12 @@ angular.module('openlayers-directive').service('olData', ["$log", "$q", function return id; } + this.resetMap = function(scopeId) { + if (angular.isDefined(maps[scopeId])) { + delete maps[scopeId]; + } + }; + }]); angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$http", function($q, $log, $http) { @@ -1331,8 +1351,9 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt case 'TopoJSON': case 'KML': case 'WKT': - case 'TileVector': return 'Vector'; + case 'TileVector': + return 'TileVector'; default: return 'Tile'; } @@ -1369,6 +1390,7 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt var createSource = function(source, projection) { var oSource; + var url; var geojsonFormat = new ol.format.GeoJSON(); // used in various switch stmnts below switch (source.type) { @@ -1377,7 +1399,7 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt $log.error('[AngularJS - Openlayers] - MapBox layer requires the map id and the access token'); return; } - var url = 'http://api.tiles.mapbox.com/v4/' + source.mapId + '/{z}/{x}/{y}.png?access_token=' + + url = 'http://api.tiles.mapbox.com/v4/' + source.mapId + '/{z}/{x}/{y}.png?access_token=' + source.accessToken; var pixelRatio = window.devicePixelRatio; @@ -1393,6 +1415,22 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }); break; + case 'MapBoxStudio': + if (!source.mapId || !source.accessToken || !source.userId) { + $log.error('[AngularJS - Openlayers] - MapBox Studio layer requires the map id' + + ', user id and the access token'); + return; + } + url = 'https://api.mapbox.com/styles/v1/' + source.userId + + '/' + source.mapId + '/tiles/{z}/{x}/{y}?access_token=' + + source.accessToken; + + oSource = new ol.source.XYZ({ + url: url, + attributions: createAttribution(source), + tileSize: source.tileSize || [512, 512] + }); + break; case 'ImageWMS': if (!source.url || !source.params) { $log.error('[AngularJS - Openlayers] - ImageWMS Layer needs ' + @@ -1402,8 +1440,9 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt url: source.url, attributions: createAttribution(source), crossOrigin: (typeof source.crossOrigin === 'undefined') ? 'anonymous' : source.crossOrigin, - params: source.params, - wrapX: (source.wrapX === undefined) ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX, + params: deepCopy(source.params), + ratio: source.ratio }); break; @@ -1415,10 +1454,14 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt var wmsConfiguration = { crossOrigin: (typeof source.crossOrigin === 'undefined') ? 'anonymous' : source.crossOrigin, - params: source.params, + params: deepCopy(source.params), attributions: createAttribution(source), wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }; + + if(source.projection){ + wmsConfiguration.projection = new ol.proj.get(source.projection); + } if (source.serverType) { wmsConfiguration.serverType = source.serverType; @@ -1454,7 +1497,8 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt resolutions: source.tileGrid.resolutions, matrixIds: source.tileGrid.matrixIds }), - wrapX: (source.wrapX === undefined) ? 1 : source.wrapX + wrapX: (source.wrapX === undefined) ? 1 : source.wrapX, + style: (source.style === 'undefined') ? 'normal' : source.style }; if (isDefined(source.url)) { @@ -1548,14 +1592,17 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt oSource = new ol.source.Vector(); var projectionToUse = projection; + var dataProjection; // Projection of geojson data if (isDefined(source.geojson.projection)) { - projectionToUse = source.geojson.projection; + dataProjection = new ol.proj.get(source.geojson.projection); + } else { + dataProjection = projection; // If not defined, features will not be reprojected. } var features = geojsonFormat.readFeatures( source.geojson.object, { featureProjection: projectionToUse, - dataProjection: projectionToUse + dataProjection: dataProjection }); oSource.addFeatures(features); @@ -1654,7 +1701,7 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt if (!source.url || !source.format) { $log.error('[AngularJS - Openlayers] - TileVector Layer needs valid url and format properties'); } - oSource = new ol.source.TileVector({ + oSource = new ol.source.VectorTile({ url: source.url, projection: projection, attributions: createAttribution(source), @@ -1747,7 +1794,7 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt attributions: createAttribution(source), imageSize: source.imageSize, projection: projection, - imageExtent: projection.getExtent(), + imageExtent: source.imageExtent ? source.imageExtent : projection.getExtent(), imageLoadFunction: source.imageLoadFunction, wrapX: (source.wrapX === undefined) ? 1 : source.wrapX }); @@ -1766,6 +1813,15 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt tileUrlFunction: source.tileUrlFunction }); break; + case 'Zoomify': + if (!source.url || !angular.isArray(source.imageSize) || source.imageSize.length !== 2) { + $log.error('[AngularJS - Openlayers] - Zoomify Layer needs valid url and imageSize properties'); + } + oSource = new ol.source.Zoomify({ + url: source.url, + size: source.imageSize + }); + break; } // log a warning when no source could be created for the given type @@ -1776,6 +1832,17 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt return oSource; }; + var deepCopy = function(oldObj) { + var newObj = oldObj; + if (oldObj && typeof oldObj === 'object') { + newObj = Object.prototype.toString.call(oldObj) === '[object Array]' ? [] : {}; + for (var i in oldObj) { + newObj[i] = deepCopy(oldObj[i]); + } + } + return newObj; + }; + var createAttribution = function(source) { var attributions = []; if (isDefined(source.attribution)) { @@ -2004,7 +2071,7 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt detectLayerType: detectLayerType, - createLayer: function(layer, projection, name) { + createLayer: function(layer, projection, name, onLayerCreatedFn) { var oLayer; var type = detectLayerType(layer); var oSource = createSource(layer.source, projection); @@ -2012,6 +2079,13 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt return; } + // handle function overloading. 'name' argument may be + // our onLayerCreateFn since name is optional + if (typeof(name) === 'function' && !onLayerCreatedFn) { + onLayerCreatedFn = name; + name = undefined; // reset, otherwise it'll be used later on + } + // Manage clustering if ((type === 'Vector') && layer.clustering) { oSource = new ol.source.Cluster({ @@ -2055,6 +2129,9 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt case 'Vector': oLayer = new ol.layer.Vector(layerConfig); break; + case 'TileVector': + oLayer = new ol.layer.VectorTile(layerConfig); + break; } // set a layer name if given @@ -2071,6 +2148,13 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt } } + // invoke the onSourceCreated callback + if (onLayerCreatedFn) { + onLayerCreatedFn({ + oLayer: oLayer + }); + } + return oLayer; }, @@ -2190,7 +2274,7 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt element.css('display', 'block'); var ov = new ol.Overlay({ position: pos, - element: element, + element: element[0], positioning: 'center-left' }); @@ -2337,6 +2421,13 @@ angular.module('openlayers-directive').factory('olMapDefaults', ["$q", "olHelper newDefaults.styles = angular.extend(newDefaults.styles, userDefaults.styles); } + if (isDefined(userDefaults.loadTilesWhileAnimating)) { + newDefaults.loadTilesWhileAnimating = userDefaults.loadTilesWhileAnimating; + } + + if (isDefined(userDefaults.loadTilesWhileInteracting)) { + newDefaults.loadTilesWhileInteracting = userDefaults.loadTilesWhileInteracting; + } } defaults[scopeId] = newDefaults; diff --git a/dist/angular-openlayers-directive.min.js b/dist/angular-openlayers-directive.min.js index c1b65cc8..67fcd0ff 100644 --- a/dist/angular-openlayers-directive.min.js +++ b/dist/angular-openlayers-directive.min.js @@ -27,6 +27,6 @@ * @authors https://github.com/tombatossals/angular-openlayers-directive/graphs/contributors */ -/*! angular-openlayers-directive 09-02-2016 */ -!function(a,b){if("function"==typeof require&&"object"==typeof exports){var c=require("openlayers");require("angular-sanitize");exports.angularOpenlayersDirective=b(c)}else"function"==typeof define&&define.amd?define(["ol"],function(c){return a.angularOpenlayersDirective=b(c)}):a.angularOpenlayersDirective=b(a.ol)}(this,function(a){return angular.module("openlayers-directive",["ngSanitize"]).directive("openlayers",["$log","$q","$compile","olHelpers","olMapDefaults","olData",function(b,c,d,e,f,g){return{restrict:"EA",transclude:!0,replace:!0,scope:{center:"=olCenter",defaults:"=olDefaults",view:"=olView",events:"=olEvents"},template:'
',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p});if(!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d){if("pixel"===g.view.projection)return void i.setCenter(c.coord);var e=a.proj.transform(d,g.view.projection,c.projection);(e[1]!==c.lat||e[0]!==c.lon)&&p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}}),f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),(!h(c.minResolution,e.minResolution)||z(d))&&g(c.minResolution)&&d.setMinResolution(c.minResolution),(!h(c.maxResolution,e.maxResolution)||z(d))&&g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)}),e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope();i.getMap().then(function(b){var d=e.getControlClasses,i=d();return a.$on("$destroy",function(){b.removeControl(f)}),h(a.properties)&&h(a.properties.control)?(f=a.properties.control,void b.addControl(f)):void(c.name&&(h(a.properties)&&(g=a.properties),f=new i[c.name](g),b.addControl(f)))})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return e.on("pointerdown",j),e.on("pointerup",j),e.on("pointerdrag",j),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e)}),k(c.properties)?void c.$watch("properties",function(d){if(e.getViewport().removeEventListener("mousemove",d.handleInteraction),e.getViewport().removeEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",d.handleTapInteraction),e.getViewport().removeEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",d.removeAllOverlays),d.handleInteraction=function(b){if(!d.label.show){var f=!1,g=e.getEventPixel(b),i=e.forEachFeatureAtPixel(g,function(a){return a}),j=!1;i===r&&(j=!0,f=!0,k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),!d.onClick||"click"!==b.type&&"touchend"!==b.type||c.$apply(function(){d.onClick.call(r,b,d)}),e.getTarget().style.cursor="pointer"),!f&&p&&(j=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),j&&b.preventDefault()}},d.handleTapInteraction=function(){function a(){c=!0,b&&clearTimeout(b),b=setTimeout(function(){c=!1,b=null},500)}var b,c=!1;return e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",a),function(){c||(d.handleInteraction.apply(null,arguments),a())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||d.onClick)&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){var d=c(a,b);a[d].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d,e=c(a,b);return d=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:f(a,b)};this.setMap=function(a,b){var c=f(d,b);c.resolve(a),e(d,b)},this.getMap=function(a){var b=g(d,a);return b.promise}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function x(a,b){var c;if(b?c=a[b]:(b="style",c=a),"style"===b&&a instanceof Function)return a;if(!(c instanceof Object))return c;var d;if("[object Object]"===Object.prototype.toString.call(c)){d={};var e=l[b];if(e&&c instanceof e)return c;Object.getOwnPropertyNames(c).forEach(function(a,f,g){var h=l[a];return e&&h&&h.prototype instanceof l[b]?(console.assert(1===g.length,"Extra parameters for "+b),d=x(c,a),m(d,h)):(d[a]=x(c,a),void("text"!==a&&"string"!=typeof d[a]&&(d[a]=m(d[a],l[a]))))})}else d=c;return m(d,l[b])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":case"TileVector":return"Vector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g,i=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");var l="http://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,m=window.devicePixelRatio;m>1&&(l=l.replace(".png","@2x.png")),g=new a.source.XYZ({url:l,attributions:s(b),tilePixelRatio:m>1?2:1,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,attributions:s(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:b.params,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:b.params,attributions:s(b),wrapX:void 0===b.wrapX?1:b.wrapX};b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={projection:f,layer:b.layer,attributions:s(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),wrapX:void 0===b.wrapX?1:b.wrapX};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({attributions:s(b),wrapX:void 0===b.wrapX?1:b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,attributions:s(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX?1:b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:s(b),layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="http://services.arcgisonline.com/ArcGIS/rest/services/",t=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:s(b),url:t,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var u=f;e(b.geojson.projection)&&(u=b.geojson.projection);var v=i.readFeatures(b.geojson.object,{featureProjection:u,dataProjection:u});g.addFeatures(v)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var w=f;e(b.wkt.projection)&&(w=b.wkt.projection);for(var x=new a.format.WKT,y=[],z=0;zd||0>e)return"";var f=b.url+c+"/"+d+"/"+e+".png";return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileImage":g=new a.source.TileImage({url:b.url,attributions:s(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=-a[2]-1,f=b.url.replace("{z}",c.toString()).replace("{x}",d.toString()).replace("{y}",e.toString());return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"KML":var B=b.extractStyles||!1;g=new a.source.Vector({url:b.url,format:new a.format.KML,radius:b.radius,extractStyles:B,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"Stamen":if(!b.layer||!q(b.layer))return void c.error("[AngularJS - Openlayers] - You need a valid Stamen layer.");g=new a.source.Stamen({layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageStatic":if(!b.url||!angular.isArray(b.imageSize)||2!==b.imageSize.length)return void c.error("[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.");g=new a.source.ImageStatic({url:b.url,attributions:s(b),imageSize:b.imageSize,projection:f,imageExtent:f.getExtent(),imageLoadFunction:b.imageLoadFunction,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"XYZ":b.url||b.tileUrlFunction||c.error("[AngularJS - Openlayers] - XYZ Layer needs valid url or tileUrlFunction properties"),g=new a.source.XYZ({url:b.url,attributions:s(b),minZoom:b.minZoom,maxZoom:b.maxZoom,wrapX:void 0===b.wrapX?1:b.wrapX,projection:b.projection,tileUrlFunction:b.tileUrlFunction})}return g||c.warn('[AngularJS - Openlayers] - No source could be found for type "'+b.type+'"'),g},s=function(b){var c=[];return e(b.attribution)&&c.unshift(new a.Attribution({html:b.attribution})),c},t=function(b){var c=new a.layer.Group;return c.set("name",b),c},u=function(b,c){var d;return angular.forEach(b,function(b){return b instanceof a.layer.Group&&b.get("name")===c?void(d=b):void 0}),d},v=function(a,b){for(var c,d=0;d',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id)}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}}),f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)}),e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope();i.getMap().then(function(b){var d=e.getControlClasses,i=d();return a.$on("$destroy",function(){b.removeControl(f)}),h(a.properties)&&h(a.properties.control)?(f=a.properties.control,void b.addControl(f)):void(c.name&&(h(a.properties)&&(g=a.properties),f=new i[c.name](g),b.addControl(f)))})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return e.on("pointerdown",j),e.on("pointerup",j),e.on("pointerdrag",j),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e)}),k(c.properties)?void c.$watch("properties",function(d){if(e.getViewport().removeEventListener("mousemove",d.handleInteraction),e.getViewport().removeEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",d.handleTapInteraction),e.getViewport().removeEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",d.removeAllOverlays),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){function a(){c=!0,b&&clearTimeout(b),b=setTimeout(function(){c=!1,b=null},500)}var b,c=!1;return e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",a),function(){c||(d.handleInteraction.apply(null,arguments),a())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){var d=c(a,b);a[d].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d,e=c(a,b);return d=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:f(a,b)};this.setMap=function(a,b){var c=f(d,b);c.resolve(a),e(d,b)},this.getMap=function(a){var b=g(d,a);return b.promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function y(a,b){var c;if(b?c=a[b]:(b="style",c=a),"style"===b&&a instanceof Function)return a;if(!(c instanceof Object))return c;var d;if("[object Object]"===Object.prototype.toString.call(c)){d={};var e=l[b];if(e&&c instanceof e)return c;Object.getOwnPropertyNames(c).forEach(function(a,f,g){var h=l[a];return e&&h&&h.prototype instanceof l[b]?(console.assert(1===g.length,"Extra parameters for "+b),d=y(c,a),m(d,h)):(d[a]=y(c,a),void("text"!==a&&"string"!=typeof d[a]&&(d[a]=m(d[a],l[a]))))})}else d=c;return m(d,l[b])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":return"Vector";case"TileVector":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g,i,l=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");i="http://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken;var m=window.devicePixelRatio;m>1&&(i=i.replace(".png","@2x.png")),g=new a.source.XYZ({url:i,attributions:t(b),tilePixelRatio:m>1?2:1,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");i="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,g=new a.source.XYZ({url:i,attributions:t(b),tileSize:b.tileSize||[512,512]});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,attributions:t(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,wrapX:void 0===b.wrapX?1:b.wrapX,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b),wrapX:void 0===b.wrapX?1:b.wrapX};b.projection&&(n.projection=new a.proj.get(b.projection)),b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),wrapX:void 0===b.wrapX?1:b.wrapX,style:"undefined"===b.style?"normal":b.style};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({attributions:t(b),wrapX:void 0===b.wrapX?1:b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX?1:b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="http://services.arcgisonline.com/ArcGIS/rest/services/",u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),url:u,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=l.readFeatures(b.geojson.object,{featureProjection:w,dataProjection:v});g.addFeatures(x)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var y=f;e(b.wkt.projection)&&(y=b.wkt.projection);for(var z=new a.format.WKT,A=[],B=0;Bd||0>e)return"";var f=b.url+c+"/"+d+"/"+e+".png";return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileImage":g=new a.source.TileImage({url:b.url,attributions:t(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=-a[2]-1,f=b.url.replace("{z}",c.toString()).replace("{x}",d.toString()).replace("{y}",e.toString());return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"KML":var D=b.extractStyles||!1;g=new a.source.Vector({url:b.url,format:new a.format.KML,radius:b.radius,extractStyles:D,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"Stamen":if(!b.layer||!q(b.layer))return void c.error("[AngularJS - Openlayers] - You need a valid Stamen layer.");g=new a.source.Stamen({layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageStatic":if(!b.url||!angular.isArray(b.imageSize)||2!==b.imageSize.length)return void c.error("[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.");g=new a.source.ImageStatic({url:b.url,attributions:t(b),imageSize:b.imageSize,projection:f,imageExtent:b.imageExtent?b.imageExtent:f.getExtent(),imageLoadFunction:b.imageLoadFunction,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"XYZ":b.url||b.tileUrlFunction||c.error("[AngularJS - Openlayers] - XYZ Layer needs valid url or tileUrlFunction properties"),g=new a.source.XYZ({url:b.url,attributions:t(b),minZoom:b.minZoom,maxZoom:b.maxZoom,wrapX:void 0===b.wrapX?1:b.wrapX,projection:b.projection,tileUrlFunction:b.tileUrlFunction});break;case"Zoomify":b.url&&angular.isArray(b.imageSize)&&2===b.imageSize.length||c.error("[AngularJS - Openlayers] - Zoomify Layer needs valid url and imageSize properties"),g=new a.source.Zoomify({url:b.url,size:b.imageSize})}return g||c.warn('[AngularJS - Openlayers] - No source could be found for type "'+b.type+'"'),g},s=function(a){var b=a;if(a&&"object"==typeof a){b="[object Array]"===Object.prototype.toString.call(a)?[]:{};for(var c in a)b[c]=s(a[c])}return b},t=function(b){var c=[];return e(b.attribution)&&c.unshift(new a.Attribution({html:b.attribution})),c},u=function(b){var c=new a.layer.Group;return c.set("name",b),c},v=function(b,c){var d;return angular.forEach(b,function(b){return b instanceof a.layer.Group&&b.get("name")===c?void(d=b):void 0}),d},w=function(a,b){for(var c,d=0;d',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p});if(!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d){if("pixel"===g.view.projection)return void i.setCenter(c.coord);var e=a.proj.transform(d,g.view.projection,c.projection);(e[1]!==c.lat||e[0]!==c.lon)&&p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}}),f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),(!h(c.minResolution,e.minResolution)||z(d))&&g(c.minResolution)&&d.setMinResolution(c.minResolution),(!h(c.maxResolution,e.maxResolution)||z(d))&&g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)}),e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope();i.getMap().then(function(b){var d=e.getControlClasses,i=d();return a.$on("$destroy",function(){b.removeControl(f)}),h(a.properties)&&h(a.properties.control)?(f=a.properties.control,void b.addControl(f)):void(c.name&&(h(a.properties)&&(g=a.properties),f=new i[c.name](g),b.addControl(f)))})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return e.on("pointerdown",j),e.on("pointerup",j),e.on("pointerdrag",j),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e)}),k(c.properties)?void c.$watch("properties",function(d){if(e.getViewport().removeEventListener("mousemove",d.handleInteraction),e.getViewport().removeEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",d.handleTapInteraction),e.getViewport().removeEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",d.removeAllOverlays),d.handleInteraction=function(b){if(!d.label.show){var f=!1,g=e.getEventPixel(b),i=e.forEachFeatureAtPixel(g,function(a){return a}),j=!1;i===r&&(j=!0,f=!0,k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),!d.onClick||"click"!==b.type&&"touchend"!==b.type||c.$apply(function(){d.onClick.call(r,b,d)}),e.getTarget().style.cursor="pointer"),!f&&p&&(j=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),j&&b.preventDefault()}},d.handleTapInteraction=function(){function a(){c=!0,b&&clearTimeout(b),b=setTimeout(function(){c=!1,b=null},500)}var b,c=!1;return e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",a),function(){c||(d.handleInteraction.apply(null,arguments),a())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||d.onClick)&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){var d=c(a,b);a[d].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d,e=c(a,b);return d=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:f(a,b)};this.setMap=function(a,b){var c=f(d,b);c.resolve(a),e(d,b)},this.getMap=function(a){var b=g(d,a);return b.promise}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function x(a,b){var c;if(b?c=a[b]:(b="style",c=a),"style"===b&&a instanceof Function)return a;if(!(c instanceof Object))return c;var d;if("[object Object]"===Object.prototype.toString.call(c)){d={};var e=l[b];if(e&&c instanceof e)return c;Object.getOwnPropertyNames(c).forEach(function(a,f,g){var h=l[a];return e&&h&&h.prototype instanceof l[b]?(console.assert(1===g.length,"Extra parameters for "+b),d=x(c,a),m(d,h)):(d[a]=x(c,a),void("text"!==a&&"string"!=typeof d[a]&&(d[a]=m(d[a],l[a]))))})}else d=c;return m(d,l[b])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":case"TileVector":return"Vector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g,i=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");var l="http://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,m=window.devicePixelRatio;m>1&&(l=l.replace(".png","@2x.png")),g=new a.source.XYZ({url:l,attributions:s(b),tilePixelRatio:m>1?2:1,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,attributions:s(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:b.params,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:b.params,attributions:s(b),wrapX:void 0===b.wrapX?1:b.wrapX};b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={projection:f,layer:b.layer,attributions:s(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),wrapX:void 0===b.wrapX?1:b.wrapX};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({attributions:s(b),wrapX:void 0===b.wrapX?1:b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,attributions:s(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX?1:b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:s(b),layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="http://services.arcgisonline.com/ArcGIS/rest/services/",t=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:s(b),url:t,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var u=f;e(b.geojson.projection)&&(u=b.geojson.projection);var v=i.readFeatures(b.geojson.object,{featureProjection:u,dataProjection:u});g.addFeatures(v)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var w=f;e(b.wkt.projection)&&(w=b.wkt.projection);for(var x=new a.format.WKT,y=[],z=0;zd||0>e)return"";var f=b.url+c+"/"+d+"/"+e+".png";return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileImage":g=new a.source.TileImage({url:b.url,attributions:s(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=-a[2]-1,f=b.url.replace("{z}",c.toString()).replace("{x}",d.toString()).replace("{y}",e.toString());return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"KML":var B=b.extractStyles||!1;g=new a.source.Vector({url:b.url,format:new a.format.KML,radius:b.radius,extractStyles:B,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"Stamen":if(!b.layer||!q(b.layer))return void c.error("[AngularJS - Openlayers] - You need a valid Stamen layer.");g=new a.source.Stamen({layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageStatic":if(!b.url||!angular.isArray(b.imageSize)||2!==b.imageSize.length)return void c.error("[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.");g=new a.source.ImageStatic({url:b.url,attributions:s(b),imageSize:b.imageSize,projection:f,imageExtent:f.getExtent(),imageLoadFunction:b.imageLoadFunction,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"XYZ":b.url||b.tileUrlFunction||c.error("[AngularJS - Openlayers] - XYZ Layer needs valid url or tileUrlFunction properties"),g=new a.source.XYZ({url:b.url,attributions:s(b),minZoom:b.minZoom,maxZoom:b.maxZoom,wrapX:void 0===b.wrapX?1:b.wrapX,projection:b.projection,tileUrlFunction:b.tileUrlFunction})}return g||c.warn('[AngularJS - Openlayers] - No source could be found for type "'+b.type+'"'),g},s=function(b){var c=[];return e(b.attribution)&&c.unshift(new a.Attribution({html:b.attribution})),c},t=function(b){var c=new a.layer.Group;return c.set("name",b),c},u=function(b,c){var d;return angular.forEach(b,function(b){return b instanceof a.layer.Group&&b.get("name")===c?void(d=b):void 0}),d},v=function(a,b){for(var c,d=0;d',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id)}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}}),f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)}),e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope();i.getMap().then(function(b){var d=e.getControlClasses,i=d();return a.$on("$destroy",function(){b.removeControl(f)}),h(a.properties)&&h(a.properties.control)?(f=a.properties.control,void b.addControl(f)):void(c.name&&(h(a.properties)&&(g=a.properties),f=new i[c.name](g),b.addControl(f)))})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return e.on("pointerdown",j),e.on("pointerup",j),e.on("pointerdrag",j),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e)}),k(c.properties)?void c.$watch("properties",function(d){if(e.getViewport().removeEventListener("mousemove",d.handleInteraction),e.getViewport().removeEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",d.handleTapInteraction),e.getViewport().removeEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",d.removeAllOverlays),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){function a(){c=!0,b&&clearTimeout(b),b=setTimeout(function(){c=!1,b=null},500)}var b,c=!1;return e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",a),function(){c||(d.handleInteraction.apply(null,arguments),a())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){var d=c(a,b);a[d].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d,e=c(a,b);return d=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:f(a,b)};this.setMap=function(a,b){var c=f(d,b);c.resolve(a),e(d,b)},this.getMap=function(a){var b=g(d,a);return b.promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function y(a,b){var c;if(b?c=a[b]:(b="style",c=a),"style"===b&&a instanceof Function)return a;if(!(c instanceof Object))return c;var d;if("[object Object]"===Object.prototype.toString.call(c)){d={};var e=l[b];if(e&&c instanceof e)return c;Object.getOwnPropertyNames(c).forEach(function(a,f,g){var h=l[a];return e&&h&&h.prototype instanceof l[b]?(console.assert(1===g.length,"Extra parameters for "+b),d=y(c,a),m(d,h)):(d[a]=y(c,a),void("text"!==a&&"string"!=typeof d[a]&&(d[a]=m(d[a],l[a]))))})}else d=c;return m(d,l[b])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":return"Vector";case"TileVector":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g,i,l=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");i="http://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken;var m=window.devicePixelRatio;m>1&&(i=i.replace(".png","@2x.png")),g=new a.source.XYZ({url:i,attributions:t(b),tilePixelRatio:m>1?2:1,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");i="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,g=new a.source.XYZ({url:i,attributions:t(b),tileSize:b.tileSize||[512,512]});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,attributions:t(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,wrapX:void 0===b.wrapX?1:b.wrapX,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b),wrapX:void 0===b.wrapX?1:b.wrapX};b.projection&&(n.projection=new a.proj.get(b.projection)),b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),wrapX:void 0===b.wrapX?1:b.wrapX,style:"undefined"===b.style?"normal":b.style};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({attributions:t(b),wrapX:void 0===b.wrapX?1:b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX?1:b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="http://services.arcgisonline.com/ArcGIS/rest/services/",u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),url:u,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=l.readFeatures(b.geojson.object,{featureProjection:w,dataProjection:v});g.addFeatures(x)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var y=f;e(b.wkt.projection)&&(y=b.wkt.projection);for(var z=new a.format.WKT,A=[],B=0;Bd||0>e)return"";var f=b.url+c+"/"+d+"/"+e+".png";return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileImage":g=new a.source.TileImage({url:b.url,attributions:t(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=-a[2]-1,f=b.url.replace("{z}",c.toString()).replace("{x}",d.toString()).replace("{y}",e.toString());return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"KML":var D=b.extractStyles||!1;g=new a.source.Vector({url:b.url,format:new a.format.KML,radius:b.radius,extractStyles:D,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"Stamen":if(!b.layer||!q(b.layer))return void c.error("[AngularJS - Openlayers] - You need a valid Stamen layer.");g=new a.source.Stamen({layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageStatic":if(!b.url||!angular.isArray(b.imageSize)||2!==b.imageSize.length)return void c.error("[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.");g=new a.source.ImageStatic({url:b.url,attributions:t(b),imageSize:b.imageSize,projection:f,imageExtent:b.imageExtent?b.imageExtent:f.getExtent(),imageLoadFunction:b.imageLoadFunction,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"XYZ":b.url||b.tileUrlFunction||c.error("[AngularJS - Openlayers] - XYZ Layer needs valid url or tileUrlFunction properties"),g=new a.source.XYZ({url:b.url,attributions:t(b),minZoom:b.minZoom,maxZoom:b.maxZoom,wrapX:void 0===b.wrapX?1:b.wrapX,projection:b.projection,tileUrlFunction:b.tileUrlFunction});break;case"Zoomify":b.url&&angular.isArray(b.imageSize)&&2===b.imageSize.length||c.error("[AngularJS - Openlayers] - Zoomify Layer needs valid url and imageSize properties"),g=new a.source.Zoomify({url:b.url,size:b.imageSize})}return g||c.warn('[AngularJS - Openlayers] - No source could be found for type "'+b.type+'"'),g},s=function(a){var b=a;if(a&&"object"==typeof a){b="[object Array]"===Object.prototype.toString.call(a)?[]:{};for(var c in a)b[c]=s(a[c])}return b},t=function(b){var c=[];return e(b.attribution)&&c.unshift(new a.Attribution({html:b.attribution})),c},u=function(b){var c=new a.layer.Group;return c.set("name",b),c},v=function(b,c){var d;return angular.forEach(b,function(b){return b instanceof a.layer.Group&&b.get("name")===c?void(d=b):void 0}),d},w=function(a,b){for(var c,d=0;d Date: Tue, 19 Jul 2016 19:47:24 +0530 Subject: [PATCH 21/53] Fix the projection value - GeoJSON and WKT Data --- dist/angular-openlayers-directive.js | 13 ++++++++----- dist/angular-openlayers-directive.min.js | 2 +- dist/angular-openlayers-directive.min.no-header.js | 2 +- dist/angular-openlayers-directive.pre.js | 13 ++++++++----- src/services/olHelpers.js | 13 ++++++++----- 5 files changed, 26 insertions(+), 17 deletions(-) diff --git a/dist/angular-openlayers-directive.js b/dist/angular-openlayers-directive.js index 3b18b24c..55e214f3 100644 --- a/dist/angular-openlayers-directive.js +++ b/dist/angular-openlayers-directive.js @@ -1601,8 +1601,8 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt var features = geojsonFormat.readFeatures( source.geojson.object, { - featureProjection: projectionToUse, - dataProjection: dataProjection + featureProjection: projectionToUse.getCode(), + dataProjection: dataProjection.getCode() }); oSource.addFeatures(features); @@ -1623,17 +1623,20 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt }); } else { oSource = new ol.source.Vector(); - - var wktProjection = projection; + var featureProjection = projection; + var wktProjection; if (isDefined(source.wkt.projection)) { wktProjection = source.wkt.projection; } + else{ + wktProjection = projection; + } var wktFormat = new ol.format.WKT(); var wktFeatures = []; for(var k = 0; k< source.wkt.object.length; k++){ var feature = wktFormat.readFeature( - source.wkt.object[k].data, {dataProjection: 'EPSG:4326',featureProjection: wktProjection }); + source.wkt.object[k].data, {dataProjection: wktProjection.getCode() ,featureProjection: featureProjection.getCode() }); if(source.wkt.object[k].properties){ feature.properties = source.wkt.object[k].properties; } diff --git a/dist/angular-openlayers-directive.min.js b/dist/angular-openlayers-directive.min.js index 67fcd0ff..78394f46 100644 --- a/dist/angular-openlayers-directive.min.js +++ b/dist/angular-openlayers-directive.min.js @@ -28,5 +28,5 @@ */ /*! angular-openlayers-directive 19-07-2016 */ -!function(a,b){if("function"==typeof require&&"object"==typeof exports){var c=require("openlayers");require("angular-sanitize");exports.angularOpenlayersDirective=b(c)}else"function"==typeof define&&define.amd?define(["ol"],function(c){return a.angularOpenlayersDirective=b(c)}):a.angularOpenlayersDirective=b(a.ol)}(this,function(a){return angular.module("openlayers-directive",["ngSanitize"]).directive("openlayers",["$log","$q","$compile","olHelpers","olMapDefaults","olData",function(b,c,d,e,f,g){return{restrict:"EA",transclude:!0,replace:!0,scope:{center:"=olCenter",defaults:"=olDefaults",view:"=olView",events:"=olEvents"},template:'
',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id)}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}}),f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)}),e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope();i.getMap().then(function(b){var d=e.getControlClasses,i=d();return a.$on("$destroy",function(){b.removeControl(f)}),h(a.properties)&&h(a.properties.control)?(f=a.properties.control,void b.addControl(f)):void(c.name&&(h(a.properties)&&(g=a.properties),f=new i[c.name](g),b.addControl(f)))})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return e.on("pointerdown",j),e.on("pointerup",j),e.on("pointerdrag",j),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e)}),k(c.properties)?void c.$watch("properties",function(d){if(e.getViewport().removeEventListener("mousemove",d.handleInteraction),e.getViewport().removeEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",d.handleTapInteraction),e.getViewport().removeEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",d.removeAllOverlays),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){function a(){c=!0,b&&clearTimeout(b),b=setTimeout(function(){c=!1,b=null},500)}var b,c=!1;return e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",a),function(){c||(d.handleInteraction.apply(null,arguments),a())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){var d=c(a,b);a[d].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d,e=c(a,b);return d=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:f(a,b)};this.setMap=function(a,b){var c=f(d,b);c.resolve(a),e(d,b)},this.getMap=function(a){var b=g(d,a);return b.promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function y(a,b){var c;if(b?c=a[b]:(b="style",c=a),"style"===b&&a instanceof Function)return a;if(!(c instanceof Object))return c;var d;if("[object Object]"===Object.prototype.toString.call(c)){d={};var e=l[b];if(e&&c instanceof e)return c;Object.getOwnPropertyNames(c).forEach(function(a,f,g){var h=l[a];return e&&h&&h.prototype instanceof l[b]?(console.assert(1===g.length,"Extra parameters for "+b),d=y(c,a),m(d,h)):(d[a]=y(c,a),void("text"!==a&&"string"!=typeof d[a]&&(d[a]=m(d[a],l[a]))))})}else d=c;return m(d,l[b])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":return"Vector";case"TileVector":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g,i,l=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");i="http://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken;var m=window.devicePixelRatio;m>1&&(i=i.replace(".png","@2x.png")),g=new a.source.XYZ({url:i,attributions:t(b),tilePixelRatio:m>1?2:1,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");i="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,g=new a.source.XYZ({url:i,attributions:t(b),tileSize:b.tileSize||[512,512]});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,attributions:t(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,wrapX:void 0===b.wrapX?1:b.wrapX,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b),wrapX:void 0===b.wrapX?1:b.wrapX};b.projection&&(n.projection=new a.proj.get(b.projection)),b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),wrapX:void 0===b.wrapX?1:b.wrapX,style:"undefined"===b.style?"normal":b.style};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({attributions:t(b),wrapX:void 0===b.wrapX?1:b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX?1:b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="http://services.arcgisonline.com/ArcGIS/rest/services/",u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),url:u,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=l.readFeatures(b.geojson.object,{featureProjection:w,dataProjection:v});g.addFeatures(x)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var y=f;e(b.wkt.projection)&&(y=b.wkt.projection);for(var z=new a.format.WKT,A=[],B=0;Bd||0>e)return"";var f=b.url+c+"/"+d+"/"+e+".png";return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileImage":g=new a.source.TileImage({url:b.url,attributions:t(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=-a[2]-1,f=b.url.replace("{z}",c.toString()).replace("{x}",d.toString()).replace("{y}",e.toString());return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"KML":var D=b.extractStyles||!1;g=new a.source.Vector({url:b.url,format:new a.format.KML,radius:b.radius,extractStyles:D,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"Stamen":if(!b.layer||!q(b.layer))return void c.error("[AngularJS - Openlayers] - You need a valid Stamen layer.");g=new a.source.Stamen({layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageStatic":if(!b.url||!angular.isArray(b.imageSize)||2!==b.imageSize.length)return void c.error("[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.");g=new a.source.ImageStatic({url:b.url,attributions:t(b),imageSize:b.imageSize,projection:f,imageExtent:b.imageExtent?b.imageExtent:f.getExtent(),imageLoadFunction:b.imageLoadFunction,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"XYZ":b.url||b.tileUrlFunction||c.error("[AngularJS - Openlayers] - XYZ Layer needs valid url or tileUrlFunction properties"),g=new a.source.XYZ({url:b.url,attributions:t(b),minZoom:b.minZoom,maxZoom:b.maxZoom,wrapX:void 0===b.wrapX?1:b.wrapX,projection:b.projection,tileUrlFunction:b.tileUrlFunction});break;case"Zoomify":b.url&&angular.isArray(b.imageSize)&&2===b.imageSize.length||c.error("[AngularJS - Openlayers] - Zoomify Layer needs valid url and imageSize properties"),g=new a.source.Zoomify({url:b.url,size:b.imageSize})}return g||c.warn('[AngularJS - Openlayers] - No source could be found for type "'+b.type+'"'),g},s=function(a){var b=a;if(a&&"object"==typeof a){b="[object Array]"===Object.prototype.toString.call(a)?[]:{};for(var c in a)b[c]=s(a[c])}return b},t=function(b){var c=[];return e(b.attribution)&&c.unshift(new a.Attribution({html:b.attribution})),c},u=function(b){var c=new a.layer.Group;return c.set("name",b),c},v=function(b,c){var d;return angular.forEach(b,function(b){return b instanceof a.layer.Group&&b.get("name")===c?void(d=b):void 0}),d},w=function(a,b){for(var c,d=0;d',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id)}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}}),f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)}),e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope();i.getMap().then(function(b){var d=e.getControlClasses,i=d();return a.$on("$destroy",function(){b.removeControl(f)}),h(a.properties)&&h(a.properties.control)?(f=a.properties.control,void b.addControl(f)):void(c.name&&(h(a.properties)&&(g=a.properties),f=new i[c.name](g),b.addControl(f)))})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return e.on("pointerdown",j),e.on("pointerup",j),e.on("pointerdrag",j),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e)}),k(c.properties)?void c.$watch("properties",function(d){if(e.getViewport().removeEventListener("mousemove",d.handleInteraction),e.getViewport().removeEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",d.handleTapInteraction),e.getViewport().removeEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",d.removeAllOverlays),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){function a(){c=!0,b&&clearTimeout(b),b=setTimeout(function(){c=!1,b=null},500)}var b,c=!1;return e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",a),function(){c||(d.handleInteraction.apply(null,arguments),a())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){var d=c(a,b);a[d].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d,e=c(a,b);return d=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:f(a,b)};this.setMap=function(a,b){var c=f(d,b);c.resolve(a),e(d,b)},this.getMap=function(a){var b=g(d,a);return b.promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function y(a,b){var c;if(b?c=a[b]:(b="style",c=a),"style"===b&&a instanceof Function)return a;if(!(c instanceof Object))return c;var d;if("[object Object]"===Object.prototype.toString.call(c)){d={};var e=l[b];if(e&&c instanceof e)return c;Object.getOwnPropertyNames(c).forEach(function(a,f,g){var h=l[a];return e&&h&&h.prototype instanceof l[b]?(console.assert(1===g.length,"Extra parameters for "+b),d=y(c,a),m(d,h)):(d[a]=y(c,a),void("text"!==a&&"string"!=typeof d[a]&&(d[a]=m(d[a],l[a]))))})}else d=c;return m(d,l[b])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":return"Vector";case"TileVector":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g,i,l=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");i="http://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken;var m=window.devicePixelRatio;m>1&&(i=i.replace(".png","@2x.png")),g=new a.source.XYZ({url:i,attributions:t(b),tilePixelRatio:m>1?2:1,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");i="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,g=new a.source.XYZ({url:i,attributions:t(b),tileSize:b.tileSize||[512,512]});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,attributions:t(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,wrapX:void 0===b.wrapX?1:b.wrapX,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b),wrapX:void 0===b.wrapX?1:b.wrapX};b.projection&&(n.projection=new a.proj.get(b.projection)),b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),wrapX:void 0===b.wrapX?1:b.wrapX,style:"undefined"===b.style?"normal":b.style};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({attributions:t(b),wrapX:void 0===b.wrapX?1:b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX?1:b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="http://services.arcgisonline.com/ArcGIS/rest/services/",u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),url:u,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=l.readFeatures(b.geojson.object,{featureProjection:w.getCode(),dataProjection:v.getCode()});g.addFeatures(x)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var y,z=f;y=e(b.wkt.projection)?b.wkt.projection:f;for(var A=new a.format.WKT,B=[],C=0;Cd||0>e)return"";var f=b.url+c+"/"+d+"/"+e+".png";return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileImage":g=new a.source.TileImage({url:b.url,attributions:t(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=-a[2]-1,f=b.url.replace("{z}",c.toString()).replace("{x}",d.toString()).replace("{y}",e.toString());return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"KML":var E=b.extractStyles||!1;g=new a.source.Vector({url:b.url,format:new a.format.KML,radius:b.radius,extractStyles:E,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"Stamen":if(!b.layer||!q(b.layer))return void c.error("[AngularJS - Openlayers] - You need a valid Stamen layer.");g=new a.source.Stamen({layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageStatic":if(!b.url||!angular.isArray(b.imageSize)||2!==b.imageSize.length)return void c.error("[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.");g=new a.source.ImageStatic({url:b.url,attributions:t(b),imageSize:b.imageSize,projection:f,imageExtent:b.imageExtent?b.imageExtent:f.getExtent(),imageLoadFunction:b.imageLoadFunction,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"XYZ":b.url||b.tileUrlFunction||c.error("[AngularJS - Openlayers] - XYZ Layer needs valid url or tileUrlFunction properties"),g=new a.source.XYZ({url:b.url,attributions:t(b),minZoom:b.minZoom,maxZoom:b.maxZoom,wrapX:void 0===b.wrapX?1:b.wrapX,projection:b.projection,tileUrlFunction:b.tileUrlFunction});break;case"Zoomify":b.url&&angular.isArray(b.imageSize)&&2===b.imageSize.length||c.error("[AngularJS - Openlayers] - Zoomify Layer needs valid url and imageSize properties"),g=new a.source.Zoomify({url:b.url,size:b.imageSize})}return g||c.warn('[AngularJS - Openlayers] - No source could be found for type "'+b.type+'"'),g},s=function(a){var b=a;if(a&&"object"==typeof a){b="[object Array]"===Object.prototype.toString.call(a)?[]:{};for(var c in a)b[c]=s(a[c])}return b},t=function(b){var c=[];return e(b.attribution)&&c.unshift(new a.Attribution({html:b.attribution})),c},u=function(b){var c=new a.layer.Group;return c.set("name",b),c},v=function(b,c){var d;return angular.forEach(b,function(b){return b instanceof a.layer.Group&&b.get("name")===c?void(d=b):void 0}),d},w=function(a,b){for(var c,d=0;d',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id)}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}}),f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)}),e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope();i.getMap().then(function(b){var d=e.getControlClasses,i=d();return a.$on("$destroy",function(){b.removeControl(f)}),h(a.properties)&&h(a.properties.control)?(f=a.properties.control,void b.addControl(f)):void(c.name&&(h(a.properties)&&(g=a.properties),f=new i[c.name](g),b.addControl(f)))})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return e.on("pointerdown",j),e.on("pointerup",j),e.on("pointerdrag",j),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e)}),k(c.properties)?void c.$watch("properties",function(d){if(e.getViewport().removeEventListener("mousemove",d.handleInteraction),e.getViewport().removeEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",d.handleTapInteraction),e.getViewport().removeEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",d.removeAllOverlays),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){function a(){c=!0,b&&clearTimeout(b),b=setTimeout(function(){c=!1,b=null},500)}var b,c=!1;return e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",a),function(){c||(d.handleInteraction.apply(null,arguments),a())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){var d=c(a,b);a[d].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d,e=c(a,b);return d=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:f(a,b)};this.setMap=function(a,b){var c=f(d,b);c.resolve(a),e(d,b)},this.getMap=function(a){var b=g(d,a);return b.promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function y(a,b){var c;if(b?c=a[b]:(b="style",c=a),"style"===b&&a instanceof Function)return a;if(!(c instanceof Object))return c;var d;if("[object Object]"===Object.prototype.toString.call(c)){d={};var e=l[b];if(e&&c instanceof e)return c;Object.getOwnPropertyNames(c).forEach(function(a,f,g){var h=l[a];return e&&h&&h.prototype instanceof l[b]?(console.assert(1===g.length,"Extra parameters for "+b),d=y(c,a),m(d,h)):(d[a]=y(c,a),void("text"!==a&&"string"!=typeof d[a]&&(d[a]=m(d[a],l[a]))))})}else d=c;return m(d,l[b])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":return"Vector";case"TileVector":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g,i,l=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");i="http://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken;var m=window.devicePixelRatio;m>1&&(i=i.replace(".png","@2x.png")),g=new a.source.XYZ({url:i,attributions:t(b),tilePixelRatio:m>1?2:1,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");i="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,g=new a.source.XYZ({url:i,attributions:t(b),tileSize:b.tileSize||[512,512]});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,attributions:t(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,wrapX:void 0===b.wrapX?1:b.wrapX,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b),wrapX:void 0===b.wrapX?1:b.wrapX};b.projection&&(n.projection=new a.proj.get(b.projection)),b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),wrapX:void 0===b.wrapX?1:b.wrapX,style:"undefined"===b.style?"normal":b.style};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({attributions:t(b),wrapX:void 0===b.wrapX?1:b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX?1:b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="http://services.arcgisonline.com/ArcGIS/rest/services/",u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),url:u,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=l.readFeatures(b.geojson.object,{featureProjection:w,dataProjection:v});g.addFeatures(x)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var y=f;e(b.wkt.projection)&&(y=b.wkt.projection);for(var z=new a.format.WKT,A=[],B=0;Bd||0>e)return"";var f=b.url+c+"/"+d+"/"+e+".png";return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileImage":g=new a.source.TileImage({url:b.url,attributions:t(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=-a[2]-1,f=b.url.replace("{z}",c.toString()).replace("{x}",d.toString()).replace("{y}",e.toString());return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"KML":var D=b.extractStyles||!1;g=new a.source.Vector({url:b.url,format:new a.format.KML,radius:b.radius,extractStyles:D,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"Stamen":if(!b.layer||!q(b.layer))return void c.error("[AngularJS - Openlayers] - You need a valid Stamen layer.");g=new a.source.Stamen({layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageStatic":if(!b.url||!angular.isArray(b.imageSize)||2!==b.imageSize.length)return void c.error("[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.");g=new a.source.ImageStatic({url:b.url,attributions:t(b),imageSize:b.imageSize,projection:f,imageExtent:b.imageExtent?b.imageExtent:f.getExtent(),imageLoadFunction:b.imageLoadFunction,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"XYZ":b.url||b.tileUrlFunction||c.error("[AngularJS - Openlayers] - XYZ Layer needs valid url or tileUrlFunction properties"),g=new a.source.XYZ({url:b.url,attributions:t(b),minZoom:b.minZoom,maxZoom:b.maxZoom,wrapX:void 0===b.wrapX?1:b.wrapX,projection:b.projection,tileUrlFunction:b.tileUrlFunction});break;case"Zoomify":b.url&&angular.isArray(b.imageSize)&&2===b.imageSize.length||c.error("[AngularJS - Openlayers] - Zoomify Layer needs valid url and imageSize properties"),g=new a.source.Zoomify({url:b.url,size:b.imageSize})}return g||c.warn('[AngularJS - Openlayers] - No source could be found for type "'+b.type+'"'),g},s=function(a){var b=a;if(a&&"object"==typeof a){b="[object Array]"===Object.prototype.toString.call(a)?[]:{};for(var c in a)b[c]=s(a[c])}return b},t=function(b){var c=[];return e(b.attribution)&&c.unshift(new a.Attribution({html:b.attribution})),c},u=function(b){var c=new a.layer.Group;return c.set("name",b),c},v=function(b,c){var d;return angular.forEach(b,function(b){return b instanceof a.layer.Group&&b.get("name")===c?void(d=b):void 0}),d},w=function(a,b){for(var c,d=0;d',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id)}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}}),f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)}),e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope();i.getMap().then(function(b){var d=e.getControlClasses,i=d();return a.$on("$destroy",function(){b.removeControl(f)}),h(a.properties)&&h(a.properties.control)?(f=a.properties.control,void b.addControl(f)):void(c.name&&(h(a.properties)&&(g=a.properties),f=new i[c.name](g),b.addControl(f)))})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return e.on("pointerdown",j),e.on("pointerup",j),e.on("pointerdrag",j),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e)}),k(c.properties)?void c.$watch("properties",function(d){if(e.getViewport().removeEventListener("mousemove",d.handleInteraction),e.getViewport().removeEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",d.handleTapInteraction),e.getViewport().removeEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",d.removeAllOverlays),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){function a(){c=!0,b&&clearTimeout(b),b=setTimeout(function(){c=!1,b=null},500)}var b,c=!1;return e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",a),function(){c||(d.handleInteraction.apply(null,arguments),a())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){var d=c(a,b);a[d].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d,e=c(a,b);return d=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:f(a,b)};this.setMap=function(a,b){var c=f(d,b);c.resolve(a),e(d,b)},this.getMap=function(a){var b=g(d,a);return b.promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function y(a,b){var c;if(b?c=a[b]:(b="style",c=a),"style"===b&&a instanceof Function)return a;if(!(c instanceof Object))return c;var d;if("[object Object]"===Object.prototype.toString.call(c)){d={};var e=l[b];if(e&&c instanceof e)return c;Object.getOwnPropertyNames(c).forEach(function(a,f,g){var h=l[a];return e&&h&&h.prototype instanceof l[b]?(console.assert(1===g.length,"Extra parameters for "+b),d=y(c,a),m(d,h)):(d[a]=y(c,a),void("text"!==a&&"string"!=typeof d[a]&&(d[a]=m(d[a],l[a]))))})}else d=c;return m(d,l[b])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":return"Vector";case"TileVector":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g,i,l=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");i="http://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken;var m=window.devicePixelRatio;m>1&&(i=i.replace(".png","@2x.png")),g=new a.source.XYZ({url:i,attributions:t(b),tilePixelRatio:m>1?2:1,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");i="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,g=new a.source.XYZ({url:i,attributions:t(b),tileSize:b.tileSize||[512,512]});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,attributions:t(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,wrapX:void 0===b.wrapX?1:b.wrapX,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b),wrapX:void 0===b.wrapX?1:b.wrapX};b.projection&&(n.projection=new a.proj.get(b.projection)),b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),wrapX:void 0===b.wrapX?1:b.wrapX,style:"undefined"===b.style?"normal":b.style};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({attributions:t(b),wrapX:void 0===b.wrapX?1:b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX?1:b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="http://services.arcgisonline.com/ArcGIS/rest/services/",u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),url:u,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=l.readFeatures(b.geojson.object,{featureProjection:w.getCode(),dataProjection:v.getCode()});g.addFeatures(x)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var y,z=f;y=e(b.wkt.projection)?b.wkt.projection:f;for(var A=new a.format.WKT,B=[],C=0;Cd||0>e)return"";var f=b.url+c+"/"+d+"/"+e+".png";return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileImage":g=new a.source.TileImage({url:b.url,attributions:t(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=-a[2]-1,f=b.url.replace("{z}",c.toString()).replace("{x}",d.toString()).replace("{y}",e.toString());return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"KML":var E=b.extractStyles||!1;g=new a.source.Vector({url:b.url,format:new a.format.KML,radius:b.radius,extractStyles:E,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"Stamen":if(!b.layer||!q(b.layer))return void c.error("[AngularJS - Openlayers] - You need a valid Stamen layer.");g=new a.source.Stamen({layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageStatic":if(!b.url||!angular.isArray(b.imageSize)||2!==b.imageSize.length)return void c.error("[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.");g=new a.source.ImageStatic({url:b.url,attributions:t(b),imageSize:b.imageSize,projection:f,imageExtent:b.imageExtent?b.imageExtent:f.getExtent(),imageLoadFunction:b.imageLoadFunction,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"XYZ":b.url||b.tileUrlFunction||c.error("[AngularJS - Openlayers] - XYZ Layer needs valid url or tileUrlFunction properties"),g=new a.source.XYZ({url:b.url,attributions:t(b),minZoom:b.minZoom,maxZoom:b.maxZoom,wrapX:void 0===b.wrapX?1:b.wrapX,projection:b.projection,tileUrlFunction:b.tileUrlFunction});break;case"Zoomify":b.url&&angular.isArray(b.imageSize)&&2===b.imageSize.length||c.error("[AngularJS - Openlayers] - Zoomify Layer needs valid url and imageSize properties"),g=new a.source.Zoomify({url:b.url,size:b.imageSize})}return g||c.warn('[AngularJS - Openlayers] - No source could be found for type "'+b.type+'"'),g},s=function(a){var b=a;if(a&&"object"==typeof a){b="[object Array]"===Object.prototype.toString.call(a)?[]:{};for(var c in a)b[c]=s(a[c])}return b},t=function(b){var c=[];return e(b.attribution)&&c.unshift(new a.Attribution({html:b.attribution})),c},u=function(b){var c=new a.layer.Group;return c.set("name",b),c},v=function(b,c){var d;return angular.forEach(b,function(b){return b instanceof a.layer.Group&&b.get("name")===c?void(d=b):void 0}),d},w=function(a,b){for(var c,d=0;d Date: Tue, 19 Jul 2016 20:01:07 +0530 Subject: [PATCH 22/53] Fix the WKT projection --- dist/angular-openlayers-directive.js | 2 +- dist/angular-openlayers-directive.min.js | 2 +- dist/angular-openlayers-directive.min.no-header.js | 2 +- dist/angular-openlayers-directive.pre.js | 2 +- src/services/olHelpers.js | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/dist/angular-openlayers-directive.js b/dist/angular-openlayers-directive.js index 55e214f3..1c1a9e0c 100644 --- a/dist/angular-openlayers-directive.js +++ b/dist/angular-openlayers-directive.js @@ -1626,7 +1626,7 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt var featureProjection = projection; var wktProjection; if (isDefined(source.wkt.projection)) { - wktProjection = source.wkt.projection; + wktProjection = new ol.proj.get(source.wkt.projection); } else{ wktProjection = projection; diff --git a/dist/angular-openlayers-directive.min.js b/dist/angular-openlayers-directive.min.js index 78394f46..597fe6e4 100644 --- a/dist/angular-openlayers-directive.min.js +++ b/dist/angular-openlayers-directive.min.js @@ -28,5 +28,5 @@ */ /*! angular-openlayers-directive 19-07-2016 */ -!function(a,b){if("function"==typeof require&&"object"==typeof exports){var c=require("openlayers");require("angular-sanitize");exports.angularOpenlayersDirective=b(c)}else"function"==typeof define&&define.amd?define(["ol"],function(c){return a.angularOpenlayersDirective=b(c)}):a.angularOpenlayersDirective=b(a.ol)}(this,function(a){return angular.module("openlayers-directive",["ngSanitize"]).directive("openlayers",["$log","$q","$compile","olHelpers","olMapDefaults","olData",function(b,c,d,e,f,g){return{restrict:"EA",transclude:!0,replace:!0,scope:{center:"=olCenter",defaults:"=olDefaults",view:"=olView",events:"=olEvents"},template:'
',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id)}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}}),f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)}),e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope();i.getMap().then(function(b){var d=e.getControlClasses,i=d();return a.$on("$destroy",function(){b.removeControl(f)}),h(a.properties)&&h(a.properties.control)?(f=a.properties.control,void b.addControl(f)):void(c.name&&(h(a.properties)&&(g=a.properties),f=new i[c.name](g),b.addControl(f)))})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return e.on("pointerdown",j),e.on("pointerup",j),e.on("pointerdrag",j),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e)}),k(c.properties)?void c.$watch("properties",function(d){if(e.getViewport().removeEventListener("mousemove",d.handleInteraction),e.getViewport().removeEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",d.handleTapInteraction),e.getViewport().removeEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",d.removeAllOverlays),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){function a(){c=!0,b&&clearTimeout(b),b=setTimeout(function(){c=!1,b=null},500)}var b,c=!1;return e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",a),function(){c||(d.handleInteraction.apply(null,arguments),a())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){var d=c(a,b);a[d].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d,e=c(a,b);return d=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:f(a,b)};this.setMap=function(a,b){var c=f(d,b);c.resolve(a),e(d,b)},this.getMap=function(a){var b=g(d,a);return b.promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function y(a,b){var c;if(b?c=a[b]:(b="style",c=a),"style"===b&&a instanceof Function)return a;if(!(c instanceof Object))return c;var d;if("[object Object]"===Object.prototype.toString.call(c)){d={};var e=l[b];if(e&&c instanceof e)return c;Object.getOwnPropertyNames(c).forEach(function(a,f,g){var h=l[a];return e&&h&&h.prototype instanceof l[b]?(console.assert(1===g.length,"Extra parameters for "+b),d=y(c,a),m(d,h)):(d[a]=y(c,a),void("text"!==a&&"string"!=typeof d[a]&&(d[a]=m(d[a],l[a]))))})}else d=c;return m(d,l[b])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":return"Vector";case"TileVector":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g,i,l=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");i="http://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken;var m=window.devicePixelRatio;m>1&&(i=i.replace(".png","@2x.png")),g=new a.source.XYZ({url:i,attributions:t(b),tilePixelRatio:m>1?2:1,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");i="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,g=new a.source.XYZ({url:i,attributions:t(b),tileSize:b.tileSize||[512,512]});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,attributions:t(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,wrapX:void 0===b.wrapX?1:b.wrapX,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b),wrapX:void 0===b.wrapX?1:b.wrapX};b.projection&&(n.projection=new a.proj.get(b.projection)),b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),wrapX:void 0===b.wrapX?1:b.wrapX,style:"undefined"===b.style?"normal":b.style};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({attributions:t(b),wrapX:void 0===b.wrapX?1:b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX?1:b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="http://services.arcgisonline.com/ArcGIS/rest/services/",u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),url:u,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=l.readFeatures(b.geojson.object,{featureProjection:w.getCode(),dataProjection:v.getCode()});g.addFeatures(x)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var y,z=f;y=e(b.wkt.projection)?b.wkt.projection:f;for(var A=new a.format.WKT,B=[],C=0;Cd||0>e)return"";var f=b.url+c+"/"+d+"/"+e+".png";return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileImage":g=new a.source.TileImage({url:b.url,attributions:t(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=-a[2]-1,f=b.url.replace("{z}",c.toString()).replace("{x}",d.toString()).replace("{y}",e.toString());return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"KML":var E=b.extractStyles||!1;g=new a.source.Vector({url:b.url,format:new a.format.KML,radius:b.radius,extractStyles:E,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"Stamen":if(!b.layer||!q(b.layer))return void c.error("[AngularJS - Openlayers] - You need a valid Stamen layer.");g=new a.source.Stamen({layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageStatic":if(!b.url||!angular.isArray(b.imageSize)||2!==b.imageSize.length)return void c.error("[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.");g=new a.source.ImageStatic({url:b.url,attributions:t(b),imageSize:b.imageSize,projection:f,imageExtent:b.imageExtent?b.imageExtent:f.getExtent(),imageLoadFunction:b.imageLoadFunction,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"XYZ":b.url||b.tileUrlFunction||c.error("[AngularJS - Openlayers] - XYZ Layer needs valid url or tileUrlFunction properties"),g=new a.source.XYZ({url:b.url,attributions:t(b),minZoom:b.minZoom,maxZoom:b.maxZoom,wrapX:void 0===b.wrapX?1:b.wrapX,projection:b.projection,tileUrlFunction:b.tileUrlFunction});break;case"Zoomify":b.url&&angular.isArray(b.imageSize)&&2===b.imageSize.length||c.error("[AngularJS - Openlayers] - Zoomify Layer needs valid url and imageSize properties"),g=new a.source.Zoomify({url:b.url,size:b.imageSize})}return g||c.warn('[AngularJS - Openlayers] - No source could be found for type "'+b.type+'"'),g},s=function(a){var b=a;if(a&&"object"==typeof a){b="[object Array]"===Object.prototype.toString.call(a)?[]:{};for(var c in a)b[c]=s(a[c])}return b},t=function(b){var c=[];return e(b.attribution)&&c.unshift(new a.Attribution({html:b.attribution})),c},u=function(b){var c=new a.layer.Group;return c.set("name",b),c},v=function(b,c){var d;return angular.forEach(b,function(b){return b instanceof a.layer.Group&&b.get("name")===c?void(d=b):void 0}),d},w=function(a,b){for(var c,d=0;d',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id)}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}}),f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)}),e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope();i.getMap().then(function(b){var d=e.getControlClasses,i=d();return a.$on("$destroy",function(){b.removeControl(f)}),h(a.properties)&&h(a.properties.control)?(f=a.properties.control,void b.addControl(f)):void(c.name&&(h(a.properties)&&(g=a.properties),f=new i[c.name](g),b.addControl(f)))})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return e.on("pointerdown",j),e.on("pointerup",j),e.on("pointerdrag",j),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e)}),k(c.properties)?void c.$watch("properties",function(d){if(e.getViewport().removeEventListener("mousemove",d.handleInteraction),e.getViewport().removeEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",d.handleTapInteraction),e.getViewport().removeEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",d.removeAllOverlays),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){function a(){c=!0,b&&clearTimeout(b),b=setTimeout(function(){c=!1,b=null},500)}var b,c=!1;return e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",a),function(){c||(d.handleInteraction.apply(null,arguments),a())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){var d=c(a,b);a[d].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d,e=c(a,b);return d=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:f(a,b)};this.setMap=function(a,b){var c=f(d,b);c.resolve(a),e(d,b)},this.getMap=function(a){var b=g(d,a);return b.promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function y(a,b){var c;if(b?c=a[b]:(b="style",c=a),"style"===b&&a instanceof Function)return a;if(!(c instanceof Object))return c;var d;if("[object Object]"===Object.prototype.toString.call(c)){d={};var e=l[b];if(e&&c instanceof e)return c;Object.getOwnPropertyNames(c).forEach(function(a,f,g){var h=l[a];return e&&h&&h.prototype instanceof l[b]?(console.assert(1===g.length,"Extra parameters for "+b),d=y(c,a),m(d,h)):(d[a]=y(c,a),void("text"!==a&&"string"!=typeof d[a]&&(d[a]=m(d[a],l[a]))))})}else d=c;return m(d,l[b])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":return"Vector";case"TileVector":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g,i,l=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");i="http://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken;var m=window.devicePixelRatio;m>1&&(i=i.replace(".png","@2x.png")),g=new a.source.XYZ({url:i,attributions:t(b),tilePixelRatio:m>1?2:1,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");i="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,g=new a.source.XYZ({url:i,attributions:t(b),tileSize:b.tileSize||[512,512]});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,attributions:t(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,wrapX:void 0===b.wrapX?1:b.wrapX,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b),wrapX:void 0===b.wrapX?1:b.wrapX};b.projection&&(n.projection=new a.proj.get(b.projection)),b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),wrapX:void 0===b.wrapX?1:b.wrapX,style:"undefined"===b.style?"normal":b.style};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({attributions:t(b),wrapX:void 0===b.wrapX?1:b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX?1:b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="http://services.arcgisonline.com/ArcGIS/rest/services/",u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),url:u,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=l.readFeatures(b.geojson.object,{featureProjection:w.getCode(),dataProjection:v.getCode()});g.addFeatures(x)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var y,z=f;y=e(b.wkt.projection)?new a.proj.get(b.wkt.projection):f;for(var A=new a.format.WKT,B=[],C=0;Cd||0>e)return"";var f=b.url+c+"/"+d+"/"+e+".png";return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileImage":g=new a.source.TileImage({url:b.url,attributions:t(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=-a[2]-1,f=b.url.replace("{z}",c.toString()).replace("{x}",d.toString()).replace("{y}",e.toString());return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"KML":var E=b.extractStyles||!1;g=new a.source.Vector({url:b.url,format:new a.format.KML,radius:b.radius,extractStyles:E,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"Stamen":if(!b.layer||!q(b.layer))return void c.error("[AngularJS - Openlayers] - You need a valid Stamen layer.");g=new a.source.Stamen({layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageStatic":if(!b.url||!angular.isArray(b.imageSize)||2!==b.imageSize.length)return void c.error("[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.");g=new a.source.ImageStatic({url:b.url,attributions:t(b),imageSize:b.imageSize,projection:f,imageExtent:b.imageExtent?b.imageExtent:f.getExtent(),imageLoadFunction:b.imageLoadFunction,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"XYZ":b.url||b.tileUrlFunction||c.error("[AngularJS - Openlayers] - XYZ Layer needs valid url or tileUrlFunction properties"),g=new a.source.XYZ({url:b.url,attributions:t(b),minZoom:b.minZoom,maxZoom:b.maxZoom,wrapX:void 0===b.wrapX?1:b.wrapX,projection:b.projection,tileUrlFunction:b.tileUrlFunction});break;case"Zoomify":b.url&&angular.isArray(b.imageSize)&&2===b.imageSize.length||c.error("[AngularJS - Openlayers] - Zoomify Layer needs valid url and imageSize properties"),g=new a.source.Zoomify({url:b.url,size:b.imageSize})}return g||c.warn('[AngularJS - Openlayers] - No source could be found for type "'+b.type+'"'),g},s=function(a){var b=a;if(a&&"object"==typeof a){b="[object Array]"===Object.prototype.toString.call(a)?[]:{};for(var c in a)b[c]=s(a[c])}return b},t=function(b){var c=[];return e(b.attribution)&&c.unshift(new a.Attribution({html:b.attribution})),c},u=function(b){var c=new a.layer.Group;return c.set("name",b),c},v=function(b,c){var d;return angular.forEach(b,function(b){return b instanceof a.layer.Group&&b.get("name")===c?void(d=b):void 0}),d},w=function(a,b){for(var c,d=0;d',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id)}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}}),f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)}),e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope();i.getMap().then(function(b){var d=e.getControlClasses,i=d();return a.$on("$destroy",function(){b.removeControl(f)}),h(a.properties)&&h(a.properties.control)?(f=a.properties.control,void b.addControl(f)):void(c.name&&(h(a.properties)&&(g=a.properties),f=new i[c.name](g),b.addControl(f)))})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return e.on("pointerdown",j),e.on("pointerup",j),e.on("pointerdrag",j),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e)}),k(c.properties)?void c.$watch("properties",function(d){if(e.getViewport().removeEventListener("mousemove",d.handleInteraction),e.getViewport().removeEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",d.handleTapInteraction),e.getViewport().removeEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",d.removeAllOverlays),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){function a(){c=!0,b&&clearTimeout(b),b=setTimeout(function(){c=!1,b=null},500)}var b,c=!1;return e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",a),function(){c||(d.handleInteraction.apply(null,arguments),a())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){var d=c(a,b);a[d].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d,e=c(a,b);return d=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:f(a,b)};this.setMap=function(a,b){var c=f(d,b);c.resolve(a),e(d,b)},this.getMap=function(a){var b=g(d,a);return b.promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function y(a,b){var c;if(b?c=a[b]:(b="style",c=a),"style"===b&&a instanceof Function)return a;if(!(c instanceof Object))return c;var d;if("[object Object]"===Object.prototype.toString.call(c)){d={};var e=l[b];if(e&&c instanceof e)return c;Object.getOwnPropertyNames(c).forEach(function(a,f,g){var h=l[a];return e&&h&&h.prototype instanceof l[b]?(console.assert(1===g.length,"Extra parameters for "+b),d=y(c,a),m(d,h)):(d[a]=y(c,a),void("text"!==a&&"string"!=typeof d[a]&&(d[a]=m(d[a],l[a]))))})}else d=c;return m(d,l[b])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":return"Vector";case"TileVector":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g,i,l=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");i="http://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken;var m=window.devicePixelRatio;m>1&&(i=i.replace(".png","@2x.png")),g=new a.source.XYZ({url:i,attributions:t(b),tilePixelRatio:m>1?2:1,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");i="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,g=new a.source.XYZ({url:i,attributions:t(b),tileSize:b.tileSize||[512,512]});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,attributions:t(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,wrapX:void 0===b.wrapX?1:b.wrapX,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b),wrapX:void 0===b.wrapX?1:b.wrapX};b.projection&&(n.projection=new a.proj.get(b.projection)),b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),wrapX:void 0===b.wrapX?1:b.wrapX,style:"undefined"===b.style?"normal":b.style};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({attributions:t(b),wrapX:void 0===b.wrapX?1:b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX?1:b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="http://services.arcgisonline.com/ArcGIS/rest/services/",u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),url:u,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=l.readFeatures(b.geojson.object,{featureProjection:w.getCode(),dataProjection:v.getCode()});g.addFeatures(x)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var y,z=f;y=e(b.wkt.projection)?b.wkt.projection:f;for(var A=new a.format.WKT,B=[],C=0;Cd||0>e)return"";var f=b.url+c+"/"+d+"/"+e+".png";return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileImage":g=new a.source.TileImage({url:b.url,attributions:t(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=-a[2]-1,f=b.url.replace("{z}",c.toString()).replace("{x}",d.toString()).replace("{y}",e.toString());return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"KML":var E=b.extractStyles||!1;g=new a.source.Vector({url:b.url,format:new a.format.KML,radius:b.radius,extractStyles:E,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"Stamen":if(!b.layer||!q(b.layer))return void c.error("[AngularJS - Openlayers] - You need a valid Stamen layer.");g=new a.source.Stamen({layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageStatic":if(!b.url||!angular.isArray(b.imageSize)||2!==b.imageSize.length)return void c.error("[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.");g=new a.source.ImageStatic({url:b.url,attributions:t(b),imageSize:b.imageSize,projection:f,imageExtent:b.imageExtent?b.imageExtent:f.getExtent(),imageLoadFunction:b.imageLoadFunction,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"XYZ":b.url||b.tileUrlFunction||c.error("[AngularJS - Openlayers] - XYZ Layer needs valid url or tileUrlFunction properties"),g=new a.source.XYZ({url:b.url,attributions:t(b),minZoom:b.minZoom,maxZoom:b.maxZoom,wrapX:void 0===b.wrapX?1:b.wrapX,projection:b.projection,tileUrlFunction:b.tileUrlFunction});break;case"Zoomify":b.url&&angular.isArray(b.imageSize)&&2===b.imageSize.length||c.error("[AngularJS - Openlayers] - Zoomify Layer needs valid url and imageSize properties"),g=new a.source.Zoomify({url:b.url,size:b.imageSize})}return g||c.warn('[AngularJS - Openlayers] - No source could be found for type "'+b.type+'"'),g},s=function(a){var b=a;if(a&&"object"==typeof a){b="[object Array]"===Object.prototype.toString.call(a)?[]:{};for(var c in a)b[c]=s(a[c])}return b},t=function(b){var c=[];return e(b.attribution)&&c.unshift(new a.Attribution({html:b.attribution})),c},u=function(b){var c=new a.layer.Group;return c.set("name",b),c},v=function(b,c){var d;return angular.forEach(b,function(b){return b instanceof a.layer.Group&&b.get("name")===c?void(d=b):void 0}),d},w=function(a,b){for(var c,d=0;d',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id)}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}}),f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)}),e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope();i.getMap().then(function(b){var d=e.getControlClasses,i=d();return a.$on("$destroy",function(){b.removeControl(f)}),h(a.properties)&&h(a.properties.control)?(f=a.properties.control,void b.addControl(f)):void(c.name&&(h(a.properties)&&(g=a.properties),f=new i[c.name](g),b.addControl(f)))})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return e.on("pointerdown",j),e.on("pointerup",j),e.on("pointerdrag",j),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e)}),k(c.properties)?void c.$watch("properties",function(d){if(e.getViewport().removeEventListener("mousemove",d.handleInteraction),e.getViewport().removeEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",d.handleTapInteraction),e.getViewport().removeEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",d.removeAllOverlays),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){function a(){c=!0,b&&clearTimeout(b),b=setTimeout(function(){c=!1,b=null},500)}var b,c=!1;return e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",a),function(){c||(d.handleInteraction.apply(null,arguments),a())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){var d=c(a,b);a[d].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d,e=c(a,b);return d=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:f(a,b)};this.setMap=function(a,b){var c=f(d,b);c.resolve(a),e(d,b)},this.getMap=function(a){var b=g(d,a);return b.promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function y(a,b){var c;if(b?c=a[b]:(b="style",c=a),"style"===b&&a instanceof Function)return a;if(!(c instanceof Object))return c;var d;if("[object Object]"===Object.prototype.toString.call(c)){d={};var e=l[b];if(e&&c instanceof e)return c;Object.getOwnPropertyNames(c).forEach(function(a,f,g){var h=l[a];return e&&h&&h.prototype instanceof l[b]?(console.assert(1===g.length,"Extra parameters for "+b),d=y(c,a),m(d,h)):(d[a]=y(c,a),void("text"!==a&&"string"!=typeof d[a]&&(d[a]=m(d[a],l[a]))))})}else d=c;return m(d,l[b])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":return"Vector";case"TileVector":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g,i,l=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");i="http://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken;var m=window.devicePixelRatio;m>1&&(i=i.replace(".png","@2x.png")),g=new a.source.XYZ({url:i,attributions:t(b),tilePixelRatio:m>1?2:1,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");i="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,g=new a.source.XYZ({url:i,attributions:t(b),tileSize:b.tileSize||[512,512]});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,attributions:t(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,wrapX:void 0===b.wrapX?1:b.wrapX,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b),wrapX:void 0===b.wrapX?1:b.wrapX};b.projection&&(n.projection=new a.proj.get(b.projection)),b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),wrapX:void 0===b.wrapX?1:b.wrapX,style:"undefined"===b.style?"normal":b.style};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({attributions:t(b),wrapX:void 0===b.wrapX?1:b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX?1:b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="http://services.arcgisonline.com/ArcGIS/rest/services/",u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),url:u,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=l.readFeatures(b.geojson.object,{featureProjection:w.getCode(),dataProjection:v.getCode()});g.addFeatures(x)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var y,z=f;y=e(b.wkt.projection)?new a.proj.get(b.wkt.projection):f;for(var A=new a.format.WKT,B=[],C=0;Cd||0>e)return"";var f=b.url+c+"/"+d+"/"+e+".png";return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileImage":g=new a.source.TileImage({url:b.url,attributions:t(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=-a[2]-1,f=b.url.replace("{z}",c.toString()).replace("{x}",d.toString()).replace("{y}",e.toString());return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"KML":var E=b.extractStyles||!1;g=new a.source.Vector({url:b.url,format:new a.format.KML,radius:b.radius,extractStyles:E,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"Stamen":if(!b.layer||!q(b.layer))return void c.error("[AngularJS - Openlayers] - You need a valid Stamen layer.");g=new a.source.Stamen({layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageStatic":if(!b.url||!angular.isArray(b.imageSize)||2!==b.imageSize.length)return void c.error("[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.");g=new a.source.ImageStatic({url:b.url,attributions:t(b),imageSize:b.imageSize,projection:f,imageExtent:b.imageExtent?b.imageExtent:f.getExtent(),imageLoadFunction:b.imageLoadFunction,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"XYZ":b.url||b.tileUrlFunction||c.error("[AngularJS - Openlayers] - XYZ Layer needs valid url or tileUrlFunction properties"),g=new a.source.XYZ({url:b.url,attributions:t(b),minZoom:b.minZoom,maxZoom:b.maxZoom,wrapX:void 0===b.wrapX?1:b.wrapX,projection:b.projection,tileUrlFunction:b.tileUrlFunction});break;case"Zoomify":b.url&&angular.isArray(b.imageSize)&&2===b.imageSize.length||c.error("[AngularJS - Openlayers] - Zoomify Layer needs valid url and imageSize properties"),g=new a.source.Zoomify({url:b.url,size:b.imageSize})}return g||c.warn('[AngularJS - Openlayers] - No source could be found for type "'+b.type+'"'),g},s=function(a){var b=a;if(a&&"object"==typeof a){b="[object Array]"===Object.prototype.toString.call(a)?[]:{};for(var c in a)b[c]=s(a[c])}return b},t=function(b){var c=[];return e(b.attribution)&&c.unshift(new a.Attribution({html:b.attribution})),c},u=function(b){var c=new a.layer.Group;return c.set("name",b),c},v=function(b,c){var d;return angular.forEach(b,function(b){return b instanceof a.layer.Group&&b.get("name")===c?void(d=b):void 0}),d},w=function(a,b){for(var c,d=0;d Date: Thu, 21 Jul 2016 16:38:39 +0530 Subject: [PATCH 23/53] fix(olHelpers.js, layersSpec.js): passing projection code instead of projection object, while converting the geojson data to vector feature --- src/services/olHelpers.js | 4 ++-- test/unit/layersSpec.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/services/olHelpers.js b/src/services/olHelpers.js index ba05e273..5b5549aa 100644 --- a/src/services/olHelpers.js +++ b/src/services/olHelpers.js @@ -392,8 +392,8 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ var features = geojsonFormat.readFeatures( source.geojson.object, { - featureProjection: projectionToUse, - dataProjection: dataProjection + featureProjection: projectionToUse.getCode(), + dataProjection: dataProjection.getCode() }); oSource.addFeatures(features); diff --git a/test/unit/layersSpec.js b/test/unit/layersSpec.js index 5719cf83..5b3a1d9d 100755 --- a/test/unit/layersSpec.js +++ b/test/unit/layersSpec.js @@ -97,10 +97,10 @@ describe('Directive: openlayers layers', function() { type: 'Feature', geometry: { type: 'Point', - coordinates: [434179, 122450] // Southampton (UK) in EPSG:27700 + coordinates: [50.909698, -1.404351] // Southampton (UK) in EPSG:4326 } }, - projection: 'EPSG:27700' + projection: 'EPSG:4326' } } }; From b35f8f2096edeecd7dfa53bdca1737161aedef23 Mon Sep 17 00:00:00 2001 From: Sathish Kesavaperumal Date: Fri, 22 Jul 2016 12:39:38 +0530 Subject: [PATCH 24/53] fix(view.js, center.js) : unregistering map events on scope destroy for better memory leak management --- src/directives/center.js | 7 +++++-- src/directives/view.js | 6 +++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/directives/center.js b/src/directives/center.js index 9ee2f753..fc8d6c7b 100644 --- a/src/directives/center.js +++ b/src/directives/center.js @@ -144,7 +144,7 @@ angular.module('openlayers-directive').directive('olCenter', function($log, $loc } }); - map.on('moveend', function() { + var moveEndEventKey = map.on('moveend', function() { safeApply(olScope, function(scope) { if (!isDefined(scope.center)) { @@ -177,7 +177,10 @@ angular.module('openlayers-directive').directive('olCenter', function($log, $loc } }); }); - + + olScope.$on('$destroy', function(){ + map.unByKey(moveEndEventKey); + }); }); } }; diff --git a/src/directives/view.js b/src/directives/view.js index 006d3e4c..b6f21c59 100644 --- a/src/directives/view.js +++ b/src/directives/view.js @@ -39,11 +39,15 @@ angular.module('openlayers-directive').directive('olView', function($log, $q, ol } }); - mapView.on('change:rotation', function() { + var rotationEventKey = mapView.on('change:rotation', function() { safeApply(olScope, function(scope) { scope.view.rotation = map.getView().getRotation(); }); }); + + olScope.$on('$destroy', function(){ + map.unByKey(rotationEventKey); + }); }); } From b2676fc9b62898b65c0cc73ce7d5d2b57cfc66f2 Mon Sep 17 00:00:00 2001 From: Sathish Kesavaperumal Date: Fri, 22 Jul 2016 12:42:44 +0530 Subject: [PATCH 25/53] memory leak compiled version --- dist/angular-openlayers-directive.js | 13 ++++++++++--- dist/angular-openlayers-directive.min.js | 4 ++-- dist/angular-openlayers-directive.min.no-header.js | 4 ++-- dist/angular-openlayers-directive.pre.js | 13 ++++++++++--- test/unit/layersSpec.js | 4 ++-- 5 files changed, 26 insertions(+), 12 deletions(-) diff --git a/dist/angular-openlayers-directive.js b/dist/angular-openlayers-directive.js index 1c1a9e0c..fda100d4 100644 --- a/dist/angular-openlayers-directive.js +++ b/dist/angular-openlayers-directive.js @@ -280,7 +280,7 @@ angular.module('openlayers-directive').directive('olCenter', ["$log", "$location } }); - map.on('moveend', function() { + var moveEndEventKey = map.on('moveend', function() { safeApply(olScope, function(scope) { if (!isDefined(scope.center)) { @@ -313,7 +313,10 @@ angular.module('openlayers-directive').directive('olCenter', ["$log", "$location } }); }); - + + olScope.$on('$destroy', function(){ + map.unByKey(moveEndEventKey); + }); }); } }; @@ -646,11 +649,15 @@ angular.module('openlayers-directive').directive('olView', ["$log", "$q", "olDat } }); - mapView.on('change:rotation', function() { + var rotationEventKey = mapView.on('change:rotation', function() { safeApply(olScope, function(scope) { scope.view.rotation = map.getView().getRotation(); }); }); + + olScope.$on('$destroy', function(){ + map.unByKey(rotationEventKey); + }); }); } diff --git a/dist/angular-openlayers-directive.min.js b/dist/angular-openlayers-directive.min.js index 597fe6e4..c9e4154c 100644 --- a/dist/angular-openlayers-directive.min.js +++ b/dist/angular-openlayers-directive.min.js @@ -27,6 +27,6 @@ * @authors https://github.com/tombatossals/angular-openlayers-directive/graphs/contributors */ -/*! angular-openlayers-directive 19-07-2016 */ -!function(a,b){if("function"==typeof require&&"object"==typeof exports){var c=require("openlayers");require("angular-sanitize");exports.angularOpenlayersDirective=b(c)}else"function"==typeof define&&define.amd?define(["ol"],function(c){return a.angularOpenlayersDirective=b(c)}):a.angularOpenlayersDirective=b(a.ol)}(this,function(a){return angular.module("openlayers-directive",["ngSanitize"]).directive("openlayers",["$log","$q","$compile","olHelpers","olMapDefaults","olData",function(b,c,d,e,f,g){return{restrict:"EA",transclude:!0,replace:!0,scope:{center:"=olCenter",defaults:"=olDefaults",view:"=olView",events:"=olEvents"},template:'
',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id)}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}}),f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)}),e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope();i.getMap().then(function(b){var d=e.getControlClasses,i=d();return a.$on("$destroy",function(){b.removeControl(f)}),h(a.properties)&&h(a.properties.control)?(f=a.properties.control,void b.addControl(f)):void(c.name&&(h(a.properties)&&(g=a.properties),f=new i[c.name](g),b.addControl(f)))})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return e.on("pointerdown",j),e.on("pointerup",j),e.on("pointerdrag",j),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e)}),k(c.properties)?void c.$watch("properties",function(d){if(e.getViewport().removeEventListener("mousemove",d.handleInteraction),e.getViewport().removeEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",d.handleTapInteraction),e.getViewport().removeEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",d.removeAllOverlays),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){function a(){c=!0,b&&clearTimeout(b),b=setTimeout(function(){c=!1,b=null},500)}var b,c=!1;return e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",a),function(){c||(d.handleInteraction.apply(null,arguments),a())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){var d=c(a,b);a[d].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d,e=c(a,b);return d=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:f(a,b)};this.setMap=function(a,b){var c=f(d,b);c.resolve(a),e(d,b)},this.getMap=function(a){var b=g(d,a);return b.promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function y(a,b){var c;if(b?c=a[b]:(b="style",c=a),"style"===b&&a instanceof Function)return a;if(!(c instanceof Object))return c;var d;if("[object Object]"===Object.prototype.toString.call(c)){d={};var e=l[b];if(e&&c instanceof e)return c;Object.getOwnPropertyNames(c).forEach(function(a,f,g){var h=l[a];return e&&h&&h.prototype instanceof l[b]?(console.assert(1===g.length,"Extra parameters for "+b),d=y(c,a),m(d,h)):(d[a]=y(c,a),void("text"!==a&&"string"!=typeof d[a]&&(d[a]=m(d[a],l[a]))))})}else d=c;return m(d,l[b])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":return"Vector";case"TileVector":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g,i,l=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");i="http://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken;var m=window.devicePixelRatio;m>1&&(i=i.replace(".png","@2x.png")),g=new a.source.XYZ({url:i,attributions:t(b),tilePixelRatio:m>1?2:1,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");i="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,g=new a.source.XYZ({url:i,attributions:t(b),tileSize:b.tileSize||[512,512]});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,attributions:t(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,wrapX:void 0===b.wrapX?1:b.wrapX,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b),wrapX:void 0===b.wrapX?1:b.wrapX};b.projection&&(n.projection=new a.proj.get(b.projection)),b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),wrapX:void 0===b.wrapX?1:b.wrapX,style:"undefined"===b.style?"normal":b.style};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({attributions:t(b),wrapX:void 0===b.wrapX?1:b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX?1:b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="http://services.arcgisonline.com/ArcGIS/rest/services/",u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),url:u,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=l.readFeatures(b.geojson.object,{featureProjection:w.getCode(),dataProjection:v.getCode()});g.addFeatures(x)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var y,z=f;y=e(b.wkt.projection)?new a.proj.get(b.wkt.projection):f;for(var A=new a.format.WKT,B=[],C=0;Cd||0>e)return"";var f=b.url+c+"/"+d+"/"+e+".png";return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileImage":g=new a.source.TileImage({url:b.url,attributions:t(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=-a[2]-1,f=b.url.replace("{z}",c.toString()).replace("{x}",d.toString()).replace("{y}",e.toString());return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"KML":var E=b.extractStyles||!1;g=new a.source.Vector({url:b.url,format:new a.format.KML,radius:b.radius,extractStyles:E,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"Stamen":if(!b.layer||!q(b.layer))return void c.error("[AngularJS - Openlayers] - You need a valid Stamen layer.");g=new a.source.Stamen({layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageStatic":if(!b.url||!angular.isArray(b.imageSize)||2!==b.imageSize.length)return void c.error("[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.");g=new a.source.ImageStatic({url:b.url,attributions:t(b),imageSize:b.imageSize,projection:f,imageExtent:b.imageExtent?b.imageExtent:f.getExtent(),imageLoadFunction:b.imageLoadFunction,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"XYZ":b.url||b.tileUrlFunction||c.error("[AngularJS - Openlayers] - XYZ Layer needs valid url or tileUrlFunction properties"),g=new a.source.XYZ({url:b.url,attributions:t(b),minZoom:b.minZoom,maxZoom:b.maxZoom,wrapX:void 0===b.wrapX?1:b.wrapX,projection:b.projection,tileUrlFunction:b.tileUrlFunction});break;case"Zoomify":b.url&&angular.isArray(b.imageSize)&&2===b.imageSize.length||c.error("[AngularJS - Openlayers] - Zoomify Layer needs valid url and imageSize properties"),g=new a.source.Zoomify({url:b.url,size:b.imageSize})}return g||c.warn('[AngularJS - Openlayers] - No source could be found for type "'+b.type+'"'),g},s=function(a){var b=a;if(a&&"object"==typeof a){b="[object Array]"===Object.prototype.toString.call(a)?[]:{};for(var c in a)b[c]=s(a[c])}return b},t=function(b){var c=[];return e(b.attribution)&&c.unshift(new a.Attribution({html:b.attribution})),c},u=function(b){var c=new a.layer.Group;return c.set("name",b),c},v=function(b,c){var d;return angular.forEach(b,function(b){return b instanceof a.layer.Group&&b.get("name")===c?void(d=b):void 0}),d},w=function(a,b){for(var c,d=0;d',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id)}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}});var w=f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})});r.$on("$destroy",function(){f.unByKey(w)})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)});var f=e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})});g.$on("$destroy",function(){a.unByKey(f)})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope();i.getMap().then(function(b){var d=e.getControlClasses,i=d();return a.$on("$destroy",function(){b.removeControl(f)}),h(a.properties)&&h(a.properties.control)?(f=a.properties.control,void b.addControl(f)):void(c.name&&(h(a.properties)&&(g=a.properties),f=new i[c.name](g),b.addControl(f)))})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return e.on("pointerdown",j),e.on("pointerup",j),e.on("pointerdrag",j),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e)}),k(c.properties)?void c.$watch("properties",function(d){if(e.getViewport().removeEventListener("mousemove",d.handleInteraction),e.getViewport().removeEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",d.handleTapInteraction),e.getViewport().removeEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",d.removeAllOverlays),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){function a(){c=!0,b&&clearTimeout(b),b=setTimeout(function(){c=!1,b=null},500)}var b,c=!1;return e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",a),function(){c||(d.handleInteraction.apply(null,arguments),a())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){var d=c(a,b);a[d].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d,e=c(a,b);return d=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:f(a,b)};this.setMap=function(a,b){var c=f(d,b);c.resolve(a),e(d,b)},this.getMap=function(a){var b=g(d,a);return b.promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function y(a,b){var c;if(b?c=a[b]:(b="style",c=a),"style"===b&&a instanceof Function)return a;if(!(c instanceof Object))return c;var d;if("[object Object]"===Object.prototype.toString.call(c)){d={};var e=l[b];if(e&&c instanceof e)return c;Object.getOwnPropertyNames(c).forEach(function(a,f,g){var h=l[a];return e&&h&&h.prototype instanceof l[b]?(console.assert(1===g.length,"Extra parameters for "+b),d=y(c,a),m(d,h)):(d[a]=y(c,a),void("text"!==a&&"string"!=typeof d[a]&&(d[a]=m(d[a],l[a]))))})}else d=c;return m(d,l[b])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":return"Vector";case"TileVector":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g,i,l=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");i="http://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken;var m=window.devicePixelRatio;m>1&&(i=i.replace(".png","@2x.png")),g=new a.source.XYZ({url:i,attributions:t(b),tilePixelRatio:m>1?2:1,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");i="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,g=new a.source.XYZ({url:i,attributions:t(b),tileSize:b.tileSize||[512,512]});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,attributions:t(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,wrapX:void 0===b.wrapX?1:b.wrapX,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b),wrapX:void 0===b.wrapX?1:b.wrapX};b.projection&&(n.projection=new a.proj.get(b.projection)),b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),wrapX:void 0===b.wrapX?1:b.wrapX,style:"undefined"===b.style?"normal":b.style};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({attributions:t(b),wrapX:void 0===b.wrapX?1:b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX?1:b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="http://services.arcgisonline.com/ArcGIS/rest/services/",u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),url:u,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=l.readFeatures(b.geojson.object,{featureProjection:w.getCode(),dataProjection:v.getCode()});g.addFeatures(x)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var y,z=f;y=e(b.wkt.projection)?new a.proj.get(b.wkt.projection):f;for(var A=new a.format.WKT,B=[],C=0;Cd||0>e)return"";var f=b.url+c+"/"+d+"/"+e+".png";return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileImage":g=new a.source.TileImage({url:b.url,attributions:t(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=-a[2]-1,f=b.url.replace("{z}",c.toString()).replace("{x}",d.toString()).replace("{y}",e.toString());return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"KML":var E=b.extractStyles||!1;g=new a.source.Vector({url:b.url,format:new a.format.KML,radius:b.radius,extractStyles:E,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"Stamen":if(!b.layer||!q(b.layer))return void c.error("[AngularJS - Openlayers] - You need a valid Stamen layer.");g=new a.source.Stamen({layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageStatic":if(!b.url||!angular.isArray(b.imageSize)||2!==b.imageSize.length)return void c.error("[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.");g=new a.source.ImageStatic({url:b.url,attributions:t(b),imageSize:b.imageSize,projection:f,imageExtent:b.imageExtent?b.imageExtent:f.getExtent(),imageLoadFunction:b.imageLoadFunction,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"XYZ":b.url||b.tileUrlFunction||c.error("[AngularJS - Openlayers] - XYZ Layer needs valid url or tileUrlFunction properties"),g=new a.source.XYZ({url:b.url,attributions:t(b),minZoom:b.minZoom,maxZoom:b.maxZoom,wrapX:void 0===b.wrapX?1:b.wrapX,projection:b.projection,tileUrlFunction:b.tileUrlFunction});break;case"Zoomify":b.url&&angular.isArray(b.imageSize)&&2===b.imageSize.length||c.error("[AngularJS - Openlayers] - Zoomify Layer needs valid url and imageSize properties"),g=new a.source.Zoomify({url:b.url,size:b.imageSize})}return g||c.warn('[AngularJS - Openlayers] - No source could be found for type "'+b.type+'"'),g},s=function(a){var b=a;if(a&&"object"==typeof a){b="[object Array]"===Object.prototype.toString.call(a)?[]:{};for(var c in a)b[c]=s(a[c])}return b},t=function(b){var c=[];return e(b.attribution)&&c.unshift(new a.Attribution({html:b.attribution})),c},u=function(b){var c=new a.layer.Group;return c.set("name",b),c},v=function(b,c){var d;return angular.forEach(b,function(b){return b instanceof a.layer.Group&&b.get("name")===c?void(d=b):void 0}),d},w=function(a,b){for(var c,d=0;d',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id)}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}}),f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)}),e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope();i.getMap().then(function(b){var d=e.getControlClasses,i=d();return a.$on("$destroy",function(){b.removeControl(f)}),h(a.properties)&&h(a.properties.control)?(f=a.properties.control,void b.addControl(f)):void(c.name&&(h(a.properties)&&(g=a.properties),f=new i[c.name](g),b.addControl(f)))})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return e.on("pointerdown",j),e.on("pointerup",j),e.on("pointerdrag",j),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e)}),k(c.properties)?void c.$watch("properties",function(d){if(e.getViewport().removeEventListener("mousemove",d.handleInteraction),e.getViewport().removeEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",d.handleTapInteraction),e.getViewport().removeEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",d.removeAllOverlays),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){function a(){c=!0,b&&clearTimeout(b),b=setTimeout(function(){c=!1,b=null},500)}var b,c=!1;return e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",a),function(){c||(d.handleInteraction.apply(null,arguments),a())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){var d=c(a,b);a[d].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d,e=c(a,b);return d=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:f(a,b)};this.setMap=function(a,b){var c=f(d,b);c.resolve(a),e(d,b)},this.getMap=function(a){var b=g(d,a);return b.promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function y(a,b){var c;if(b?c=a[b]:(b="style",c=a),"style"===b&&a instanceof Function)return a;if(!(c instanceof Object))return c;var d;if("[object Object]"===Object.prototype.toString.call(c)){d={};var e=l[b];if(e&&c instanceof e)return c;Object.getOwnPropertyNames(c).forEach(function(a,f,g){var h=l[a];return e&&h&&h.prototype instanceof l[b]?(console.assert(1===g.length,"Extra parameters for "+b),d=y(c,a),m(d,h)):(d[a]=y(c,a),void("text"!==a&&"string"!=typeof d[a]&&(d[a]=m(d[a],l[a]))))})}else d=c;return m(d,l[b])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":return"Vector";case"TileVector":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g,i,l=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");i="http://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken;var m=window.devicePixelRatio;m>1&&(i=i.replace(".png","@2x.png")),g=new a.source.XYZ({url:i,attributions:t(b),tilePixelRatio:m>1?2:1,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");i="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,g=new a.source.XYZ({url:i,attributions:t(b),tileSize:b.tileSize||[512,512]});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,attributions:t(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,wrapX:void 0===b.wrapX?1:b.wrapX,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b),wrapX:void 0===b.wrapX?1:b.wrapX};b.projection&&(n.projection=new a.proj.get(b.projection)),b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),wrapX:void 0===b.wrapX?1:b.wrapX,style:"undefined"===b.style?"normal":b.style};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({attributions:t(b),wrapX:void 0===b.wrapX?1:b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX?1:b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="http://services.arcgisonline.com/ArcGIS/rest/services/",u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),url:u,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=l.readFeatures(b.geojson.object,{featureProjection:w.getCode(),dataProjection:v.getCode()});g.addFeatures(x)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var y,z=f;y=e(b.wkt.projection)?new a.proj.get(b.wkt.projection):f;for(var A=new a.format.WKT,B=[],C=0;Cd||0>e)return"";var f=b.url+c+"/"+d+"/"+e+".png";return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileImage":g=new a.source.TileImage({url:b.url,attributions:t(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=-a[2]-1,f=b.url.replace("{z}",c.toString()).replace("{x}",d.toString()).replace("{y}",e.toString());return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"KML":var E=b.extractStyles||!1;g=new a.source.Vector({url:b.url,format:new a.format.KML,radius:b.radius,extractStyles:E,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"Stamen":if(!b.layer||!q(b.layer))return void c.error("[AngularJS - Openlayers] - You need a valid Stamen layer.");g=new a.source.Stamen({layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageStatic":if(!b.url||!angular.isArray(b.imageSize)||2!==b.imageSize.length)return void c.error("[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.");g=new a.source.ImageStatic({url:b.url,attributions:t(b),imageSize:b.imageSize,projection:f,imageExtent:b.imageExtent?b.imageExtent:f.getExtent(),imageLoadFunction:b.imageLoadFunction,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"XYZ":b.url||b.tileUrlFunction||c.error("[AngularJS - Openlayers] - XYZ Layer needs valid url or tileUrlFunction properties"),g=new a.source.XYZ({url:b.url,attributions:t(b),minZoom:b.minZoom,maxZoom:b.maxZoom,wrapX:void 0===b.wrapX?1:b.wrapX,projection:b.projection,tileUrlFunction:b.tileUrlFunction});break;case"Zoomify":b.url&&angular.isArray(b.imageSize)&&2===b.imageSize.length||c.error("[AngularJS - Openlayers] - Zoomify Layer needs valid url and imageSize properties"),g=new a.source.Zoomify({url:b.url,size:b.imageSize})}return g||c.warn('[AngularJS - Openlayers] - No source could be found for type "'+b.type+'"'),g},s=function(a){var b=a;if(a&&"object"==typeof a){b="[object Array]"===Object.prototype.toString.call(a)?[]:{};for(var c in a)b[c]=s(a[c])}return b},t=function(b){var c=[];return e(b.attribution)&&c.unshift(new a.Attribution({html:b.attribution})),c},u=function(b){var c=new a.layer.Group;return c.set("name",b),c},v=function(b,c){var d;return angular.forEach(b,function(b){return b instanceof a.layer.Group&&b.get("name")===c?void(d=b):void 0}),d},w=function(a,b){for(var c,d=0;d',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id)}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}});var w=f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})});r.$on("$destroy",function(){f.unByKey(w)})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)});var f=e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})});g.$on("$destroy",function(){a.unByKey(f)})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope();i.getMap().then(function(b){var d=e.getControlClasses,i=d();return a.$on("$destroy",function(){b.removeControl(f)}),h(a.properties)&&h(a.properties.control)?(f=a.properties.control,void b.addControl(f)):void(c.name&&(h(a.properties)&&(g=a.properties),f=new i[c.name](g),b.addControl(f)))})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return e.on("pointerdown",j),e.on("pointerup",j),e.on("pointerdrag",j),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e)}),k(c.properties)?void c.$watch("properties",function(d){if(e.getViewport().removeEventListener("mousemove",d.handleInteraction),e.getViewport().removeEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",d.handleTapInteraction),e.getViewport().removeEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",d.removeAllOverlays),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){function a(){c=!0,b&&clearTimeout(b),b=setTimeout(function(){c=!1,b=null},500)}var b,c=!1;return e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",a),function(){c||(d.handleInteraction.apply(null,arguments),a())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){var d=c(a,b);a[d].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d,e=c(a,b);return d=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:f(a,b)};this.setMap=function(a,b){var c=f(d,b);c.resolve(a),e(d,b)},this.getMap=function(a){var b=g(d,a);return b.promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function y(a,b){var c;if(b?c=a[b]:(b="style",c=a),"style"===b&&a instanceof Function)return a;if(!(c instanceof Object))return c;var d;if("[object Object]"===Object.prototype.toString.call(c)){d={};var e=l[b];if(e&&c instanceof e)return c;Object.getOwnPropertyNames(c).forEach(function(a,f,g){var h=l[a];return e&&h&&h.prototype instanceof l[b]?(console.assert(1===g.length,"Extra parameters for "+b),d=y(c,a),m(d,h)):(d[a]=y(c,a),void("text"!==a&&"string"!=typeof d[a]&&(d[a]=m(d[a],l[a]))))})}else d=c;return m(d,l[b])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":return"Vector";case"TileVector":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g,i,l=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");i="http://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken;var m=window.devicePixelRatio;m>1&&(i=i.replace(".png","@2x.png")),g=new a.source.XYZ({url:i,attributions:t(b),tilePixelRatio:m>1?2:1,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");i="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,g=new a.source.XYZ({url:i,attributions:t(b),tileSize:b.tileSize||[512,512]});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,attributions:t(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,wrapX:void 0===b.wrapX?1:b.wrapX,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b),wrapX:void 0===b.wrapX?1:b.wrapX};b.projection&&(n.projection=new a.proj.get(b.projection)),b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),wrapX:void 0===b.wrapX?1:b.wrapX,style:"undefined"===b.style?"normal":b.style};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({attributions:t(b),wrapX:void 0===b.wrapX?1:b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX?1:b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="http://services.arcgisonline.com/ArcGIS/rest/services/",u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),url:u,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=l.readFeatures(b.geojson.object,{featureProjection:w.getCode(),dataProjection:v.getCode()});g.addFeatures(x)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var y,z=f;y=e(b.wkt.projection)?new a.proj.get(b.wkt.projection):f;for(var A=new a.format.WKT,B=[],C=0;Cd||0>e)return"";var f=b.url+c+"/"+d+"/"+e+".png";return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileImage":g=new a.source.TileImage({url:b.url,attributions:t(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=-a[2]-1,f=b.url.replace("{z}",c.toString()).replace("{x}",d.toString()).replace("{y}",e.toString());return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"KML":var E=b.extractStyles||!1;g=new a.source.Vector({url:b.url,format:new a.format.KML,radius:b.radius,extractStyles:E,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"Stamen":if(!b.layer||!q(b.layer))return void c.error("[AngularJS - Openlayers] - You need a valid Stamen layer.");g=new a.source.Stamen({layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageStatic":if(!b.url||!angular.isArray(b.imageSize)||2!==b.imageSize.length)return void c.error("[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.");g=new a.source.ImageStatic({url:b.url,attributions:t(b),imageSize:b.imageSize,projection:f,imageExtent:b.imageExtent?b.imageExtent:f.getExtent(),imageLoadFunction:b.imageLoadFunction,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"XYZ":b.url||b.tileUrlFunction||c.error("[AngularJS - Openlayers] - XYZ Layer needs valid url or tileUrlFunction properties"),g=new a.source.XYZ({url:b.url,attributions:t(b),minZoom:b.minZoom,maxZoom:b.maxZoom,wrapX:void 0===b.wrapX?1:b.wrapX,projection:b.projection,tileUrlFunction:b.tileUrlFunction});break;case"Zoomify":b.url&&angular.isArray(b.imageSize)&&2===b.imageSize.length||c.error("[AngularJS - Openlayers] - Zoomify Layer needs valid url and imageSize properties"),g=new a.source.Zoomify({url:b.url,size:b.imageSize})}return g||c.warn('[AngularJS - Openlayers] - No source could be found for type "'+b.type+'"'),g},s=function(a){var b=a;if(a&&"object"==typeof a){b="[object Array]"===Object.prototype.toString.call(a)?[]:{};for(var c in a)b[c]=s(a[c])}return b},t=function(b){var c=[];return e(b.attribution)&&c.unshift(new a.Attribution({html:b.attribution})),c},u=function(b){var c=new a.layer.Group;return c.set("name",b),c},v=function(b,c){var d;return angular.forEach(b,function(b){return b instanceof a.layer.Group&&b.get("name")===c?void(d=b):void 0}),d},w=function(a,b){for(var c,d=0;d Date: Fri, 22 Jul 2016 12:48:24 +0530 Subject: [PATCH 26/53] fix(view.js, center.js) : unregistering map events on scope destroy for better memory leak management --- src/directives/center.js | 7 +++++-- src/directives/view.js | 6 +++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/directives/center.js b/src/directives/center.js index 9ee2f753..fc8d6c7b 100644 --- a/src/directives/center.js +++ b/src/directives/center.js @@ -144,7 +144,7 @@ angular.module('openlayers-directive').directive('olCenter', function($log, $loc } }); - map.on('moveend', function() { + var moveEndEventKey = map.on('moveend', function() { safeApply(olScope, function(scope) { if (!isDefined(scope.center)) { @@ -177,7 +177,10 @@ angular.module('openlayers-directive').directive('olCenter', function($log, $loc } }); }); - + + olScope.$on('$destroy', function(){ + map.unByKey(moveEndEventKey); + }); }); } }; diff --git a/src/directives/view.js b/src/directives/view.js index 006d3e4c..b6f21c59 100644 --- a/src/directives/view.js +++ b/src/directives/view.js @@ -39,11 +39,15 @@ angular.module('openlayers-directive').directive('olView', function($log, $q, ol } }); - mapView.on('change:rotation', function() { + var rotationEventKey = mapView.on('change:rotation', function() { safeApply(olScope, function(scope) { scope.view.rotation = map.getView().getRotation(); }); }); + + olScope.$on('$destroy', function(){ + map.unByKey(rotationEventKey); + }); }); } From b7e109a979329e8dc789b94e7948df455cee6573 Mon Sep 17 00:00:00 2001 From: Sathish Kesavaperumal Date: Fri, 22 Jul 2016 12:48:24 +0530 Subject: [PATCH 27/53] fix(view.js, center.js) : unregistering map events on scope destroy for better memory leak management --- src/directives/center.js | 7 +++++-- src/directives/view.js | 6 +++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/directives/center.js b/src/directives/center.js index 9ee2f753..fc8d6c7b 100644 --- a/src/directives/center.js +++ b/src/directives/center.js @@ -144,7 +144,7 @@ angular.module('openlayers-directive').directive('olCenter', function($log, $loc } }); - map.on('moveend', function() { + var moveEndEventKey = map.on('moveend', function() { safeApply(olScope, function(scope) { if (!isDefined(scope.center)) { @@ -177,7 +177,10 @@ angular.module('openlayers-directive').directive('olCenter', function($log, $loc } }); }); - + + olScope.$on('$destroy', function(){ + map.unByKey(moveEndEventKey); + }); }); } }; diff --git a/src/directives/view.js b/src/directives/view.js index 006d3e4c..b6f21c59 100644 --- a/src/directives/view.js +++ b/src/directives/view.js @@ -39,11 +39,15 @@ angular.module('openlayers-directive').directive('olView', function($log, $q, ol } }); - mapView.on('change:rotation', function() { + var rotationEventKey = mapView.on('change:rotation', function() { safeApply(olScope, function(scope) { scope.view.rotation = map.getView().getRotation(); }); }); + + olScope.$on('$destroy', function(){ + map.unByKey(rotationEventKey); + }); }); } From b38c8660e8510f68f693c5f78344ca4383292bfc Mon Sep 17 00:00:00 2001 From: Sathish Kesavaperumal Date: Fri, 22 Jul 2016 20:03:43 +0530 Subject: [PATCH 28/53] fix(view.js, center.js): Resolve lint issue for the previous commit --- src/directives/center.js | 2 +- src/directives/view.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/directives/center.js b/src/directives/center.js index fc8d6c7b..dcefe269 100644 --- a/src/directives/center.js +++ b/src/directives/center.js @@ -178,7 +178,7 @@ angular.module('openlayers-directive').directive('olCenter', function($log, $loc }); }); - olScope.$on('$destroy', function(){ + olScope.$on('$destroy', function() { map.unByKey(moveEndEventKey); }); }); diff --git a/src/directives/view.js b/src/directives/view.js index b6f21c59..c11649bf 100644 --- a/src/directives/view.js +++ b/src/directives/view.js @@ -45,7 +45,7 @@ angular.module('openlayers-directive').directive('olView', function($log, $q, ol }); }); - olScope.$on('$destroy', function(){ + olScope.$on('$destroy', function() { map.unByKey(rotationEventKey); }); From 2f82ff068eb4dbc4ca5a689efbb74b0c34a0b61a Mon Sep 17 00:00:00 2001 From: Sathish Kesavaperumal Date: Fri, 22 Jul 2016 20:17:27 +0530 Subject: [PATCH 29/53] fix(view.js, center.js): Resolve lint issue of trailing whitespace --- src/directives/center.js | 2 +- src/directives/view.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/directives/center.js b/src/directives/center.js index dcefe269..cb1964df 100644 --- a/src/directives/center.js +++ b/src/directives/center.js @@ -177,7 +177,7 @@ angular.module('openlayers-directive').directive('olCenter', function($log, $loc } }); }); - + olScope.$on('$destroy', function() { map.unByKey(moveEndEventKey); }); diff --git a/src/directives/view.js b/src/directives/view.js index c11649bf..c1aa08a2 100644 --- a/src/directives/view.js +++ b/src/directives/view.js @@ -44,7 +44,7 @@ angular.module('openlayers-directive').directive('olView', function($log, $q, ol scope.view.rotation = map.getView().getRotation(); }); }); - + olScope.$on('$destroy', function() { map.unByKey(rotationEventKey); }); From 11ac2ae2b7736e6d6dda69845212364107f89338 Mon Sep 17 00:00:00 2001 From: Sathish Kesavaperumal Date: Mon, 25 Jul 2016 16:02:20 +0530 Subject: [PATCH 30/53] resolved commit issue --- src/directives/view.js | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/directives/view.js b/src/directives/view.js index ef69b9f5..31e4dd3e 100644 --- a/src/directives/view.js +++ b/src/directives/view.js @@ -44,16 +44,8 @@ angular.module('openlayers-directive').directive('olView', function($log, $q, ol scope.view.rotation = map.getView().getRotation(); }); }); - - olScope.$on('$destroy', function(){ - map.unByKey(rotationEventKey); - }); - olScope.$on('$destroy', function() { - map.unByKey(rotationEventKey); - }); - - olScope.$on('$destroy', function() { + olScope.$on('$destroy', function(){ map.unByKey(rotationEventKey); }); From f54d08d41a922a74aa1f6cf6e1a704557545a554 Mon Sep 17 00:00:00 2001 From: Clay Anderson Date: Wed, 17 Aug 2016 16:12:34 -0600 Subject: [PATCH 31/53] Change to openlayers-prebuilt --- dist/angular-openlayers-directive.js | 2 +- dist/angular-openlayers-directive.min.js | 2 +- dist/angular-openlayers-directive.min.no-header.js | 2 +- dist/angular-openlayers-directive.pre.js | 2 +- grunt/concat.js | 2 +- package.json | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dist/angular-openlayers-directive.js b/dist/angular-openlayers-directive.js index fda100d4..e830ca80 100644 --- a/dist/angular-openlayers-directive.js +++ b/dist/angular-openlayers-directive.js @@ -1,7 +1,7 @@ (function (root, factory) { if (typeof require === 'function' && typeof exports === 'object') { // CommonJS - var ol = require('openlayers'); + var ol = require('openlayers-prebuilt'); var ngSanitize = require('angular-sanitize'); exports.angularOpenlayersDirective = factory(ol); } else if (typeof define === 'function' && define.amd) { diff --git a/dist/angular-openlayers-directive.min.js b/dist/angular-openlayers-directive.min.js index c9e4154c..7de455e5 100644 --- a/dist/angular-openlayers-directive.min.js +++ b/dist/angular-openlayers-directive.min.js @@ -28,5 +28,5 @@ */ /*! angular-openlayers-directive 22-07-2016 */ -!function(a,b){if("function"==typeof require&&"object"==typeof exports){var c=require("openlayers");require("angular-sanitize");exports.angularOpenlayersDirective=b(c)}else"function"==typeof define&&define.amd?define(["ol"],function(c){return a.angularOpenlayersDirective=b(c)}):a.angularOpenlayersDirective=b(a.ol)}(this,function(a){return angular.module("openlayers-directive",["ngSanitize"]).directive("openlayers",["$log","$q","$compile","olHelpers","olMapDefaults","olData",function(b,c,d,e,f,g){return{restrict:"EA",transclude:!0,replace:!0,scope:{center:"=olCenter",defaults:"=olDefaults",view:"=olView",events:"=olEvents"},template:'
',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id)}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}});var w=f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})});r.$on("$destroy",function(){f.unByKey(w)})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)});var f=e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})});g.$on("$destroy",function(){a.unByKey(f)})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope();i.getMap().then(function(b){var d=e.getControlClasses,i=d();return a.$on("$destroy",function(){b.removeControl(f)}),h(a.properties)&&h(a.properties.control)?(f=a.properties.control,void b.addControl(f)):void(c.name&&(h(a.properties)&&(g=a.properties),f=new i[c.name](g),b.addControl(f)))})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return e.on("pointerdown",j),e.on("pointerup",j),e.on("pointerdrag",j),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e)}),k(c.properties)?void c.$watch("properties",function(d){if(e.getViewport().removeEventListener("mousemove",d.handleInteraction),e.getViewport().removeEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",d.handleTapInteraction),e.getViewport().removeEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",d.removeAllOverlays),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){function a(){c=!0,b&&clearTimeout(b),b=setTimeout(function(){c=!1,b=null},500)}var b,c=!1;return e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",a),function(){c||(d.handleInteraction.apply(null,arguments),a())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){var d=c(a,b);a[d].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d,e=c(a,b);return d=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:f(a,b)};this.setMap=function(a,b){var c=f(d,b);c.resolve(a),e(d,b)},this.getMap=function(a){var b=g(d,a);return b.promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function y(a,b){var c;if(b?c=a[b]:(b="style",c=a),"style"===b&&a instanceof Function)return a;if(!(c instanceof Object))return c;var d;if("[object Object]"===Object.prototype.toString.call(c)){d={};var e=l[b];if(e&&c instanceof e)return c;Object.getOwnPropertyNames(c).forEach(function(a,f,g){var h=l[a];return e&&h&&h.prototype instanceof l[b]?(console.assert(1===g.length,"Extra parameters for "+b),d=y(c,a),m(d,h)):(d[a]=y(c,a),void("text"!==a&&"string"!=typeof d[a]&&(d[a]=m(d[a],l[a]))))})}else d=c;return m(d,l[b])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":return"Vector";case"TileVector":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g,i,l=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");i="http://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken;var m=window.devicePixelRatio;m>1&&(i=i.replace(".png","@2x.png")),g=new a.source.XYZ({url:i,attributions:t(b),tilePixelRatio:m>1?2:1,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");i="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,g=new a.source.XYZ({url:i,attributions:t(b),tileSize:b.tileSize||[512,512]});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,attributions:t(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,wrapX:void 0===b.wrapX?1:b.wrapX,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b),wrapX:void 0===b.wrapX?1:b.wrapX};b.projection&&(n.projection=new a.proj.get(b.projection)),b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),wrapX:void 0===b.wrapX?1:b.wrapX,style:"undefined"===b.style?"normal":b.style};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({attributions:t(b),wrapX:void 0===b.wrapX?1:b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX?1:b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="http://services.arcgisonline.com/ArcGIS/rest/services/",u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),url:u,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=l.readFeatures(b.geojson.object,{featureProjection:w.getCode(),dataProjection:v.getCode()});g.addFeatures(x)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var y,z=f;y=e(b.wkt.projection)?new a.proj.get(b.wkt.projection):f;for(var A=new a.format.WKT,B=[],C=0;Cd||0>e)return"";var f=b.url+c+"/"+d+"/"+e+".png";return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileImage":g=new a.source.TileImage({url:b.url,attributions:t(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=-a[2]-1,f=b.url.replace("{z}",c.toString()).replace("{x}",d.toString()).replace("{y}",e.toString());return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"KML":var E=b.extractStyles||!1;g=new a.source.Vector({url:b.url,format:new a.format.KML,radius:b.radius,extractStyles:E,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"Stamen":if(!b.layer||!q(b.layer))return void c.error("[AngularJS - Openlayers] - You need a valid Stamen layer.");g=new a.source.Stamen({layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageStatic":if(!b.url||!angular.isArray(b.imageSize)||2!==b.imageSize.length)return void c.error("[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.");g=new a.source.ImageStatic({url:b.url,attributions:t(b),imageSize:b.imageSize,projection:f,imageExtent:b.imageExtent?b.imageExtent:f.getExtent(),imageLoadFunction:b.imageLoadFunction,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"XYZ":b.url||b.tileUrlFunction||c.error("[AngularJS - Openlayers] - XYZ Layer needs valid url or tileUrlFunction properties"),g=new a.source.XYZ({url:b.url,attributions:t(b),minZoom:b.minZoom,maxZoom:b.maxZoom,wrapX:void 0===b.wrapX?1:b.wrapX,projection:b.projection,tileUrlFunction:b.tileUrlFunction});break;case"Zoomify":b.url&&angular.isArray(b.imageSize)&&2===b.imageSize.length||c.error("[AngularJS - Openlayers] - Zoomify Layer needs valid url and imageSize properties"),g=new a.source.Zoomify({url:b.url,size:b.imageSize})}return g||c.warn('[AngularJS - Openlayers] - No source could be found for type "'+b.type+'"'),g},s=function(a){var b=a;if(a&&"object"==typeof a){b="[object Array]"===Object.prototype.toString.call(a)?[]:{};for(var c in a)b[c]=s(a[c])}return b},t=function(b){var c=[];return e(b.attribution)&&c.unshift(new a.Attribution({html:b.attribution})),c},u=function(b){var c=new a.layer.Group;return c.set("name",b),c},v=function(b,c){var d;return angular.forEach(b,function(b){return b instanceof a.layer.Group&&b.get("name")===c?void(d=b):void 0}),d},w=function(a,b){for(var c,d=0;d',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id)}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}});var w=f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})});r.$on("$destroy",function(){f.unByKey(w)})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)});var f=e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})});g.$on("$destroy",function(){a.unByKey(f)})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope();i.getMap().then(function(b){var d=e.getControlClasses,i=d();return a.$on("$destroy",function(){b.removeControl(f)}),h(a.properties)&&h(a.properties.control)?(f=a.properties.control,void b.addControl(f)):void(c.name&&(h(a.properties)&&(g=a.properties),f=new i[c.name](g),b.addControl(f)))})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return e.on("pointerdown",j),e.on("pointerup",j),e.on("pointerdrag",j),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e)}),k(c.properties)?void c.$watch("properties",function(d){if(e.getViewport().removeEventListener("mousemove",d.handleInteraction),e.getViewport().removeEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",d.handleTapInteraction),e.getViewport().removeEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",d.removeAllOverlays),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){function a(){c=!0,b&&clearTimeout(b),b=setTimeout(function(){c=!1,b=null},500)}var b,c=!1;return e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",a),function(){c||(d.handleInteraction.apply(null,arguments),a())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){var d=c(a,b);a[d].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d,e=c(a,b);return d=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:f(a,b)};this.setMap=function(a,b){var c=f(d,b);c.resolve(a),e(d,b)},this.getMap=function(a){var b=g(d,a);return b.promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function y(a,b){var c;if(b?c=a[b]:(b="style",c=a),"style"===b&&a instanceof Function)return a;if(!(c instanceof Object))return c;var d;if("[object Object]"===Object.prototype.toString.call(c)){d={};var e=l[b];if(e&&c instanceof e)return c;Object.getOwnPropertyNames(c).forEach(function(a,f,g){var h=l[a];return e&&h&&h.prototype instanceof l[b]?(console.assert(1===g.length,"Extra parameters for "+b),d=y(c,a),m(d,h)):(d[a]=y(c,a),void("text"!==a&&"string"!=typeof d[a]&&(d[a]=m(d[a],l[a]))))})}else d=c;return m(d,l[b])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":return"Vector";case"TileVector":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g,i,l=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");i="http://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken;var m=window.devicePixelRatio;m>1&&(i=i.replace(".png","@2x.png")),g=new a.source.XYZ({url:i,attributions:t(b),tilePixelRatio:m>1?2:1,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");i="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,g=new a.source.XYZ({url:i,attributions:t(b),tileSize:b.tileSize||[512,512]});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,attributions:t(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,wrapX:void 0===b.wrapX?1:b.wrapX,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b),wrapX:void 0===b.wrapX?1:b.wrapX};b.projection&&(n.projection=new a.proj.get(b.projection)),b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),wrapX:void 0===b.wrapX?1:b.wrapX,style:"undefined"===b.style?"normal":b.style};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({attributions:t(b),wrapX:void 0===b.wrapX?1:b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX?1:b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="http://services.arcgisonline.com/ArcGIS/rest/services/",u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),url:u,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=l.readFeatures(b.geojson.object,{featureProjection:w.getCode(),dataProjection:v.getCode()});g.addFeatures(x)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var y,z=f;y=e(b.wkt.projection)?new a.proj.get(b.wkt.projection):f;for(var A=new a.format.WKT,B=[],C=0;Cd||0>e)return"";var f=b.url+c+"/"+d+"/"+e+".png";return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileImage":g=new a.source.TileImage({url:b.url,attributions:t(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=-a[2]-1,f=b.url.replace("{z}",c.toString()).replace("{x}",d.toString()).replace("{y}",e.toString());return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"KML":var E=b.extractStyles||!1;g=new a.source.Vector({url:b.url,format:new a.format.KML,radius:b.radius,extractStyles:E,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"Stamen":if(!b.layer||!q(b.layer))return void c.error("[AngularJS - Openlayers] - You need a valid Stamen layer.");g=new a.source.Stamen({layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageStatic":if(!b.url||!angular.isArray(b.imageSize)||2!==b.imageSize.length)return void c.error("[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.");g=new a.source.ImageStatic({url:b.url,attributions:t(b),imageSize:b.imageSize,projection:f,imageExtent:b.imageExtent?b.imageExtent:f.getExtent(),imageLoadFunction:b.imageLoadFunction,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"XYZ":b.url||b.tileUrlFunction||c.error("[AngularJS - Openlayers] - XYZ Layer needs valid url or tileUrlFunction properties"),g=new a.source.XYZ({url:b.url,attributions:t(b),minZoom:b.minZoom,maxZoom:b.maxZoom,wrapX:void 0===b.wrapX?1:b.wrapX,projection:b.projection,tileUrlFunction:b.tileUrlFunction});break;case"Zoomify":b.url&&angular.isArray(b.imageSize)&&2===b.imageSize.length||c.error("[AngularJS - Openlayers] - Zoomify Layer needs valid url and imageSize properties"),g=new a.source.Zoomify({url:b.url,size:b.imageSize})}return g||c.warn('[AngularJS - Openlayers] - No source could be found for type "'+b.type+'"'),g},s=function(a){var b=a;if(a&&"object"==typeof a){b="[object Array]"===Object.prototype.toString.call(a)?[]:{};for(var c in a)b[c]=s(a[c])}return b},t=function(b){var c=[];return e(b.attribution)&&c.unshift(new a.Attribution({html:b.attribution})),c},u=function(b){var c=new a.layer.Group;return c.set("name",b),c},v=function(b,c){var d;return angular.forEach(b,function(b){return b instanceof a.layer.Group&&b.get("name")===c?void(d=b):void 0}),d},w=function(a,b){for(var c,d=0;d',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id)}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}});var w=f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})});r.$on("$destroy",function(){f.unByKey(w)})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)});var f=e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})});g.$on("$destroy",function(){a.unByKey(f)})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope();i.getMap().then(function(b){var d=e.getControlClasses,i=d();return a.$on("$destroy",function(){b.removeControl(f)}),h(a.properties)&&h(a.properties.control)?(f=a.properties.control,void b.addControl(f)):void(c.name&&(h(a.properties)&&(g=a.properties),f=new i[c.name](g),b.addControl(f)))})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return e.on("pointerdown",j),e.on("pointerup",j),e.on("pointerdrag",j),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e)}),k(c.properties)?void c.$watch("properties",function(d){if(e.getViewport().removeEventListener("mousemove",d.handleInteraction),e.getViewport().removeEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",d.handleTapInteraction),e.getViewport().removeEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",d.removeAllOverlays),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){function a(){c=!0,b&&clearTimeout(b),b=setTimeout(function(){c=!1,b=null},500)}var b,c=!1;return e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",a),function(){c||(d.handleInteraction.apply(null,arguments),a())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){var d=c(a,b);a[d].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d,e=c(a,b);return d=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:f(a,b)};this.setMap=function(a,b){var c=f(d,b);c.resolve(a),e(d,b)},this.getMap=function(a){var b=g(d,a);return b.promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function y(a,b){var c;if(b?c=a[b]:(b="style",c=a),"style"===b&&a instanceof Function)return a;if(!(c instanceof Object))return c;var d;if("[object Object]"===Object.prototype.toString.call(c)){d={};var e=l[b];if(e&&c instanceof e)return c;Object.getOwnPropertyNames(c).forEach(function(a,f,g){var h=l[a];return e&&h&&h.prototype instanceof l[b]?(console.assert(1===g.length,"Extra parameters for "+b),d=y(c,a),m(d,h)):(d[a]=y(c,a),void("text"!==a&&"string"!=typeof d[a]&&(d[a]=m(d[a],l[a]))))})}else d=c;return m(d,l[b])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":return"Vector";case"TileVector":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g,i,l=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");i="http://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken;var m=window.devicePixelRatio;m>1&&(i=i.replace(".png","@2x.png")),g=new a.source.XYZ({url:i,attributions:t(b),tilePixelRatio:m>1?2:1,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");i="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,g=new a.source.XYZ({url:i,attributions:t(b),tileSize:b.tileSize||[512,512]});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,attributions:t(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,wrapX:void 0===b.wrapX?1:b.wrapX,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b),wrapX:void 0===b.wrapX?1:b.wrapX};b.projection&&(n.projection=new a.proj.get(b.projection)),b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),wrapX:void 0===b.wrapX?1:b.wrapX,style:"undefined"===b.style?"normal":b.style};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({attributions:t(b),wrapX:void 0===b.wrapX?1:b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX?1:b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="http://services.arcgisonline.com/ArcGIS/rest/services/",u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),url:u,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=l.readFeatures(b.geojson.object,{featureProjection:w.getCode(),dataProjection:v.getCode()});g.addFeatures(x)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var y,z=f;y=e(b.wkt.projection)?new a.proj.get(b.wkt.projection):f;for(var A=new a.format.WKT,B=[],C=0;Cd||0>e)return"";var f=b.url+c+"/"+d+"/"+e+".png";return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileImage":g=new a.source.TileImage({url:b.url,attributions:t(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=-a[2]-1,f=b.url.replace("{z}",c.toString()).replace("{x}",d.toString()).replace("{y}",e.toString());return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"KML":var E=b.extractStyles||!1;g=new a.source.Vector({url:b.url,format:new a.format.KML,radius:b.radius,extractStyles:E,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"Stamen":if(!b.layer||!q(b.layer))return void c.error("[AngularJS - Openlayers] - You need a valid Stamen layer.");g=new a.source.Stamen({layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageStatic":if(!b.url||!angular.isArray(b.imageSize)||2!==b.imageSize.length)return void c.error("[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.");g=new a.source.ImageStatic({url:b.url,attributions:t(b),imageSize:b.imageSize,projection:f,imageExtent:b.imageExtent?b.imageExtent:f.getExtent(),imageLoadFunction:b.imageLoadFunction,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"XYZ":b.url||b.tileUrlFunction||c.error("[AngularJS - Openlayers] - XYZ Layer needs valid url or tileUrlFunction properties"),g=new a.source.XYZ({url:b.url,attributions:t(b),minZoom:b.minZoom,maxZoom:b.maxZoom,wrapX:void 0===b.wrapX?1:b.wrapX,projection:b.projection,tileUrlFunction:b.tileUrlFunction});break;case"Zoomify":b.url&&angular.isArray(b.imageSize)&&2===b.imageSize.length||c.error("[AngularJS - Openlayers] - Zoomify Layer needs valid url and imageSize properties"),g=new a.source.Zoomify({url:b.url,size:b.imageSize})}return g||c.warn('[AngularJS - Openlayers] - No source could be found for type "'+b.type+'"'),g},s=function(a){var b=a;if(a&&"object"==typeof a){b="[object Array]"===Object.prototype.toString.call(a)?[]:{};for(var c in a)b[c]=s(a[c])}return b},t=function(b){var c=[];return e(b.attribution)&&c.unshift(new a.Attribution({html:b.attribution})),c},u=function(b){var c=new a.layer.Group;return c.set("name",b),c},v=function(b,c){var d;return angular.forEach(b,function(b){return b instanceof a.layer.Group&&b.get("name")===c?void(d=b):void 0}),d},w=function(a,b){for(var c,d=0;d',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id)}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}});var w=f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})});r.$on("$destroy",function(){f.unByKey(w)})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)});var f=e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})});g.$on("$destroy",function(){a.unByKey(f)})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope();i.getMap().then(function(b){var d=e.getControlClasses,i=d();return a.$on("$destroy",function(){b.removeControl(f)}),h(a.properties)&&h(a.properties.control)?(f=a.properties.control,void b.addControl(f)):void(c.name&&(h(a.properties)&&(g=a.properties),f=new i[c.name](g),b.addControl(f)))})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return e.on("pointerdown",j),e.on("pointerup",j),e.on("pointerdrag",j),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e)}),k(c.properties)?void c.$watch("properties",function(d){if(e.getViewport().removeEventListener("mousemove",d.handleInteraction),e.getViewport().removeEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",d.handleTapInteraction),e.getViewport().removeEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",d.removeAllOverlays),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){function a(){c=!0,b&&clearTimeout(b),b=setTimeout(function(){c=!1,b=null},500)}var b,c=!1;return e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",a),function(){c||(d.handleInteraction.apply(null,arguments),a())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){var d=c(a,b);a[d].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d,e=c(a,b);return d=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:f(a,b)};this.setMap=function(a,b){var c=f(d,b);c.resolve(a),e(d,b)},this.getMap=function(a){var b=g(d,a);return b.promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function y(a,b){var c;if(b?c=a[b]:(b="style",c=a),"style"===b&&a instanceof Function)return a;if(!(c instanceof Object))return c;var d;if("[object Object]"===Object.prototype.toString.call(c)){d={};var e=l[b];if(e&&c instanceof e)return c;Object.getOwnPropertyNames(c).forEach(function(a,f,g){var h=l[a];return e&&h&&h.prototype instanceof l[b]?(console.assert(1===g.length,"Extra parameters for "+b),d=y(c,a),m(d,h)):(d[a]=y(c,a),void("text"!==a&&"string"!=typeof d[a]&&(d[a]=m(d[a],l[a]))))})}else d=c;return m(d,l[b])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":return"Vector";case"TileVector":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g,i,l=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");i="http://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken;var m=window.devicePixelRatio;m>1&&(i=i.replace(".png","@2x.png")),g=new a.source.XYZ({url:i,attributions:t(b),tilePixelRatio:m>1?2:1,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");i="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,g=new a.source.XYZ({url:i,attributions:t(b),tileSize:b.tileSize||[512,512]});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,attributions:t(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,wrapX:void 0===b.wrapX?1:b.wrapX,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b),wrapX:void 0===b.wrapX?1:b.wrapX};b.projection&&(n.projection=new a.proj.get(b.projection)),b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),wrapX:void 0===b.wrapX?1:b.wrapX,style:"undefined"===b.style?"normal":b.style};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({attributions:t(b),wrapX:void 0===b.wrapX?1:b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX?1:b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="http://services.arcgisonline.com/ArcGIS/rest/services/",u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),url:u,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=l.readFeatures(b.geojson.object,{featureProjection:w.getCode(),dataProjection:v.getCode()});g.addFeatures(x)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var y,z=f;y=e(b.wkt.projection)?new a.proj.get(b.wkt.projection):f;for(var A=new a.format.WKT,B=[],C=0;Cd||0>e)return"";var f=b.url+c+"/"+d+"/"+e+".png";return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileImage":g=new a.source.TileImage({url:b.url,attributions:t(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=-a[2]-1,f=b.url.replace("{z}",c.toString()).replace("{x}",d.toString()).replace("{y}",e.toString());return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"KML":var E=b.extractStyles||!1;g=new a.source.Vector({url:b.url,format:new a.format.KML,radius:b.radius,extractStyles:E,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"Stamen":if(!b.layer||!q(b.layer))return void c.error("[AngularJS - Openlayers] - You need a valid Stamen layer.");g=new a.source.Stamen({layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageStatic":if(!b.url||!angular.isArray(b.imageSize)||2!==b.imageSize.length)return void c.error("[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.");g=new a.source.ImageStatic({url:b.url,attributions:t(b),imageSize:b.imageSize,projection:f,imageExtent:b.imageExtent?b.imageExtent:f.getExtent(),imageLoadFunction:b.imageLoadFunction,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"XYZ":b.url||b.tileUrlFunction||c.error("[AngularJS - Openlayers] - XYZ Layer needs valid url or tileUrlFunction properties"),g=new a.source.XYZ({url:b.url,attributions:t(b),minZoom:b.minZoom,maxZoom:b.maxZoom,wrapX:void 0===b.wrapX?1:b.wrapX,projection:b.projection,tileUrlFunction:b.tileUrlFunction});break;case"Zoomify":b.url&&angular.isArray(b.imageSize)&&2===b.imageSize.length||c.error("[AngularJS - Openlayers] - Zoomify Layer needs valid url and imageSize properties"),g=new a.source.Zoomify({url:b.url,size:b.imageSize})}return g||c.warn('[AngularJS - Openlayers] - No source could be found for type "'+b.type+'"'),g},s=function(a){var b=a;if(a&&"object"==typeof a){b="[object Array]"===Object.prototype.toString.call(a)?[]:{};for(var c in a)b[c]=s(a[c])}return b},t=function(b){var c=[];return e(b.attribution)&&c.unshift(new a.Attribution({html:b.attribution})),c},u=function(b){var c=new a.layer.Group;return c.set("name",b),c},v=function(b,c){var d;return angular.forEach(b,function(b){return b instanceof a.layer.Group&&b.get("name")===c?void(d=b):void 0}),d},w=function(a,b){for(var c,d=0;d Date: Tue, 28 Feb 2017 16:59:34 +0530 Subject: [PATCH 32/53] Lint Issue fixed --- src/directives/view.js | 2 +- src/services/olHelpers.js | 41 +++++++++++++++++++-------------------- 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/src/directives/view.js b/src/directives/view.js index 31e4dd3e..c1aa08a2 100644 --- a/src/directives/view.js +++ b/src/directives/view.js @@ -45,7 +45,7 @@ angular.module('openlayers-directive').directive('olView', function($log, $q, ol }); }); - olScope.$on('$destroy', function(){ + olScope.$on('$destroy', function() { map.unByKey(rotationEventKey); }); diff --git a/src/services/olHelpers.js b/src/services/olHelpers.js index 110b85a3..29c2e135 100644 --- a/src/services/olHelpers.js +++ b/src/services/olHelpers.js @@ -286,10 +286,10 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ attributions: createAttribution(source), wrapX: source.wrapX !== undefined ? source.wrapX : true }; - - if(source.projection){ + + if (source.projection) { wmsConfiguration.projection = new ol.proj.get(source.projection); - } + } if (source.serverType) { wmsConfiguration.serverType = source.serverType; @@ -455,12 +455,11 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ oSource.addFeatures(features); } - break; - case 'WKT': + case 'WKT': if (!(source.wkt || source.url)) { $log.error('[AngularJS - Openlayers] - You need a WKT ' + - 'property to add a GeoJSON layer.'); + 'property to add a GeoJSON layer.'); return; } if (isDefined(source.url)) { @@ -471,26 +470,26 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ }); } else { oSource = new ol.source.Vector(); - var featureProjection = projection; + var featureProjection = projection; var wktProjection; if (isDefined(source.wkt.projection)) { wktProjection = new ol.proj.get(source.wkt.projection); - } - else{ - wktProjection = projection; + } else { + wktProjection = projection; } var wktFormat = new ol.format.WKT(); - var wktFeatures = []; - for(var k = 0; k< source.wkt.object.length; k++){ - var feature = wktFormat.readFeature( - source.wkt.object[k].data, {dataProjection: wktProjection.getCode() ,featureProjection: featureProjection.getCode() }); - if(source.wkt.object[k].properties){ - feature.properties = source.wkt.object[k].properties; - } - wktFeatures.push(feature); - } - oSource.addFeatures(wktFeatures); + var wktFeatures = []; + for (var k = 0; k < source.wkt.object.length; k++) { + var feature = wktFormat.readFeature( + source.wkt.object[k].data, {dataProjection: wktProjection.getCode() , + featureProjection: featureProjection.getCode() }); + if (source.wkt.object[k].properties) { + feature.properties = source.wkt.object[k].properties; + } + wktFeatures.push(feature); + } + oSource.addFeatures(wktFeatures); } break; @@ -528,7 +527,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ if (source.url) { oSource = new ol.source.Vector({ format: new ol.format.TopoJSON(), - url: source.url + url: source.url }); } else { oSource = new ol.source.Vector(angular.extend(source.topojson, { From 5c299b7045e9b192ee444faf623898fdc8f7bb56 Mon Sep 17 00:00:00 2001 From: Sathish Kesavaperumal Date: Tue, 28 Feb 2017 17:01:38 +0530 Subject: [PATCH 33/53] Built Version --- dist/angular-openlayers-directive.js | 293 ++++++++++++------ dist/angular-openlayers-directive.min.js | 6 +- ...ular-openlayers-directive.min.no-header.js | 6 +- dist/angular-openlayers-directive.pre.js | 293 ++++++++++++------ 4 files changed, 414 insertions(+), 184 deletions(-) diff --git a/dist/angular-openlayers-directive.js b/dist/angular-openlayers-directive.js index e830ca80..6c409736 100644 --- a/dist/angular-openlayers-directive.js +++ b/dist/angular-openlayers-directive.js @@ -313,8 +313,8 @@ angular.module('openlayers-directive').directive('olCenter', ["$log", "$location } }); }); - - olScope.$on('$destroy', function(){ + + olScope.$on('$destroy', function() { map.unByKey(moveEndEventKey); }); }); @@ -654,8 +654,8 @@ angular.module('openlayers-directive').directive('olView', ["$log", "$q", "olDat scope.view.rotation = map.getView().getRotation(); }); }); - - olScope.$on('$destroy', function(){ + + olScope.$on('$destroy', function() { map.unByKey(rotationEventKey); }); @@ -664,8 +664,8 @@ angular.module('openlayers-directive').directive('olView', ["$log", "$q", "olDat }; }]); -angular.module('openlayers-directive').directive('olControl', ["$log", "$q", "olData", "olMapDefaults", "olHelpers", function($log, $q, olData, olMapDefaults, olHelpers) { - +angular.module('openlayers-directive') +.directive('olControl', ["$log", "$q", "olData", "olMapDefaults", "olHelpers", function($log, $q, olData, olMapDefaults, olHelpers) { return { restrict: 'E', scope: { @@ -678,29 +678,58 @@ angular.module('openlayers-directive').directive('olControl', ["$log", "$q", "ol var olScope = controller.getOpenlayersScope(); var olControl; var olControlOps; + var getControlClasses = olHelpers.getControlClasses; + var controlClasses = getControlClasses(); olScope.getMap().then(function(map) { - var getControlClasses = olHelpers.getControlClasses; - var controlClasses = getControlClasses(); scope.$on('$destroy', function() { map.removeControl(olControl); }); - if (!isDefined(scope.properties) || !isDefined(scope.properties.control)) { - if (attrs.name) { - if (isDefined(scope.properties)) { - olControlOps = scope.properties; + scope.$watch('properties', function(properties) { + if (!isDefined(properties)) { + return; + } + + initCtrls(properties); + }); + + function initCtrls(properties) { + if (properties && properties.control) { + // the control instance is already defined, + // so simply use it and go ahead + + // is there already a control, so destroy and recreate it? + if (olControl) { + map.removeControl(olControl); } - olControl = new controlClasses[attrs.name](olControlOps); + + olControl = properties.control; map.addControl(olControl); + } else { + + // the name is the key to instantiate an ol3 control + if (attrs.name) { + if (isDefined(properties)) { + olControlOps = properties; + } + + // is there already a control, so destroy and recreate it? + if (olControl) { + map.removeControl(olControl); + } + + olControl = new controlClasses[attrs.name](olControlOps); + map.addControl(olControl); + } } - return; } - olControl = scope.properties.control; - map.addControl(olControl); + initCtrls(scope.properties); + }); + } }; }]); @@ -765,6 +794,7 @@ angular.module('openlayers-directive').directive('olMarker', ["$log", "$q", "olM if (!scopes.length) { map.removeLayer(mapDict[mapIndex].markerLayer); + delete mapDict[mapIndex].markerLayer; delete mapDict[mapIndex]; } } @@ -809,7 +839,7 @@ angular.module('openlayers-directive').directive('olMarker', ["$log", "$q", "olM // This function handles dragging a marker var pickOffset = null; var pickProperties = null; - function handleDrag(evt) { + scope.handleDrag = function(evt) { var coord = evt.coordinate; var proj = map.getView().getProjection().getCode(); if (proj === 'pixel') { @@ -858,12 +888,25 @@ angular.module('openlayers-directive').directive('olMarker', ["$log", "$q", "olM }); } } + }; + + function unregisterHandlers() { + if (!scope.properties) { return ; } + // Remove previous listeners if any + map.getViewport().removeEventListener('mousemove', scope.properties.handleInteraction); + map.getViewport().removeEventListener('click', scope.properties.handleTapInteraction); + map.getViewport().querySelector('canvas.ol-unselectable').removeEventListener( + 'touchend', scope.properties.handleTapInteraction); + map.getViewport().removeEventListener('mousemove', scope.properties.showAtLeastOneOverlay); + map.getViewport().removeEventListener('click', scope.properties.removeAllOverlays); + map.getViewport().querySelector('canvas.ol-unselectable').removeEventListener( + 'touchmove', scope.properties.activateCooldown); } // Setup generic handlers for marker drag - map.on('pointerdown', handleDrag); - map.on('pointerup', handleDrag); - map.on('pointerdrag', handleDrag); + map.on('pointerdown', scope.handleDrag); + map.on('pointerup', scope.handleDrag); + map.on('pointerdrag', scope.handleDrag); scope.$on('$destroy', function() { markerLayer.getSource().removeFeature(marker); @@ -871,6 +914,10 @@ angular.module('openlayers-directive').directive('olMarker', ["$log", "$q", "olM map.removeOverlay(label); } markerLayerManager.deregisterScope(scope, map); + map.un('pointerdown', scope.handleDrag); + map.un('pointerup', scope.handleDrag); + map.un('pointerdrag', scope.handleDrag); + unregisterHandlers(); }); if (!isDefined(scope.properties)) { @@ -900,13 +947,7 @@ angular.module('openlayers-directive').directive('olMarker', ["$log", "$q", "olM scope.$watch('properties', function(properties) { - // Remove previous listeners if any - map.getViewport().removeEventListener('mousemove', properties.handleInteraction); - map.getViewport().removeEventListener('click', properties.handleTapInteraction); - map.getViewport().querySelector('canvas.ol-unselectable').removeEventListener( - 'touchend', properties.handleTapInteraction); - map.getViewport().removeEventListener('mousemove', properties.showAtLeastOneOverlay); - map.getViewport().removeEventListener('click', properties.removeAllOverlays); + unregisterHandlers(); // This function handles popup on mouse over/click properties.handleInteraction = function(evt) { @@ -965,7 +1006,7 @@ angular.module('openlayers-directive').directive('olMarker', ["$log", "$q", "olM var prevTimeout; // Sets the cooldown flag to filter out any subsequent events within 500 ms - function activateCooldown() { + properties.activateCooldown = function() { cooldownActive = true; if (prevTimeout) { clearTimeout(prevTimeout); @@ -974,16 +1015,20 @@ angular.module('openlayers-directive').directive('olMarker', ["$log", "$q", "olM cooldownActive = false; prevTimeout = null; }, 500); - } + }; // Preventing from 'touchend' to be considered a tap, if fired immediately after 'touchmove' + if (properties.activateCooldown) { + map.getViewport().querySelector('canvas.ol-unselectable').removeEventListener( + 'touchmove', properties.activateCooldown); + } map.getViewport().querySelector('canvas.ol-unselectable').addEventListener( - 'touchmove', activateCooldown); + 'touchmove', properties.activateCooldown); return function() { if (!cooldownActive) { properties.handleInteraction.apply(null, arguments); - activateCooldown(); + properties.activateCooldown(); } }; })(); @@ -1257,7 +1302,8 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt var esriBaseLayers = ['World_Imagery', 'World_Street_Map', 'World_Topo_Map', 'World_Physical_Map', 'World_Terrain_Base', - 'Ocean_Basemap', 'NatGeo_World_Map']; + 'Ocean_Basemap', 'NatGeo_World_Map', + 'World_Light_Gray_Base', 'World_Dark_Gray_Base']; var styleMap = { 'style': ol.style.Style, @@ -1357,9 +1403,10 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt case 'JSONP': case 'TopoJSON': case 'KML': - case 'WKT': + case 'WKT': return 'Vector'; case 'TileVector': + case 'MVT': return 'TileVector'; default: return 'Tile'; @@ -1397,6 +1444,7 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt var createSource = function(source, projection) { var oSource; + var pixelRatio; var url; var geojsonFormat = new ol.format.GeoJSON(); // used in various switch stmnts below @@ -1406,10 +1454,10 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt $log.error('[AngularJS - Openlayers] - MapBox layer requires the map id and the access token'); return; } - url = 'http://api.tiles.mapbox.com/v4/' + source.mapId + '/{z}/{x}/{y}.png?access_token=' + + url = 'https://api.tiles.mapbox.com/v4/' + source.mapId + '/{z}/{x}/{y}.png?access_token=' + source.accessToken; - var pixelRatio = window.devicePixelRatio; + pixelRatio = window.devicePixelRatio; if (pixelRatio > 1) { url = url.replace('.png', '@2x.png'); @@ -1417,9 +1465,10 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt oSource = new ol.source.XYZ({ url: url, + tileLoadFunction: source.tileLoadFunction, attributions: createAttribution(source), tilePixelRatio: pixelRatio > 1 ? 2 : 1, - wrapX: (source.wrapX === undefined) ? 1 : source.wrapX + wrapX: source.wrapX !== undefined ? source.wrapX : true }); break; case 'MapBoxStudio': @@ -1432,10 +1481,32 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt '/' + source.mapId + '/tiles/{z}/{x}/{y}?access_token=' + source.accessToken; + pixelRatio = window.devicePixelRatio; + + if (pixelRatio > 1) { + url = url.replace('{y}?access_token', '{y}@2x?access_token'); + } + oSource = new ol.source.XYZ({ url: url, + tileLoadFunction: source.tileLoadFunction, attributions: createAttribution(source), - tileSize: source.tileSize || [512, 512] + tilePixelRatio: pixelRatio > 1 ? 2 : 1, + tileSize: source.tileSize || [512, 512], + wrapX: source.wrapX !== undefined ? source.wrapX : true + }); + break; + case 'MVT': + if (!source.url) { + $log.error('[AngularJS - Openlayers] - MVT layer requires the source url'); + return; + } + oSource = new ol.source.VectorTile({ + attributions: source.attributions || '', + format: new ol.format.MVT(), + tileGrid: ol.tilegrid.createXYZ({maxZoom: source.maxZoom || 22}), + tilePixelRatio: source.tilePixelRatio || 16, + url: source.url }); break; case 'ImageWMS': @@ -1445,9 +1516,9 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt } oSource = new ol.source.ImageWMS({ url: source.url, + imageLoadFunction: source.imageLoadFunction, attributions: createAttribution(source), crossOrigin: (typeof source.crossOrigin === 'undefined') ? 'anonymous' : source.crossOrigin, - wrapX: (source.wrapX === undefined) ? 1 : source.wrapX, params: deepCopy(source.params), ratio: source.ratio }); @@ -1460,15 +1531,16 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt } var wmsConfiguration = { + tileLoadFunction: source.tileLoadFunction, crossOrigin: (typeof source.crossOrigin === 'undefined') ? 'anonymous' : source.crossOrigin, params: deepCopy(source.params), attributions: createAttribution(source), - wrapX: (source.wrapX === undefined) ? 1 : source.wrapX + wrapX: source.wrapX !== undefined ? source.wrapX : true }; - - if(source.projection){ + + if (source.projection) { wmsConfiguration.projection = new ol.proj.get(source.projection); - } + } if (source.serverType) { wmsConfiguration.serverType = source.serverType; @@ -1492,6 +1564,7 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt } var wmtsConfiguration = { + tileLoadFunction: source.tileLoadFunction, projection: projection, layer: source.layer, attributions: createAttribution(source), @@ -1504,8 +1577,8 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt resolutions: source.tileGrid.resolutions, matrixIds: source.tileGrid.matrixIds }), - wrapX: (source.wrapX === undefined) ? 1 : source.wrapX, - style: (source.style === 'undefined') ? 'normal' : source.style + style: (source.style === 'undefined') ? 'normal' : source.style, + wrapX: source.wrapX !== undefined ? source.wrapX : true }; if (isDefined(source.url)) { @@ -1521,8 +1594,9 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt case 'OSM': oSource = new ol.source.OSM({ + tileLoadFunction: source.tileLoadFunction, attributions: createAttribution(source), - wrapX: (source.wrapX === undefined) ? 1 : source.wrapX + wrapX: source.wrapX !== undefined ? source.wrapX : true }); if (source.url) { @@ -1538,10 +1612,11 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt var bingConfiguration = { key: source.key, + tileLoadFunction: source.tileLoadFunction, attributions: createAttribution(source), imagerySet: source.imagerySet ? source.imagerySet : bingImagerySets[0], culture: source.culture, - wrapX: (source.wrapX === undefined) ? 1 : source.wrapX + wrapX: source.wrapX !== undefined ? source.wrapX : true }; if (source.maxZoom) { @@ -1560,7 +1635,7 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt oSource = new ol.source.MapQuest({ attributions: createAttribution(source), layer: source.layer, - wrapX: (source.wrapX === undefined) ? 1 : source.wrapX + wrapX: source.wrapX !== undefined ? source.wrapX : true }); break; @@ -1572,12 +1647,30 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt } var _urlBase = 'http://services.arcgisonline.com/ArcGIS/rest/services/'; + if (source.layer === 'World_Light_Gray_Base' || source.layer === 'World_Dark_Gray_Base') { + _urlBase = _urlBase + 'Canvas/'; + } var _url = _urlBase + source.layer + '/MapServer/tile/{z}/{y}/{x}'; oSource = new ol.source.XYZ({ attributions: createAttribution(source), + tileLoadFunction: source.tileLoadFunction, url: _url, - wrapX: (source.wrapX === undefined) ? 1 : source.wrapX + wrapX: source.wrapX !== undefined ? source.wrapX : true + }); + + break; + + case 'TileArcGISRest': + if (!source.url) { + $log.error('[AngularJS - Openlayers] - TileArcGISRest Layer needs valid url'); + } + + oSource = new ol.source.TileArcGISRest({ + attributions: createAttribution(source), + tileLoadFunction: source.tileLoadFunction, + url: source.url, + wrapX: source.wrapX !== undefined ? source.wrapX : true }); break; @@ -1592,8 +1685,7 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt if (isDefined(source.url)) { oSource = new ol.source.Vector({ format: new ol.format.GeoJSON(), - url: source.url, - wrapX: (source.wrapX === undefined) ? 1 : source.wrapX + url: source.url }); } else { oSource = new ol.source.Vector(); @@ -1614,42 +1706,41 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt oSource.addFeatures(features); } - break; - case 'WKT': + case 'WKT': if (!(source.wkt || source.url)) { $log.error('[AngularJS - Openlayers] - You need a WKT ' + - 'property to add a GeoJSON layer.'); + 'property to add a GeoJSON layer.'); return; } if (isDefined(source.url)) { oSource = new ol.source.Vector({ format: new ol.format.WKT(), url: source.url, - wrapX: (source.wrapX === undefined) ? 1 : source.wrapX + wrapX: source.wrapX !== undefined ? source.wrapX : true }); } else { oSource = new ol.source.Vector(); - var featureProjection = projection; + var featureProjection = projection; var wktProjection; if (isDefined(source.wkt.projection)) { wktProjection = new ol.proj.get(source.wkt.projection); - } - else{ - wktProjection = projection; + } else { + wktProjection = projection; } var wktFormat = new ol.format.WKT(); - var wktFeatures = []; - for(var k = 0; k< source.wkt.object.length; k++){ - var feature = wktFormat.readFeature( - source.wkt.object[k].data, {dataProjection: wktProjection.getCode() ,featureProjection: featureProjection.getCode() }); - if(source.wkt.object[k].properties){ - feature.properties = source.wkt.object[k].properties; - } - wktFeatures.push(feature); - } - oSource.addFeatures(wktFeatures); + var wktFeatures = []; + for (var k = 0; k < source.wkt.object.length; k++) { + var feature = wktFormat.readFeature( + source.wkt.object[k].data, {dataProjection: wktProjection.getCode() , + featureProjection: featureProjection.getCode() }); + if (source.wkt.object[k].properties) { + feature.properties = source.wkt.object[k].properties; + } + wktFeatures.push(feature); + } + oSource.addFeatures(wktFeatures); } break; @@ -1673,7 +1764,6 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt $log(response); }); }, - wrapX: (source.wrapX === undefined) ? 1 : source.wrapX, projection: projection }); } @@ -1688,13 +1778,11 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt if (source.url) { oSource = new ol.source.Vector({ format: new ol.format.TopoJSON(), - url: source.url, - wrapX: (source.wrapX === undefined) ? 1 : source.wrapX + url: source.url }); } else { oSource = new ol.source.Vector(angular.extend(source.topojson, { - format: new ol.format.TopoJSON(), - wrapX: (source.wrapX === undefined) ? 1 : source.wrapX + format: new ol.format.TopoJSON() })); } break; @@ -1702,8 +1790,9 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt oSource = new ol.source.TileJSON({ url: source.url, attributions: createAttribution(source), + tileLoadFunction: source.tileLoadFunction, crossOrigin: 'anonymous', - wrapX: (source.wrapX === undefined) ? 1 : source.wrapX + wrapX: source.wrapX !== undefined ? source.wrapX : true }); break; @@ -1715,11 +1804,12 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt url: source.url, projection: projection, attributions: createAttribution(source), + tileLoadFunction: source.tileLoadFunction, format: source.format, tileGrid: new ol.tilegrid.createXYZ({ maxZoom: source.maxZoom || 19 }), - wrapX: (source.wrapX === undefined) ? 1 : source.wrapX + wrapX: source.wrapX !== undefined ? source.wrapX : true }); break; @@ -1731,6 +1821,7 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt url: source.url, maxExtent: source.maxExtent, attributions: createAttribution(source), + tileLoadFunction: source.tileLoadFunction, tileGrid: new ol.tilegrid.TileGrid({ origin: source.tileGrid.origin, resolutions: source.tileGrid.resolutions @@ -1749,13 +1840,14 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt return url; }, - wrapX: (source.wrapX === undefined) ? 1 : source.wrapX + wrapX: source.wrapX !== undefined ? source.wrapX : true }); break; case 'TileImage': oSource = new ol.source.TileImage({ url: source.url, attributions: createAttribution(source), + tileLoadFunction: source.tileLoadFunction, tileGrid: new ol.tilegrid.TileGrid({ origin: source.tileGrid.origin, // top left corner of the pixel projection's extent resolutions: source.tileGrid.resolutions @@ -1770,17 +1862,17 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt .replace('{y}', y.toString()); return url; }, - wrapX: (source.wrapX === undefined) ? 1 : source.wrapX + wrapX: source.wrapX !== undefined ? source.wrapX : true }); break; case 'KML': var extractStyles = source.extractStyles || false; oSource = new ol.source.Vector({ url: source.url, - format: new ol.format.KML(), - radius: source.radius, - extractStyles: extractStyles, - wrapX: (source.wrapX === undefined) ? 1 : source.wrapX + format: new ol.format.KML({ + extractStyles: extractStyles + }), + radius: source.radius }); break; case 'Stamen': @@ -1789,8 +1881,9 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt return; } oSource = new ol.source.Stamen({ + tileLoadFunction: source.tileLoadFunction, layer: source.layer, - wrapX: (source.wrapX === undefined) ? 1 : source.wrapX + wrapX: source.wrapX !== undefined ? source.wrapX : true }); break; case 'ImageStatic': @@ -1805,8 +1898,7 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt imageSize: source.imageSize, projection: projection, imageExtent: source.imageExtent ? source.imageExtent : projection.getExtent(), - imageLoadFunction: source.imageLoadFunction, - wrapX: (source.wrapX === undefined) ? 1 : source.wrapX + imageLoadFunction: source.imageLoadFunction }); break; case 'XYZ': @@ -1818,9 +1910,10 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt attributions: createAttribution(source), minZoom: source.minZoom, maxZoom: source.maxZoom, - wrapX: (source.wrapX === undefined) ? 1 : source.wrapX, projection: source.projection, - tileUrlFunction: source.tileUrlFunction + tileUrlFunction: source.tileUrlFunction, + tileLoadFunction: source.tileLoadFunction, + wrapX: source.wrapX !== undefined ? source.wrapX : true }); break; case 'Zoomify': @@ -1829,7 +1922,8 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt } oSource = new ol.source.Zoomify({ url: source.url, - size: source.imageSize + size: source.imageSize, + wrapX: source.wrapX !== undefined ? source.wrapX : true }); break; } @@ -2104,7 +2198,22 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt }); } - var layerConfig = { source: oSource }; + var layerConfig = {}; + + // copy over eventual properties set on the passed layerconfig which + // can later be retrieved via layer.get('propName'); + for (var property in layer) { + if (layer.hasOwnProperty(property) && + // ignore props like source or those angular might add (starting with $) + !property.startsWith('$') && + !property.startsWith('source') && + !property.startsWith('style') + ) { + layerConfig[property] = layer[property]; + } + } + + layerConfig.source = oSource; // ol.layer.Layer configuration options if (isDefinedAndNotNull(layer.opacity)) { @@ -2125,6 +2234,9 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt if (isDefinedAndNotNull(layer.maxResolution)) { layerConfig.maxResolution = layer.maxResolution; } + if (isDefinedAndNotNull(layer.style) && type === 'TileVector') { + layerConfig.style = layer.style; + } switch (type) { case 'Image': @@ -2261,6 +2373,7 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt while (layers.getLength() < index) { var nullLayer = new ol.layer.Image(); nullLayer.index = layers.getLength(); // add index which will be equal to the length in this case + nullLayer.name = '(null-layer)'; // we need a marker somehow layers.push(nullLayer); } layer.index = index; @@ -2268,9 +2381,11 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt } else { layer.index = index; layers.insertAt(layer.index, layer); + + // remove eventual null layers for (var i = index + 1; i < layers.getLength(); i++) { var l = layers.item(i); - if (l === null) { + if (l.name === '(null-layer)') { layers.removeAt(i); break; } else { diff --git a/dist/angular-openlayers-directive.min.js b/dist/angular-openlayers-directive.min.js index 7de455e5..b437b287 100644 --- a/dist/angular-openlayers-directive.min.js +++ b/dist/angular-openlayers-directive.min.js @@ -27,6 +27,6 @@ * @authors https://github.com/tombatossals/angular-openlayers-directive/graphs/contributors */ -/*! angular-openlayers-directive 22-07-2016 */ -!function(a,b){if("function"==typeof require&&"object"==typeof exports){var c=require("openlayers-prebuilt");require("angular-sanitize");exports.angularOpenlayersDirective=b(c)}else"function"==typeof define&&define.amd?define(["ol"],function(c){return a.angularOpenlayersDirective=b(c)}):a.angularOpenlayersDirective=b(a.ol)}(this,function(a){return angular.module("openlayers-directive",["ngSanitize"]).directive("openlayers",["$log","$q","$compile","olHelpers","olMapDefaults","olData",function(b,c,d,e,f,g){return{restrict:"EA",transclude:!0,replace:!0,scope:{center:"=olCenter",defaults:"=olDefaults",view:"=olView",events:"=olEvents"},template:'
',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id)}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}});var w=f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})});r.$on("$destroy",function(){f.unByKey(w)})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)});var f=e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})});g.$on("$destroy",function(){a.unByKey(f)})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope();i.getMap().then(function(b){var d=e.getControlClasses,i=d();return a.$on("$destroy",function(){b.removeControl(f)}),h(a.properties)&&h(a.properties.control)?(f=a.properties.control,void b.addControl(f)):void(c.name&&(h(a.properties)&&(g=a.properties),f=new i[c.name](g),b.addControl(f)))})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return e.on("pointerdown",j),e.on("pointerup",j),e.on("pointerdrag",j),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e)}),k(c.properties)?void c.$watch("properties",function(d){if(e.getViewport().removeEventListener("mousemove",d.handleInteraction),e.getViewport().removeEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",d.handleTapInteraction),e.getViewport().removeEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",d.removeAllOverlays),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){function a(){c=!0,b&&clearTimeout(b),b=setTimeout(function(){c=!1,b=null},500)}var b,c=!1;return e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",a),function(){c||(d.handleInteraction.apply(null,arguments),a())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){var d=c(a,b);a[d].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d,e=c(a,b);return d=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:f(a,b)};this.setMap=function(a,b){var c=f(d,b);c.resolve(a),e(d,b)},this.getMap=function(a){var b=g(d,a);return b.promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function y(a,b){var c;if(b?c=a[b]:(b="style",c=a),"style"===b&&a instanceof Function)return a;if(!(c instanceof Object))return c;var d;if("[object Object]"===Object.prototype.toString.call(c)){d={};var e=l[b];if(e&&c instanceof e)return c;Object.getOwnPropertyNames(c).forEach(function(a,f,g){var h=l[a];return e&&h&&h.prototype instanceof l[b]?(console.assert(1===g.length,"Extra parameters for "+b),d=y(c,a),m(d,h)):(d[a]=y(c,a),void("text"!==a&&"string"!=typeof d[a]&&(d[a]=m(d[a],l[a]))))})}else d=c;return m(d,l[b])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":return"Vector";case"TileVector":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g,i,l=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");i="http://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken;var m=window.devicePixelRatio;m>1&&(i=i.replace(".png","@2x.png")),g=new a.source.XYZ({url:i,attributions:t(b),tilePixelRatio:m>1?2:1,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");i="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,g=new a.source.XYZ({url:i,attributions:t(b),tileSize:b.tileSize||[512,512]});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,attributions:t(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,wrapX:void 0===b.wrapX?1:b.wrapX,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b),wrapX:void 0===b.wrapX?1:b.wrapX};b.projection&&(n.projection=new a.proj.get(b.projection)),b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),wrapX:void 0===b.wrapX?1:b.wrapX,style:"undefined"===b.style?"normal":b.style};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({attributions:t(b),wrapX:void 0===b.wrapX?1:b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX?1:b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="http://services.arcgisonline.com/ArcGIS/rest/services/",u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),url:u,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=l.readFeatures(b.geojson.object,{featureProjection:w.getCode(),dataProjection:v.getCode()});g.addFeatures(x)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var y,z=f;y=e(b.wkt.projection)?new a.proj.get(b.wkt.projection):f;for(var A=new a.format.WKT,B=[],C=0;Cd||0>e)return"";var f=b.url+c+"/"+d+"/"+e+".png";return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileImage":g=new a.source.TileImage({url:b.url,attributions:t(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=-a[2]-1,f=b.url.replace("{z}",c.toString()).replace("{x}",d.toString()).replace("{y}",e.toString());return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"KML":var E=b.extractStyles||!1;g=new a.source.Vector({url:b.url,format:new a.format.KML,radius:b.radius,extractStyles:E,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"Stamen":if(!b.layer||!q(b.layer))return void c.error("[AngularJS - Openlayers] - You need a valid Stamen layer.");g=new a.source.Stamen({layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageStatic":if(!b.url||!angular.isArray(b.imageSize)||2!==b.imageSize.length)return void c.error("[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.");g=new a.source.ImageStatic({url:b.url,attributions:t(b),imageSize:b.imageSize,projection:f,imageExtent:b.imageExtent?b.imageExtent:f.getExtent(),imageLoadFunction:b.imageLoadFunction,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"XYZ":b.url||b.tileUrlFunction||c.error("[AngularJS - Openlayers] - XYZ Layer needs valid url or tileUrlFunction properties"),g=new a.source.XYZ({url:b.url,attributions:t(b),minZoom:b.minZoom,maxZoom:b.maxZoom,wrapX:void 0===b.wrapX?1:b.wrapX,projection:b.projection,tileUrlFunction:b.tileUrlFunction});break;case"Zoomify":b.url&&angular.isArray(b.imageSize)&&2===b.imageSize.length||c.error("[AngularJS - Openlayers] - Zoomify Layer needs valid url and imageSize properties"),g=new a.source.Zoomify({url:b.url,size:b.imageSize})}return g||c.warn('[AngularJS - Openlayers] - No source could be found for type "'+b.type+'"'),g},s=function(a){var b=a;if(a&&"object"==typeof a){b="[object Array]"===Object.prototype.toString.call(a)?[]:{};for(var c in a)b[c]=s(a[c])}return b},t=function(b){var c=[];return e(b.attribution)&&c.unshift(new a.Attribution({html:b.attribution})),c},u=function(b){var c=new a.layer.Group;return c.set("name",b),c},v=function(b,c){var d;return angular.forEach(b,function(b){return b instanceof a.layer.Group&&b.get("name")===c?void(d=b):void 0}),d},w=function(a,b){for(var c,d=0;d',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id)}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(h.olCenter.search("-")!==-1)return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}});var w=f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})});r.$on("$destroy",function(){f.unByKey(w)})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)});var f=e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})});g.$on("$destroy",function(){a.unByKey(f)})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope(),j=e.getControlClasses,k=j();i.getMap().then(function(b){function d(a){a&&a.control?(f&&b.removeControl(f),f=a.control,b.addControl(f)):c.name&&(h(a)&&(g=a),f&&b.removeControl(f),f=new k[c.name](g),b.addControl(f))}a.$on("$destroy",function(){b.removeControl(f)}),a.$watch("properties",function(a){h(a)&&d(a)}),d(a.properties)})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(f===-1){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(e===-1)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(g===-1)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e].markerLayer,delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(){c.properties&&(e.getViewport().removeEventListener("mousemove",c.properties.handleInteraction),e.getViewport().removeEventListener("click",c.properties.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",c.properties.handleTapInteraction),e.getViewport().removeEventListener("mousemove",c.properties.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",c.properties.removeAllOverlays),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",c.properties.activateCooldown))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return c.handleDrag=function(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))},e.on("pointerdown",c.handleDrag),e.on("pointerup",c.handleDrag),e.on("pointerdrag",c.handleDrag),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e),e.un("pointerdown",c.handleDrag),e.un("pointerup",c.handleDrag),e.un("pointerdrag",c.handleDrag),j()}),k(c.properties)?void c.$watch("properties",function(d){if(j(),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){var a,b=!1;return d.activateCooldown=function(){b=!0,a&&clearTimeout(a),a=setTimeout(function(){b=!1,a=null},500)},d.activateCooldown&&e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",d.activateCooldown),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",d.activateCooldown),function(){b||(d.handleInteraction.apply(null,arguments),d.activateCooldown())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){var d=c(a,b);a[d].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d,e=c(a,b);return d=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:f(a,b)};this.setMap=function(a,b){var c=f(d,b);c.resolve(a),e(d,b)},this.getMap=function(a){var b=g(d,a);return b.promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map","World_Light_Gray_Base","World_Dark_Gray_Base"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function a(b,c){var d;if(c?d=b[c]:(c="style",d=b),"style"===c&&b instanceof Function)return b;if(!(d instanceof Object))return d;var e;if("[object Object]"===Object.prototype.toString.call(d)){e={};var f=l[c];if(f&&d instanceof f)return d;Object.getOwnPropertyNames(d).forEach(function(b,g,h){var i=l[b];return f&&i&&i.prototype instanceof l[c]?(console.assert(1===h.length,"Extra parameters for "+c),e=a(d,b),m(e,i)):(e[b]=a(d,b),void("text"!==b&&"string"!=typeof e[b]&&(e[b]=m(e[b],l[b]))))})}else e=d;return m(e,l[c])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":return"Vector";case"TileVector":case"MVT":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return["watercolor","terrain","toner"].indexOf(a)!==-1},r=function(b,f){var g,i,l,m=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");l="https://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace(".png","@2x.png")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,wrapX:void 0===b.wrapX||b.wrapX});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");l="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace("{y}?access_token","{y}@2x?access_token")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,tileSize:b.tileSize||[512,512],wrapX:void 0===b.wrapX||b.wrapX});break;case"MVT":if(!b.url)return void c.error("[AngularJS - Openlayers] - MVT layer requires the source url");g=new a.source.VectorTile({attributions:b.attributions||"",format:new a.format.MVT,tileGrid:a.tilegrid.createXYZ({maxZoom:b.maxZoom||22}),tilePixelRatio:b.tilePixelRatio||16,url:b.url});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,imageLoadFunction:b.imageLoadFunction,attributions:t(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={tileLoadFunction:b.tileLoadFunction,crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX};b.projection&&(n.projection=new a.proj.get(b.projection)),b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={tileLoadFunction:b.tileLoadFunction,projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),style:"undefined"===b.style?"normal":b.style,wrapX:void 0===b.wrapX||b.wrapX};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({tileLoadFunction:b.tileLoadFunction,attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,tileLoadFunction:b.tileLoadFunction,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX||b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||j.indexOf(b.layer)===-1)return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer,wrapX:void 0===b.wrapX||b.wrapX});break;case"EsriBaseMaps":if(!b.layer||k.indexOf(b.layer)===-1)return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="http://services.arcgisonline.com/ArcGIS/rest/services/";"World_Light_Gray_Base"!==b.layer&&"World_Dark_Gray_Base"!==b.layer||(r+="Canvas/");var u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:u,wrapX:void 0===b.wrapX||b.wrapX});break;case"TileArcGISRest":b.url||c.error("[AngularJS - Openlayers] - TileArcGISRest Layer needs valid url"),g=new a.source.TileArcGISRest({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=m.readFeatures(b.geojson.object,{featureProjection:w.getCode(),dataProjection:v.getCode()});g.addFeatures(x)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});else{g=new a.source.Vector;var y,z=f;y=e(b.wkt.projection)?new a.proj.get(b.wkt.projection):f;for(var A=new a.format.WKT,B=[],C=0;C',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id)}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}});var w=f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})});r.$on("$destroy",function(){f.unByKey(w)})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)});var f=e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})});g.$on("$destroy",function(){a.unByKey(f)})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope();i.getMap().then(function(b){var d=e.getControlClasses,i=d();return a.$on("$destroy",function(){b.removeControl(f)}),h(a.properties)&&h(a.properties.control)?(f=a.properties.control,void b.addControl(f)):void(c.name&&(h(a.properties)&&(g=a.properties),f=new i[c.name](g),b.addControl(f)))})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return e.on("pointerdown",j),e.on("pointerup",j),e.on("pointerdrag",j),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e)}),k(c.properties)?void c.$watch("properties",function(d){if(e.getViewport().removeEventListener("mousemove",d.handleInteraction),e.getViewport().removeEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",d.handleTapInteraction),e.getViewport().removeEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",d.removeAllOverlays),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){function a(){c=!0,b&&clearTimeout(b),b=setTimeout(function(){c=!1,b=null},500)}var b,c=!1;return e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",a),function(){c||(d.handleInteraction.apply(null,arguments),a())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){var d=c(a,b);a[d].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d,e=c(a,b);return d=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:f(a,b)};this.setMap=function(a,b){var c=f(d,b);c.resolve(a),e(d,b)},this.getMap=function(a){var b=g(d,a);return b.promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function y(a,b){var c;if(b?c=a[b]:(b="style",c=a),"style"===b&&a instanceof Function)return a;if(!(c instanceof Object))return c;var d;if("[object Object]"===Object.prototype.toString.call(c)){d={};var e=l[b];if(e&&c instanceof e)return c;Object.getOwnPropertyNames(c).forEach(function(a,f,g){var h=l[a];return e&&h&&h.prototype instanceof l[b]?(console.assert(1===g.length,"Extra parameters for "+b),d=y(c,a),m(d,h)):(d[a]=y(c,a),void("text"!==a&&"string"!=typeof d[a]&&(d[a]=m(d[a],l[a]))))})}else d=c;return m(d,l[b])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":return"Vector";case"TileVector":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g,i,l=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");i="http://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken;var m=window.devicePixelRatio;m>1&&(i=i.replace(".png","@2x.png")),g=new a.source.XYZ({url:i,attributions:t(b),tilePixelRatio:m>1?2:1,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");i="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,g=new a.source.XYZ({url:i,attributions:t(b),tileSize:b.tileSize||[512,512]});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,attributions:t(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,wrapX:void 0===b.wrapX?1:b.wrapX,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b),wrapX:void 0===b.wrapX?1:b.wrapX};b.projection&&(n.projection=new a.proj.get(b.projection)),b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),wrapX:void 0===b.wrapX?1:b.wrapX,style:"undefined"===b.style?"normal":b.style};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({attributions:t(b),wrapX:void 0===b.wrapX?1:b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX?1:b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="http://services.arcgisonline.com/ArcGIS/rest/services/",u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),url:u,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=l.readFeatures(b.geojson.object,{featureProjection:w.getCode(),dataProjection:v.getCode()});g.addFeatures(x)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX?1:b.wrapX});else{g=new a.source.Vector;var y,z=f;y=e(b.wkt.projection)?new a.proj.get(b.wkt.projection):f;for(var A=new a.format.WKT,B=[],C=0;Cd||0>e)return"";var f=b.url+c+"/"+d+"/"+e+".png";return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"TileImage":g=new a.source.TileImage({url:b.url,attributions:t(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=-a[2]-1,f=b.url.replace("{z}",c.toString()).replace("{x}",d.toString()).replace("{y}",e.toString());return f},wrapX:void 0===b.wrapX?1:b.wrapX});break;case"KML":var E=b.extractStyles||!1;g=new a.source.Vector({url:b.url,format:new a.format.KML,radius:b.radius,extractStyles:E,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"Stamen":if(!b.layer||!q(b.layer))return void c.error("[AngularJS - Openlayers] - You need a valid Stamen layer.");g=new a.source.Stamen({layer:b.layer,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"ImageStatic":if(!b.url||!angular.isArray(b.imageSize)||2!==b.imageSize.length)return void c.error("[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.");g=new a.source.ImageStatic({url:b.url,attributions:t(b),imageSize:b.imageSize,projection:f,imageExtent:b.imageExtent?b.imageExtent:f.getExtent(),imageLoadFunction:b.imageLoadFunction,wrapX:void 0===b.wrapX?1:b.wrapX});break;case"XYZ":b.url||b.tileUrlFunction||c.error("[AngularJS - Openlayers] - XYZ Layer needs valid url or tileUrlFunction properties"),g=new a.source.XYZ({url:b.url,attributions:t(b),minZoom:b.minZoom,maxZoom:b.maxZoom,wrapX:void 0===b.wrapX?1:b.wrapX,projection:b.projection,tileUrlFunction:b.tileUrlFunction});break;case"Zoomify":b.url&&angular.isArray(b.imageSize)&&2===b.imageSize.length||c.error("[AngularJS - Openlayers] - Zoomify Layer needs valid url and imageSize properties"),g=new a.source.Zoomify({url:b.url,size:b.imageSize})}return g||c.warn('[AngularJS - Openlayers] - No source could be found for type "'+b.type+'"'),g},s=function(a){var b=a;if(a&&"object"==typeof a){b="[object Array]"===Object.prototype.toString.call(a)?[]:{};for(var c in a)b[c]=s(a[c])}return b},t=function(b){var c=[];return e(b.attribution)&&c.unshift(new a.Attribution({html:b.attribution})),c},u=function(b){var c=new a.layer.Group;return c.set("name",b),c},v=function(b,c){var d;return angular.forEach(b,function(b){return b instanceof a.layer.Group&&b.get("name")===c?void(d=b):void 0}),d},w=function(a,b){for(var c,d=0;d',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id)}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(h.olCenter.search("-")!==-1)return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}});var w=f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})});r.$on("$destroy",function(){f.unByKey(w)})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)});var f=e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})});g.$on("$destroy",function(){a.unByKey(f)})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope(),j=e.getControlClasses,k=j();i.getMap().then(function(b){function d(a){a&&a.control?(f&&b.removeControl(f),f=a.control,b.addControl(f)):c.name&&(h(a)&&(g=a),f&&b.removeControl(f),f=new k[c.name](g),b.addControl(f))}a.$on("$destroy",function(){b.removeControl(f)}),a.$watch("properties",function(a){h(a)&&d(a)}),d(a.properties)})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(f===-1){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(e===-1)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(g===-1)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e].markerLayer,delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(){c.properties&&(e.getViewport().removeEventListener("mousemove",c.properties.handleInteraction),e.getViewport().removeEventListener("click",c.properties.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",c.properties.handleTapInteraction),e.getViewport().removeEventListener("mousemove",c.properties.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",c.properties.removeAllOverlays),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",c.properties.activateCooldown))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return c.handleDrag=function(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))},e.on("pointerdown",c.handleDrag),e.on("pointerup",c.handleDrag),e.on("pointerdrag",c.handleDrag),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e),e.un("pointerdown",c.handleDrag),e.un("pointerup",c.handleDrag),e.un("pointerdrag",c.handleDrag),j()}),k(c.properties)?void c.$watch("properties",function(d){if(j(),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){var a,b=!1;return d.activateCooldown=function(){b=!0,a&&clearTimeout(a),a=setTimeout(function(){b=!1,a=null},500)},d.activateCooldown&&e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",d.activateCooldown),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",d.activateCooldown),function(){b||(d.handleInteraction.apply(null,arguments),d.activateCooldown())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){var d=c(a,b);a[d].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d,e=c(a,b);return d=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:f(a,b)};this.setMap=function(a,b){var c=f(d,b);c.resolve(a),e(d,b)},this.getMap=function(a){var b=g(d,a);return b.promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map","World_Light_Gray_Base","World_Dark_Gray_Base"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function a(b,c){var d;if(c?d=b[c]:(c="style",d=b),"style"===c&&b instanceof Function)return b;if(!(d instanceof Object))return d;var e;if("[object Object]"===Object.prototype.toString.call(d)){e={};var f=l[c];if(f&&d instanceof f)return d;Object.getOwnPropertyNames(d).forEach(function(b,g,h){var i=l[b];return f&&i&&i.prototype instanceof l[c]?(console.assert(1===h.length,"Extra parameters for "+c),e=a(d,b),m(e,i)):(e[b]=a(d,b),void("text"!==b&&"string"!=typeof e[b]&&(e[b]=m(e[b],l[b]))))})}else e=d;return m(e,l[c])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":return"Vector";case"TileVector":case"MVT":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return["watercolor","terrain","toner"].indexOf(a)!==-1},r=function(b,f){var g,i,l,m=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");l="https://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace(".png","@2x.png")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,wrapX:void 0===b.wrapX||b.wrapX});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");l="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace("{y}?access_token","{y}@2x?access_token")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,tileSize:b.tileSize||[512,512],wrapX:void 0===b.wrapX||b.wrapX});break;case"MVT":if(!b.url)return void c.error("[AngularJS - Openlayers] - MVT layer requires the source url");g=new a.source.VectorTile({attributions:b.attributions||"",format:new a.format.MVT,tileGrid:a.tilegrid.createXYZ({maxZoom:b.maxZoom||22}),tilePixelRatio:b.tilePixelRatio||16,url:b.url});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,imageLoadFunction:b.imageLoadFunction,attributions:t(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={tileLoadFunction:b.tileLoadFunction,crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX};b.projection&&(n.projection=new a.proj.get(b.projection)),b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={tileLoadFunction:b.tileLoadFunction,projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),style:"undefined"===b.style?"normal":b.style,wrapX:void 0===b.wrapX||b.wrapX};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({tileLoadFunction:b.tileLoadFunction,attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,tileLoadFunction:b.tileLoadFunction,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX||b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||j.indexOf(b.layer)===-1)return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer,wrapX:void 0===b.wrapX||b.wrapX});break;case"EsriBaseMaps":if(!b.layer||k.indexOf(b.layer)===-1)return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="http://services.arcgisonline.com/ArcGIS/rest/services/";"World_Light_Gray_Base"!==b.layer&&"World_Dark_Gray_Base"!==b.layer||(r+="Canvas/");var u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:u,wrapX:void 0===b.wrapX||b.wrapX});break;case"TileArcGISRest":b.url||c.error("[AngularJS - Openlayers] - TileArcGISRest Layer needs valid url"),g=new a.source.TileArcGISRest({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=m.readFeatures(b.geojson.object,{featureProjection:w.getCode(),dataProjection:v.getCode()});g.addFeatures(x)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});else{g=new a.source.Vector;var y,z=f;y=e(b.wkt.projection)?new a.proj.get(b.wkt.projection):f;for(var A=new a.format.WKT,B=[],C=0;C 1 ? 2 : 1, - wrapX: (source.wrapX === undefined) ? 1 : source.wrapX + wrapX: source.wrapX !== undefined ? source.wrapX : true }); break; case 'MapBoxStudio': @@ -1432,10 +1481,32 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ '/' + source.mapId + '/tiles/{z}/{x}/{y}?access_token=' + source.accessToken; + pixelRatio = window.devicePixelRatio; + + if (pixelRatio > 1) { + url = url.replace('{y}?access_token', '{y}@2x?access_token'); + } + oSource = new ol.source.XYZ({ url: url, + tileLoadFunction: source.tileLoadFunction, attributions: createAttribution(source), - tileSize: source.tileSize || [512, 512] + tilePixelRatio: pixelRatio > 1 ? 2 : 1, + tileSize: source.tileSize || [512, 512], + wrapX: source.wrapX !== undefined ? source.wrapX : true + }); + break; + case 'MVT': + if (!source.url) { + $log.error('[AngularJS - Openlayers] - MVT layer requires the source url'); + return; + } + oSource = new ol.source.VectorTile({ + attributions: source.attributions || '', + format: new ol.format.MVT(), + tileGrid: ol.tilegrid.createXYZ({maxZoom: source.maxZoom || 22}), + tilePixelRatio: source.tilePixelRatio || 16, + url: source.url }); break; case 'ImageWMS': @@ -1445,9 +1516,9 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ } oSource = new ol.source.ImageWMS({ url: source.url, + imageLoadFunction: source.imageLoadFunction, attributions: createAttribution(source), crossOrigin: (typeof source.crossOrigin === 'undefined') ? 'anonymous' : source.crossOrigin, - wrapX: (source.wrapX === undefined) ? 1 : source.wrapX, params: deepCopy(source.params), ratio: source.ratio }); @@ -1460,15 +1531,16 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ } var wmsConfiguration = { + tileLoadFunction: source.tileLoadFunction, crossOrigin: (typeof source.crossOrigin === 'undefined') ? 'anonymous' : source.crossOrigin, params: deepCopy(source.params), attributions: createAttribution(source), - wrapX: (source.wrapX === undefined) ? 1 : source.wrapX + wrapX: source.wrapX !== undefined ? source.wrapX : true }; - - if(source.projection){ + + if (source.projection) { wmsConfiguration.projection = new ol.proj.get(source.projection); - } + } if (source.serverType) { wmsConfiguration.serverType = source.serverType; @@ -1492,6 +1564,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ } var wmtsConfiguration = { + tileLoadFunction: source.tileLoadFunction, projection: projection, layer: source.layer, attributions: createAttribution(source), @@ -1504,8 +1577,8 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ resolutions: source.tileGrid.resolutions, matrixIds: source.tileGrid.matrixIds }), - wrapX: (source.wrapX === undefined) ? 1 : source.wrapX, - style: (source.style === 'undefined') ? 'normal' : source.style + style: (source.style === 'undefined') ? 'normal' : source.style, + wrapX: source.wrapX !== undefined ? source.wrapX : true }; if (isDefined(source.url)) { @@ -1521,8 +1594,9 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ case 'OSM': oSource = new ol.source.OSM({ + tileLoadFunction: source.tileLoadFunction, attributions: createAttribution(source), - wrapX: (source.wrapX === undefined) ? 1 : source.wrapX + wrapX: source.wrapX !== undefined ? source.wrapX : true }); if (source.url) { @@ -1538,10 +1612,11 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ var bingConfiguration = { key: source.key, + tileLoadFunction: source.tileLoadFunction, attributions: createAttribution(source), imagerySet: source.imagerySet ? source.imagerySet : bingImagerySets[0], culture: source.culture, - wrapX: (source.wrapX === undefined) ? 1 : source.wrapX + wrapX: source.wrapX !== undefined ? source.wrapX : true }; if (source.maxZoom) { @@ -1560,7 +1635,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ oSource = new ol.source.MapQuest({ attributions: createAttribution(source), layer: source.layer, - wrapX: (source.wrapX === undefined) ? 1 : source.wrapX + wrapX: source.wrapX !== undefined ? source.wrapX : true }); break; @@ -1572,12 +1647,30 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ } var _urlBase = 'http://services.arcgisonline.com/ArcGIS/rest/services/'; + if (source.layer === 'World_Light_Gray_Base' || source.layer === 'World_Dark_Gray_Base') { + _urlBase = _urlBase + 'Canvas/'; + } var _url = _urlBase + source.layer + '/MapServer/tile/{z}/{y}/{x}'; oSource = new ol.source.XYZ({ attributions: createAttribution(source), + tileLoadFunction: source.tileLoadFunction, url: _url, - wrapX: (source.wrapX === undefined) ? 1 : source.wrapX + wrapX: source.wrapX !== undefined ? source.wrapX : true + }); + + break; + + case 'TileArcGISRest': + if (!source.url) { + $log.error('[AngularJS - Openlayers] - TileArcGISRest Layer needs valid url'); + } + + oSource = new ol.source.TileArcGISRest({ + attributions: createAttribution(source), + tileLoadFunction: source.tileLoadFunction, + url: source.url, + wrapX: source.wrapX !== undefined ? source.wrapX : true }); break; @@ -1592,8 +1685,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ if (isDefined(source.url)) { oSource = new ol.source.Vector({ format: new ol.format.GeoJSON(), - url: source.url, - wrapX: (source.wrapX === undefined) ? 1 : source.wrapX + url: source.url }); } else { oSource = new ol.source.Vector(); @@ -1614,42 +1706,41 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ oSource.addFeatures(features); } - break; - case 'WKT': + case 'WKT': if (!(source.wkt || source.url)) { $log.error('[AngularJS - Openlayers] - You need a WKT ' + - 'property to add a GeoJSON layer.'); + 'property to add a GeoJSON layer.'); return; } if (isDefined(source.url)) { oSource = new ol.source.Vector({ format: new ol.format.WKT(), url: source.url, - wrapX: (source.wrapX === undefined) ? 1 : source.wrapX + wrapX: source.wrapX !== undefined ? source.wrapX : true }); } else { oSource = new ol.source.Vector(); - var featureProjection = projection; + var featureProjection = projection; var wktProjection; if (isDefined(source.wkt.projection)) { wktProjection = new ol.proj.get(source.wkt.projection); - } - else{ - wktProjection = projection; + } else { + wktProjection = projection; } var wktFormat = new ol.format.WKT(); - var wktFeatures = []; - for(var k = 0; k< source.wkt.object.length; k++){ - var feature = wktFormat.readFeature( - source.wkt.object[k].data, {dataProjection: wktProjection.getCode() ,featureProjection: featureProjection.getCode() }); - if(source.wkt.object[k].properties){ - feature.properties = source.wkt.object[k].properties; - } - wktFeatures.push(feature); - } - oSource.addFeatures(wktFeatures); + var wktFeatures = []; + for (var k = 0; k < source.wkt.object.length; k++) { + var feature = wktFormat.readFeature( + source.wkt.object[k].data, {dataProjection: wktProjection.getCode() , + featureProjection: featureProjection.getCode() }); + if (source.wkt.object[k].properties) { + feature.properties = source.wkt.object[k].properties; + } + wktFeatures.push(feature); + } + oSource.addFeatures(wktFeatures); } break; @@ -1673,7 +1764,6 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ $log(response); }); }, - wrapX: (source.wrapX === undefined) ? 1 : source.wrapX, projection: projection }); } @@ -1688,13 +1778,11 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ if (source.url) { oSource = new ol.source.Vector({ format: new ol.format.TopoJSON(), - url: source.url, - wrapX: (source.wrapX === undefined) ? 1 : source.wrapX + url: source.url }); } else { oSource = new ol.source.Vector(angular.extend(source.topojson, { - format: new ol.format.TopoJSON(), - wrapX: (source.wrapX === undefined) ? 1 : source.wrapX + format: new ol.format.TopoJSON() })); } break; @@ -1702,8 +1790,9 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ oSource = new ol.source.TileJSON({ url: source.url, attributions: createAttribution(source), + tileLoadFunction: source.tileLoadFunction, crossOrigin: 'anonymous', - wrapX: (source.wrapX === undefined) ? 1 : source.wrapX + wrapX: source.wrapX !== undefined ? source.wrapX : true }); break; @@ -1715,11 +1804,12 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ url: source.url, projection: projection, attributions: createAttribution(source), + tileLoadFunction: source.tileLoadFunction, format: source.format, tileGrid: new ol.tilegrid.createXYZ({ maxZoom: source.maxZoom || 19 }), - wrapX: (source.wrapX === undefined) ? 1 : source.wrapX + wrapX: source.wrapX !== undefined ? source.wrapX : true }); break; @@ -1731,6 +1821,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ url: source.url, maxExtent: source.maxExtent, attributions: createAttribution(source), + tileLoadFunction: source.tileLoadFunction, tileGrid: new ol.tilegrid.TileGrid({ origin: source.tileGrid.origin, resolutions: source.tileGrid.resolutions @@ -1749,13 +1840,14 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ return url; }, - wrapX: (source.wrapX === undefined) ? 1 : source.wrapX + wrapX: source.wrapX !== undefined ? source.wrapX : true }); break; case 'TileImage': oSource = new ol.source.TileImage({ url: source.url, attributions: createAttribution(source), + tileLoadFunction: source.tileLoadFunction, tileGrid: new ol.tilegrid.TileGrid({ origin: source.tileGrid.origin, // top left corner of the pixel projection's extent resolutions: source.tileGrid.resolutions @@ -1770,17 +1862,17 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ .replace('{y}', y.toString()); return url; }, - wrapX: (source.wrapX === undefined) ? 1 : source.wrapX + wrapX: source.wrapX !== undefined ? source.wrapX : true }); break; case 'KML': var extractStyles = source.extractStyles || false; oSource = new ol.source.Vector({ url: source.url, - format: new ol.format.KML(), - radius: source.radius, - extractStyles: extractStyles, - wrapX: (source.wrapX === undefined) ? 1 : source.wrapX + format: new ol.format.KML({ + extractStyles: extractStyles + }), + radius: source.radius }); break; case 'Stamen': @@ -1789,8 +1881,9 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ return; } oSource = new ol.source.Stamen({ + tileLoadFunction: source.tileLoadFunction, layer: source.layer, - wrapX: (source.wrapX === undefined) ? 1 : source.wrapX + wrapX: source.wrapX !== undefined ? source.wrapX : true }); break; case 'ImageStatic': @@ -1805,8 +1898,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ imageSize: source.imageSize, projection: projection, imageExtent: source.imageExtent ? source.imageExtent : projection.getExtent(), - imageLoadFunction: source.imageLoadFunction, - wrapX: (source.wrapX === undefined) ? 1 : source.wrapX + imageLoadFunction: source.imageLoadFunction }); break; case 'XYZ': @@ -1818,9 +1910,10 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ attributions: createAttribution(source), minZoom: source.minZoom, maxZoom: source.maxZoom, - wrapX: (source.wrapX === undefined) ? 1 : source.wrapX, projection: source.projection, - tileUrlFunction: source.tileUrlFunction + tileUrlFunction: source.tileUrlFunction, + tileLoadFunction: source.tileLoadFunction, + wrapX: source.wrapX !== undefined ? source.wrapX : true }); break; case 'Zoomify': @@ -1829,7 +1922,8 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ } oSource = new ol.source.Zoomify({ url: source.url, - size: source.imageSize + size: source.imageSize, + wrapX: source.wrapX !== undefined ? source.wrapX : true }); break; } @@ -2104,7 +2198,22 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ }); } - var layerConfig = { source: oSource }; + var layerConfig = {}; + + // copy over eventual properties set on the passed layerconfig which + // can later be retrieved via layer.get('propName'); + for (var property in layer) { + if (layer.hasOwnProperty(property) && + // ignore props like source or those angular might add (starting with $) + !property.startsWith('$') && + !property.startsWith('source') && + !property.startsWith('style') + ) { + layerConfig[property] = layer[property]; + } + } + + layerConfig.source = oSource; // ol.layer.Layer configuration options if (isDefinedAndNotNull(layer.opacity)) { @@ -2125,6 +2234,9 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ if (isDefinedAndNotNull(layer.maxResolution)) { layerConfig.maxResolution = layer.maxResolution; } + if (isDefinedAndNotNull(layer.style) && type === 'TileVector') { + layerConfig.style = layer.style; + } switch (type) { case 'Image': @@ -2261,6 +2373,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ while (layers.getLength() < index) { var nullLayer = new ol.layer.Image(); nullLayer.index = layers.getLength(); // add index which will be equal to the length in this case + nullLayer.name = '(null-layer)'; // we need a marker somehow layers.push(nullLayer); } layer.index = index; @@ -2268,9 +2381,11 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ } else { layer.index = index; layers.insertAt(layer.index, layer); + + // remove eventual null layers for (var i = index + 1; i < layers.getLength(); i++) { var l = layers.item(i); - if (l === null) { + if (l.name === '(null-layer)') { layers.removeAt(i); break; } else { From d87a57692087016e20ee0c065d144959c159e441 Mon Sep 17 00:00:00 2001 From: Sathish Kesavaperumal Date: Tue, 28 Feb 2017 17:44:22 +0530 Subject: [PATCH 34/53] Revert "Merge branch 'master' into latest" This reverts commit 2344b346808c107e02b491540642380fb09f2143, reversing changes made to 04de95e08d6ca65f328788d173fc31a5abd9972a. --- .jscsrc | 1 + CONTRIBUTING.md | 4 +- dist/angular-openlayers-directive.js | 297 ++++-------------- dist/angular-openlayers-directive.min.js | 6 +- ...ular-openlayers-directive.min.no-header.js | 6 +- dist/angular-openlayers-directive.pre.js | 297 ++++-------------- grunt/concat.js | 7 +- node_modules/.bin/grunt-open | 15 - package.json | 10 +- src/directives/center.js | 4 +- src/directives/control.js | 53 +--- src/directives/marker.js | 46 +-- src/directives/view.js | 4 - src/services/olHelpers.js | 165 ++-------- test/unit/layersSpec.js | 113 ------- test/unit/markerSpec.js | 23 -- 16 files changed, 176 insertions(+), 875 deletions(-) delete mode 100644 node_modules/.bin/grunt-open delete mode 100644 test/unit/markerSpec.js diff --git a/.jscsrc b/.jscsrc index 495d984b..d70efa61 100644 --- a/.jscsrc +++ b/.jscsrc @@ -4,6 +4,7 @@ "requireParenthesesAroundIIFE": true, "maximumLineLength": 120, + "validateLineBreaks": "LF", "validateIndentation": 4, "disallowKeywords": ["with"], diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d1c889c0..3fd1ee5a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -118,7 +118,7 @@ Once you have the development dependencies installed, we can use our predefined * **grunt test**. Executes the karma unitary tests and the protractor e2e tests, reporting the actual state of the project. * **grunt test:unit**. Executes only the karma unitary tests. * **grunt test:e2e**. Executes only the protractor e2e tests. -* **grunt coverage**. Generates a "coverage" folder with an [istanbul](https://github.com/gotwarlost/istanbul) report of which part of the code is covered by the actual tests. +* **grunt coverage**. Generates a "coverage" folder with an [istanbul](https://github.com/gotwarlost/istanbul) report of wich part of the code is covered by the actual tests. * **grunt**. The default task watches for project files changes and when a change is detected, tries to build the library file passing the jshint filter and the tests. Let's see an example: ``` @@ -139,7 +139,7 @@ Running "jshint:grunt" (jshint) task Running "concat:dist" (concat) task File "dist/angular-openlayers-directive.js" created. -Running "ngAnnotate" (ngAnnotate) task +Running "ngmin:directives" (ngmin) task ngminifying dist/angular-openlayers-directive.js Running "uglify:dist" (uglify) task diff --git a/dist/angular-openlayers-directive.js b/dist/angular-openlayers-directive.js index 6c409736..418184c3 100644 --- a/dist/angular-openlayers-directive.js +++ b/dist/angular-openlayers-directive.js @@ -1,8 +1,7 @@ (function (root, factory) { if (typeof require === 'function' && typeof exports === 'object') { // CommonJS - var ol = require('openlayers-prebuilt'); - var ngSanitize = require('angular-sanitize'); + var ol = require('openlayers'); exports.angularOpenlayersDirective = factory(ol); } else if (typeof define === 'function' && define.amd) { // AMD. @@ -280,7 +279,7 @@ angular.module('openlayers-directive').directive('olCenter', ["$log", "$location } }); - var moveEndEventKey = map.on('moveend', function() { + map.on('moveend', function() { safeApply(olScope, function(scope) { if (!isDefined(scope.center)) { @@ -314,9 +313,6 @@ angular.module('openlayers-directive').directive('olCenter', ["$log", "$location }); }); - olScope.$on('$destroy', function() { - map.unByKey(moveEndEventKey); - }); }); } }; @@ -649,23 +645,19 @@ angular.module('openlayers-directive').directive('olView', ["$log", "$q", "olDat } }); - var rotationEventKey = mapView.on('change:rotation', function() { + mapView.on('change:rotation', function() { safeApply(olScope, function(scope) { scope.view.rotation = map.getView().getRotation(); }); }); - olScope.$on('$destroy', function() { - map.unByKey(rotationEventKey); - }); - }); } }; }]); -angular.module('openlayers-directive') -.directive('olControl', ["$log", "$q", "olData", "olMapDefaults", "olHelpers", function($log, $q, olData, olMapDefaults, olHelpers) { +angular.module('openlayers-directive').directive('olControl', ["$log", "$q", "olData", "olMapDefaults", "olHelpers", function($log, $q, olData, olMapDefaults, olHelpers) { + return { restrict: 'E', scope: { @@ -678,58 +670,29 @@ angular.module('openlayers-directive') var olScope = controller.getOpenlayersScope(); var olControl; var olControlOps; - var getControlClasses = olHelpers.getControlClasses; - var controlClasses = getControlClasses(); olScope.getMap().then(function(map) { + var getControlClasses = olHelpers.getControlClasses; + var controlClasses = getControlClasses(); scope.$on('$destroy', function() { map.removeControl(olControl); }); - scope.$watch('properties', function(properties) { - if (!isDefined(properties)) { - return; - } - - initCtrls(properties); - }); - - function initCtrls(properties) { - if (properties && properties.control) { - // the control instance is already defined, - // so simply use it and go ahead - - // is there already a control, so destroy and recreate it? - if (olControl) { - map.removeControl(olControl); + if (!isDefined(scope.properties) || !isDefined(scope.properties.control)) { + if (attrs.name) { + if (isDefined(scope.properties)) { + olControlOps = scope.properties; } - - olControl = properties.control; + olControl = new controlClasses[attrs.name](olControlOps); map.addControl(olControl); - } else { - - // the name is the key to instantiate an ol3 control - if (attrs.name) { - if (isDefined(properties)) { - olControlOps = properties; - } - - // is there already a control, so destroy and recreate it? - if (olControl) { - map.removeControl(olControl); - } - - olControl = new controlClasses[attrs.name](olControlOps); - map.addControl(olControl); - } } + return; } - initCtrls(scope.properties); - + olControl = scope.properties.control; + map.addControl(olControl); }); - } }; }]); @@ -794,7 +757,6 @@ angular.module('openlayers-directive').directive('olMarker', ["$log", "$q", "olM if (!scopes.length) { map.removeLayer(mapDict[mapIndex].markerLayer); - delete mapDict[mapIndex].markerLayer; delete mapDict[mapIndex]; } } @@ -839,7 +801,7 @@ angular.module('openlayers-directive').directive('olMarker', ["$log", "$q", "olM // This function handles dragging a marker var pickOffset = null; var pickProperties = null; - scope.handleDrag = function(evt) { + function handleDrag(evt) { var coord = evt.coordinate; var proj = map.getView().getProjection().getCode(); if (proj === 'pixel') { @@ -888,25 +850,12 @@ angular.module('openlayers-directive').directive('olMarker', ["$log", "$q", "olM }); } } - }; - - function unregisterHandlers() { - if (!scope.properties) { return ; } - // Remove previous listeners if any - map.getViewport().removeEventListener('mousemove', scope.properties.handleInteraction); - map.getViewport().removeEventListener('click', scope.properties.handleTapInteraction); - map.getViewport().querySelector('canvas.ol-unselectable').removeEventListener( - 'touchend', scope.properties.handleTapInteraction); - map.getViewport().removeEventListener('mousemove', scope.properties.showAtLeastOneOverlay); - map.getViewport().removeEventListener('click', scope.properties.removeAllOverlays); - map.getViewport().querySelector('canvas.ol-unselectable').removeEventListener( - 'touchmove', scope.properties.activateCooldown); } // Setup generic handlers for marker drag - map.on('pointerdown', scope.handleDrag); - map.on('pointerup', scope.handleDrag); - map.on('pointerdrag', scope.handleDrag); + map.on('pointerdown', handleDrag); + map.on('pointerup', handleDrag); + map.on('pointerdrag', handleDrag); scope.$on('$destroy', function() { markerLayer.getSource().removeFeature(marker); @@ -914,10 +863,6 @@ angular.module('openlayers-directive').directive('olMarker', ["$log", "$q", "olM map.removeOverlay(label); } markerLayerManager.deregisterScope(scope, map); - map.un('pointerdown', scope.handleDrag); - map.un('pointerup', scope.handleDrag); - map.un('pointerdrag', scope.handleDrag); - unregisterHandlers(); }); if (!isDefined(scope.properties)) { @@ -947,7 +892,13 @@ angular.module('openlayers-directive').directive('olMarker', ["$log", "$q", "olM scope.$watch('properties', function(properties) { - unregisterHandlers(); + // Remove previous listeners if any + map.getViewport().removeEventListener('mousemove', properties.handleInteraction); + map.getViewport().removeEventListener('click', properties.handleTapInteraction); + map.getViewport().querySelector('canvas.ol-unselectable').removeEventListener( + 'touchend', properties.handleTapInteraction); + map.getViewport().removeEventListener('mousemove', properties.showAtLeastOneOverlay); + map.getViewport().removeEventListener('click', properties.removeAllOverlays); // This function handles popup on mouse over/click properties.handleInteraction = function(evt) { @@ -1006,7 +957,7 @@ angular.module('openlayers-directive').directive('olMarker', ["$log", "$q", "olM var prevTimeout; // Sets the cooldown flag to filter out any subsequent events within 500 ms - properties.activateCooldown = function() { + function activateCooldown() { cooldownActive = true; if (prevTimeout) { clearTimeout(prevTimeout); @@ -1015,20 +966,16 @@ angular.module('openlayers-directive').directive('olMarker', ["$log", "$q", "olM cooldownActive = false; prevTimeout = null; }, 500); - }; + } // Preventing from 'touchend' to be considered a tap, if fired immediately after 'touchmove' - if (properties.activateCooldown) { - map.getViewport().querySelector('canvas.ol-unselectable').removeEventListener( - 'touchmove', properties.activateCooldown); - } map.getViewport().querySelector('canvas.ol-unselectable').addEventListener( - 'touchmove', properties.activateCooldown); + 'touchmove', activateCooldown); return function() { if (!cooldownActive) { properties.handleInteraction.apply(null, arguments); - properties.activateCooldown(); + activateCooldown(); } }; })(); @@ -1302,8 +1249,7 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt var esriBaseLayers = ['World_Imagery', 'World_Street_Map', 'World_Topo_Map', 'World_Physical_Map', 'World_Terrain_Base', - 'Ocean_Basemap', 'NatGeo_World_Map', - 'World_Light_Gray_Base', 'World_Dark_Gray_Base']; + 'Ocean_Basemap', 'NatGeo_World_Map']; var styleMap = { 'style': ol.style.Style, @@ -1403,10 +1349,8 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt case 'JSONP': case 'TopoJSON': case 'KML': - case 'WKT': return 'Vector'; case 'TileVector': - case 'MVT': return 'TileVector'; default: return 'Tile'; @@ -1444,7 +1388,6 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt var createSource = function(source, projection) { var oSource; - var pixelRatio; var url; var geojsonFormat = new ol.format.GeoJSON(); // used in various switch stmnts below @@ -1454,10 +1397,10 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt $log.error('[AngularJS - Openlayers] - MapBox layer requires the map id and the access token'); return; } - url = 'https://api.tiles.mapbox.com/v4/' + source.mapId + '/{z}/{x}/{y}.png?access_token=' + + url = 'http://api.tiles.mapbox.com/v4/' + source.mapId + '/{z}/{x}/{y}.png?access_token=' + source.accessToken; - pixelRatio = window.devicePixelRatio; + var pixelRatio = window.devicePixelRatio; if (pixelRatio > 1) { url = url.replace('.png', '@2x.png'); @@ -1465,10 +1408,8 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt oSource = new ol.source.XYZ({ url: url, - tileLoadFunction: source.tileLoadFunction, attributions: createAttribution(source), - tilePixelRatio: pixelRatio > 1 ? 2 : 1, - wrapX: source.wrapX !== undefined ? source.wrapX : true + tilePixelRatio: pixelRatio > 1 ? 2 : 1 }); break; case 'MapBoxStudio': @@ -1481,32 +1422,10 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt '/' + source.mapId + '/tiles/{z}/{x}/{y}?access_token=' + source.accessToken; - pixelRatio = window.devicePixelRatio; - - if (pixelRatio > 1) { - url = url.replace('{y}?access_token', '{y}@2x?access_token'); - } - oSource = new ol.source.XYZ({ url: url, - tileLoadFunction: source.tileLoadFunction, attributions: createAttribution(source), - tilePixelRatio: pixelRatio > 1 ? 2 : 1, - tileSize: source.tileSize || [512, 512], - wrapX: source.wrapX !== undefined ? source.wrapX : true - }); - break; - case 'MVT': - if (!source.url) { - $log.error('[AngularJS - Openlayers] - MVT layer requires the source url'); - return; - } - oSource = new ol.source.VectorTile({ - attributions: source.attributions || '', - format: new ol.format.MVT(), - tileGrid: ol.tilegrid.createXYZ({maxZoom: source.maxZoom || 22}), - tilePixelRatio: source.tilePixelRatio || 16, - url: source.url + tileSize: source.tileSize || [512, 512] }); break; case 'ImageWMS': @@ -1516,7 +1435,6 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt } oSource = new ol.source.ImageWMS({ url: source.url, - imageLoadFunction: source.imageLoadFunction, attributions: createAttribution(source), crossOrigin: (typeof source.crossOrigin === 'undefined') ? 'anonymous' : source.crossOrigin, params: deepCopy(source.params), @@ -1531,17 +1449,11 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt } var wmsConfiguration = { - tileLoadFunction: source.tileLoadFunction, crossOrigin: (typeof source.crossOrigin === 'undefined') ? 'anonymous' : source.crossOrigin, params: deepCopy(source.params), - attributions: createAttribution(source), - wrapX: source.wrapX !== undefined ? source.wrapX : true + attributions: createAttribution(source) }; - if (source.projection) { - wmsConfiguration.projection = new ol.proj.get(source.projection); - } - if (source.serverType) { wmsConfiguration.serverType = source.serverType; } @@ -1564,7 +1476,6 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt } var wmtsConfiguration = { - tileLoadFunction: source.tileLoadFunction, projection: projection, layer: source.layer, attributions: createAttribution(source), @@ -1577,8 +1488,7 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt resolutions: source.tileGrid.resolutions, matrixIds: source.tileGrid.matrixIds }), - style: (source.style === 'undefined') ? 'normal' : source.style, - wrapX: source.wrapX !== undefined ? source.wrapX : true + style: (source.style === 'undefined') ? 'normal' : source.style }; if (isDefined(source.url)) { @@ -1594,9 +1504,7 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt case 'OSM': oSource = new ol.source.OSM({ - tileLoadFunction: source.tileLoadFunction, - attributions: createAttribution(source), - wrapX: source.wrapX !== undefined ? source.wrapX : true + attributions: createAttribution(source) }); if (source.url) { @@ -1612,11 +1520,9 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt var bingConfiguration = { key: source.key, - tileLoadFunction: source.tileLoadFunction, attributions: createAttribution(source), imagerySet: source.imagerySet ? source.imagerySet : bingImagerySets[0], - culture: source.culture, - wrapX: source.wrapX !== undefined ? source.wrapX : true + culture: source.culture }; if (source.maxZoom) { @@ -1634,8 +1540,7 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt oSource = new ol.source.MapQuest({ attributions: createAttribution(source), - layer: source.layer, - wrapX: source.wrapX !== undefined ? source.wrapX : true + layer: source.layer }); break; @@ -1647,30 +1552,11 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt } var _urlBase = 'http://services.arcgisonline.com/ArcGIS/rest/services/'; - if (source.layer === 'World_Light_Gray_Base' || source.layer === 'World_Dark_Gray_Base') { - _urlBase = _urlBase + 'Canvas/'; - } var _url = _urlBase + source.layer + '/MapServer/tile/{z}/{y}/{x}'; oSource = new ol.source.XYZ({ attributions: createAttribution(source), - tileLoadFunction: source.tileLoadFunction, - url: _url, - wrapX: source.wrapX !== undefined ? source.wrapX : true - }); - - break; - - case 'TileArcGISRest': - if (!source.url) { - $log.error('[AngularJS - Openlayers] - TileArcGISRest Layer needs valid url'); - } - - oSource = new ol.source.TileArcGISRest({ - attributions: createAttribution(source), - tileLoadFunction: source.tileLoadFunction, - url: source.url, - wrapX: source.wrapX !== undefined ? source.wrapX : true + url: _url }); break; @@ -1700,48 +1586,12 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt var features = geojsonFormat.readFeatures( source.geojson.object, { - featureProjection: projectionToUse.getCode(), - dataProjection: dataProjection.getCode() + featureProjection: projectionToUse, + dataProjection: dataProjection }); oSource.addFeatures(features); } - break; - case 'WKT': - if (!(source.wkt || source.url)) { - $log.error('[AngularJS - Openlayers] - You need a WKT ' + - 'property to add a GeoJSON layer.'); - return; - } - if (isDefined(source.url)) { - oSource = new ol.source.Vector({ - format: new ol.format.WKT(), - url: source.url, - wrapX: source.wrapX !== undefined ? source.wrapX : true - }); - } else { - oSource = new ol.source.Vector(); - var featureProjection = projection; - var wktProjection; - if (isDefined(source.wkt.projection)) { - wktProjection = new ol.proj.get(source.wkt.projection); - } else { - wktProjection = projection; - } - - var wktFormat = new ol.format.WKT(); - var wktFeatures = []; - for (var k = 0; k < source.wkt.object.length; k++) { - var feature = wktFormat.readFeature( - source.wkt.object[k].data, {dataProjection: wktProjection.getCode() , - featureProjection: featureProjection.getCode() }); - if (source.wkt.object[k].properties) { - feature.properties = source.wkt.object[k].properties; - } - wktFeatures.push(feature); - } - oSource.addFeatures(wktFeatures); - } break; case 'JSONP': @@ -1790,9 +1640,7 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt oSource = new ol.source.TileJSON({ url: source.url, attributions: createAttribution(source), - tileLoadFunction: source.tileLoadFunction, - crossOrigin: 'anonymous', - wrapX: source.wrapX !== undefined ? source.wrapX : true + crossOrigin: 'anonymous' }); break; @@ -1804,12 +1652,10 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt url: source.url, projection: projection, attributions: createAttribution(source), - tileLoadFunction: source.tileLoadFunction, format: source.format, tileGrid: new ol.tilegrid.createXYZ({ maxZoom: source.maxZoom || 19 - }), - wrapX: source.wrapX !== undefined ? source.wrapX : true + }) }); break; @@ -1821,7 +1667,6 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt url: source.url, maxExtent: source.maxExtent, attributions: createAttribution(source), - tileLoadFunction: source.tileLoadFunction, tileGrid: new ol.tilegrid.TileGrid({ origin: source.tileGrid.origin, resolutions: source.tileGrid.resolutions @@ -1839,15 +1684,13 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt var url = source.url + z + '/' + x + '/' + y + '.png'; return url; - }, - wrapX: source.wrapX !== undefined ? source.wrapX : true + } }); break; case 'TileImage': oSource = new ol.source.TileImage({ url: source.url, attributions: createAttribution(source), - tileLoadFunction: source.tileLoadFunction, tileGrid: new ol.tilegrid.TileGrid({ origin: source.tileGrid.origin, // top left corner of the pixel projection's extent resolutions: source.tileGrid.resolutions @@ -1861,18 +1704,16 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt .replace('{x}', x.toString()) .replace('{y}', y.toString()); return url; - }, - wrapX: source.wrapX !== undefined ? source.wrapX : true + } }); break; case 'KML': var extractStyles = source.extractStyles || false; oSource = new ol.source.Vector({ url: source.url, - format: new ol.format.KML({ - extractStyles: extractStyles - }), - radius: source.radius + format: new ol.format.KML(), + radius: source.radius, + extractStyles: extractStyles }); break; case 'Stamen': @@ -1881,9 +1722,7 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt return; } oSource = new ol.source.Stamen({ - tileLoadFunction: source.tileLoadFunction, - layer: source.layer, - wrapX: source.wrapX !== undefined ? source.wrapX : true + layer: source.layer }); break; case 'ImageStatic': @@ -1911,9 +1750,7 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt minZoom: source.minZoom, maxZoom: source.maxZoom, projection: source.projection, - tileUrlFunction: source.tileUrlFunction, - tileLoadFunction: source.tileLoadFunction, - wrapX: source.wrapX !== undefined ? source.wrapX : true + tileUrlFunction: source.tileUrlFunction }); break; case 'Zoomify': @@ -1922,8 +1759,7 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt } oSource = new ol.source.Zoomify({ url: source.url, - size: source.imageSize, - wrapX: source.wrapX !== undefined ? source.wrapX : true + size: source.imageSize }); break; } @@ -2198,22 +2034,7 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt }); } - var layerConfig = {}; - - // copy over eventual properties set on the passed layerconfig which - // can later be retrieved via layer.get('propName'); - for (var property in layer) { - if (layer.hasOwnProperty(property) && - // ignore props like source or those angular might add (starting with $) - !property.startsWith('$') && - !property.startsWith('source') && - !property.startsWith('style') - ) { - layerConfig[property] = layer[property]; - } - } - - layerConfig.source = oSource; + var layerConfig = { source: oSource }; // ol.layer.Layer configuration options if (isDefinedAndNotNull(layer.opacity)) { @@ -2234,9 +2055,6 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt if (isDefinedAndNotNull(layer.maxResolution)) { layerConfig.maxResolution = layer.maxResolution; } - if (isDefinedAndNotNull(layer.style) && type === 'TileVector') { - layerConfig.style = layer.style; - } switch (type) { case 'Image': @@ -2373,7 +2191,6 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt while (layers.getLength() < index) { var nullLayer = new ol.layer.Image(); nullLayer.index = layers.getLength(); // add index which will be equal to the length in this case - nullLayer.name = '(null-layer)'; // we need a marker somehow layers.push(nullLayer); } layer.index = index; @@ -2381,11 +2198,9 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt } else { layer.index = index; layers.insertAt(layer.index, layer); - - // remove eventual null layers for (var i = index + 1; i < layers.getLength(); i++) { var l = layers.item(i); - if (l.name === '(null-layer)') { + if (l === null) { layers.removeAt(i); break; } else { @@ -2560,5 +2375,5 @@ angular.module('openlayers-directive').factory('olMapDefaults', ["$q", "olHelper } }; }]); -return angular.module('openlayers-directive'); + })); \ No newline at end of file diff --git a/dist/angular-openlayers-directive.min.js b/dist/angular-openlayers-directive.min.js index b437b287..77e2eaa4 100644 --- a/dist/angular-openlayers-directive.min.js +++ b/dist/angular-openlayers-directive.min.js @@ -27,6 +27,6 @@ * @authors https://github.com/tombatossals/angular-openlayers-directive/graphs/contributors */ -/*! angular-openlayers-directive 28-02-2017 */ -!function(a,b){if("function"==typeof require&&"object"==typeof exports){var c=require("openlayers-prebuilt");require("angular-sanitize");exports.angularOpenlayersDirective=b(c)}else"function"==typeof define&&define.amd?define(["ol"],function(c){return a.angularOpenlayersDirective=b(c)}):a.angularOpenlayersDirective=b(a.ol)}(this,function(a){return angular.module("openlayers-directive",["ngSanitize"]).directive("openlayers",["$log","$q","$compile","olHelpers","olMapDefaults","olData",function(b,c,d,e,f,g){return{restrict:"EA",transclude:!0,replace:!0,scope:{center:"=olCenter",defaults:"=olDefaults",view:"=olView",events:"=olEvents"},template:'
',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id)}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(h.olCenter.search("-")!==-1)return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}});var w=f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})});r.$on("$destroy",function(){f.unByKey(w)})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)});var f=e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})});g.$on("$destroy",function(){a.unByKey(f)})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope(),j=e.getControlClasses,k=j();i.getMap().then(function(b){function d(a){a&&a.control?(f&&b.removeControl(f),f=a.control,b.addControl(f)):c.name&&(h(a)&&(g=a),f&&b.removeControl(f),f=new k[c.name](g),b.addControl(f))}a.$on("$destroy",function(){b.removeControl(f)}),a.$watch("properties",function(a){h(a)&&d(a)}),d(a.properties)})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(f===-1){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(e===-1)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(g===-1)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e].markerLayer,delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(){c.properties&&(e.getViewport().removeEventListener("mousemove",c.properties.handleInteraction),e.getViewport().removeEventListener("click",c.properties.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",c.properties.handleTapInteraction),e.getViewport().removeEventListener("mousemove",c.properties.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",c.properties.removeAllOverlays),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",c.properties.activateCooldown))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return c.handleDrag=function(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))},e.on("pointerdown",c.handleDrag),e.on("pointerup",c.handleDrag),e.on("pointerdrag",c.handleDrag),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e),e.un("pointerdown",c.handleDrag),e.un("pointerup",c.handleDrag),e.un("pointerdrag",c.handleDrag),j()}),k(c.properties)?void c.$watch("properties",function(d){if(j(),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){var a,b=!1;return d.activateCooldown=function(){b=!0,a&&clearTimeout(a),a=setTimeout(function(){b=!1,a=null},500)},d.activateCooldown&&e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",d.activateCooldown),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",d.activateCooldown),function(){b||(d.handleInteraction.apply(null,arguments),d.activateCooldown())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){var d=c(a,b);a[d].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d,e=c(a,b);return d=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:f(a,b)};this.setMap=function(a,b){var c=f(d,b);c.resolve(a),e(d,b)},this.getMap=function(a){var b=g(d,a);return b.promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map","World_Light_Gray_Base","World_Dark_Gray_Base"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function a(b,c){var d;if(c?d=b[c]:(c="style",d=b),"style"===c&&b instanceof Function)return b;if(!(d instanceof Object))return d;var e;if("[object Object]"===Object.prototype.toString.call(d)){e={};var f=l[c];if(f&&d instanceof f)return d;Object.getOwnPropertyNames(d).forEach(function(b,g,h){var i=l[b];return f&&i&&i.prototype instanceof l[c]?(console.assert(1===h.length,"Extra parameters for "+c),e=a(d,b),m(e,i)):(e[b]=a(d,b),void("text"!==b&&"string"!=typeof e[b]&&(e[b]=m(e[b],l[b]))))})}else e=d;return m(e,l[c])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":return"Vector";case"TileVector":case"MVT":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return["watercolor","terrain","toner"].indexOf(a)!==-1},r=function(b,f){var g,i,l,m=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");l="https://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace(".png","@2x.png")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,wrapX:void 0===b.wrapX||b.wrapX});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");l="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace("{y}?access_token","{y}@2x?access_token")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,tileSize:b.tileSize||[512,512],wrapX:void 0===b.wrapX||b.wrapX});break;case"MVT":if(!b.url)return void c.error("[AngularJS - Openlayers] - MVT layer requires the source url");g=new a.source.VectorTile({attributions:b.attributions||"",format:new a.format.MVT,tileGrid:a.tilegrid.createXYZ({maxZoom:b.maxZoom||22}),tilePixelRatio:b.tilePixelRatio||16,url:b.url});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,imageLoadFunction:b.imageLoadFunction,attributions:t(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={tileLoadFunction:b.tileLoadFunction,crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX};b.projection&&(n.projection=new a.proj.get(b.projection)),b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={tileLoadFunction:b.tileLoadFunction,projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),style:"undefined"===b.style?"normal":b.style,wrapX:void 0===b.wrapX||b.wrapX};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({tileLoadFunction:b.tileLoadFunction,attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,tileLoadFunction:b.tileLoadFunction,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX||b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||j.indexOf(b.layer)===-1)return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer,wrapX:void 0===b.wrapX||b.wrapX});break;case"EsriBaseMaps":if(!b.layer||k.indexOf(b.layer)===-1)return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="http://services.arcgisonline.com/ArcGIS/rest/services/";"World_Light_Gray_Base"!==b.layer&&"World_Dark_Gray_Base"!==b.layer||(r+="Canvas/");var u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:u,wrapX:void 0===b.wrapX||b.wrapX});break;case"TileArcGISRest":b.url||c.error("[AngularJS - Openlayers] - TileArcGISRest Layer needs valid url"),g=new a.source.TileArcGISRest({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=m.readFeatures(b.geojson.object,{featureProjection:w.getCode(),dataProjection:v.getCode()});g.addFeatures(x)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});else{g=new a.source.Vector;var y,z=f;y=e(b.wkt.projection)?new a.proj.get(b.wkt.projection):f;for(var A=new a.format.WKT,B=[],C=0;C',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id)}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(h.olCenter.search("-")!==-1)return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}}),f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)}),e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope();i.getMap().then(function(b){var d=e.getControlClasses,i=d();return a.$on("$destroy",function(){b.removeControl(f)}),h(a.properties)&&h(a.properties.control)?(f=a.properties.control,void b.addControl(f)):void(c.name&&(h(a.properties)&&(g=a.properties),f=new i[c.name](g),b.addControl(f)))})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(f===-1){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(e===-1)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(g===-1)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return e.on("pointerdown",j),e.on("pointerup",j),e.on("pointerdrag",j),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e)}),k(c.properties)?void c.$watch("properties",function(d){if(e.getViewport().removeEventListener("mousemove",d.handleInteraction),e.getViewport().removeEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",d.handleTapInteraction),e.getViewport().removeEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",d.removeAllOverlays),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){function a(){c=!0,b&&clearTimeout(b),b=setTimeout(function(){c=!1,b=null},500)}var b,c=!1;return e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",a),function(){c||(d.handleInteraction.apply(null,arguments),a())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){var d=c(a,b);a[d].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d,e=c(a,b);return d=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:f(a,b)};this.setMap=function(a,b){var c=f(d,b);c.resolve(a),e(d,b)},this.getMap=function(a){var b=g(d,a);return b.promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function y(a,b){var c;if(b?c=a[b]:(b="style",c=a),"style"===b&&a instanceof Function)return a;if(!(c instanceof Object))return c;var d;if("[object Object]"===Object.prototype.toString.call(c)){d={};var e=l[b];if(e&&c instanceof e)return c;Object.getOwnPropertyNames(c).forEach(function(a,f,g){var h=l[a];return e&&h&&h.prototype instanceof l[b]?(console.assert(1===g.length,"Extra parameters for "+b),d=y(c,a),m(d,h)):(d[a]=y(c,a),void("text"!==a&&"string"!=typeof d[a]&&(d[a]=m(d[a],l[a]))))})}else d=c;return m(d,l[b])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":return"Vector";case"TileVector":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return["watercolor","terrain","toner"].indexOf(a)!==-1},r=function(b,f){var g,i,l=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");i="http://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken;var m=window.devicePixelRatio;m>1&&(i=i.replace(".png","@2x.png")),g=new a.source.XYZ({url:i,attributions:t(b),tilePixelRatio:m>1?2:1});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");i="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,g=new a.source.XYZ({url:i,attributions:t(b),tileSize:b.tileSize||[512,512]});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,attributions:t(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b)};b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),style:"undefined"===b.style?"normal":b.style};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({attributions:t(b)}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||j.indexOf(b.layer)===-1)return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer});break;case"EsriBaseMaps":if(!b.layer||k.indexOf(b.layer)===-1)return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="http://services.arcgisonline.com/ArcGIS/rest/services/",u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),url:u});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=l.readFeatures(b.geojson.object,{featureProjection:w,dataProjection:v});g.addFeatures(x)}break;case"JSONP":if(!b.url)return void c.error("[AngularJS - Openlayers] - You need an url properly configured to add a JSONP layer.");e(b.url)&&(g=new a.source.ServerVector({format:l,loader:function(){var a=b.url+"&outputFormat=text/javascript&format_options=callback:JSON_CALLBACK";d.jsonp(a,{cache:b.cache}).success(function(a){g.addFeatures(l.readFeatures(a))}).error(function(a){c(a)})},projection:f}));break;case"TopoJSON":if(!b.topojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a topojson property to add a TopoJSON layer.");g=b.url?new a.source.Vector({format:new a.format.TopoJSON,url:b.url}):new a.source.Vector(angular.extend(b.topojson,{format:new a.format.TopoJSON}));break;case"TileJSON":g=new a.source.TileJSON({url:b.url,attributions:t(b),crossOrigin:"anonymous"});break;case"TileVector":b.url&&b.format||c.error("[AngularJS - Openlayers] - TileVector Layer needs valid url and format properties"),g=new a.source.VectorTile({url:b.url,projection:f,attributions:t(b),format:b.format,tileGrid:new a.tilegrid.createXYZ({maxZoom:b.maxZoom||19})});break;case"TileTMS":b.url&&b.tileGrid||c.error("[AngularJS - Openlayers] - TileTMS Layer needs valid url and tileGrid properties"),g=new a.source.TileImage({url:b.url,maxExtent:b.maxExtent,attributions:t(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=a[2];if(d<0||e<0)return"";var f=b.url+c+"/"+d+"/"+e+".png";return f}});break;case"TileImage":g=new a.source.TileImage({url:b.url,attributions:t(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=-a[2]-1,f=b.url.replace("{z}",c.toString()).replace("{x}",d.toString()).replace("{y}",e.toString());return f}});break;case"KML":var y=b.extractStyles||!1;g=new a.source.Vector({url:b.url,format:new a.format.KML,radius:b.radius,extractStyles:y});break;case"Stamen":if(!b.layer||!q(b.layer))return void c.error("[AngularJS - Openlayers] - You need a valid Stamen layer.");g=new a.source.Stamen({layer:b.layer});break;case"ImageStatic":if(!b.url||!angular.isArray(b.imageSize)||2!==b.imageSize.length)return void c.error("[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.");g=new a.source.ImageStatic({url:b.url,attributions:t(b),imageSize:b.imageSize,projection:f,imageExtent:b.imageExtent?b.imageExtent:f.getExtent(),imageLoadFunction:b.imageLoadFunction});break;case"XYZ":b.url||b.tileUrlFunction||c.error("[AngularJS - Openlayers] - XYZ Layer needs valid url or tileUrlFunction properties"),g=new a.source.XYZ({url:b.url,attributions:t(b),minZoom:b.minZoom,maxZoom:b.maxZoom,projection:b.projection,tileUrlFunction:b.tileUrlFunction});break;case"Zoomify":b.url&&angular.isArray(b.imageSize)&&2===b.imageSize.length||c.error("[AngularJS - Openlayers] - Zoomify Layer needs valid url and imageSize properties"),g=new a.source.Zoomify({url:b.url,size:b.imageSize})}return g||c.warn('[AngularJS - Openlayers] - No source could be found for type "'+b.type+'"'),g},s=function(a){var b=a;if(a&&"object"==typeof a){b="[object Array]"===Object.prototype.toString.call(a)?[]:{};for(var c in a)b[c]=s(a[c])}return b},t=function(b){var c=[];return e(b.attribution)&&c.unshift(new a.Attribution({html:b.attribution})),c},u=function(b){var c=new a.layer.Group;return c.set("name",b),c},v=function(b,c){var d;return angular.forEach(b,function(b){if(b instanceof a.layer.Group&&b.get("name")===c)return void(d=b)}),d},w=function(a,b){for(var c,d=0;d',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id)}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(h.olCenter.search("-")!==-1)return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}});var w=f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})});r.$on("$destroy",function(){f.unByKey(w)})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)});var f=e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})});g.$on("$destroy",function(){a.unByKey(f)})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope(),j=e.getControlClasses,k=j();i.getMap().then(function(b){function d(a){a&&a.control?(f&&b.removeControl(f),f=a.control,b.addControl(f)):c.name&&(h(a)&&(g=a),f&&b.removeControl(f),f=new k[c.name](g),b.addControl(f))}a.$on("$destroy",function(){b.removeControl(f)}),a.$watch("properties",function(a){h(a)&&d(a)}),d(a.properties)})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(f===-1){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(e===-1)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(g===-1)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e].markerLayer,delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(){c.properties&&(e.getViewport().removeEventListener("mousemove",c.properties.handleInteraction),e.getViewport().removeEventListener("click",c.properties.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",c.properties.handleTapInteraction),e.getViewport().removeEventListener("mousemove",c.properties.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",c.properties.removeAllOverlays),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",c.properties.activateCooldown))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return c.handleDrag=function(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))},e.on("pointerdown",c.handleDrag),e.on("pointerup",c.handleDrag),e.on("pointerdrag",c.handleDrag),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e),e.un("pointerdown",c.handleDrag),e.un("pointerup",c.handleDrag),e.un("pointerdrag",c.handleDrag),j()}),k(c.properties)?void c.$watch("properties",function(d){if(j(),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){var a,b=!1;return d.activateCooldown=function(){b=!0,a&&clearTimeout(a),a=setTimeout(function(){b=!1,a=null},500)},d.activateCooldown&&e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",d.activateCooldown),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",d.activateCooldown),function(){b||(d.handleInteraction.apply(null,arguments),d.activateCooldown())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){var d=c(a,b);a[d].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d,e=c(a,b);return d=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:f(a,b)};this.setMap=function(a,b){var c=f(d,b);c.resolve(a),e(d,b)},this.getMap=function(a){var b=g(d,a);return b.promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map","World_Light_Gray_Base","World_Dark_Gray_Base"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function a(b,c){var d;if(c?d=b[c]:(c="style",d=b),"style"===c&&b instanceof Function)return b;if(!(d instanceof Object))return d;var e;if("[object Object]"===Object.prototype.toString.call(d)){e={};var f=l[c];if(f&&d instanceof f)return d;Object.getOwnPropertyNames(d).forEach(function(b,g,h){var i=l[b];return f&&i&&i.prototype instanceof l[c]?(console.assert(1===h.length,"Extra parameters for "+c),e=a(d,b),m(e,i)):(e[b]=a(d,b),void("text"!==b&&"string"!=typeof e[b]&&(e[b]=m(e[b],l[b]))))})}else e=d;return m(e,l[c])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":return"Vector";case"TileVector":case"MVT":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return["watercolor","terrain","toner"].indexOf(a)!==-1},r=function(b,f){var g,i,l,m=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");l="https://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace(".png","@2x.png")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,wrapX:void 0===b.wrapX||b.wrapX});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");l="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace("{y}?access_token","{y}@2x?access_token")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,tileSize:b.tileSize||[512,512],wrapX:void 0===b.wrapX||b.wrapX});break;case"MVT":if(!b.url)return void c.error("[AngularJS - Openlayers] - MVT layer requires the source url");g=new a.source.VectorTile({attributions:b.attributions||"",format:new a.format.MVT,tileGrid:a.tilegrid.createXYZ({maxZoom:b.maxZoom||22}),tilePixelRatio:b.tilePixelRatio||16,url:b.url});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,imageLoadFunction:b.imageLoadFunction,attributions:t(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={tileLoadFunction:b.tileLoadFunction,crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX};b.projection&&(n.projection=new a.proj.get(b.projection)),b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={tileLoadFunction:b.tileLoadFunction,projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),style:"undefined"===b.style?"normal":b.style,wrapX:void 0===b.wrapX||b.wrapX};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({tileLoadFunction:b.tileLoadFunction,attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,tileLoadFunction:b.tileLoadFunction,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX||b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||j.indexOf(b.layer)===-1)return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer,wrapX:void 0===b.wrapX||b.wrapX});break;case"EsriBaseMaps":if(!b.layer||k.indexOf(b.layer)===-1)return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="http://services.arcgisonline.com/ArcGIS/rest/services/";"World_Light_Gray_Base"!==b.layer&&"World_Dark_Gray_Base"!==b.layer||(r+="Canvas/");var u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:u,wrapX:void 0===b.wrapX||b.wrapX});break;case"TileArcGISRest":b.url||c.error("[AngularJS - Openlayers] - TileArcGISRest Layer needs valid url"),g=new a.source.TileArcGISRest({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=m.readFeatures(b.geojson.object,{featureProjection:w.getCode(),dataProjection:v.getCode()});g.addFeatures(x)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});else{g=new a.source.Vector;var y,z=f;y=e(b.wkt.projection)?new a.proj.get(b.wkt.projection):f;for(var A=new a.format.WKT,B=[],C=0;C',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id)}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(h.olCenter.search("-")!==-1)return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}}),f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)}),e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope();i.getMap().then(function(b){var d=e.getControlClasses,i=d();return a.$on("$destroy",function(){b.removeControl(f)}),h(a.properties)&&h(a.properties.control)?(f=a.properties.control,void b.addControl(f)):void(c.name&&(h(a.properties)&&(g=a.properties),f=new i[c.name](g),b.addControl(f)))})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(f===-1){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(e===-1)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(g===-1)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return e.on("pointerdown",j),e.on("pointerup",j),e.on("pointerdrag",j),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e)}),k(c.properties)?void c.$watch("properties",function(d){if(e.getViewport().removeEventListener("mousemove",d.handleInteraction),e.getViewport().removeEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",d.handleTapInteraction),e.getViewport().removeEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",d.removeAllOverlays),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){function a(){c=!0,b&&clearTimeout(b),b=setTimeout(function(){c=!1,b=null},500)}var b,c=!1;return e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",a),function(){c||(d.handleInteraction.apply(null,arguments),a())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){var d=c(a,b);a[d].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d,e=c(a,b);return d=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:f(a,b)};this.setMap=function(a,b){var c=f(d,b);c.resolve(a),e(d,b)},this.getMap=function(a){var b=g(d,a);return b.promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function y(a,b){var c;if(b?c=a[b]:(b="style",c=a),"style"===b&&a instanceof Function)return a;if(!(c instanceof Object))return c;var d;if("[object Object]"===Object.prototype.toString.call(c)){d={};var e=l[b];if(e&&c instanceof e)return c;Object.getOwnPropertyNames(c).forEach(function(a,f,g){var h=l[a];return e&&h&&h.prototype instanceof l[b]?(console.assert(1===g.length,"Extra parameters for "+b),d=y(c,a),m(d,h)):(d[a]=y(c,a),void("text"!==a&&"string"!=typeof d[a]&&(d[a]=m(d[a],l[a]))))})}else d=c;return m(d,l[b])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":return"Vector";case"TileVector":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return["watercolor","terrain","toner"].indexOf(a)!==-1},r=function(b,f){var g,i,l=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");i="http://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken;var m=window.devicePixelRatio;m>1&&(i=i.replace(".png","@2x.png")),g=new a.source.XYZ({url:i,attributions:t(b),tilePixelRatio:m>1?2:1});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");i="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,g=new a.source.XYZ({url:i,attributions:t(b),tileSize:b.tileSize||[512,512]});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,attributions:t(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b)};b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),style:"undefined"===b.style?"normal":b.style};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({attributions:t(b)}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||j.indexOf(b.layer)===-1)return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer});break;case"EsriBaseMaps":if(!b.layer||k.indexOf(b.layer)===-1)return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="http://services.arcgisonline.com/ArcGIS/rest/services/",u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),url:u});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=l.readFeatures(b.geojson.object,{featureProjection:w,dataProjection:v});g.addFeatures(x)}break;case"JSONP":if(!b.url)return void c.error("[AngularJS - Openlayers] - You need an url properly configured to add a JSONP layer.");e(b.url)&&(g=new a.source.ServerVector({format:l,loader:function(){var a=b.url+"&outputFormat=text/javascript&format_options=callback:JSON_CALLBACK";d.jsonp(a,{cache:b.cache}).success(function(a){g.addFeatures(l.readFeatures(a))}).error(function(a){c(a)})},projection:f}));break;case"TopoJSON":if(!b.topojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a topojson property to add a TopoJSON layer.");g=b.url?new a.source.Vector({format:new a.format.TopoJSON,url:b.url}):new a.source.Vector(angular.extend(b.topojson,{format:new a.format.TopoJSON}));break;case"TileJSON":g=new a.source.TileJSON({url:b.url,attributions:t(b),crossOrigin:"anonymous"});break;case"TileVector":b.url&&b.format||c.error("[AngularJS - Openlayers] - TileVector Layer needs valid url and format properties"),g=new a.source.VectorTile({url:b.url,projection:f,attributions:t(b),format:b.format,tileGrid:new a.tilegrid.createXYZ({maxZoom:b.maxZoom||19})});break;case"TileTMS":b.url&&b.tileGrid||c.error("[AngularJS - Openlayers] - TileTMS Layer needs valid url and tileGrid properties"),g=new a.source.TileImage({url:b.url,maxExtent:b.maxExtent,attributions:t(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=a[2];if(d<0||e<0)return"";var f=b.url+c+"/"+d+"/"+e+".png";return f}});break;case"TileImage":g=new a.source.TileImage({url:b.url,attributions:t(b),tileGrid:new a.tilegrid.TileGrid({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions}),tileUrlFunction:function(a){var c=a[0],d=a[1],e=-a[2]-1,f=b.url.replace("{z}",c.toString()).replace("{x}",d.toString()).replace("{y}",e.toString());return f}});break;case"KML":var y=b.extractStyles||!1;g=new a.source.Vector({url:b.url,format:new a.format.KML,radius:b.radius,extractStyles:y});break;case"Stamen":if(!b.layer||!q(b.layer))return void c.error("[AngularJS - Openlayers] - You need a valid Stamen layer.");g=new a.source.Stamen({layer:b.layer});break;case"ImageStatic":if(!b.url||!angular.isArray(b.imageSize)||2!==b.imageSize.length)return void c.error("[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.");g=new a.source.ImageStatic({url:b.url,attributions:t(b),imageSize:b.imageSize,projection:f,imageExtent:b.imageExtent?b.imageExtent:f.getExtent(),imageLoadFunction:b.imageLoadFunction});break;case"XYZ":b.url||b.tileUrlFunction||c.error("[AngularJS - Openlayers] - XYZ Layer needs valid url or tileUrlFunction properties"),g=new a.source.XYZ({url:b.url,attributions:t(b),minZoom:b.minZoom,maxZoom:b.maxZoom,projection:b.projection,tileUrlFunction:b.tileUrlFunction});break;case"Zoomify":b.url&&angular.isArray(b.imageSize)&&2===b.imageSize.length||c.error("[AngularJS - Openlayers] - Zoomify Layer needs valid url and imageSize properties"),g=new a.source.Zoomify({url:b.url,size:b.imageSize})}return g||c.warn('[AngularJS - Openlayers] - No source could be found for type "'+b.type+'"'),g},s=function(a){var b=a;if(a&&"object"==typeof a){b="[object Array]"===Object.prototype.toString.call(a)?[]:{};for(var c in a)b[c]=s(a[c])}return b},t=function(b){var c=[];return e(b.attribution)&&c.unshift(new a.Attribution({html:b.attribution})),c},u=function(b){var c=new a.layer.Group;return c.set("name",b),c},v=function(b,c){var d;return angular.forEach(b,function(b){if(b instanceof a.layer.Group&&b.get("name")===c)return void(d=b)}),d},w=function(a,b){for(var c,d=0;d 1 ? 2 : 1, - wrapX: source.wrapX !== undefined ? source.wrapX : true + tilePixelRatio: pixelRatio > 1 ? 2 : 1 }); break; case 'MapBoxStudio': @@ -1481,32 +1422,10 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ '/' + source.mapId + '/tiles/{z}/{x}/{y}?access_token=' + source.accessToken; - pixelRatio = window.devicePixelRatio; - - if (pixelRatio > 1) { - url = url.replace('{y}?access_token', '{y}@2x?access_token'); - } - oSource = new ol.source.XYZ({ url: url, - tileLoadFunction: source.tileLoadFunction, attributions: createAttribution(source), - tilePixelRatio: pixelRatio > 1 ? 2 : 1, - tileSize: source.tileSize || [512, 512], - wrapX: source.wrapX !== undefined ? source.wrapX : true - }); - break; - case 'MVT': - if (!source.url) { - $log.error('[AngularJS - Openlayers] - MVT layer requires the source url'); - return; - } - oSource = new ol.source.VectorTile({ - attributions: source.attributions || '', - format: new ol.format.MVT(), - tileGrid: ol.tilegrid.createXYZ({maxZoom: source.maxZoom || 22}), - tilePixelRatio: source.tilePixelRatio || 16, - url: source.url + tileSize: source.tileSize || [512, 512] }); break; case 'ImageWMS': @@ -1516,7 +1435,6 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ } oSource = new ol.source.ImageWMS({ url: source.url, - imageLoadFunction: source.imageLoadFunction, attributions: createAttribution(source), crossOrigin: (typeof source.crossOrigin === 'undefined') ? 'anonymous' : source.crossOrigin, params: deepCopy(source.params), @@ -1531,17 +1449,11 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ } var wmsConfiguration = { - tileLoadFunction: source.tileLoadFunction, crossOrigin: (typeof source.crossOrigin === 'undefined') ? 'anonymous' : source.crossOrigin, params: deepCopy(source.params), - attributions: createAttribution(source), - wrapX: source.wrapX !== undefined ? source.wrapX : true + attributions: createAttribution(source) }; - if (source.projection) { - wmsConfiguration.projection = new ol.proj.get(source.projection); - } - if (source.serverType) { wmsConfiguration.serverType = source.serverType; } @@ -1564,7 +1476,6 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ } var wmtsConfiguration = { - tileLoadFunction: source.tileLoadFunction, projection: projection, layer: source.layer, attributions: createAttribution(source), @@ -1577,8 +1488,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ resolutions: source.tileGrid.resolutions, matrixIds: source.tileGrid.matrixIds }), - style: (source.style === 'undefined') ? 'normal' : source.style, - wrapX: source.wrapX !== undefined ? source.wrapX : true + style: (source.style === 'undefined') ? 'normal' : source.style }; if (isDefined(source.url)) { @@ -1594,9 +1504,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ case 'OSM': oSource = new ol.source.OSM({ - tileLoadFunction: source.tileLoadFunction, - attributions: createAttribution(source), - wrapX: source.wrapX !== undefined ? source.wrapX : true + attributions: createAttribution(source) }); if (source.url) { @@ -1612,11 +1520,9 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ var bingConfiguration = { key: source.key, - tileLoadFunction: source.tileLoadFunction, attributions: createAttribution(source), imagerySet: source.imagerySet ? source.imagerySet : bingImagerySets[0], - culture: source.culture, - wrapX: source.wrapX !== undefined ? source.wrapX : true + culture: source.culture }; if (source.maxZoom) { @@ -1634,8 +1540,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ oSource = new ol.source.MapQuest({ attributions: createAttribution(source), - layer: source.layer, - wrapX: source.wrapX !== undefined ? source.wrapX : true + layer: source.layer }); break; @@ -1647,30 +1552,11 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ } var _urlBase = 'http://services.arcgisonline.com/ArcGIS/rest/services/'; - if (source.layer === 'World_Light_Gray_Base' || source.layer === 'World_Dark_Gray_Base') { - _urlBase = _urlBase + 'Canvas/'; - } var _url = _urlBase + source.layer + '/MapServer/tile/{z}/{y}/{x}'; oSource = new ol.source.XYZ({ attributions: createAttribution(source), - tileLoadFunction: source.tileLoadFunction, - url: _url, - wrapX: source.wrapX !== undefined ? source.wrapX : true - }); - - break; - - case 'TileArcGISRest': - if (!source.url) { - $log.error('[AngularJS - Openlayers] - TileArcGISRest Layer needs valid url'); - } - - oSource = new ol.source.TileArcGISRest({ - attributions: createAttribution(source), - tileLoadFunction: source.tileLoadFunction, - url: source.url, - wrapX: source.wrapX !== undefined ? source.wrapX : true + url: _url }); break; @@ -1700,48 +1586,12 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ var features = geojsonFormat.readFeatures( source.geojson.object, { - featureProjection: projectionToUse.getCode(), - dataProjection: dataProjection.getCode() + featureProjection: projectionToUse, + dataProjection: dataProjection }); oSource.addFeatures(features); } - break; - case 'WKT': - if (!(source.wkt || source.url)) { - $log.error('[AngularJS - Openlayers] - You need a WKT ' + - 'property to add a GeoJSON layer.'); - return; - } - if (isDefined(source.url)) { - oSource = new ol.source.Vector({ - format: new ol.format.WKT(), - url: source.url, - wrapX: source.wrapX !== undefined ? source.wrapX : true - }); - } else { - oSource = new ol.source.Vector(); - var featureProjection = projection; - var wktProjection; - if (isDefined(source.wkt.projection)) { - wktProjection = new ol.proj.get(source.wkt.projection); - } else { - wktProjection = projection; - } - - var wktFormat = new ol.format.WKT(); - var wktFeatures = []; - for (var k = 0; k < source.wkt.object.length; k++) { - var feature = wktFormat.readFeature( - source.wkt.object[k].data, {dataProjection: wktProjection.getCode() , - featureProjection: featureProjection.getCode() }); - if (source.wkt.object[k].properties) { - feature.properties = source.wkt.object[k].properties; - } - wktFeatures.push(feature); - } - oSource.addFeatures(wktFeatures); - } break; case 'JSONP': @@ -1790,9 +1640,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ oSource = new ol.source.TileJSON({ url: source.url, attributions: createAttribution(source), - tileLoadFunction: source.tileLoadFunction, - crossOrigin: 'anonymous', - wrapX: source.wrapX !== undefined ? source.wrapX : true + crossOrigin: 'anonymous' }); break; @@ -1804,12 +1652,10 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ url: source.url, projection: projection, attributions: createAttribution(source), - tileLoadFunction: source.tileLoadFunction, format: source.format, tileGrid: new ol.tilegrid.createXYZ({ maxZoom: source.maxZoom || 19 - }), - wrapX: source.wrapX !== undefined ? source.wrapX : true + }) }); break; @@ -1821,7 +1667,6 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ url: source.url, maxExtent: source.maxExtent, attributions: createAttribution(source), - tileLoadFunction: source.tileLoadFunction, tileGrid: new ol.tilegrid.TileGrid({ origin: source.tileGrid.origin, resolutions: source.tileGrid.resolutions @@ -1839,15 +1684,13 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ var url = source.url + z + '/' + x + '/' + y + '.png'; return url; - }, - wrapX: source.wrapX !== undefined ? source.wrapX : true + } }); break; case 'TileImage': oSource = new ol.source.TileImage({ url: source.url, attributions: createAttribution(source), - tileLoadFunction: source.tileLoadFunction, tileGrid: new ol.tilegrid.TileGrid({ origin: source.tileGrid.origin, // top left corner of the pixel projection's extent resolutions: source.tileGrid.resolutions @@ -1861,18 +1704,16 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ .replace('{x}', x.toString()) .replace('{y}', y.toString()); return url; - }, - wrapX: source.wrapX !== undefined ? source.wrapX : true + } }); break; case 'KML': var extractStyles = source.extractStyles || false; oSource = new ol.source.Vector({ url: source.url, - format: new ol.format.KML({ - extractStyles: extractStyles - }), - radius: source.radius + format: new ol.format.KML(), + radius: source.radius, + extractStyles: extractStyles }); break; case 'Stamen': @@ -1881,9 +1722,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ return; } oSource = new ol.source.Stamen({ - tileLoadFunction: source.tileLoadFunction, - layer: source.layer, - wrapX: source.wrapX !== undefined ? source.wrapX : true + layer: source.layer }); break; case 'ImageStatic': @@ -1911,9 +1750,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ minZoom: source.minZoom, maxZoom: source.maxZoom, projection: source.projection, - tileUrlFunction: source.tileUrlFunction, - tileLoadFunction: source.tileLoadFunction, - wrapX: source.wrapX !== undefined ? source.wrapX : true + tileUrlFunction: source.tileUrlFunction }); break; case 'Zoomify': @@ -1922,8 +1759,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ } oSource = new ol.source.Zoomify({ url: source.url, - size: source.imageSize, - wrapX: source.wrapX !== undefined ? source.wrapX : true + size: source.imageSize }); break; } @@ -2198,22 +2034,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ }); } - var layerConfig = {}; - - // copy over eventual properties set on the passed layerconfig which - // can later be retrieved via layer.get('propName'); - for (var property in layer) { - if (layer.hasOwnProperty(property) && - // ignore props like source or those angular might add (starting with $) - !property.startsWith('$') && - !property.startsWith('source') && - !property.startsWith('style') - ) { - layerConfig[property] = layer[property]; - } - } - - layerConfig.source = oSource; + var layerConfig = { source: oSource }; // ol.layer.Layer configuration options if (isDefinedAndNotNull(layer.opacity)) { @@ -2234,9 +2055,6 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ if (isDefinedAndNotNull(layer.maxResolution)) { layerConfig.maxResolution = layer.maxResolution; } - if (isDefinedAndNotNull(layer.style) && type === 'TileVector') { - layerConfig.style = layer.style; - } switch (type) { case 'Image': @@ -2373,7 +2191,6 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ while (layers.getLength() < index) { var nullLayer = new ol.layer.Image(); nullLayer.index = layers.getLength(); // add index which will be equal to the length in this case - nullLayer.name = '(null-layer)'; // we need a marker somehow layers.push(nullLayer); } layer.index = index; @@ -2381,11 +2198,9 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ } else { layer.index = index; layers.insertAt(layer.index, layer); - - // remove eventual null layers for (var i = index + 1; i < layers.getLength(); i++) { var l = layers.item(i); - if (l.name === '(null-layer)') { + if (l === null) { layers.removeAt(i); break; } else { @@ -2560,5 +2375,5 @@ angular.module('openlayers-directive').factory('olMapDefaults', function($q, olH } }; }); -return angular.module('openlayers-directive'); + })); \ No newline at end of file diff --git a/grunt/concat.js b/grunt/concat.js index a0aaa9c0..31e34c2f 100644 --- a/grunt/concat.js +++ b/grunt/concat.js @@ -3,8 +3,7 @@ var banner = '(function (root, factory) {\n' + ' if (typeof require === \'function\' && typeof exports === \'object\') {\n' + ' // CommonJS\n' + - ' var ol = require(\'openlayers-prebuilt\');\n' + - ' var ngSanitize = require(\'angular-sanitize\');\n' + + ' var ol = require(\'openlayers\');\n' + ' exports.angularOpenlayersDirective = factory(ol);\n' + ' } else if (typeof define === \'function\' && define.amd) {\n' + ' // AMD.\n' + @@ -16,15 +15,13 @@ var banner = '(function (root, factory) {\n' + ' root.angularOpenlayersDirective = factory(root.ol);\n' + ' }\n' + '}(this, function (ol) {\n'; -var footer = 'return angular.module(\'openlayers-directive\');' + - '\n}));'; module.exports = function (grunt, options) { return { dist: { options: { banner: banner, - footer: footer + footer: '\n}));' }, src: [ 'src/directives/openlayers.js', diff --git a/node_modules/.bin/grunt-open b/node_modules/.bin/grunt-open deleted file mode 100644 index b6035be1..00000000 --- a/node_modules/.bin/grunt-open +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh -basedir=`dirname "$0"` - -case `uname` in - *CYGWIN*) basedir=`cygpath -w "$basedir"`;; -esac - -if [ -x "$basedir/node" ]; then - "$basedir/node" "$basedir/../grunt-open/bin/grunt-open" "$@" - ret=$? -else - node "$basedir/../grunt-open/bin/grunt-open" "$@" - ret=$? -fi -exit $ret diff --git a/package.json b/package.json index 8b7700c1..4320cc43 100644 --- a/package.json +++ b/package.json @@ -17,9 +17,9 @@ ], "license": "MIT", "dependencies": { - "angular": "^1.4.8", - "angular-sanitize": "^1.4.8", - "openlayers-prebuilt": "^3.12.1" + "angular": "~1.4.8", + "angular-sanitize": "~1.4.8", + "openlayers": "~3.8" }, "devDependencies": { "grunt": "~0.4.5", @@ -65,5 +65,5 @@ "semantic-release": "semantic-release pre && npm publish && semantic-release post" }, "main": "dist/angular-openlayers-directive", - "version": "1.19.1" -} + "version": "1.15.1" +} \ No newline at end of file diff --git a/src/directives/center.js b/src/directives/center.js index cb1964df..fc8d6c7b 100644 --- a/src/directives/center.js +++ b/src/directives/center.js @@ -177,8 +177,8 @@ angular.module('openlayers-directive').directive('olCenter', function($log, $loc } }); }); - - olScope.$on('$destroy', function() { + + olScope.$on('$destroy', function(){ map.unByKey(moveEndEventKey); }); }); diff --git a/src/directives/control.js b/src/directives/control.js index 76b11fbd..ee9f0bc0 100644 --- a/src/directives/control.js +++ b/src/directives/control.js @@ -1,5 +1,5 @@ -angular.module('openlayers-directive') -.directive('olControl', function($log, $q, olData, olMapDefaults, olHelpers) { +angular.module('openlayers-directive').directive('olControl', function($log, $q, olData, olMapDefaults, olHelpers) { + return { restrict: 'E', scope: { @@ -12,58 +12,29 @@ angular.module('openlayers-directive') var olScope = controller.getOpenlayersScope(); var olControl; var olControlOps; - var getControlClasses = olHelpers.getControlClasses; - var controlClasses = getControlClasses(); olScope.getMap().then(function(map) { + var getControlClasses = olHelpers.getControlClasses; + var controlClasses = getControlClasses(); scope.$on('$destroy', function() { map.removeControl(olControl); }); - scope.$watch('properties', function(properties) { - if (!isDefined(properties)) { - return; - } - - initCtrls(properties); - }); - - function initCtrls(properties) { - if (properties && properties.control) { - // the control instance is already defined, - // so simply use it and go ahead - - // is there already a control, so destroy and recreate it? - if (olControl) { - map.removeControl(olControl); + if (!isDefined(scope.properties) || !isDefined(scope.properties.control)) { + if (attrs.name) { + if (isDefined(scope.properties)) { + olControlOps = scope.properties; } - - olControl = properties.control; + olControl = new controlClasses[attrs.name](olControlOps); map.addControl(olControl); - } else { - - // the name is the key to instantiate an ol3 control - if (attrs.name) { - if (isDefined(properties)) { - olControlOps = properties; - } - - // is there already a control, so destroy and recreate it? - if (olControl) { - map.removeControl(olControl); - } - - olControl = new controlClasses[attrs.name](olControlOps); - map.addControl(olControl); - } } + return; } - initCtrls(scope.properties); - + olControl = scope.properties.control; + map.addControl(olControl); }); - } }; }); diff --git a/src/directives/marker.js b/src/directives/marker.js index 5fa0aa0a..daee51a2 100644 --- a/src/directives/marker.js +++ b/src/directives/marker.js @@ -58,7 +58,6 @@ angular.module('openlayers-directive').directive('olMarker', function($log, $q, if (!scopes.length) { map.removeLayer(mapDict[mapIndex].markerLayer); - delete mapDict[mapIndex].markerLayer; delete mapDict[mapIndex]; } } @@ -103,7 +102,7 @@ angular.module('openlayers-directive').directive('olMarker', function($log, $q, // This function handles dragging a marker var pickOffset = null; var pickProperties = null; - scope.handleDrag = function(evt) { + function handleDrag(evt) { var coord = evt.coordinate; var proj = map.getView().getProjection().getCode(); if (proj === 'pixel') { @@ -152,25 +151,12 @@ angular.module('openlayers-directive').directive('olMarker', function($log, $q, }); } } - }; - - function unregisterHandlers() { - if (!scope.properties) { return ; } - // Remove previous listeners if any - map.getViewport().removeEventListener('mousemove', scope.properties.handleInteraction); - map.getViewport().removeEventListener('click', scope.properties.handleTapInteraction); - map.getViewport().querySelector('canvas.ol-unselectable').removeEventListener( - 'touchend', scope.properties.handleTapInteraction); - map.getViewport().removeEventListener('mousemove', scope.properties.showAtLeastOneOverlay); - map.getViewport().removeEventListener('click', scope.properties.removeAllOverlays); - map.getViewport().querySelector('canvas.ol-unselectable').removeEventListener( - 'touchmove', scope.properties.activateCooldown); } // Setup generic handlers for marker drag - map.on('pointerdown', scope.handleDrag); - map.on('pointerup', scope.handleDrag); - map.on('pointerdrag', scope.handleDrag); + map.on('pointerdown', handleDrag); + map.on('pointerup', handleDrag); + map.on('pointerdrag', handleDrag); scope.$on('$destroy', function() { markerLayer.getSource().removeFeature(marker); @@ -178,10 +164,6 @@ angular.module('openlayers-directive').directive('olMarker', function($log, $q, map.removeOverlay(label); } markerLayerManager.deregisterScope(scope, map); - map.un('pointerdown', scope.handleDrag); - map.un('pointerup', scope.handleDrag); - map.un('pointerdrag', scope.handleDrag); - unregisterHandlers(); }); if (!isDefined(scope.properties)) { @@ -211,7 +193,13 @@ angular.module('openlayers-directive').directive('olMarker', function($log, $q, scope.$watch('properties', function(properties) { - unregisterHandlers(); + // Remove previous listeners if any + map.getViewport().removeEventListener('mousemove', properties.handleInteraction); + map.getViewport().removeEventListener('click', properties.handleTapInteraction); + map.getViewport().querySelector('canvas.ol-unselectable').removeEventListener( + 'touchend', properties.handleTapInteraction); + map.getViewport().removeEventListener('mousemove', properties.showAtLeastOneOverlay); + map.getViewport().removeEventListener('click', properties.removeAllOverlays); // This function handles popup on mouse over/click properties.handleInteraction = function(evt) { @@ -270,7 +258,7 @@ angular.module('openlayers-directive').directive('olMarker', function($log, $q, var prevTimeout; // Sets the cooldown flag to filter out any subsequent events within 500 ms - properties.activateCooldown = function() { + function activateCooldown() { cooldownActive = true; if (prevTimeout) { clearTimeout(prevTimeout); @@ -279,20 +267,16 @@ angular.module('openlayers-directive').directive('olMarker', function($log, $q, cooldownActive = false; prevTimeout = null; }, 500); - }; + } // Preventing from 'touchend' to be considered a tap, if fired immediately after 'touchmove' - if (properties.activateCooldown) { - map.getViewport().querySelector('canvas.ol-unselectable').removeEventListener( - 'touchmove', properties.activateCooldown); - } map.getViewport().querySelector('canvas.ol-unselectable').addEventListener( - 'touchmove', properties.activateCooldown); + 'touchmove', activateCooldown); return function() { if (!cooldownActive) { properties.handleInteraction.apply(null, arguments); - properties.activateCooldown(); + activateCooldown(); } }; })(); diff --git a/src/directives/view.js b/src/directives/view.js index 10f28d1e..b6f21c59 100644 --- a/src/directives/view.js +++ b/src/directives/view.js @@ -49,10 +49,6 @@ angular.module('openlayers-directive').directive('olView', function($log, $q, ol map.unByKey(rotationEventKey); }); - olScope.$on('$destroy', function() { - map.unByKey(rotationEventKey); - }); - }); } }; diff --git a/src/services/olHelpers.js b/src/services/olHelpers.js index 29c2e135..5b5549aa 100644 --- a/src/services/olHelpers.js +++ b/src/services/olHelpers.js @@ -152,10 +152,8 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ case 'JSONP': case 'TopoJSON': case 'KML': - case 'WKT': return 'Vector'; case 'TileVector': - case 'MVT': return 'TileVector'; default: return 'Tile'; @@ -193,7 +191,6 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ var createSource = function(source, projection) { var oSource; - var pixelRatio; var url; var geojsonFormat = new ol.format.GeoJSON(); // used in various switch stmnts below @@ -203,10 +200,10 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ $log.error('[AngularJS - Openlayers] - MapBox layer requires the map id and the access token'); return; } - url = 'https://api.tiles.mapbox.com/v4/' + source.mapId + '/{z}/{x}/{y}.png?access_token=' + + url = 'http://api.tiles.mapbox.com/v4/' + source.mapId + '/{z}/{x}/{y}.png?access_token=' + source.accessToken; - pixelRatio = window.devicePixelRatio; + var pixelRatio = window.devicePixelRatio; if (pixelRatio > 1) { url = url.replace('.png', '@2x.png'); @@ -214,10 +211,8 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ oSource = new ol.source.XYZ({ url: url, - tileLoadFunction: source.tileLoadFunction, attributions: createAttribution(source), - tilePixelRatio: pixelRatio > 1 ? 2 : 1, - wrapX: source.wrapX !== undefined ? source.wrapX : true + tilePixelRatio: pixelRatio > 1 ? 2 : 1 }); break; case 'MapBoxStudio': @@ -230,32 +225,10 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ '/' + source.mapId + '/tiles/{z}/{x}/{y}?access_token=' + source.accessToken; - pixelRatio = window.devicePixelRatio; - - if (pixelRatio > 1) { - url = url.replace('{y}?access_token', '{y}@2x?access_token'); - } - oSource = new ol.source.XYZ({ url: url, - tileLoadFunction: source.tileLoadFunction, attributions: createAttribution(source), - tilePixelRatio: pixelRatio > 1 ? 2 : 1, - tileSize: source.tileSize || [512, 512], - wrapX: source.wrapX !== undefined ? source.wrapX : true - }); - break; - case 'MVT': - if (!source.url) { - $log.error('[AngularJS - Openlayers] - MVT layer requires the source url'); - return; - } - oSource = new ol.source.VectorTile({ - attributions: source.attributions || '', - format: new ol.format.MVT(), - tileGrid: ol.tilegrid.createXYZ({maxZoom: source.maxZoom || 22}), - tilePixelRatio: source.tilePixelRatio || 16, - url: source.url + tileSize: source.tileSize || [512, 512] }); break; case 'ImageWMS': @@ -265,7 +238,6 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ } oSource = new ol.source.ImageWMS({ url: source.url, - imageLoadFunction: source.imageLoadFunction, attributions: createAttribution(source), crossOrigin: (typeof source.crossOrigin === 'undefined') ? 'anonymous' : source.crossOrigin, params: deepCopy(source.params), @@ -280,17 +252,11 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ } var wmsConfiguration = { - tileLoadFunction: source.tileLoadFunction, crossOrigin: (typeof source.crossOrigin === 'undefined') ? 'anonymous' : source.crossOrigin, params: deepCopy(source.params), - attributions: createAttribution(source), - wrapX: source.wrapX !== undefined ? source.wrapX : true + attributions: createAttribution(source) }; - if (source.projection) { - wmsConfiguration.projection = new ol.proj.get(source.projection); - } - if (source.serverType) { wmsConfiguration.serverType = source.serverType; } @@ -313,7 +279,6 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ } var wmtsConfiguration = { - tileLoadFunction: source.tileLoadFunction, projection: projection, layer: source.layer, attributions: createAttribution(source), @@ -326,8 +291,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ resolutions: source.tileGrid.resolutions, matrixIds: source.tileGrid.matrixIds }), - style: (source.style === 'undefined') ? 'normal' : source.style, - wrapX: source.wrapX !== undefined ? source.wrapX : true + style: (source.style === 'undefined') ? 'normal' : source.style }; if (isDefined(source.url)) { @@ -343,9 +307,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ case 'OSM': oSource = new ol.source.OSM({ - tileLoadFunction: source.tileLoadFunction, - attributions: createAttribution(source), - wrapX: source.wrapX !== undefined ? source.wrapX : true + attributions: createAttribution(source) }); if (source.url) { @@ -361,11 +323,9 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ var bingConfiguration = { key: source.key, - tileLoadFunction: source.tileLoadFunction, attributions: createAttribution(source), imagerySet: source.imagerySet ? source.imagerySet : bingImagerySets[0], - culture: source.culture, - wrapX: source.wrapX !== undefined ? source.wrapX : true + culture: source.culture }; if (source.maxZoom) { @@ -383,8 +343,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ oSource = new ol.source.MapQuest({ attributions: createAttribution(source), - layer: source.layer, - wrapX: source.wrapX !== undefined ? source.wrapX : true + layer: source.layer }); break; @@ -403,23 +362,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ oSource = new ol.source.XYZ({ attributions: createAttribution(source), - tileLoadFunction: source.tileLoadFunction, - url: _url, - wrapX: source.wrapX !== undefined ? source.wrapX : true - }); - - break; - - case 'TileArcGISRest': - if (!source.url) { - $log.error('[AngularJS - Openlayers] - TileArcGISRest Layer needs valid url'); - } - - oSource = new ol.source.TileArcGISRest({ - attributions: createAttribution(source), - tileLoadFunction: source.tileLoadFunction, - url: source.url, - wrapX: source.wrapX !== undefined ? source.wrapX : true + url: _url }); break; @@ -455,42 +398,6 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ oSource.addFeatures(features); } - break; - case 'WKT': - if (!(source.wkt || source.url)) { - $log.error('[AngularJS - Openlayers] - You need a WKT ' + - 'property to add a GeoJSON layer.'); - return; - } - if (isDefined(source.url)) { - oSource = new ol.source.Vector({ - format: new ol.format.WKT(), - url: source.url, - wrapX: source.wrapX !== undefined ? source.wrapX : true - }); - } else { - oSource = new ol.source.Vector(); - var featureProjection = projection; - var wktProjection; - if (isDefined(source.wkt.projection)) { - wktProjection = new ol.proj.get(source.wkt.projection); - } else { - wktProjection = projection; - } - - var wktFormat = new ol.format.WKT(); - var wktFeatures = []; - for (var k = 0; k < source.wkt.object.length; k++) { - var feature = wktFormat.readFeature( - source.wkt.object[k].data, {dataProjection: wktProjection.getCode() , - featureProjection: featureProjection.getCode() }); - if (source.wkt.object[k].properties) { - feature.properties = source.wkt.object[k].properties; - } - wktFeatures.push(feature); - } - oSource.addFeatures(wktFeatures); - } break; case 'JSONP': @@ -539,9 +446,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ oSource = new ol.source.TileJSON({ url: source.url, attributions: createAttribution(source), - tileLoadFunction: source.tileLoadFunction, - crossOrigin: 'anonymous', - wrapX: source.wrapX !== undefined ? source.wrapX : true + crossOrigin: 'anonymous' }); break; @@ -553,12 +458,10 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ url: source.url, projection: projection, attributions: createAttribution(source), - tileLoadFunction: source.tileLoadFunction, format: source.format, tileGrid: new ol.tilegrid.createXYZ({ maxZoom: source.maxZoom || 19 - }), - wrapX: source.wrapX !== undefined ? source.wrapX : true + }) }); break; @@ -570,7 +473,6 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ url: source.url, maxExtent: source.maxExtent, attributions: createAttribution(source), - tileLoadFunction: source.tileLoadFunction, tileGrid: new ol.tilegrid.TileGrid({ origin: source.tileGrid.origin, resolutions: source.tileGrid.resolutions @@ -588,15 +490,13 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ var url = source.url + z + '/' + x + '/' + y + '.png'; return url; - }, - wrapX: source.wrapX !== undefined ? source.wrapX : true + } }); break; case 'TileImage': oSource = new ol.source.TileImage({ url: source.url, attributions: createAttribution(source), - tileLoadFunction: source.tileLoadFunction, tileGrid: new ol.tilegrid.TileGrid({ origin: source.tileGrid.origin, // top left corner of the pixel projection's extent resolutions: source.tileGrid.resolutions @@ -610,8 +510,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ .replace('{x}', x.toString()) .replace('{y}', y.toString()); return url; - }, - wrapX: source.wrapX !== undefined ? source.wrapX : true + } }); break; case 'KML': @@ -630,9 +529,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ return; } oSource = new ol.source.Stamen({ - tileLoadFunction: source.tileLoadFunction, - layer: source.layer, - wrapX: source.wrapX !== undefined ? source.wrapX : true + layer: source.layer }); break; case 'ImageStatic': @@ -660,9 +557,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ minZoom: source.minZoom, maxZoom: source.maxZoom, projection: source.projection, - tileUrlFunction: source.tileUrlFunction, - tileLoadFunction: source.tileLoadFunction, - wrapX: source.wrapX !== undefined ? source.wrapX : true + tileUrlFunction: source.tileUrlFunction }); break; case 'Zoomify': @@ -671,8 +566,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ } oSource = new ol.source.Zoomify({ url: source.url, - size: source.imageSize, - wrapX: source.wrapX !== undefined ? source.wrapX : true + size: source.imageSize }); break; } @@ -947,22 +841,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ }); } - var layerConfig = {}; - - // copy over eventual properties set on the passed layerconfig which - // can later be retrieved via layer.get('propName'); - for (var property in layer) { - if (layer.hasOwnProperty(property) && - // ignore props like source or those angular might add (starting with $) - !property.startsWith('$') && - !property.startsWith('source') && - !property.startsWith('style') - ) { - layerConfig[property] = layer[property]; - } - } - - layerConfig.source = oSource; + var layerConfig = { source: oSource }; // ol.layer.Layer configuration options if (isDefinedAndNotNull(layer.opacity)) { @@ -983,9 +862,6 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ if (isDefinedAndNotNull(layer.maxResolution)) { layerConfig.maxResolution = layer.maxResolution; } - if (isDefinedAndNotNull(layer.style) && type === 'TileVector') { - layerConfig.style = layer.style; - } switch (type) { case 'Image': @@ -1122,7 +998,6 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ while (layers.getLength() < index) { var nullLayer = new ol.layer.Image(); nullLayer.index = layers.getLength(); // add index which will be equal to the length in this case - nullLayer.name = '(null-layer)'; // we need a marker somehow layers.push(nullLayer); } layer.index = index; @@ -1130,11 +1005,9 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ } else { layer.index = index; layers.insertAt(layer.index, layer); - - // remove eventual null layers for (var i = index + 1; i < layers.getLength(); i++) { var l = layers.item(i); - if (l.name === '(null-layer)') { + if (l === null) { layers.removeAt(i); break; } else { diff --git a/test/unit/layersSpec.js b/test/unit/layersSpec.js index 7e04d3d7..5b3a1d9d 100755 --- a/test/unit/layersSpec.js +++ b/test/unit/layersSpec.js @@ -124,38 +124,6 @@ describe('Directive: openlayers layers', function() { expect(geoJsonLayer.getSource().getFeatures().length).not.toBe(0); }); - it('should properly render a vector layer containing the WKT format object', function() { - scope.wktLayer = { - source: { - type: 'WKT', - wkt: { - data: 'POLYGON((72.564697265625 61.3916015625, 79.595947265625 56.4697265625, ' + - '82.408447265625 63.5009765625, 71.861572265625 59.9853515625, ' + - '72.564697265625 61.3916015625))', - projection: 'EPSG:4326' - } - } - }; - - var element = angular.element('' + - '' + - ''); - element = $compile(element)(scope); - - var layers; - olData.getMap().then(function(olMap) { - layers = olMap.getLayers(); - }); - - scope.$digest(); - expect(layers.item(0).getSource() instanceof ol.source.OSM).toBe(true); - expect(layers.getLength()).toBe(2); - - var wktLayer = layers.item(1); - expect(wktLayer.getSource() instanceof ol.source.Vector).toBe(true); - expect(wktLayer.getSource().getFeatures().length).not.toBe(0); - }); - it('should have one layer if custom-layers is used', function() { scope.mapbox = { source: { @@ -405,85 +373,4 @@ describe('Directive: openlayers layers', function() { expect(otherLayer.getLayers().getArray()[0].get('group')).toEqual('Other'); }); - - describe('when setting the index', function() { - - it('should correctly fill up the layer collection with null layers', function() { - scope.layers = [ - { - index: 2, - name: 'Spain', - source: { - type: 'GeoJSON', - url: 'json/ESP.geo.json' - } - } - ]; - - var element = angular - .element('' + - '' + - ''); - element = $compile(element)(scope); - - var layers; - olData.getMap().then(function(olMap) { - layers = olMap.getLayers(); - }); - - scope.$digest(); - expect(layers.getLength()).toBe(3); - - expect(layers.item(2).getSource() instanceof ol.source.Vector).toBeTruthy(); - }); - - it('should correctly populate the layer collection with when layers are provided in random order', function() { - scope.layers = [ - { - index: 1, - name: 'Spain', - source: { - type: 'GeoJSON', - url: 'json/ESP.geo.json' - } - }, - { - index: 2, - name: 'Italy', - source: { - type: 'GeoJSON', - url: 'json/ESP.geo.json' - } - }, - { - index: 0, - name: 'Germany', - source: { - type: 'GeoJSON', - url: 'json/ESP.geo.json' - } - } - ]; - - var element = angular - .element('' + - '' + - ''); - element = $compile(element)(scope); - - var layers; - olData.getMap().then(function(olMap) { - layers = olMap.getLayers(); - }); - - scope.$digest(); - expect(layers.getLength()).toBe(3); - - expect(layers.item(0).get('name')).toBe('Germany'); - expect(layers.item(1).get('name')).toBe('Spain'); - expect(layers.item(2).get('name')).toBe('Italy'); - }); - - }); - }); diff --git a/test/unit/markerSpec.js b/test/unit/markerSpec.js deleted file mode 100644 index d2b839c2..00000000 --- a/test/unit/markerSpec.js +++ /dev/null @@ -1,23 +0,0 @@ -'use strict'; -/*jshint -W117 */ -/*jshint globalstrict: true*/ -/* jasmine specs for directives go here */ - -describe('Directive: openlayers marker', function() { - var $compile = null; - var scope; - - beforeEach(module('openlayers-directive')); - beforeEach(inject(function(_$compile_, $rootScope) { - $compile = _$compile_; - - scope = $rootScope.$new(); - })); - - it('should not error on $scope.$destroy', function() { - var element = angular.element(''); - element = $compile(element)(scope); - scope.$digest(); - expect(function() { scope.$destroy(); }).not.toThrow(); - }); -}); From 9d48de90ee0c1858fc1b6c7b8e91357855247a35 Mon Sep 17 00:00:00 2001 From: Sathish Kesavaperumal Date: Mon, 13 Mar 2017 14:42:31 +0530 Subject: [PATCH 35/53] Generate the dist files for 1.19.2 version --- dist/angular-openlayers-directive.js | 7 ++++--- dist/angular-openlayers-directive.min.js | 6 +++--- dist/angular-openlayers-directive.min.no-header.js | 6 +++--- dist/angular-openlayers-directive.pre.js | 7 ++++--- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/dist/angular-openlayers-directive.js b/dist/angular-openlayers-directive.js index 6c409736..2ae6297b 100644 --- a/dist/angular-openlayers-directive.js +++ b/dist/angular-openlayers-directive.js @@ -2205,9 +2205,10 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt for (var property in layer) { if (layer.hasOwnProperty(property) && // ignore props like source or those angular might add (starting with $) - !property.startsWith('$') && - !property.startsWith('source') && - !property.startsWith('style') + // don't use startsWith as it is not supported in IE + property.indexOf('$', 0) !== 0 && + property.indexOf('source', 0) !== 0 && + property.indexOf('style', 0) !== 0 ) { layerConfig[property] = layer[property]; } diff --git a/dist/angular-openlayers-directive.min.js b/dist/angular-openlayers-directive.min.js index b437b287..5b7aa5df 100644 --- a/dist/angular-openlayers-directive.min.js +++ b/dist/angular-openlayers-directive.min.js @@ -27,6 +27,6 @@ * @authors https://github.com/tombatossals/angular-openlayers-directive/graphs/contributors */ -/*! angular-openlayers-directive 28-02-2017 */ -!function(a,b){if("function"==typeof require&&"object"==typeof exports){var c=require("openlayers-prebuilt");require("angular-sanitize");exports.angularOpenlayersDirective=b(c)}else"function"==typeof define&&define.amd?define(["ol"],function(c){return a.angularOpenlayersDirective=b(c)}):a.angularOpenlayersDirective=b(a.ol)}(this,function(a){return angular.module("openlayers-directive",["ngSanitize"]).directive("openlayers",["$log","$q","$compile","olHelpers","olMapDefaults","olData",function(b,c,d,e,f,g){return{restrict:"EA",transclude:!0,replace:!0,scope:{center:"=olCenter",defaults:"=olDefaults",view:"=olView",events:"=olEvents"},template:'
',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id)}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(h.olCenter.search("-")!==-1)return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}});var w=f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})});r.$on("$destroy",function(){f.unByKey(w)})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)});var f=e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})});g.$on("$destroy",function(){a.unByKey(f)})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope(),j=e.getControlClasses,k=j();i.getMap().then(function(b){function d(a){a&&a.control?(f&&b.removeControl(f),f=a.control,b.addControl(f)):c.name&&(h(a)&&(g=a),f&&b.removeControl(f),f=new k[c.name](g),b.addControl(f))}a.$on("$destroy",function(){b.removeControl(f)}),a.$watch("properties",function(a){h(a)&&d(a)}),d(a.properties)})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(f===-1){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(e===-1)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(g===-1)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e].markerLayer,delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(){c.properties&&(e.getViewport().removeEventListener("mousemove",c.properties.handleInteraction),e.getViewport().removeEventListener("click",c.properties.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",c.properties.handleTapInteraction),e.getViewport().removeEventListener("mousemove",c.properties.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",c.properties.removeAllOverlays),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",c.properties.activateCooldown))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return c.handleDrag=function(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))},e.on("pointerdown",c.handleDrag),e.on("pointerup",c.handleDrag),e.on("pointerdrag",c.handleDrag),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e),e.un("pointerdown",c.handleDrag),e.un("pointerup",c.handleDrag),e.un("pointerdrag",c.handleDrag),j()}),k(c.properties)?void c.$watch("properties",function(d){if(j(),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){var a,b=!1;return d.activateCooldown=function(){b=!0,a&&clearTimeout(a),a=setTimeout(function(){b=!1,a=null},500)},d.activateCooldown&&e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",d.activateCooldown),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",d.activateCooldown),function(){b||(d.handleInteraction.apply(null,arguments),d.activateCooldown())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){var d=c(a,b);a[d].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d,e=c(a,b);return d=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:f(a,b)};this.setMap=function(a,b){var c=f(d,b);c.resolve(a),e(d,b)},this.getMap=function(a){var b=g(d,a);return b.promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map","World_Light_Gray_Base","World_Dark_Gray_Base"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function a(b,c){var d;if(c?d=b[c]:(c="style",d=b),"style"===c&&b instanceof Function)return b;if(!(d instanceof Object))return d;var e;if("[object Object]"===Object.prototype.toString.call(d)){e={};var f=l[c];if(f&&d instanceof f)return d;Object.getOwnPropertyNames(d).forEach(function(b,g,h){var i=l[b];return f&&i&&i.prototype instanceof l[c]?(console.assert(1===h.length,"Extra parameters for "+c),e=a(d,b),m(e,i)):(e[b]=a(d,b),void("text"!==b&&"string"!=typeof e[b]&&(e[b]=m(e[b],l[b]))))})}else e=d;return m(e,l[c])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":return"Vector";case"TileVector":case"MVT":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return["watercolor","terrain","toner"].indexOf(a)!==-1},r=function(b,f){var g,i,l,m=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");l="https://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace(".png","@2x.png")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,wrapX:void 0===b.wrapX||b.wrapX});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");l="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace("{y}?access_token","{y}@2x?access_token")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,tileSize:b.tileSize||[512,512],wrapX:void 0===b.wrapX||b.wrapX});break;case"MVT":if(!b.url)return void c.error("[AngularJS - Openlayers] - MVT layer requires the source url");g=new a.source.VectorTile({attributions:b.attributions||"",format:new a.format.MVT,tileGrid:a.tilegrid.createXYZ({maxZoom:b.maxZoom||22}),tilePixelRatio:b.tilePixelRatio||16,url:b.url});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,imageLoadFunction:b.imageLoadFunction,attributions:t(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={tileLoadFunction:b.tileLoadFunction,crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX};b.projection&&(n.projection=new a.proj.get(b.projection)),b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={tileLoadFunction:b.tileLoadFunction,projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),style:"undefined"===b.style?"normal":b.style,wrapX:void 0===b.wrapX||b.wrapX};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({tileLoadFunction:b.tileLoadFunction,attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,tileLoadFunction:b.tileLoadFunction,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX||b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||j.indexOf(b.layer)===-1)return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer,wrapX:void 0===b.wrapX||b.wrapX});break;case"EsriBaseMaps":if(!b.layer||k.indexOf(b.layer)===-1)return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="http://services.arcgisonline.com/ArcGIS/rest/services/";"World_Light_Gray_Base"!==b.layer&&"World_Dark_Gray_Base"!==b.layer||(r+="Canvas/");var u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:u,wrapX:void 0===b.wrapX||b.wrapX});break;case"TileArcGISRest":b.url||c.error("[AngularJS - Openlayers] - TileArcGISRest Layer needs valid url"),g=new a.source.TileArcGISRest({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=m.readFeatures(b.geojson.object,{featureProjection:w.getCode(),dataProjection:v.getCode()});g.addFeatures(x)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});else{g=new a.source.Vector;var y,z=f;y=e(b.wkt.projection)?new a.proj.get(b.wkt.projection):f;for(var A=new a.format.WKT,B=[],C=0;C',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id)}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(h.olCenter.search("-")!==-1)return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}});var w=f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})});r.$on("$destroy",function(){f.unByKey(w)})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)});var f=e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})});g.$on("$destroy",function(){a.unByKey(f)})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope(),j=e.getControlClasses,k=j();i.getMap().then(function(b){function d(a){a&&a.control?(f&&b.removeControl(f),f=a.control,b.addControl(f)):c.name&&(h(a)&&(g=a),f&&b.removeControl(f),f=new k[c.name](g),b.addControl(f))}a.$on("$destroy",function(){b.removeControl(f)}),a.$watch("properties",function(a){h(a)&&d(a)}),d(a.properties)})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(f===-1){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(e===-1)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(g===-1)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e].markerLayer,delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(){c.properties&&(e.getViewport().removeEventListener("mousemove",c.properties.handleInteraction),e.getViewport().removeEventListener("click",c.properties.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",c.properties.handleTapInteraction),e.getViewport().removeEventListener("mousemove",c.properties.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",c.properties.removeAllOverlays),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",c.properties.activateCooldown))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return c.handleDrag=function(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))},e.on("pointerdown",c.handleDrag),e.on("pointerup",c.handleDrag),e.on("pointerdrag",c.handleDrag),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e),e.un("pointerdown",c.handleDrag),e.un("pointerup",c.handleDrag),e.un("pointerdrag",c.handleDrag),j()}),k(c.properties)?void c.$watch("properties",function(d){if(j(),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){var a,b=!1;return d.activateCooldown=function(){b=!0,a&&clearTimeout(a),a=setTimeout(function(){b=!1,a=null},500)},d.activateCooldown&&e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",d.activateCooldown),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",d.activateCooldown),function(){b||(d.handleInteraction.apply(null,arguments),d.activateCooldown())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){var d=c(a,b);a[d].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d,e=c(a,b);return d=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:f(a,b)};this.setMap=function(a,b){var c=f(d,b);c.resolve(a),e(d,b)},this.getMap=function(a){var b=g(d,a);return b.promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map","World_Light_Gray_Base","World_Dark_Gray_Base"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function a(b,c){var d;if(c?d=b[c]:(c="style",d=b),"style"===c&&b instanceof Function)return b;if(!(d instanceof Object))return d;var e;if("[object Object]"===Object.prototype.toString.call(d)){e={};var f=l[c];if(f&&d instanceof f)return d;Object.getOwnPropertyNames(d).forEach(function(b,g,h){var i=l[b];return f&&i&&i.prototype instanceof l[c]?(console.assert(1===h.length,"Extra parameters for "+c),e=a(d,b),m(e,i)):(e[b]=a(d,b),void("text"!==b&&"string"!=typeof e[b]&&(e[b]=m(e[b],l[b]))))})}else e=d;return m(e,l[c])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":return"Vector";case"TileVector":case"MVT":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return["watercolor","terrain","toner"].indexOf(a)!==-1},r=function(b,f){var g,i,l,m=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");l="https://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace(".png","@2x.png")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,wrapX:void 0===b.wrapX||b.wrapX});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");l="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace("{y}?access_token","{y}@2x?access_token")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,tileSize:b.tileSize||[512,512],wrapX:void 0===b.wrapX||b.wrapX});break;case"MVT":if(!b.url)return void c.error("[AngularJS - Openlayers] - MVT layer requires the source url");g=new a.source.VectorTile({attributions:b.attributions||"",format:new a.format.MVT,tileGrid:a.tilegrid.createXYZ({maxZoom:b.maxZoom||22}),tilePixelRatio:b.tilePixelRatio||16,url:b.url});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,imageLoadFunction:b.imageLoadFunction,attributions:t(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={tileLoadFunction:b.tileLoadFunction,crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX};b.projection&&(n.projection=new a.proj.get(b.projection)),b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={tileLoadFunction:b.tileLoadFunction,projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),style:"undefined"===b.style?"normal":b.style,wrapX:void 0===b.wrapX||b.wrapX};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({tileLoadFunction:b.tileLoadFunction,attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,tileLoadFunction:b.tileLoadFunction,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX||b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||j.indexOf(b.layer)===-1)return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer,wrapX:void 0===b.wrapX||b.wrapX});break;case"EsriBaseMaps":if(!b.layer||k.indexOf(b.layer)===-1)return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="http://services.arcgisonline.com/ArcGIS/rest/services/";"World_Light_Gray_Base"!==b.layer&&"World_Dark_Gray_Base"!==b.layer||(r+="Canvas/");var u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:u,wrapX:void 0===b.wrapX||b.wrapX});break;case"TileArcGISRest":b.url||c.error("[AngularJS - Openlayers] - TileArcGISRest Layer needs valid url"),g=new a.source.TileArcGISRest({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=m.readFeatures(b.geojson.object,{featureProjection:w.getCode(),dataProjection:v.getCode()});g.addFeatures(x)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});else{g=new a.source.Vector;var y,z=f;y=e(b.wkt.projection)?new a.proj.get(b.wkt.projection):f;for(var A=new a.format.WKT,B=[],C=0;C',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id)}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(h.olCenter.search("-")!==-1)return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}});var w=f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})});r.$on("$destroy",function(){f.unByKey(w)})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)});var f=e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})});g.$on("$destroy",function(){a.unByKey(f)})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope(),j=e.getControlClasses,k=j();i.getMap().then(function(b){function d(a){a&&a.control?(f&&b.removeControl(f),f=a.control,b.addControl(f)):c.name&&(h(a)&&(g=a),f&&b.removeControl(f),f=new k[c.name](g),b.addControl(f))}a.$on("$destroy",function(){b.removeControl(f)}),a.$watch("properties",function(a){h(a)&&d(a)}),d(a.properties)})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(f===-1){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(e===-1)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(g===-1)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e].markerLayer,delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(){c.properties&&(e.getViewport().removeEventListener("mousemove",c.properties.handleInteraction),e.getViewport().removeEventListener("click",c.properties.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",c.properties.handleTapInteraction),e.getViewport().removeEventListener("mousemove",c.properties.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",c.properties.removeAllOverlays),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",c.properties.activateCooldown))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return c.handleDrag=function(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))},e.on("pointerdown",c.handleDrag),e.on("pointerup",c.handleDrag),e.on("pointerdrag",c.handleDrag),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e),e.un("pointerdown",c.handleDrag),e.un("pointerup",c.handleDrag),e.un("pointerdrag",c.handleDrag),j()}),k(c.properties)?void c.$watch("properties",function(d){if(j(),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){var a,b=!1;return d.activateCooldown=function(){b=!0,a&&clearTimeout(a),a=setTimeout(function(){b=!1,a=null},500)},d.activateCooldown&&e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",d.activateCooldown),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",d.activateCooldown),function(){b||(d.handleInteraction.apply(null,arguments),d.activateCooldown())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){var d=c(a,b);a[d].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d,e=c(a,b);return d=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:f(a,b)};this.setMap=function(a,b){var c=f(d,b);c.resolve(a),e(d,b)},this.getMap=function(a){var b=g(d,a);return b.promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map","World_Light_Gray_Base","World_Dark_Gray_Base"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function a(b,c){var d;if(c?d=b[c]:(c="style",d=b),"style"===c&&b instanceof Function)return b;if(!(d instanceof Object))return d;var e;if("[object Object]"===Object.prototype.toString.call(d)){e={};var f=l[c];if(f&&d instanceof f)return d;Object.getOwnPropertyNames(d).forEach(function(b,g,h){var i=l[b];return f&&i&&i.prototype instanceof l[c]?(console.assert(1===h.length,"Extra parameters for "+c),e=a(d,b),m(e,i)):(e[b]=a(d,b),void("text"!==b&&"string"!=typeof e[b]&&(e[b]=m(e[b],l[b]))))})}else e=d;return m(e,l[c])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":return"Vector";case"TileVector":case"MVT":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return["watercolor","terrain","toner"].indexOf(a)!==-1},r=function(b,f){var g,i,l,m=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");l="https://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace(".png","@2x.png")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,wrapX:void 0===b.wrapX||b.wrapX});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");l="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace("{y}?access_token","{y}@2x?access_token")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,tileSize:b.tileSize||[512,512],wrapX:void 0===b.wrapX||b.wrapX});break;case"MVT":if(!b.url)return void c.error("[AngularJS - Openlayers] - MVT layer requires the source url");g=new a.source.VectorTile({attributions:b.attributions||"",format:new a.format.MVT,tileGrid:a.tilegrid.createXYZ({maxZoom:b.maxZoom||22}),tilePixelRatio:b.tilePixelRatio||16,url:b.url});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,imageLoadFunction:b.imageLoadFunction,attributions:t(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={tileLoadFunction:b.tileLoadFunction,crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX};b.projection&&(n.projection=new a.proj.get(b.projection)),b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={tileLoadFunction:b.tileLoadFunction,projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),style:"undefined"===b.style?"normal":b.style,wrapX:void 0===b.wrapX||b.wrapX};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({tileLoadFunction:b.tileLoadFunction,attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,tileLoadFunction:b.tileLoadFunction,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX||b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||j.indexOf(b.layer)===-1)return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer,wrapX:void 0===b.wrapX||b.wrapX});break;case"EsriBaseMaps":if(!b.layer||k.indexOf(b.layer)===-1)return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="http://services.arcgisonline.com/ArcGIS/rest/services/";"World_Light_Gray_Base"!==b.layer&&"World_Dark_Gray_Base"!==b.layer||(r+="Canvas/");var u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:u,wrapX:void 0===b.wrapX||b.wrapX});break;case"TileArcGISRest":b.url||c.error("[AngularJS - Openlayers] - TileArcGISRest Layer needs valid url"),g=new a.source.TileArcGISRest({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=m.readFeatures(b.geojson.object,{featureProjection:w.getCode(),dataProjection:v.getCode()});g.addFeatures(x)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});else{g=new a.source.Vector;var y,z=f;y=e(b.wkt.projection)?new a.proj.get(b.wkt.projection):f;for(var A=new a.format.WKT,B=[],C=0;C',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id)}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(h.olCenter.search("-")!==-1)return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}});var w=f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})});r.$on("$destroy",function(){f.unByKey(w)})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)});var f=e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})});g.$on("$destroy",function(){a.unByKey(f)})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope(),j=e.getControlClasses,k=j();i.getMap().then(function(b){function d(a){a&&a.control?(f&&b.removeControl(f),f=a.control,b.addControl(f)):c.name&&(h(a)&&(g=a),f&&b.removeControl(f),f=new k[c.name](g),b.addControl(f))}a.$on("$destroy",function(){b.removeControl(f)}),a.$watch("properties",function(a){h(a)&&d(a)}),d(a.properties)})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(f===-1){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(e===-1)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(g===-1)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e].markerLayer,delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(){c.properties&&(e.getViewport().removeEventListener("mousemove",c.properties.handleInteraction),e.getViewport().removeEventListener("click",c.properties.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",c.properties.handleTapInteraction),e.getViewport().removeEventListener("mousemove",c.properties.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",c.properties.removeAllOverlays),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",c.properties.activateCooldown))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return c.handleDrag=function(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))},e.on("pointerdown",c.handleDrag),e.on("pointerup",c.handleDrag),e.on("pointerdrag",c.handleDrag),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e),e.un("pointerdown",c.handleDrag),e.un("pointerup",c.handleDrag),e.un("pointerdrag",c.handleDrag),j()}),k(c.properties)?void c.$watch("properties",function(d){if(j(),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){var a,b=!1;return d.activateCooldown=function(){b=!0,a&&clearTimeout(a),a=setTimeout(function(){b=!1,a=null},500)},d.activateCooldown&&e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",d.activateCooldown),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",d.activateCooldown),function(){b||(d.handleInteraction.apply(null,arguments),d.activateCooldown())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){var d=c(a,b);a[d].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d,e=c(a,b);return d=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:f(a,b)};this.setMap=function(a,b){var c=f(d,b);c.resolve(a),e(d,b)},this.getMap=function(a){var b=g(d,a);return b.promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map","World_Light_Gray_Base","World_Dark_Gray_Base"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function a(b,c){var d;if(c?d=b[c]:(c="style",d=b),"style"===c&&b instanceof Function)return b;if(!(d instanceof Object))return d;var e;if("[object Object]"===Object.prototype.toString.call(d)){e={};var f=l[c];if(f&&d instanceof f)return d;Object.getOwnPropertyNames(d).forEach(function(b,g,h){var i=l[b];return f&&i&&i.prototype instanceof l[c]?(console.assert(1===h.length,"Extra parameters for "+c),e=a(d,b),m(e,i)):(e[b]=a(d,b),void("text"!==b&&"string"!=typeof e[b]&&(e[b]=m(e[b],l[b]))))})}else e=d;return m(e,l[c])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":return"Vector";case"TileVector":case"MVT":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return["watercolor","terrain","toner"].indexOf(a)!==-1},r=function(b,f){var g,i,l,m=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");l="https://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace(".png","@2x.png")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,wrapX:void 0===b.wrapX||b.wrapX});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");l="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace("{y}?access_token","{y}@2x?access_token")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,tileSize:b.tileSize||[512,512],wrapX:void 0===b.wrapX||b.wrapX});break;case"MVT":if(!b.url)return void c.error("[AngularJS - Openlayers] - MVT layer requires the source url");g=new a.source.VectorTile({attributions:b.attributions||"",format:new a.format.MVT,tileGrid:a.tilegrid.createXYZ({maxZoom:b.maxZoom||22}),tilePixelRatio:b.tilePixelRatio||16,url:b.url});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,imageLoadFunction:b.imageLoadFunction,attributions:t(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={tileLoadFunction:b.tileLoadFunction,crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX};b.projection&&(n.projection=new a.proj.get(b.projection)),b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={tileLoadFunction:b.tileLoadFunction,projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),style:"undefined"===b.style?"normal":b.style,wrapX:void 0===b.wrapX||b.wrapX};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({tileLoadFunction:b.tileLoadFunction,attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,tileLoadFunction:b.tileLoadFunction,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX||b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||j.indexOf(b.layer)===-1)return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer,wrapX:void 0===b.wrapX||b.wrapX});break;case"EsriBaseMaps":if(!b.layer||k.indexOf(b.layer)===-1)return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="http://services.arcgisonline.com/ArcGIS/rest/services/";"World_Light_Gray_Base"!==b.layer&&"World_Dark_Gray_Base"!==b.layer||(r+="Canvas/");var u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:u,wrapX:void 0===b.wrapX||b.wrapX});break;case"TileArcGISRest":b.url||c.error("[AngularJS - Openlayers] - TileArcGISRest Layer needs valid url"),g=new a.source.TileArcGISRest({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=m.readFeatures(b.geojson.object,{featureProjection:w.getCode(),dataProjection:v.getCode()});g.addFeatures(x)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});else{g=new a.source.Vector;var y,z=f;y=e(b.wkt.projection)?new a.proj.get(b.wkt.projection):f;for(var A=new a.format.WKT,B=[],C=0;C Date: Tue, 21 Mar 2017 15:25:21 +0530 Subject: [PATCH 36/53] Updated the Proper version number --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8b7700c1..e67607b9 100644 --- a/package.json +++ b/package.json @@ -65,5 +65,5 @@ "semantic-release": "semantic-release pre && npm publish && semantic-release post" }, "main": "dist/angular-openlayers-directive", - "version": "1.19.1" + "version": "1.19.2" } From 4a4258550532a7bbadfccf15947eab1eff81e845 Mon Sep 17 00:00:00 2001 From: Sathish Kesavaperumal Date: Wed, 19 Jul 2017 17:38:50 +0530 Subject: [PATCH 37/53] fix - set the target element to null to release the html element object to avoid memory leak. --- src/directives/openlayers.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/directives/openlayers.js b/src/directives/openlayers.js index 0ec74a55..26a5753b 100644 --- a/src/directives/openlayers.js +++ b/src/directives/openlayers.js @@ -79,6 +79,7 @@ angular.module('openlayers-directive', ['ngSanitize']).directive('openlayers', f scope.$on('$destroy', function() { olData.resetMap(attrs.id); + map.setTarget(null); }); // If no layer is defined, set the default tileLayer From eaeed11394a671e7154d9c663ae99d8b7624ccb6 Mon Sep 17 00:00:00 2001 From: Sathish Kesavaperumal Date: Wed, 19 Jul 2017 17:52:29 +0530 Subject: [PATCH 38/53] fix(layer): set the target element to null to release the html element object to avoid memory leak --- dist/angular-openlayers-directive.js | 1 + dist/angular-openlayers-directive.min.js | 6 +++--- dist/angular-openlayers-directive.min.no-header.js | 6 +++--- dist/angular-openlayers-directive.pre.js | 1 + 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/dist/angular-openlayers-directive.js b/dist/angular-openlayers-directive.js index 2ae6297b..7082d909 100644 --- a/dist/angular-openlayers-directive.js +++ b/dist/angular-openlayers-directive.js @@ -95,6 +95,7 @@ angular.module('openlayers-directive', ['ngSanitize']).directive('openlayers', [ scope.$on('$destroy', function() { olData.resetMap(attrs.id); + map.setTarget(null); }); // If no layer is defined, set the default tileLayer diff --git a/dist/angular-openlayers-directive.min.js b/dist/angular-openlayers-directive.min.js index 5b7aa5df..76056988 100644 --- a/dist/angular-openlayers-directive.min.js +++ b/dist/angular-openlayers-directive.min.js @@ -27,6 +27,6 @@ * @authors https://github.com/tombatossals/angular-openlayers-directive/graphs/contributors */ -/*! angular-openlayers-directive 13-03-2017 */ -!function(a,b){if("function"==typeof require&&"object"==typeof exports){var c=require("openlayers-prebuilt");require("angular-sanitize");exports.angularOpenlayersDirective=b(c)}else"function"==typeof define&&define.amd?define(["ol"],function(c){return a.angularOpenlayersDirective=b(c)}):a.angularOpenlayersDirective=b(a.ol)}(this,function(a){return angular.module("openlayers-directive",["ngSanitize"]).directive("openlayers",["$log","$q","$compile","olHelpers","olMapDefaults","olData",function(b,c,d,e,f,g){return{restrict:"EA",transclude:!0,replace:!0,scope:{center:"=olCenter",defaults:"=olDefaults",view:"=olView",events:"=olEvents"},template:'
',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id)}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(h.olCenter.search("-")!==-1)return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}});var w=f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})});r.$on("$destroy",function(){f.unByKey(w)})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)});var f=e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})});g.$on("$destroy",function(){a.unByKey(f)})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope(),j=e.getControlClasses,k=j();i.getMap().then(function(b){function d(a){a&&a.control?(f&&b.removeControl(f),f=a.control,b.addControl(f)):c.name&&(h(a)&&(g=a),f&&b.removeControl(f),f=new k[c.name](g),b.addControl(f))}a.$on("$destroy",function(){b.removeControl(f)}),a.$watch("properties",function(a){h(a)&&d(a)}),d(a.properties)})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(f===-1){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(e===-1)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(g===-1)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e].markerLayer,delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(){c.properties&&(e.getViewport().removeEventListener("mousemove",c.properties.handleInteraction),e.getViewport().removeEventListener("click",c.properties.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",c.properties.handleTapInteraction),e.getViewport().removeEventListener("mousemove",c.properties.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",c.properties.removeAllOverlays),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",c.properties.activateCooldown))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return c.handleDrag=function(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))},e.on("pointerdown",c.handleDrag),e.on("pointerup",c.handleDrag),e.on("pointerdrag",c.handleDrag),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e),e.un("pointerdown",c.handleDrag),e.un("pointerup",c.handleDrag),e.un("pointerdrag",c.handleDrag),j()}),k(c.properties)?void c.$watch("properties",function(d){if(j(),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){var a,b=!1;return d.activateCooldown=function(){b=!0,a&&clearTimeout(a),a=setTimeout(function(){b=!1,a=null},500)},d.activateCooldown&&e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",d.activateCooldown),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",d.activateCooldown),function(){b||(d.handleInteraction.apply(null,arguments),d.activateCooldown())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){var d=c(a,b);a[d].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d,e=c(a,b);return d=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:f(a,b)};this.setMap=function(a,b){var c=f(d,b);c.resolve(a),e(d,b)},this.getMap=function(a){var b=g(d,a);return b.promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map","World_Light_Gray_Base","World_Dark_Gray_Base"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function a(b,c){var d;if(c?d=b[c]:(c="style",d=b),"style"===c&&b instanceof Function)return b;if(!(d instanceof Object))return d;var e;if("[object Object]"===Object.prototype.toString.call(d)){e={};var f=l[c];if(f&&d instanceof f)return d;Object.getOwnPropertyNames(d).forEach(function(b,g,h){var i=l[b];return f&&i&&i.prototype instanceof l[c]?(console.assert(1===h.length,"Extra parameters for "+c),e=a(d,b),m(e,i)):(e[b]=a(d,b),void("text"!==b&&"string"!=typeof e[b]&&(e[b]=m(e[b],l[b]))))})}else e=d;return m(e,l[c])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":return"Vector";case"TileVector":case"MVT":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return["watercolor","terrain","toner"].indexOf(a)!==-1},r=function(b,f){var g,i,l,m=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");l="https://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace(".png","@2x.png")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,wrapX:void 0===b.wrapX||b.wrapX});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");l="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace("{y}?access_token","{y}@2x?access_token")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,tileSize:b.tileSize||[512,512],wrapX:void 0===b.wrapX||b.wrapX});break;case"MVT":if(!b.url)return void c.error("[AngularJS - Openlayers] - MVT layer requires the source url");g=new a.source.VectorTile({attributions:b.attributions||"",format:new a.format.MVT,tileGrid:a.tilegrid.createXYZ({maxZoom:b.maxZoom||22}),tilePixelRatio:b.tilePixelRatio||16,url:b.url});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,imageLoadFunction:b.imageLoadFunction,attributions:t(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={tileLoadFunction:b.tileLoadFunction,crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX};b.projection&&(n.projection=new a.proj.get(b.projection)),b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={tileLoadFunction:b.tileLoadFunction,projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),style:"undefined"===b.style?"normal":b.style,wrapX:void 0===b.wrapX||b.wrapX};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({tileLoadFunction:b.tileLoadFunction,attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,tileLoadFunction:b.tileLoadFunction,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX||b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||j.indexOf(b.layer)===-1)return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer,wrapX:void 0===b.wrapX||b.wrapX});break;case"EsriBaseMaps":if(!b.layer||k.indexOf(b.layer)===-1)return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="http://services.arcgisonline.com/ArcGIS/rest/services/";"World_Light_Gray_Base"!==b.layer&&"World_Dark_Gray_Base"!==b.layer||(r+="Canvas/");var u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:u,wrapX:void 0===b.wrapX||b.wrapX});break;case"TileArcGISRest":b.url||c.error("[AngularJS - Openlayers] - TileArcGISRest Layer needs valid url"),g=new a.source.TileArcGISRest({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=m.readFeatures(b.geojson.object,{featureProjection:w.getCode(),dataProjection:v.getCode()});g.addFeatures(x)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});else{g=new a.source.Vector;var y,z=f;y=e(b.wkt.projection)?new a.proj.get(b.wkt.projection):f;for(var A=new a.format.WKT,B=[],C=0;C',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id),q.setTarget(null)}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);if(!0===s.centerUrlHash){var t=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t(),r.$on("$locationChangeSuccess",function(){var a=t();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var u;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return u||(u=new a.Geolocation({projection:a.proj.get(c.projection)}),u.on("change",function(){if(c.autodiscover){var a=u.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,u.setTracking(!1)})}})),void u.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}});var v=f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})});r.$on("$destroy",function(){f.unByKey(v)})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)});var f=e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})});g.$on("$destroy",function(){a.unByKey(f)})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope(),j=e.getControlClasses,k=j();i.getMap().then(function(b){function d(a){a&&a.control?(f&&b.removeControl(f),f=a.control,b.addControl(f)):c.name&&(h(a)&&(g=a),f&&b.removeControl(f),f=new k[c.name](g),b.addControl(f))}a.$on("$destroy",function(){b.removeControl(f)}),a.$watch("properties",function(a){h(a)&&d(a)}),d(a.properties)})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e].markerLayer,delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(){c.properties&&(e.getViewport().removeEventListener("mousemove",c.properties.handleInteraction),e.getViewport().removeEventListener("click",c.properties.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",c.properties.handleTapInteraction),e.getViewport().removeEventListener("mousemove",c.properties.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",c.properties.removeAllOverlays),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",c.properties.activateCooldown))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;if(c.handleDrag=function(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(!(x=g?g.get("marker"):null)||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))},e.on("pointerdown",c.handleDrag),e.on("pointerup",c.handleDrag),e.on("pointerdrag",c.handleDrag),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e),e.un("pointerdown",c.handleDrag),e.un("pointerup",c.handleDrag),e.un("pointerdrag",c.handleDrag),j()}),!k(c.properties))return t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p)));c.$watch("properties",function(d){if(j(),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){var a,b=!1;return d.activateCooldown=function(){b=!0,a&&clearTimeout(a),a=setTimeout(function(){b=!1,a=null},500)},d.activateCooldown&&e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",d.activateCooldown),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",d.activateCooldown),function(){b||(d.handleInteraction.apply(null,arguments),d.activateCooldown())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&!0===d.label.show&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&!1===d.label.show&&(e.removeOverlay(p),p=void 0),d.label&&!1===d.label.show&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&!1===d.label.show&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&!1===d.label.show&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0)})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){a[c(a,b)].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&!0!==a[f].resolvedDefer?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d=c(a,b);return angular.isDefined(a[d])&&!1!==a[d].resolvedDefer?a[d].defer:f(a,b)};this.setMap=function(a,b){f(d,b).resolve(a),e(d,b)},this.getMap=function(a){return g(d,a).promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map","World_Light_Gray_Base","World_Dark_Gray_Base"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function a(b,c){var d;if(c?d=b[c]:(c="style",d=b),"style"===c&&b instanceof Function)return b;if(!(d instanceof Object))return d;var e;if("[object Object]"===Object.prototype.toString.call(d)){e={};var f=l[c];if(f&&d instanceof f)return d;Object.getOwnPropertyNames(d).forEach(function(b,g,h){var i=l[b];if(f&&i&&i.prototype instanceof l[c])return console.assert(1===h.length,"Extra parameters for "+c),e=a(d,b),m(e,i);e[b]=a(d,b),"text"!==b&&"string"!=typeof e[b]&&(e[b]=m(e[b],l[b]))})}else e=d;return m(e,l[c])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":return"Vector";case"TileVector":case"MVT":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g,i,l,m=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");l="https://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace(".png","@2x.png")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,wrapX:void 0===b.wrapX||b.wrapX});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");l="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace("{y}?access_token","{y}@2x?access_token")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,tileSize:b.tileSize||[512,512],wrapX:void 0===b.wrapX||b.wrapX});break;case"MVT":if(!b.url)return void c.error("[AngularJS - Openlayers] - MVT layer requires the source url");g=new a.source.VectorTile({attributions:b.attributions||"",format:new a.format.MVT,tileGrid:a.tilegrid.createXYZ({maxZoom:b.maxZoom||22}),tilePixelRatio:b.tilePixelRatio||16,url:b.url});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,imageLoadFunction:b.imageLoadFunction,attributions:t(b),crossOrigin:void 0===b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={tileLoadFunction:b.tileLoadFunction,crossOrigin:void 0===b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX};b.projection&&(n.projection=new a.proj.get(b.projection)),b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={tileLoadFunction:b.tileLoadFunction,projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),style:"undefined"===b.style?"normal":b.style,wrapX:void 0===b.wrapX||b.wrapX};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({tileLoadFunction:b.tileLoadFunction,attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,tileLoadFunction:b.tileLoadFunction,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX||b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer,wrapX:void 0===b.wrapX||b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="http://services.arcgisonline.com/ArcGIS/rest/services/";"World_Light_Gray_Base"!==b.layer&&"World_Dark_Gray_Base"!==b.layer||(r+="Canvas/");var u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:u,wrapX:void 0===b.wrapX||b.wrapX});break;case"TileArcGISRest":b.url||c.error("[AngularJS - Openlayers] - TileArcGISRest Layer needs valid url"),g=new a.source.TileArcGISRest({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=m.readFeatures(b.geojson.object,{featureProjection:w.getCode(),dataProjection:v.getCode()});g.addFeatures(x)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});else{g=new a.source.Vector;var y,z=f;y=e(b.wkt.projection)?new a.proj.get(b.wkt.projection):f;for(var A=new a.format.WKT,B=[],C=0;C',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id)}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(h.olCenter.search("-")!==-1)return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);var t;if(s.centerUrlHash===!0){var u=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t=u(),r.$on("$locationChangeSuccess",function(){var a=u();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var v;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return v||(v=new a.Geolocation({projection:a.proj.get(c.projection)}),v.on("change",function(){if(c.autodiscover){var a=v.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,v.setTracking(!1)})}})),void v.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}});var w=f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})});r.$on("$destroy",function(){f.unByKey(w)})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)});var f=e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})});g.$on("$destroy",function(){a.unByKey(f)})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope(),j=e.getControlClasses,k=j();i.getMap().then(function(b){function d(a){a&&a.control?(f&&b.removeControl(f),f=a.control,b.addControl(f)):c.name&&(h(a)&&(g=a),f&&b.removeControl(f),f=new k[c.name](g),b.addControl(f))}a.$on("$destroy",function(){b.removeControl(f)}),a.$watch("properties",function(a){h(a)&&d(a)}),d(a.properties)})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(f===-1){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(e===-1)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(g===-1)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e].markerLayer,delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(){c.properties&&(e.getViewport().removeEventListener("mousemove",c.properties.handleInteraction),e.getViewport().removeEventListener("click",c.properties.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",c.properties.handleTapInteraction),e.getViewport().removeEventListener("mousemove",c.properties.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",c.properties.removeAllOverlays),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",c.properties.activateCooldown))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;return c.handleDrag=function(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(x=g?g.get("marker"):null,!x||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))},e.on("pointerdown",c.handleDrag),e.on("pointerup",c.handleDrag),e.on("pointerdrag",c.handleDrag),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e),e.un("pointerdown",c.handleDrag),e.un("pointerup",c.handleDrag),e.un("pointerdrag",c.handleDrag),j()}),k(c.properties)?void c.$watch("properties",function(d){if(j(),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){var a,b=!1;return d.activateCooldown=function(){b=!0,a&&clearTimeout(a),a=setTimeout(function(){b=!1,a=null},500)},d.activateCooldown&&e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",d.activateCooldown),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",d.activateCooldown),function(){b||(d.handleInteraction.apply(null,arguments),d.activateCooldown())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&d.label.show===!0&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&d.label.show===!1&&(e.removeOverlay(p),p=void 0),d.label&&d.label.show===!1&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&d.label.show===!1&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&d.label.show===!1&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0):(t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p))))})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){var d=c(a,b);a[d].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&a[f].resolvedDefer!==!0?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d,e=c(a,b);return d=angular.isDefined(a[e])&&a[e].resolvedDefer!==!1?a[e].defer:f(a,b)};this.setMap=function(a,b){var c=f(d,b);c.resolve(a),e(d,b)},this.getMap=function(a){var b=g(d,a);return b.promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map","World_Light_Gray_Base","World_Dark_Gray_Base"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function a(b,c){var d;if(c?d=b[c]:(c="style",d=b),"style"===c&&b instanceof Function)return b;if(!(d instanceof Object))return d;var e;if("[object Object]"===Object.prototype.toString.call(d)){e={};var f=l[c];if(f&&d instanceof f)return d;Object.getOwnPropertyNames(d).forEach(function(b,g,h){var i=l[b];return f&&i&&i.prototype instanceof l[c]?(console.assert(1===h.length,"Extra parameters for "+c),e=a(d,b),m(e,i)):(e[b]=a(d,b),void("text"!==b&&"string"!=typeof e[b]&&(e[b]=m(e[b],l[b]))))})}else e=d;return m(e,l[c])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":return"Image";case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":return"Vector";case"TileVector":case"MVT":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return["watercolor","terrain","toner"].indexOf(a)!==-1},r=function(b,f){var g,i,l,m=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");l="https://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace(".png","@2x.png")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,wrapX:void 0===b.wrapX||b.wrapX});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");l="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace("{y}?access_token","{y}@2x?access_token")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,tileSize:b.tileSize||[512,512],wrapX:void 0===b.wrapX||b.wrapX});break;case"MVT":if(!b.url)return void c.error("[AngularJS - Openlayers] - MVT layer requires the source url");g=new a.source.VectorTile({attributions:b.attributions||"",format:new a.format.MVT,tileGrid:a.tilegrid.createXYZ({maxZoom:b.maxZoom||22}),tilePixelRatio:b.tilePixelRatio||16,url:b.url});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,imageLoadFunction:b.imageLoadFunction,attributions:t(b),crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={tileLoadFunction:b.tileLoadFunction,crossOrigin:"undefined"==typeof b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX};b.projection&&(n.projection=new a.proj.get(b.projection)),b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={tileLoadFunction:b.tileLoadFunction,projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),style:"undefined"===b.style?"normal":b.style,wrapX:void 0===b.wrapX||b.wrapX};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({tileLoadFunction:b.tileLoadFunction,attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,tileLoadFunction:b.tileLoadFunction,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX||b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||j.indexOf(b.layer)===-1)return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer,wrapX:void 0===b.wrapX||b.wrapX});break;case"EsriBaseMaps":if(!b.layer||k.indexOf(b.layer)===-1)return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="http://services.arcgisonline.com/ArcGIS/rest/services/";"World_Light_Gray_Base"!==b.layer&&"World_Dark_Gray_Base"!==b.layer||(r+="Canvas/");var u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:u,wrapX:void 0===b.wrapX||b.wrapX});break;case"TileArcGISRest":b.url||c.error("[AngularJS - Openlayers] - TileArcGISRest Layer needs valid url"),g=new a.source.TileArcGISRest({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=m.readFeatures(b.geojson.object,{featureProjection:w.getCode(),dataProjection:v.getCode()});g.addFeatures(x)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});else{g=new a.source.Vector;var y,z=f;y=e(b.wkt.projection)?new a.proj.get(b.wkt.projection):f;for(var A=new a.format.WKT,B=[],C=0;C',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id),q.setTarget(null)}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);if(!0===s.centerUrlHash){var t=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t(),r.$on("$locationChangeSuccess",function(){var a=t();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var u;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return u||(u=new a.Geolocation({projection:a.proj.get(c.projection)}),u.on("change",function(){if(c.autodiscover){var a=u.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,u.setTracking(!1)})}})),void u.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}});var v=f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})});r.$on("$destroy",function(){f.unByKey(v)})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)});var f=e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})});g.$on("$destroy",function(){a.unByKey(f)})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope(),j=e.getControlClasses,k=j();i.getMap().then(function(b){function d(a){a&&a.control?(f&&b.removeControl(f),f=a.control,b.addControl(f)):c.name&&(h(a)&&(g=a),f&&b.removeControl(f),f=new k[c.name](g),b.addControl(f))}a.$on("$destroy",function(){b.removeControl(f)}),a.$watch("properties",function(a){h(a)&&d(a)}),d(a.properties)})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e].markerLayer,delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(){c.properties&&(e.getViewport().removeEventListener("mousemove",c.properties.handleInteraction),e.getViewport().removeEventListener("click",c.properties.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",c.properties.handleTapInteraction),e.getViewport().removeEventListener("mousemove",c.properties.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",c.properties.removeAllOverlays),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",c.properties.activateCooldown))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;if(c.handleDrag=function(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(!(x=g?g.get("marker"):null)||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))},e.on("pointerdown",c.handleDrag),e.on("pointerup",c.handleDrag),e.on("pointerdrag",c.handleDrag),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e),e.un("pointerdown",c.handleDrag),e.un("pointerup",c.handleDrag),e.un("pointerdrag",c.handleDrag),j()}),!k(c.properties))return t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p)));c.$watch("properties",function(d){if(j(),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){var a,b=!1;return d.activateCooldown=function(){b=!0,a&&clearTimeout(a),a=setTimeout(function(){b=!1,a=null},500)},d.activateCooldown&&e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",d.activateCooldown),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",d.activateCooldown),function(){b||(d.handleInteraction.apply(null,arguments),d.activateCooldown())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&!0===d.label.show&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&!1===d.label.show&&(e.removeOverlay(p),p=void 0),d.label&&!1===d.label.show&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&!1===d.label.show&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&!1===d.label.show&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0)})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){a[c(a,b)].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&!0!==a[f].resolvedDefer?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d=c(a,b);return angular.isDefined(a[d])&&!1!==a[d].resolvedDefer?a[d].defer:f(a,b)};this.setMap=function(a,b){f(d,b).resolve(a),e(d,b)},this.getMap=function(a){return g(d,a).promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map","World_Light_Gray_Base","World_Dark_Gray_Base"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function a(b,c){var d;if(c?d=b[c]:(c="style",d=b),"style"===c&&b instanceof Function)return b;if(!(d instanceof Object))return d;var e;if("[object Object]"===Object.prototype.toString.call(d)){e={};var f=l[c];if(f&&d instanceof f)return d;Object.getOwnPropertyNames(d).forEach(function(b,g,h){var i=l[b];if(f&&i&&i.prototype instanceof l[c])return console.assert(1===h.length,"Extra parameters for "+c),e=a(d,b),m(e,i);e[b]=a(d,b),"text"!==b&&"string"!=typeof e[b]&&(e[b]=m(e[b],l[b]))})}else e=d;return m(e,l[c])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":return"Vector";case"TileVector":case"MVT":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g,i,l,m=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");l="https://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace(".png","@2x.png")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,wrapX:void 0===b.wrapX||b.wrapX});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");l="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace("{y}?access_token","{y}@2x?access_token")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,tileSize:b.tileSize||[512,512],wrapX:void 0===b.wrapX||b.wrapX});break;case"MVT":if(!b.url)return void c.error("[AngularJS - Openlayers] - MVT layer requires the source url");g=new a.source.VectorTile({attributions:b.attributions||"",format:new a.format.MVT,tileGrid:a.tilegrid.createXYZ({maxZoom:b.maxZoom||22}),tilePixelRatio:b.tilePixelRatio||16,url:b.url});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,imageLoadFunction:b.imageLoadFunction,attributions:t(b),crossOrigin:void 0===b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={tileLoadFunction:b.tileLoadFunction,crossOrigin:void 0===b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX};b.projection&&(n.projection=new a.proj.get(b.projection)),b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={tileLoadFunction:b.tileLoadFunction,projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),style:"undefined"===b.style?"normal":b.style,wrapX:void 0===b.wrapX||b.wrapX};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({tileLoadFunction:b.tileLoadFunction,attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,tileLoadFunction:b.tileLoadFunction,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX||b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer,wrapX:void 0===b.wrapX||b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="http://services.arcgisonline.com/ArcGIS/rest/services/";"World_Light_Gray_Base"!==b.layer&&"World_Dark_Gray_Base"!==b.layer||(r+="Canvas/");var u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:u,wrapX:void 0===b.wrapX||b.wrapX});break;case"TileArcGISRest":b.url||c.error("[AngularJS - Openlayers] - TileArcGISRest Layer needs valid url"),g=new a.source.TileArcGISRest({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=m.readFeatures(b.geojson.object,{featureProjection:w.getCode(),dataProjection:v.getCode()});g.addFeatures(x)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});else{g=new a.source.Vector;var y,z=f;y=e(b.wkt.projection)?new a.proj.get(b.wkt.projection):f;for(var A=new a.format.WKT,B=[],C=0;C Date: Thu, 3 Aug 2017 16:49:22 +0530 Subject: [PATCH 39/53] fix(layer): Added multiple tile urls support for xyz tile source --- src/services/olHelpers.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/services/olHelpers.js b/src/services/olHelpers.js index dbacd3ca..9cddc375 100644 --- a/src/services/olHelpers.js +++ b/src/services/olHelpers.js @@ -651,11 +651,12 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ }); break; case 'XYZ': - if (!source.url && !source.tileUrlFunction) { - $log.error('[AngularJS - Openlayers] - XYZ Layer needs valid url or tileUrlFunction properties'); + if (!source.url && !source.urls && !source.tileUrlFunction) { + $log.error('[AngularJS - Openlayers] - XYZ Layer needs valid urls or tileUrlFunction properties'); } oSource = new ol.source.XYZ({ url: source.url, + urls: source.urls, attributions: createAttribution(source), minZoom: source.minZoom, maxZoom: source.maxZoom, From ebf62b724d84c3616d1963473570ca5e80e325cb Mon Sep 17 00:00:00 2001 From: Sathish Kesavaperumal Date: Thu, 3 Aug 2017 17:12:03 +0530 Subject: [PATCH 40/53] fix(layer): Added multiple tile urls support for xyz tile source --- dist/angular-openlayers-directive.js | 5 +++-- dist/angular-openlayers-directive.min.js | 4 ++-- dist/angular-openlayers-directive.min.no-header.js | 4 ++-- dist/angular-openlayers-directive.pre.js | 5 +++-- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/dist/angular-openlayers-directive.js b/dist/angular-openlayers-directive.js index 7082d909..bfe8bf36 100644 --- a/dist/angular-openlayers-directive.js +++ b/dist/angular-openlayers-directive.js @@ -1903,11 +1903,12 @@ angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$htt }); break; case 'XYZ': - if (!source.url && !source.tileUrlFunction) { - $log.error('[AngularJS - Openlayers] - XYZ Layer needs valid url or tileUrlFunction properties'); + if (!source.url && !source.urls && !source.tileUrlFunction) { + $log.error('[AngularJS - Openlayers] - XYZ Layer needs valid urls or tileUrlFunction properties'); } oSource = new ol.source.XYZ({ url: source.url, + urls: source.urls, attributions: createAttribution(source), minZoom: source.minZoom, maxZoom: source.maxZoom, diff --git a/dist/angular-openlayers-directive.min.js b/dist/angular-openlayers-directive.min.js index 76056988..f301c7a9 100644 --- a/dist/angular-openlayers-directive.min.js +++ b/dist/angular-openlayers-directive.min.js @@ -27,6 +27,6 @@ * @authors https://github.com/tombatossals/angular-openlayers-directive/graphs/contributors */ -/*! angular-openlayers-directive 19-07-2017 */ -!function(a,b){if("function"==typeof require&&"object"==typeof exports){var c=require("openlayers-prebuilt");require("angular-sanitize");exports.angularOpenlayersDirective=b(c)}else"function"==typeof define&&define.amd?define(["ol"],function(c){return a.angularOpenlayersDirective=b(c)}):a.angularOpenlayersDirective=b(a.ol)}(this,function(a){return angular.module("openlayers-directive",["ngSanitize"]).directive("openlayers",["$log","$q","$compile","olHelpers","olMapDefaults","olData",function(b,c,d,e,f,g){return{restrict:"EA",transclude:!0,replace:!0,scope:{center:"=olCenter",defaults:"=olDefaults",view:"=olView",events:"=olEvents"},template:'
',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id),q.setTarget(null)}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);if(!0===s.centerUrlHash){var t=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t(),r.$on("$locationChangeSuccess",function(){var a=t();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var u;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return u||(u=new a.Geolocation({projection:a.proj.get(c.projection)}),u.on("change",function(){if(c.autodiscover){var a=u.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,u.setTracking(!1)})}})),void u.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}});var v=f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})});r.$on("$destroy",function(){f.unByKey(v)})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)});var f=e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})});g.$on("$destroy",function(){a.unByKey(f)})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope(),j=e.getControlClasses,k=j();i.getMap().then(function(b){function d(a){a&&a.control?(f&&b.removeControl(f),f=a.control,b.addControl(f)):c.name&&(h(a)&&(g=a),f&&b.removeControl(f),f=new k[c.name](g),b.addControl(f))}a.$on("$destroy",function(){b.removeControl(f)}),a.$watch("properties",function(a){h(a)&&d(a)}),d(a.properties)})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e].markerLayer,delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(){c.properties&&(e.getViewport().removeEventListener("mousemove",c.properties.handleInteraction),e.getViewport().removeEventListener("click",c.properties.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",c.properties.handleTapInteraction),e.getViewport().removeEventListener("mousemove",c.properties.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",c.properties.removeAllOverlays),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",c.properties.activateCooldown))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;if(c.handleDrag=function(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(!(x=g?g.get("marker"):null)||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))},e.on("pointerdown",c.handleDrag),e.on("pointerup",c.handleDrag),e.on("pointerdrag",c.handleDrag),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e),e.un("pointerdown",c.handleDrag),e.un("pointerup",c.handleDrag),e.un("pointerdrag",c.handleDrag),j()}),!k(c.properties))return t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p)));c.$watch("properties",function(d){if(j(),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){var a,b=!1;return d.activateCooldown=function(){b=!0,a&&clearTimeout(a),a=setTimeout(function(){b=!1,a=null},500)},d.activateCooldown&&e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",d.activateCooldown),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",d.activateCooldown),function(){b||(d.handleInteraction.apply(null,arguments),d.activateCooldown())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&!0===d.label.show&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&!1===d.label.show&&(e.removeOverlay(p),p=void 0),d.label&&!1===d.label.show&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&!1===d.label.show&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&!1===d.label.show&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0)})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){a[c(a,b)].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&!0!==a[f].resolvedDefer?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d=c(a,b);return angular.isDefined(a[d])&&!1!==a[d].resolvedDefer?a[d].defer:f(a,b)};this.setMap=function(a,b){f(d,b).resolve(a),e(d,b)},this.getMap=function(a){return g(d,a).promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map","World_Light_Gray_Base","World_Dark_Gray_Base"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function a(b,c){var d;if(c?d=b[c]:(c="style",d=b),"style"===c&&b instanceof Function)return b;if(!(d instanceof Object))return d;var e;if("[object Object]"===Object.prototype.toString.call(d)){e={};var f=l[c];if(f&&d instanceof f)return d;Object.getOwnPropertyNames(d).forEach(function(b,g,h){var i=l[b];if(f&&i&&i.prototype instanceof l[c])return console.assert(1===h.length,"Extra parameters for "+c),e=a(d,b),m(e,i);e[b]=a(d,b),"text"!==b&&"string"!=typeof e[b]&&(e[b]=m(e[b],l[b]))})}else e=d;return m(e,l[c])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":return"Vector";case"TileVector":case"MVT":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g,i,l,m=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");l="https://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace(".png","@2x.png")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,wrapX:void 0===b.wrapX||b.wrapX});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");l="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace("{y}?access_token","{y}@2x?access_token")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,tileSize:b.tileSize||[512,512],wrapX:void 0===b.wrapX||b.wrapX});break;case"MVT":if(!b.url)return void c.error("[AngularJS - Openlayers] - MVT layer requires the source url");g=new a.source.VectorTile({attributions:b.attributions||"",format:new a.format.MVT,tileGrid:a.tilegrid.createXYZ({maxZoom:b.maxZoom||22}),tilePixelRatio:b.tilePixelRatio||16,url:b.url});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,imageLoadFunction:b.imageLoadFunction,attributions:t(b),crossOrigin:void 0===b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={tileLoadFunction:b.tileLoadFunction,crossOrigin:void 0===b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX};b.projection&&(n.projection=new a.proj.get(b.projection)),b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={tileLoadFunction:b.tileLoadFunction,projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),style:"undefined"===b.style?"normal":b.style,wrapX:void 0===b.wrapX||b.wrapX};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({tileLoadFunction:b.tileLoadFunction,attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,tileLoadFunction:b.tileLoadFunction,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX||b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer,wrapX:void 0===b.wrapX||b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="http://services.arcgisonline.com/ArcGIS/rest/services/";"World_Light_Gray_Base"!==b.layer&&"World_Dark_Gray_Base"!==b.layer||(r+="Canvas/");var u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:u,wrapX:void 0===b.wrapX||b.wrapX});break;case"TileArcGISRest":b.url||c.error("[AngularJS - Openlayers] - TileArcGISRest Layer needs valid url"),g=new a.source.TileArcGISRest({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=m.readFeatures(b.geojson.object,{featureProjection:w.getCode(),dataProjection:v.getCode()});g.addFeatures(x)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});else{g=new a.source.Vector;var y,z=f;y=e(b.wkt.projection)?new a.proj.get(b.wkt.projection):f;for(var A=new a.format.WKT,B=[],C=0;C',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id),q.setTarget(null)}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);if(!0===s.centerUrlHash){var t=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t(),r.$on("$locationChangeSuccess",function(){var a=t();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var u;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return u||(u=new a.Geolocation({projection:a.proj.get(c.projection)}),u.on("change",function(){if(c.autodiscover){var a=u.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,u.setTracking(!1)})}})),void u.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}});var v=f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})});r.$on("$destroy",function(){f.unByKey(v)})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)});var f=e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})});g.$on("$destroy",function(){a.unByKey(f)})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope(),j=e.getControlClasses,k=j();i.getMap().then(function(b){function d(a){a&&a.control?(f&&b.removeControl(f),f=a.control,b.addControl(f)):c.name&&(h(a)&&(g=a),f&&b.removeControl(f),f=new k[c.name](g),b.addControl(f))}a.$on("$destroy",function(){b.removeControl(f)}),a.$watch("properties",function(a){h(a)&&d(a)}),d(a.properties)})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e].markerLayer,delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(){c.properties&&(e.getViewport().removeEventListener("mousemove",c.properties.handleInteraction),e.getViewport().removeEventListener("click",c.properties.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",c.properties.handleTapInteraction),e.getViewport().removeEventListener("mousemove",c.properties.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",c.properties.removeAllOverlays),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",c.properties.activateCooldown))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;if(c.handleDrag=function(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(!(x=g?g.get("marker"):null)||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))},e.on("pointerdown",c.handleDrag),e.on("pointerup",c.handleDrag),e.on("pointerdrag",c.handleDrag),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e),e.un("pointerdown",c.handleDrag),e.un("pointerup",c.handleDrag),e.un("pointerdrag",c.handleDrag),j()}),!k(c.properties))return t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p)));c.$watch("properties",function(d){if(j(),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){var a,b=!1;return d.activateCooldown=function(){b=!0,a&&clearTimeout(a),a=setTimeout(function(){b=!1,a=null},500)},d.activateCooldown&&e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",d.activateCooldown),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",d.activateCooldown),function(){b||(d.handleInteraction.apply(null,arguments),d.activateCooldown())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&!0===d.label.show&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&!1===d.label.show&&(e.removeOverlay(p),p=void 0),d.label&&!1===d.label.show&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&!1===d.label.show&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&!1===d.label.show&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0)})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){a[c(a,b)].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&!0!==a[f].resolvedDefer?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d=c(a,b);return angular.isDefined(a[d])&&!1!==a[d].resolvedDefer?a[d].defer:f(a,b)};this.setMap=function(a,b){f(d,b).resolve(a),e(d,b)},this.getMap=function(a){return g(d,a).promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map","World_Light_Gray_Base","World_Dark_Gray_Base"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function a(b,c){var d;if(c?d=b[c]:(c="style",d=b),"style"===c&&b instanceof Function)return b;if(!(d instanceof Object))return d;var e;if("[object Object]"===Object.prototype.toString.call(d)){e={};var f=l[c];if(f&&d instanceof f)return d;Object.getOwnPropertyNames(d).forEach(function(b,g,h){var i=l[b];if(f&&i&&i.prototype instanceof l[c])return console.assert(1===h.length,"Extra parameters for "+c),e=a(d,b),m(e,i);e[b]=a(d,b),"text"!==b&&"string"!=typeof e[b]&&(e[b]=m(e[b],l[b]))})}else e=d;return m(e,l[c])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":return"Vector";case"TileVector":case"MVT":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g,i,l,m=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");l="https://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace(".png","@2x.png")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,wrapX:void 0===b.wrapX||b.wrapX});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");l="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace("{y}?access_token","{y}@2x?access_token")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,tileSize:b.tileSize||[512,512],wrapX:void 0===b.wrapX||b.wrapX});break;case"MVT":if(!b.url)return void c.error("[AngularJS - Openlayers] - MVT layer requires the source url");g=new a.source.VectorTile({attributions:b.attributions||"",format:new a.format.MVT,tileGrid:a.tilegrid.createXYZ({maxZoom:b.maxZoom||22}),tilePixelRatio:b.tilePixelRatio||16,url:b.url});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,imageLoadFunction:b.imageLoadFunction,attributions:t(b),crossOrigin:void 0===b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={tileLoadFunction:b.tileLoadFunction,crossOrigin:void 0===b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX};b.projection&&(n.projection=new a.proj.get(b.projection)),b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={tileLoadFunction:b.tileLoadFunction,projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),style:"undefined"===b.style?"normal":b.style,wrapX:void 0===b.wrapX||b.wrapX};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({tileLoadFunction:b.tileLoadFunction,attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,tileLoadFunction:b.tileLoadFunction,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX||b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer,wrapX:void 0===b.wrapX||b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="http://services.arcgisonline.com/ArcGIS/rest/services/";"World_Light_Gray_Base"!==b.layer&&"World_Dark_Gray_Base"!==b.layer||(r+="Canvas/");var u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:u,wrapX:void 0===b.wrapX||b.wrapX});break;case"TileArcGISRest":b.url||c.error("[AngularJS - Openlayers] - TileArcGISRest Layer needs valid url"),g=new a.source.TileArcGISRest({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=m.readFeatures(b.geojson.object,{featureProjection:w.getCode(),dataProjection:v.getCode()});g.addFeatures(x)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});else{g=new a.source.Vector;var y,z=f;y=e(b.wkt.projection)?new a.proj.get(b.wkt.projection):f;for(var A=new a.format.WKT,B=[],C=0;C',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id),q.setTarget(null)}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);if(!0===s.centerUrlHash){var t=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t(),r.$on("$locationChangeSuccess",function(){var a=t();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var u;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return u||(u=new a.Geolocation({projection:a.proj.get(c.projection)}),u.on("change",function(){if(c.autodiscover){var a=u.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,u.setTracking(!1)})}})),void u.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}});var v=f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})});r.$on("$destroy",function(){f.unByKey(v)})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)});var f=e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})});g.$on("$destroy",function(){a.unByKey(f)})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope(),j=e.getControlClasses,k=j();i.getMap().then(function(b){function d(a){a&&a.control?(f&&b.removeControl(f),f=a.control,b.addControl(f)):c.name&&(h(a)&&(g=a),f&&b.removeControl(f),f=new k[c.name](g),b.addControl(f))}a.$on("$destroy",function(){b.removeControl(f)}),a.$watch("properties",function(a){h(a)&&d(a)}),d(a.properties)})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e].markerLayer,delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(){c.properties&&(e.getViewport().removeEventListener("mousemove",c.properties.handleInteraction),e.getViewport().removeEventListener("click",c.properties.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",c.properties.handleTapInteraction),e.getViewport().removeEventListener("mousemove",c.properties.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",c.properties.removeAllOverlays),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",c.properties.activateCooldown))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;if(c.handleDrag=function(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(!(x=g?g.get("marker"):null)||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))},e.on("pointerdown",c.handleDrag),e.on("pointerup",c.handleDrag),e.on("pointerdrag",c.handleDrag),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e),e.un("pointerdown",c.handleDrag),e.un("pointerup",c.handleDrag),e.un("pointerdrag",c.handleDrag),j()}),!k(c.properties))return t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p)));c.$watch("properties",function(d){if(j(),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){var a,b=!1;return d.activateCooldown=function(){b=!0,a&&clearTimeout(a),a=setTimeout(function(){b=!1,a=null},500)},d.activateCooldown&&e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",d.activateCooldown),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",d.activateCooldown),function(){b||(d.handleInteraction.apply(null,arguments),d.activateCooldown())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&!0===d.label.show&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&!1===d.label.show&&(e.removeOverlay(p),p=void 0),d.label&&!1===d.label.show&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&!1===d.label.show&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&!1===d.label.show&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0)})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){a[c(a,b)].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&!0!==a[f].resolvedDefer?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d=c(a,b);return angular.isDefined(a[d])&&!1!==a[d].resolvedDefer?a[d].defer:f(a,b)};this.setMap=function(a,b){f(d,b).resolve(a),e(d,b)},this.getMap=function(a){return g(d,a).promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map","World_Light_Gray_Base","World_Dark_Gray_Base"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function a(b,c){var d;if(c?d=b[c]:(c="style",d=b),"style"===c&&b instanceof Function)return b;if(!(d instanceof Object))return d;var e;if("[object Object]"===Object.prototype.toString.call(d)){e={};var f=l[c];if(f&&d instanceof f)return d;Object.getOwnPropertyNames(d).forEach(function(b,g,h){var i=l[b];if(f&&i&&i.prototype instanceof l[c])return console.assert(1===h.length,"Extra parameters for "+c),e=a(d,b),m(e,i);e[b]=a(d,b),"text"!==b&&"string"!=typeof e[b]&&(e[b]=m(e[b],l[b]))})}else e=d;return m(e,l[c])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":return"Vector";case"TileVector":case"MVT":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g,i,l,m=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");l="https://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace(".png","@2x.png")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,wrapX:void 0===b.wrapX||b.wrapX});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");l="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace("{y}?access_token","{y}@2x?access_token")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,tileSize:b.tileSize||[512,512],wrapX:void 0===b.wrapX||b.wrapX});break;case"MVT":if(!b.url)return void c.error("[AngularJS - Openlayers] - MVT layer requires the source url");g=new a.source.VectorTile({attributions:b.attributions||"",format:new a.format.MVT,tileGrid:a.tilegrid.createXYZ({maxZoom:b.maxZoom||22}),tilePixelRatio:b.tilePixelRatio||16,url:b.url});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,imageLoadFunction:b.imageLoadFunction,attributions:t(b),crossOrigin:void 0===b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={tileLoadFunction:b.tileLoadFunction,crossOrigin:void 0===b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX};b.projection&&(n.projection=new a.proj.get(b.projection)),b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={tileLoadFunction:b.tileLoadFunction,projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),style:"undefined"===b.style?"normal":b.style,wrapX:void 0===b.wrapX||b.wrapX};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({tileLoadFunction:b.tileLoadFunction,attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,tileLoadFunction:b.tileLoadFunction,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX||b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer,wrapX:void 0===b.wrapX||b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="http://services.arcgisonline.com/ArcGIS/rest/services/";"World_Light_Gray_Base"!==b.layer&&"World_Dark_Gray_Base"!==b.layer||(r+="Canvas/");var u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:u,wrapX:void 0===b.wrapX||b.wrapX});break;case"TileArcGISRest":b.url||c.error("[AngularJS - Openlayers] - TileArcGISRest Layer needs valid url"),g=new a.source.TileArcGISRest({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=m.readFeatures(b.geojson.object,{featureProjection:w.getCode(),dataProjection:v.getCode()});g.addFeatures(x)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});else{g=new a.source.Vector;var y,z=f;y=e(b.wkt.projection)?new a.proj.get(b.wkt.projection):f;for(var A=new a.format.WKT,B=[],C=0;C',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id),q.setTarget(null)}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);if(!0===s.centerUrlHash){var t=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t(),r.$on("$locationChangeSuccess",function(){var a=t();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var u;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return u||(u=new a.Geolocation({projection:a.proj.get(c.projection)}),u.on("change",function(){if(c.autodiscover){var a=u.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,u.setTracking(!1)})}})),void u.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}});var v=f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})});r.$on("$destroy",function(){f.unByKey(v)})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)});var f=e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})});g.$on("$destroy",function(){a.unByKey(f)})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope(),j=e.getControlClasses,k=j();i.getMap().then(function(b){function d(a){a&&a.control?(f&&b.removeControl(f),f=a.control,b.addControl(f)):c.name&&(h(a)&&(g=a),f&&b.removeControl(f),f=new k[c.name](g),b.addControl(f))}a.$on("$destroy",function(){b.removeControl(f)}),a.$watch("properties",function(a){h(a)&&d(a)}),d(a.properties)})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e].markerLayer,delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(){c.properties&&(e.getViewport().removeEventListener("mousemove",c.properties.handleInteraction),e.getViewport().removeEventListener("click",c.properties.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",c.properties.handleTapInteraction),e.getViewport().removeEventListener("mousemove",c.properties.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",c.properties.removeAllOverlays),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",c.properties.activateCooldown))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;if(c.handleDrag=function(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(!(x=g?g.get("marker"):null)||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))},e.on("pointerdown",c.handleDrag),e.on("pointerup",c.handleDrag),e.on("pointerdrag",c.handleDrag),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e),e.un("pointerdown",c.handleDrag),e.un("pointerup",c.handleDrag),e.un("pointerdrag",c.handleDrag),j()}),!k(c.properties))return t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p)));c.$watch("properties",function(d){if(j(),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){var a,b=!1;return d.activateCooldown=function(){b=!0,a&&clearTimeout(a),a=setTimeout(function(){b=!1,a=null},500)},d.activateCooldown&&e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",d.activateCooldown),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",d.activateCooldown),function(){b||(d.handleInteraction.apply(null,arguments),d.activateCooldown())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&!0===d.label.show&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&!1===d.label.show&&(e.removeOverlay(p),p=void 0),d.label&&!1===d.label.show&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&!1===d.label.show&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&!1===d.label.show&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0)})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){a[c(a,b)].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&!0!==a[f].resolvedDefer?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d=c(a,b);return angular.isDefined(a[d])&&!1!==a[d].resolvedDefer?a[d].defer:f(a,b)};this.setMap=function(a,b){f(d,b).resolve(a),e(d,b)},this.getMap=function(a){return g(d,a).promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map","World_Light_Gray_Base","World_Dark_Gray_Base"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function a(b,c){var d;if(c?d=b[c]:(c="style",d=b),"style"===c&&b instanceof Function)return b;if(!(d instanceof Object))return d;var e;if("[object Object]"===Object.prototype.toString.call(d)){e={};var f=l[c];if(f&&d instanceof f)return d;Object.getOwnPropertyNames(d).forEach(function(b,g,h){var i=l[b];if(f&&i&&i.prototype instanceof l[c])return console.assert(1===h.length,"Extra parameters for "+c),e=a(d,b),m(e,i);e[b]=a(d,b),"text"!==b&&"string"!=typeof e[b]&&(e[b]=m(e[b],l[b]))})}else e=d;return m(e,l[c])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":return"Vector";case"TileVector":case"MVT":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g,i,l,m=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");l="https://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace(".png","@2x.png")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,wrapX:void 0===b.wrapX||b.wrapX});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");l="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace("{y}?access_token","{y}@2x?access_token")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,tileSize:b.tileSize||[512,512],wrapX:void 0===b.wrapX||b.wrapX});break;case"MVT":if(!b.url)return void c.error("[AngularJS - Openlayers] - MVT layer requires the source url");g=new a.source.VectorTile({attributions:b.attributions||"",format:new a.format.MVT,tileGrid:a.tilegrid.createXYZ({maxZoom:b.maxZoom||22}),tilePixelRatio:b.tilePixelRatio||16,url:b.url});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,imageLoadFunction:b.imageLoadFunction,attributions:t(b),crossOrigin:void 0===b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={tileLoadFunction:b.tileLoadFunction,crossOrigin:void 0===b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX};b.projection&&(n.projection=new a.proj.get(b.projection)),b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={tileLoadFunction:b.tileLoadFunction,projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),style:"undefined"===b.style?"normal":b.style,wrapX:void 0===b.wrapX||b.wrapX};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({tileLoadFunction:b.tileLoadFunction,attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,tileLoadFunction:b.tileLoadFunction,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX||b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer,wrapX:void 0===b.wrapX||b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="http://services.arcgisonline.com/ArcGIS/rest/services/";"World_Light_Gray_Base"!==b.layer&&"World_Dark_Gray_Base"!==b.layer||(r+="Canvas/");var u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:u,wrapX:void 0===b.wrapX||b.wrapX});break;case"TileArcGISRest":b.url||c.error("[AngularJS - Openlayers] - TileArcGISRest Layer needs valid url"),g=new a.source.TileArcGISRest({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=m.readFeatures(b.geojson.object,{featureProjection:w.getCode(),dataProjection:v.getCode()});g.addFeatures(x)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});else{g=new a.source.Vector;var y,z=f;y=e(b.wkt.projection)?new a.proj.get(b.wkt.projection):f;for(var A=new a.format.WKT,B=[],C=0;C Date: Wed, 7 Mar 2018 11:27:39 +0530 Subject: [PATCH 41/53] Synced with Master --- .jscsrc | 1 - grunt/concat.js | 7 ++++-- src/directives/control.js | 53 ++++++++++++++++++++++++++++++--------- src/directives/marker.js | 46 ++++++++++++++++++++++----------- 4 files changed, 77 insertions(+), 30 deletions(-) diff --git a/.jscsrc b/.jscsrc index d70efa61..495d984b 100644 --- a/.jscsrc +++ b/.jscsrc @@ -4,7 +4,6 @@ "requireParenthesesAroundIIFE": true, "maximumLineLength": 120, - "validateLineBreaks": "LF", "validateIndentation": 4, "disallowKeywords": ["with"], diff --git a/grunt/concat.js b/grunt/concat.js index 31e34c2f..a0aaa9c0 100644 --- a/grunt/concat.js +++ b/grunt/concat.js @@ -3,7 +3,8 @@ var banner = '(function (root, factory) {\n' + ' if (typeof require === \'function\' && typeof exports === \'object\') {\n' + ' // CommonJS\n' + - ' var ol = require(\'openlayers\');\n' + + ' var ol = require(\'openlayers-prebuilt\');\n' + + ' var ngSanitize = require(\'angular-sanitize\');\n' + ' exports.angularOpenlayersDirective = factory(ol);\n' + ' } else if (typeof define === \'function\' && define.amd) {\n' + ' // AMD.\n' + @@ -15,13 +16,15 @@ var banner = '(function (root, factory) {\n' + ' root.angularOpenlayersDirective = factory(root.ol);\n' + ' }\n' + '}(this, function (ol) {\n'; +var footer = 'return angular.module(\'openlayers-directive\');' + + '\n}));'; module.exports = function (grunt, options) { return { dist: { options: { banner: banner, - footer: '\n}));' + footer: footer }, src: [ 'src/directives/openlayers.js', diff --git a/src/directives/control.js b/src/directives/control.js index ee9f0bc0..76b11fbd 100644 --- a/src/directives/control.js +++ b/src/directives/control.js @@ -1,5 +1,5 @@ -angular.module('openlayers-directive').directive('olControl', function($log, $q, olData, olMapDefaults, olHelpers) { - +angular.module('openlayers-directive') +.directive('olControl', function($log, $q, olData, olMapDefaults, olHelpers) { return { restrict: 'E', scope: { @@ -12,29 +12,58 @@ angular.module('openlayers-directive').directive('olControl', function($log, $q, var olScope = controller.getOpenlayersScope(); var olControl; var olControlOps; + var getControlClasses = olHelpers.getControlClasses; + var controlClasses = getControlClasses(); olScope.getMap().then(function(map) { - var getControlClasses = olHelpers.getControlClasses; - var controlClasses = getControlClasses(); scope.$on('$destroy', function() { map.removeControl(olControl); }); - if (!isDefined(scope.properties) || !isDefined(scope.properties.control)) { - if (attrs.name) { - if (isDefined(scope.properties)) { - olControlOps = scope.properties; + scope.$watch('properties', function(properties) { + if (!isDefined(properties)) { + return; + } + + initCtrls(properties); + }); + + function initCtrls(properties) { + if (properties && properties.control) { + // the control instance is already defined, + // so simply use it and go ahead + + // is there already a control, so destroy and recreate it? + if (olControl) { + map.removeControl(olControl); } - olControl = new controlClasses[attrs.name](olControlOps); + + olControl = properties.control; map.addControl(olControl); + } else { + + // the name is the key to instantiate an ol3 control + if (attrs.name) { + if (isDefined(properties)) { + olControlOps = properties; + } + + // is there already a control, so destroy and recreate it? + if (olControl) { + map.removeControl(olControl); + } + + olControl = new controlClasses[attrs.name](olControlOps); + map.addControl(olControl); + } } - return; } - olControl = scope.properties.control; - map.addControl(olControl); + initCtrls(scope.properties); + }); + } }; }); diff --git a/src/directives/marker.js b/src/directives/marker.js index daee51a2..5fa0aa0a 100644 --- a/src/directives/marker.js +++ b/src/directives/marker.js @@ -58,6 +58,7 @@ angular.module('openlayers-directive').directive('olMarker', function($log, $q, if (!scopes.length) { map.removeLayer(mapDict[mapIndex].markerLayer); + delete mapDict[mapIndex].markerLayer; delete mapDict[mapIndex]; } } @@ -102,7 +103,7 @@ angular.module('openlayers-directive').directive('olMarker', function($log, $q, // This function handles dragging a marker var pickOffset = null; var pickProperties = null; - function handleDrag(evt) { + scope.handleDrag = function(evt) { var coord = evt.coordinate; var proj = map.getView().getProjection().getCode(); if (proj === 'pixel') { @@ -151,12 +152,25 @@ angular.module('openlayers-directive').directive('olMarker', function($log, $q, }); } } + }; + + function unregisterHandlers() { + if (!scope.properties) { return ; } + // Remove previous listeners if any + map.getViewport().removeEventListener('mousemove', scope.properties.handleInteraction); + map.getViewport().removeEventListener('click', scope.properties.handleTapInteraction); + map.getViewport().querySelector('canvas.ol-unselectable').removeEventListener( + 'touchend', scope.properties.handleTapInteraction); + map.getViewport().removeEventListener('mousemove', scope.properties.showAtLeastOneOverlay); + map.getViewport().removeEventListener('click', scope.properties.removeAllOverlays); + map.getViewport().querySelector('canvas.ol-unselectable').removeEventListener( + 'touchmove', scope.properties.activateCooldown); } // Setup generic handlers for marker drag - map.on('pointerdown', handleDrag); - map.on('pointerup', handleDrag); - map.on('pointerdrag', handleDrag); + map.on('pointerdown', scope.handleDrag); + map.on('pointerup', scope.handleDrag); + map.on('pointerdrag', scope.handleDrag); scope.$on('$destroy', function() { markerLayer.getSource().removeFeature(marker); @@ -164,6 +178,10 @@ angular.module('openlayers-directive').directive('olMarker', function($log, $q, map.removeOverlay(label); } markerLayerManager.deregisterScope(scope, map); + map.un('pointerdown', scope.handleDrag); + map.un('pointerup', scope.handleDrag); + map.un('pointerdrag', scope.handleDrag); + unregisterHandlers(); }); if (!isDefined(scope.properties)) { @@ -193,13 +211,7 @@ angular.module('openlayers-directive').directive('olMarker', function($log, $q, scope.$watch('properties', function(properties) { - // Remove previous listeners if any - map.getViewport().removeEventListener('mousemove', properties.handleInteraction); - map.getViewport().removeEventListener('click', properties.handleTapInteraction); - map.getViewport().querySelector('canvas.ol-unselectable').removeEventListener( - 'touchend', properties.handleTapInteraction); - map.getViewport().removeEventListener('mousemove', properties.showAtLeastOneOverlay); - map.getViewport().removeEventListener('click', properties.removeAllOverlays); + unregisterHandlers(); // This function handles popup on mouse over/click properties.handleInteraction = function(evt) { @@ -258,7 +270,7 @@ angular.module('openlayers-directive').directive('olMarker', function($log, $q, var prevTimeout; // Sets the cooldown flag to filter out any subsequent events within 500 ms - function activateCooldown() { + properties.activateCooldown = function() { cooldownActive = true; if (prevTimeout) { clearTimeout(prevTimeout); @@ -267,16 +279,20 @@ angular.module('openlayers-directive').directive('olMarker', function($log, $q, cooldownActive = false; prevTimeout = null; }, 500); - } + }; // Preventing from 'touchend' to be considered a tap, if fired immediately after 'touchmove' + if (properties.activateCooldown) { + map.getViewport().querySelector('canvas.ol-unselectable').removeEventListener( + 'touchmove', properties.activateCooldown); + } map.getViewport().querySelector('canvas.ol-unselectable').addEventListener( - 'touchmove', activateCooldown); + 'touchmove', properties.activateCooldown); return function() { if (!cooldownActive) { properties.handleInteraction.apply(null, arguments); - activateCooldown(); + properties.activateCooldown(); } }; })(); From 7b0c5a5baddafa476d52e49ed08513233e9c709d Mon Sep 17 00:00:00 2001 From: Sathish Kesavaperumal Date: Wed, 7 Mar 2018 15:40:07 +0530 Subject: [PATCH 42/53] Synced with master - second part --- dist/angular-openlayers-directive.js | 104 +++++++++++++----- dist/angular-openlayers-directive.min.js | 6 +- ...ular-openlayers-directive.min.no-header.js | 6 +- dist/angular-openlayers-directive.pre.js | 104 +++++++++++++----- test/unit/markerSpec.js | 23 ++++ 5 files changed, 179 insertions(+), 64 deletions(-) create mode 100644 test/unit/markerSpec.js diff --git a/dist/angular-openlayers-directive.js b/dist/angular-openlayers-directive.js index 255b0aff..3f86617a 100644 --- a/dist/angular-openlayers-directive.js +++ b/dist/angular-openlayers-directive.js @@ -1,7 +1,8 @@ (function (root, factory) { if (typeof require === 'function' && typeof exports === 'object') { // CommonJS - var ol = require('openlayers'); + var ol = require('openlayers-prebuilt'); + var ngSanitize = require('angular-sanitize'); exports.angularOpenlayersDirective = factory(ol); } else if (typeof define === 'function' && define.amd) { // AMD. @@ -671,8 +672,8 @@ angular.module('openlayers-directive').directive('olView', ["$log", "$q", "olDat }; }]); -angular.module('openlayers-directive').directive('olControl', ["$log", "$q", "olData", "olMapDefaults", "olHelpers", function($log, $q, olData, olMapDefaults, olHelpers) { - +angular.module('openlayers-directive') +.directive('olControl', ["$log", "$q", "olData", "olMapDefaults", "olHelpers", function($log, $q, olData, olMapDefaults, olHelpers) { return { restrict: 'E', scope: { @@ -685,29 +686,58 @@ angular.module('openlayers-directive').directive('olControl', ["$log", "$q", "ol var olScope = controller.getOpenlayersScope(); var olControl; var olControlOps; + var getControlClasses = olHelpers.getControlClasses; + var controlClasses = getControlClasses(); olScope.getMap().then(function(map) { - var getControlClasses = olHelpers.getControlClasses; - var controlClasses = getControlClasses(); scope.$on('$destroy', function() { map.removeControl(olControl); }); - if (!isDefined(scope.properties) || !isDefined(scope.properties.control)) { - if (attrs.name) { - if (isDefined(scope.properties)) { - olControlOps = scope.properties; + scope.$watch('properties', function(properties) { + if (!isDefined(properties)) { + return; + } + + initCtrls(properties); + }); + + function initCtrls(properties) { + if (properties && properties.control) { + // the control instance is already defined, + // so simply use it and go ahead + + // is there already a control, so destroy and recreate it? + if (olControl) { + map.removeControl(olControl); } - olControl = new controlClasses[attrs.name](olControlOps); + + olControl = properties.control; map.addControl(olControl); + } else { + + // the name is the key to instantiate an ol3 control + if (attrs.name) { + if (isDefined(properties)) { + olControlOps = properties; + } + + // is there already a control, so destroy and recreate it? + if (olControl) { + map.removeControl(olControl); + } + + olControl = new controlClasses[attrs.name](olControlOps); + map.addControl(olControl); + } } - return; } - olControl = scope.properties.control; - map.addControl(olControl); + initCtrls(scope.properties); + }); + } }; }]); @@ -772,6 +802,7 @@ angular.module('openlayers-directive').directive('olMarker', ["$log", "$q", "olM if (!scopes.length) { map.removeLayer(mapDict[mapIndex].markerLayer); + delete mapDict[mapIndex].markerLayer; delete mapDict[mapIndex]; } } @@ -816,7 +847,7 @@ angular.module('openlayers-directive').directive('olMarker', ["$log", "$q", "olM // This function handles dragging a marker var pickOffset = null; var pickProperties = null; - function handleDrag(evt) { + scope.handleDrag = function(evt) { var coord = evt.coordinate; var proj = map.getView().getProjection().getCode(); if (proj === 'pixel') { @@ -865,12 +896,25 @@ angular.module('openlayers-directive').directive('olMarker', ["$log", "$q", "olM }); } } + }; + + function unregisterHandlers() { + if (!scope.properties) { return ; } + // Remove previous listeners if any + map.getViewport().removeEventListener('mousemove', scope.properties.handleInteraction); + map.getViewport().removeEventListener('click', scope.properties.handleTapInteraction); + map.getViewport().querySelector('canvas.ol-unselectable').removeEventListener( + 'touchend', scope.properties.handleTapInteraction); + map.getViewport().removeEventListener('mousemove', scope.properties.showAtLeastOneOverlay); + map.getViewport().removeEventListener('click', scope.properties.removeAllOverlays); + map.getViewport().querySelector('canvas.ol-unselectable').removeEventListener( + 'touchmove', scope.properties.activateCooldown); } // Setup generic handlers for marker drag - map.on('pointerdown', handleDrag); - map.on('pointerup', handleDrag); - map.on('pointerdrag', handleDrag); + map.on('pointerdown', scope.handleDrag); + map.on('pointerup', scope.handleDrag); + map.on('pointerdrag', scope.handleDrag); scope.$on('$destroy', function() { markerLayer.getSource().removeFeature(marker); @@ -878,6 +922,10 @@ angular.module('openlayers-directive').directive('olMarker', ["$log", "$q", "olM map.removeOverlay(label); } markerLayerManager.deregisterScope(scope, map); + map.un('pointerdown', scope.handleDrag); + map.un('pointerup', scope.handleDrag); + map.un('pointerdrag', scope.handleDrag); + unregisterHandlers(); }); if (!isDefined(scope.properties)) { @@ -907,13 +955,7 @@ angular.module('openlayers-directive').directive('olMarker', ["$log", "$q", "olM scope.$watch('properties', function(properties) { - // Remove previous listeners if any - map.getViewport().removeEventListener('mousemove', properties.handleInteraction); - map.getViewport().removeEventListener('click', properties.handleTapInteraction); - map.getViewport().querySelector('canvas.ol-unselectable').removeEventListener( - 'touchend', properties.handleTapInteraction); - map.getViewport().removeEventListener('mousemove', properties.showAtLeastOneOverlay); - map.getViewport().removeEventListener('click', properties.removeAllOverlays); + unregisterHandlers(); // This function handles popup on mouse over/click properties.handleInteraction = function(evt) { @@ -972,7 +1014,7 @@ angular.module('openlayers-directive').directive('olMarker', ["$log", "$q", "olM var prevTimeout; // Sets the cooldown flag to filter out any subsequent events within 500 ms - function activateCooldown() { + properties.activateCooldown = function() { cooldownActive = true; if (prevTimeout) { clearTimeout(prevTimeout); @@ -981,16 +1023,20 @@ angular.module('openlayers-directive').directive('olMarker', ["$log", "$q", "olM cooldownActive = false; prevTimeout = null; }, 500); - } + }; // Preventing from 'touchend' to be considered a tap, if fired immediately after 'touchmove' + if (properties.activateCooldown) { + map.getViewport().querySelector('canvas.ol-unselectable').removeEventListener( + 'touchmove', properties.activateCooldown); + } map.getViewport().querySelector('canvas.ol-unselectable').addEventListener( - 'touchmove', activateCooldown); + 'touchmove', properties.activateCooldown); return function() { if (!cooldownActive) { properties.handleInteraction.apply(null, arguments); - activateCooldown(); + properties.activateCooldown(); } }; })(); @@ -2553,5 +2599,5 @@ angular.module('openlayers-directive').factory('olMapDefaults', ["$q", "olHelper } }; }]); - +return angular.module('openlayers-directive'); })); \ No newline at end of file diff --git a/dist/angular-openlayers-directive.min.js b/dist/angular-openlayers-directive.min.js index c79ef7ec..929ee66a 100644 --- a/dist/angular-openlayers-directive.min.js +++ b/dist/angular-openlayers-directive.min.js @@ -27,6 +27,6 @@ * @authors https://github.com/tombatossals/angular-openlayers-directive/graphs/contributors */ -/*! angular-openlayers-directive 06-03-2018 */ -!function(a,b){if("function"==typeof require&&"object"==typeof exports){var c=require("openlayers");exports.angularOpenlayersDirective=b(c)}else"function"==typeof define&&define.amd?define(["ol"],function(c){return a.angularOpenlayersDirective=b(c)}):a.angularOpenlayersDirective=b(a.ol)}(this,function(a){angular.module("openlayers-directive",["ngSanitize"]).directive("openlayers",["$log","$q","$compile","olHelpers","olMapDefaults","olData",function(b,c,d,e,f,g){return{restrict:"EA",transclude:!0,replace:!0,scope:{center:"=olCenter",defaults:"=olDefaults",view:"=olView",events:"=olEvents"},template:'
',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id),q.setTarget(null),q=null}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);if(!0===s.centerUrlHash){var t=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t(),r.$on("$locationChangeSuccess",function(){var a=t();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var u;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return u||(u=new a.Geolocation({projection:a.proj.get(c.projection)}),u.on("change",function(){if(c.autodiscover){var a=u.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,u.setTracking(!1)})}})),void u.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}});var v=f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})});r.$on("$destroy",function(){a.Observable.unByKey(v)})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),g(e)&&n(c.visible)&&(c.visible!==e.visible||z(d)||d.getVisible()!==c.visible)&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(b,c,d,e,f){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(b,c,d,g){var h=g.getOpenlayersScope(),i=f.isNumber,j=f.safeApply,k=f.createView;h.getMap().then(function(b){var c=e.getDefaults(h),d=h.view;d.projection||(d.projection=c.view.projection),d.maxZoom||(d.maxZoom=c.view.maxZoom),d.minZoom||(d.minZoom=c.view.minZoom),d.rotation||(d.rotation=c.view.rotation);var f=k(d);b.setView(f),h.$watchCollection("view",function(a){i(a.rotation)&&f.setRotation(a.rotation)});var g=f.on("change:rotation",function(){j(h,function(a){a.view.rotation=b.getView().getRotation()})});h.$on("$destroy",function(){a.Observable.unByKey(g)})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope();i.getMap().then(function(b){var d=e.getControlClasses,i=d();if(a.$on("$destroy",function(){b.removeControl(f)}),!h(a.properties)||!h(a.properties.control))return void(c.name&&(h(a.properties)&&(g=a.properties),f=new i[c.name](g),b.addControl(f)));f=a.properties.control,b.addControl(f)})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(!(x=g?g.get("marker"):null)||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;if(e.on("pointerdown",j),e.on("pointerup",j),e.on("pointerdrag",j),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e)}),!k(c.properties))return t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p)));c.$watch("properties",function(d){if(e.getViewport().removeEventListener("mousemove",d.handleInteraction),e.getViewport().removeEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",d.handleTapInteraction),e.getViewport().removeEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",d.removeAllOverlays),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){function a(){c=!0,b&&clearTimeout(b),b=setTimeout(function(){c=!1,b=null},500)}var b,c=!1;return e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",a),function(){c||(d.handleInteraction.apply(null,arguments),a())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&!0===d.label.show&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&!1===d.label.show&&(e.removeOverlay(p),p=void 0),d.label&&!1===d.label.show&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&!1===d.label.show&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&!1===d.label.show&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0)})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){a[c(a,b)].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&!0!==a[f].resolvedDefer?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d=c(a,b);return angular.isDefined(a[d])&&!1!==a[d].resolvedDefer?a[d].defer:f(a,b)};this.setMap=function(a,b){f(d,b).resolve(a),e(d,b)},this.getMap=function(a){return g(d,a).promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map","World_Light_Gray_Base","World_Dark_Gray_Base"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function a(b,c){var d;if(c?d=b[c]:(c="style",d=b),"style"===c&&b instanceof Function)return b;if(!(d instanceof Object))return d;var e;if("[object Object]"===Object.prototype.toString.call(d)){e={};var f=l[c];if(f&&d instanceof f)return d;Object.getOwnPropertyNames(d).forEach(function(b,g,h){var i=l[b];if(f&&i&&i.prototype instanceof l[c])return console.assert(1===h.length,"Extra parameters for "+c),e=a(d,b),m(e,i);e[b]=a(d,b),"text"!==b&&"string"!=typeof e[b]&&(e[b]=m(e[b],l[b]))})}else e=d;return m(e,l[c])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":return"Vector";case"TileVector":case"MVT":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g,i,l,m=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");l="https://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace(".png","@2x.png")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,wrapX:void 0===b.wrapX||b.wrapX});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");l="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace("{y}?access_token","{y}@2x?access_token")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,tileSize:b.tileSize||[512,512],wrapX:void 0===b.wrapX||b.wrapX});break;case"MVT":if(!b.url)return void c.error("[AngularJS - Openlayers] - MVT layer requires the source url");g=new a.source.VectorTile({attributions:b.attributions||"",format:new a.format.MVT,tileGrid:a.tilegrid.createXYZ({maxZoom:b.maxZoom||22}),tilePixelRatio:b.tilePixelRatio||16,url:b.url});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,imageLoadFunction:b.imageLoadFunction,attributions:t(b),crossOrigin:void 0===b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={tileLoadFunction:b.tileLoadFunction,crossOrigin:void 0===b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX};b.projection&&(n.projection=new a.proj.get(b.projection)),b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={tileLoadFunction:b.tileLoadFunction,projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),style:"undefined"===b.style?"normal":b.style,wrapX:void 0===b.wrapX||b.wrapX};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({tileLoadFunction:b.tileLoadFunction,attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,tileLoadFunction:b.tileLoadFunction,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX||b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer,wrapX:void 0===b.wrapX||b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="https://services.arcgisonline.com/ArcGIS/rest/services/";"World_Light_Gray_Base"!==b.layer&&"World_Dark_Gray_Base"!==b.layer||(r+="Canvas/");var u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:u,wrapX:void 0===b.wrapX||b.wrapX});break;case"TileArcGISRest":b.url||c.error("[AngularJS - Openlayers] - TileArcGISRest Layer needs valid url"),g=new a.source.TileArcGISRest({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=m.readFeatures(b.geojson.object,{featureProjection:w.getCode(),dataProjection:v.getCode()});g.addFeatures(x)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});else{g=new a.source.Vector;var y,z=f;y=e(b.wkt.projection)?new a.proj.get(b.wkt.projection):f;for(var A=new a.format.WKT,B=[],C=0;C-1)return a.source[b.type][d]}return null},v=function(b){var c=new a.layer.Group;return c.set("name",b),c},w=function(b,c){var d;return angular.forEach(b,function(b){if(b instanceof a.layer.Group&&b.get("name")===c)return void(d=b)}),d},x=function(a,b){for(var c,d=0;d',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id),q.setTarget(null),q=null}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);if(!0===s.centerUrlHash){var t=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t(),r.$on("$locationChangeSuccess",function(){var a=t();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var u;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return u||(u=new a.Geolocation({projection:a.proj.get(c.projection)}),u.on("change",function(){if(c.autodiscover){var a=u.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,u.setTracking(!1)})}})),void u.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}});var v=f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})});r.$on("$destroy",function(){a.Observable.unByKey(v)})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),g(e)&&n(c.visible)&&(c.visible!==e.visible||z(d)||d.getVisible()!==c.visible)&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(b,c,d,e,f){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(b,c,d,g){var h=g.getOpenlayersScope(),i=f.isNumber,j=f.safeApply,k=f.createView;h.getMap().then(function(b){var c=e.getDefaults(h),d=h.view;d.projection||(d.projection=c.view.projection),d.maxZoom||(d.maxZoom=c.view.maxZoom),d.minZoom||(d.minZoom=c.view.minZoom),d.rotation||(d.rotation=c.view.rotation);var f=k(d);b.setView(f),h.$watchCollection("view",function(a){i(a.rotation)&&f.setRotation(a.rotation)});var g=f.on("change:rotation",function(){j(h,function(a){a.view.rotation=b.getView().getRotation()})});h.$on("$destroy",function(){a.Observable.unByKey(g)})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope(),j=e.getControlClasses,k=j();i.getMap().then(function(b){function d(a){a&&a.control?(f&&b.removeControl(f),f=a.control,b.addControl(f)):c.name&&(h(a)&&(g=a),f&&b.removeControl(f),f=new k[c.name](g),b.addControl(f))}a.$on("$destroy",function(){b.removeControl(f)}),a.$watch("properties",function(a){h(a)&&d(a)}),d(a.properties)})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e].markerLayer,delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(){c.properties&&(e.getViewport().removeEventListener("mousemove",c.properties.handleInteraction),e.getViewport().removeEventListener("click",c.properties.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",c.properties.handleTapInteraction),e.getViewport().removeEventListener("mousemove",c.properties.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",c.properties.removeAllOverlays),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",c.properties.activateCooldown))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;if(c.handleDrag=function(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(!(x=g?g.get("marker"):null)||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))},e.on("pointerdown",c.handleDrag),e.on("pointerup",c.handleDrag),e.on("pointerdrag",c.handleDrag),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e),e.un("pointerdown",c.handleDrag),e.un("pointerup",c.handleDrag),e.un("pointerdrag",c.handleDrag),j()}),!k(c.properties))return t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p)));c.$watch("properties",function(d){if(j(),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){var a,b=!1;return d.activateCooldown=function(){b=!0,a&&clearTimeout(a),a=setTimeout(function(){b=!1,a=null},500)},d.activateCooldown&&e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",d.activateCooldown),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",d.activateCooldown),function(){b||(d.handleInteraction.apply(null,arguments),d.activateCooldown())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&!0===d.label.show&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&!1===d.label.show&&(e.removeOverlay(p),p=void 0),d.label&&!1===d.label.show&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&!1===d.label.show&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&!1===d.label.show&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0)})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){a[c(a,b)].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&!0!==a[f].resolvedDefer?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d=c(a,b);return angular.isDefined(a[d])&&!1!==a[d].resolvedDefer?a[d].defer:f(a,b)};this.setMap=function(a,b){f(d,b).resolve(a),e(d,b)},this.getMap=function(a){return g(d,a).promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map","World_Light_Gray_Base","World_Dark_Gray_Base"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function a(b,c){var d;if(c?d=b[c]:(c="style",d=b),"style"===c&&b instanceof Function)return b;if(!(d instanceof Object))return d;var e;if("[object Object]"===Object.prototype.toString.call(d)){e={};var f=l[c];if(f&&d instanceof f)return d;Object.getOwnPropertyNames(d).forEach(function(b,g,h){var i=l[b];if(f&&i&&i.prototype instanceof l[c])return console.assert(1===h.length,"Extra parameters for "+c),e=a(d,b),m(e,i);e[b]=a(d,b),"text"!==b&&"string"!=typeof e[b]&&(e[b]=m(e[b],l[b]))})}else e=d;return m(e,l[c])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":return"Vector";case"TileVector":case"MVT":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g,i,l,m=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");l="https://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace(".png","@2x.png")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,wrapX:void 0===b.wrapX||b.wrapX});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");l="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace("{y}?access_token","{y}@2x?access_token")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,tileSize:b.tileSize||[512,512],wrapX:void 0===b.wrapX||b.wrapX});break;case"MVT":if(!b.url)return void c.error("[AngularJS - Openlayers] - MVT layer requires the source url");g=new a.source.VectorTile({attributions:b.attributions||"",format:new a.format.MVT,tileGrid:a.tilegrid.createXYZ({maxZoom:b.maxZoom||22}),tilePixelRatio:b.tilePixelRatio||16,url:b.url});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,imageLoadFunction:b.imageLoadFunction,attributions:t(b),crossOrigin:void 0===b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={tileLoadFunction:b.tileLoadFunction,crossOrigin:void 0===b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX};b.projection&&(n.projection=new a.proj.get(b.projection)),b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={tileLoadFunction:b.tileLoadFunction,projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),style:"undefined"===b.style?"normal":b.style,wrapX:void 0===b.wrapX||b.wrapX};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({tileLoadFunction:b.tileLoadFunction,attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,tileLoadFunction:b.tileLoadFunction,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX||b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer,wrapX:void 0===b.wrapX||b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="https://services.arcgisonline.com/ArcGIS/rest/services/";"World_Light_Gray_Base"!==b.layer&&"World_Dark_Gray_Base"!==b.layer||(r+="Canvas/");var u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:u,wrapX:void 0===b.wrapX||b.wrapX});break;case"TileArcGISRest":b.url||c.error("[AngularJS - Openlayers] - TileArcGISRest Layer needs valid url"),g=new a.source.TileArcGISRest({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=m.readFeatures(b.geojson.object,{featureProjection:w.getCode(),dataProjection:v.getCode()});g.addFeatures(x)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});else{g=new a.source.Vector;var y,z=f;y=e(b.wkt.projection)?new a.proj.get(b.wkt.projection):f;for(var A=new a.format.WKT,B=[],C=0;C-1)return a.source[b.type][d]}return null},v=function(b){var c=new a.layer.Group;return c.set("name",b),c},w=function(b,c){var d;return angular.forEach(b,function(b){if(b instanceof a.layer.Group&&b.get("name")===c)return void(d=b)}),d},x=function(a,b){for(var c,d=0;d',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id),q.setTarget(null),q=null}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);if(!0===s.centerUrlHash){var t=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t(),r.$on("$locationChangeSuccess",function(){var a=t();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var u;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return u||(u=new a.Geolocation({projection:a.proj.get(c.projection)}),u.on("change",function(){if(c.autodiscover){var a=u.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,u.setTracking(!1)})}})),void u.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}});var v=f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})});r.$on("$destroy",function(){a.Observable.unByKey(v)})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),g(e)&&n(c.visible)&&(c.visible!==e.visible||z(d)||d.getVisible()!==c.visible)&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(b,c,d,e,f){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(b,c,d,g){var h=g.getOpenlayersScope(),i=f.isNumber,j=f.safeApply,k=f.createView;h.getMap().then(function(b){var c=e.getDefaults(h),d=h.view;d.projection||(d.projection=c.view.projection),d.maxZoom||(d.maxZoom=c.view.maxZoom),d.minZoom||(d.minZoom=c.view.minZoom),d.rotation||(d.rotation=c.view.rotation);var f=k(d);b.setView(f),h.$watchCollection("view",function(a){i(a.rotation)&&f.setRotation(a.rotation)});var g=f.on("change:rotation",function(){j(h,function(a){a.view.rotation=b.getView().getRotation()})});h.$on("$destroy",function(){a.Observable.unByKey(g)})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope();i.getMap().then(function(b){var d=e.getControlClasses,i=d();if(a.$on("$destroy",function(){b.removeControl(f)}),!h(a.properties)||!h(a.properties.control))return void(c.name&&(h(a.properties)&&(g=a.properties),f=new i[c.name](g),b.addControl(f)));f=a.properties.control,b.addControl(f)})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(!(x=g?g.get("marker"):null)||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;if(e.on("pointerdown",j),e.on("pointerup",j),e.on("pointerdrag",j),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e)}),!k(c.properties))return t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p)));c.$watch("properties",function(d){if(e.getViewport().removeEventListener("mousemove",d.handleInteraction),e.getViewport().removeEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",d.handleTapInteraction),e.getViewport().removeEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",d.removeAllOverlays),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){function a(){c=!0,b&&clearTimeout(b),b=setTimeout(function(){c=!1,b=null},500)}var b,c=!1;return e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",a),function(){c||(d.handleInteraction.apply(null,arguments),a())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&!0===d.label.show&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&!1===d.label.show&&(e.removeOverlay(p),p=void 0),d.label&&!1===d.label.show&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&!1===d.label.show&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&!1===d.label.show&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0)})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){a[c(a,b)].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&!0!==a[f].resolvedDefer?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d=c(a,b);return angular.isDefined(a[d])&&!1!==a[d].resolvedDefer?a[d].defer:f(a,b)};this.setMap=function(a,b){f(d,b).resolve(a),e(d,b)},this.getMap=function(a){return g(d,a).promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map","World_Light_Gray_Base","World_Dark_Gray_Base"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function a(b,c){var d;if(c?d=b[c]:(c="style",d=b),"style"===c&&b instanceof Function)return b;if(!(d instanceof Object))return d;var e;if("[object Object]"===Object.prototype.toString.call(d)){e={};var f=l[c];if(f&&d instanceof f)return d;Object.getOwnPropertyNames(d).forEach(function(b,g,h){var i=l[b];if(f&&i&&i.prototype instanceof l[c])return console.assert(1===h.length,"Extra parameters for "+c),e=a(d,b),m(e,i);e[b]=a(d,b),"text"!==b&&"string"!=typeof e[b]&&(e[b]=m(e[b],l[b]))})}else e=d;return m(e,l[c])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":return"Vector";case"TileVector":case"MVT":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g,i,l,m=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");l="https://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace(".png","@2x.png")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,wrapX:void 0===b.wrapX||b.wrapX});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");l="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace("{y}?access_token","{y}@2x?access_token")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,tileSize:b.tileSize||[512,512],wrapX:void 0===b.wrapX||b.wrapX});break;case"MVT":if(!b.url)return void c.error("[AngularJS - Openlayers] - MVT layer requires the source url");g=new a.source.VectorTile({attributions:b.attributions||"",format:new a.format.MVT,tileGrid:a.tilegrid.createXYZ({maxZoom:b.maxZoom||22}),tilePixelRatio:b.tilePixelRatio||16,url:b.url});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,imageLoadFunction:b.imageLoadFunction,attributions:t(b),crossOrigin:void 0===b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={tileLoadFunction:b.tileLoadFunction,crossOrigin:void 0===b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX};b.projection&&(n.projection=new a.proj.get(b.projection)),b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={tileLoadFunction:b.tileLoadFunction,projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),style:"undefined"===b.style?"normal":b.style,wrapX:void 0===b.wrapX||b.wrapX};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({tileLoadFunction:b.tileLoadFunction,attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,tileLoadFunction:b.tileLoadFunction,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX||b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer,wrapX:void 0===b.wrapX||b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="https://services.arcgisonline.com/ArcGIS/rest/services/";"World_Light_Gray_Base"!==b.layer&&"World_Dark_Gray_Base"!==b.layer||(r+="Canvas/");var u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:u,wrapX:void 0===b.wrapX||b.wrapX});break;case"TileArcGISRest":b.url||c.error("[AngularJS - Openlayers] - TileArcGISRest Layer needs valid url"),g=new a.source.TileArcGISRest({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=m.readFeatures(b.geojson.object,{featureProjection:w.getCode(),dataProjection:v.getCode()});g.addFeatures(x)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});else{g=new a.source.Vector;var y,z=f;y=e(b.wkt.projection)?new a.proj.get(b.wkt.projection):f;for(var A=new a.format.WKT,B=[],C=0;C-1)return a.source[b.type][d]}return null},v=function(b){var c=new a.layer.Group;return c.set("name",b),c},w=function(b,c){var d;return angular.forEach(b,function(b){if(b instanceof a.layer.Group&&b.get("name")===c)return void(d=b)}),d},x=function(a,b){for(var c,d=0;d',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id),q.setTarget(null),q=null}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);if(!0===s.centerUrlHash){var t=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t(),r.$on("$locationChangeSuccess",function(){var a=t();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var u;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return u||(u=new a.Geolocation({projection:a.proj.get(c.projection)}),u.on("change",function(){if(c.autodiscover){var a=u.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,u.setTracking(!1)})}})),void u.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}});var v=f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})});r.$on("$destroy",function(){a.Observable.unByKey(v)})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),g(e)&&n(c.visible)&&(c.visible!==e.visible||z(d)||d.getVisible()!==c.visible)&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(b,c,d,e,f){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(b,c,d,g){var h=g.getOpenlayersScope(),i=f.isNumber,j=f.safeApply,k=f.createView;h.getMap().then(function(b){var c=e.getDefaults(h),d=h.view;d.projection||(d.projection=c.view.projection),d.maxZoom||(d.maxZoom=c.view.maxZoom),d.minZoom||(d.minZoom=c.view.minZoom),d.rotation||(d.rotation=c.view.rotation);var f=k(d);b.setView(f),h.$watchCollection("view",function(a){i(a.rotation)&&f.setRotation(a.rotation)});var g=f.on("change:rotation",function(){j(h,function(a){a.view.rotation=b.getView().getRotation()})});h.$on("$destroy",function(){a.Observable.unByKey(g)})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope(),j=e.getControlClasses,k=j();i.getMap().then(function(b){function d(a){a&&a.control?(f&&b.removeControl(f),f=a.control,b.addControl(f)):c.name&&(h(a)&&(g=a),f&&b.removeControl(f),f=new k[c.name](g),b.addControl(f))}a.$on("$destroy",function(){b.removeControl(f)}),a.$watch("properties",function(a){h(a)&&d(a)}),d(a.properties)})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e].markerLayer,delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(){c.properties&&(e.getViewport().removeEventListener("mousemove",c.properties.handleInteraction),e.getViewport().removeEventListener("click",c.properties.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",c.properties.handleTapInteraction),e.getViewport().removeEventListener("mousemove",c.properties.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",c.properties.removeAllOverlays),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",c.properties.activateCooldown))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;if(c.handleDrag=function(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(!(x=g?g.get("marker"):null)||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))},e.on("pointerdown",c.handleDrag),e.on("pointerup",c.handleDrag),e.on("pointerdrag",c.handleDrag),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e),e.un("pointerdown",c.handleDrag),e.un("pointerup",c.handleDrag),e.un("pointerdrag",c.handleDrag),j()}),!k(c.properties))return t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p)));c.$watch("properties",function(d){if(j(),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){var a,b=!1;return d.activateCooldown=function(){b=!0,a&&clearTimeout(a),a=setTimeout(function(){b=!1,a=null},500)},d.activateCooldown&&e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",d.activateCooldown),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",d.activateCooldown),function(){b||(d.handleInteraction.apply(null,arguments),d.activateCooldown())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&!0===d.label.show&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&!1===d.label.show&&(e.removeOverlay(p),p=void 0),d.label&&!1===d.label.show&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&!1===d.label.show&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&!1===d.label.show&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0)})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){a[c(a,b)].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&!0!==a[f].resolvedDefer?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d=c(a,b);return angular.isDefined(a[d])&&!1!==a[d].resolvedDefer?a[d].defer:f(a,b)};this.setMap=function(a,b){f(d,b).resolve(a),e(d,b)},this.getMap=function(a){return g(d,a).promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map","World_Light_Gray_Base","World_Dark_Gray_Base"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function a(b,c){var d;if(c?d=b[c]:(c="style",d=b),"style"===c&&b instanceof Function)return b;if(!(d instanceof Object))return d;var e;if("[object Object]"===Object.prototype.toString.call(d)){e={};var f=l[c];if(f&&d instanceof f)return d;Object.getOwnPropertyNames(d).forEach(function(b,g,h){var i=l[b];if(f&&i&&i.prototype instanceof l[c])return console.assert(1===h.length,"Extra parameters for "+c),e=a(d,b),m(e,i);e[b]=a(d,b),"text"!==b&&"string"!=typeof e[b]&&(e[b]=m(e[b],l[b]))})}else e=d;return m(e,l[c])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":return"Vector";case"TileVector":case"MVT":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g,i,l,m=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");l="https://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace(".png","@2x.png")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,wrapX:void 0===b.wrapX||b.wrapX});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");l="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace("{y}?access_token","{y}@2x?access_token")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,tileSize:b.tileSize||[512,512],wrapX:void 0===b.wrapX||b.wrapX});break;case"MVT":if(!b.url)return void c.error("[AngularJS - Openlayers] - MVT layer requires the source url");g=new a.source.VectorTile({attributions:b.attributions||"",format:new a.format.MVT,tileGrid:a.tilegrid.createXYZ({maxZoom:b.maxZoom||22}),tilePixelRatio:b.tilePixelRatio||16,url:b.url});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,imageLoadFunction:b.imageLoadFunction,attributions:t(b),crossOrigin:void 0===b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={tileLoadFunction:b.tileLoadFunction,crossOrigin:void 0===b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX};b.projection&&(n.projection=new a.proj.get(b.projection)),b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={tileLoadFunction:b.tileLoadFunction,projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),style:"undefined"===b.style?"normal":b.style,wrapX:void 0===b.wrapX||b.wrapX};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({tileLoadFunction:b.tileLoadFunction,attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,tileLoadFunction:b.tileLoadFunction,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX||b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer,wrapX:void 0===b.wrapX||b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="https://services.arcgisonline.com/ArcGIS/rest/services/";"World_Light_Gray_Base"!==b.layer&&"World_Dark_Gray_Base"!==b.layer||(r+="Canvas/");var u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:u,wrapX:void 0===b.wrapX||b.wrapX});break;case"TileArcGISRest":b.url||c.error("[AngularJS - Openlayers] - TileArcGISRest Layer needs valid url"),g=new a.source.TileArcGISRest({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=m.readFeatures(b.geojson.object,{featureProjection:w.getCode(),dataProjection:v.getCode()});g.addFeatures(x)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});else{g=new a.source.Vector;var y,z=f;y=e(b.wkt.projection)?new a.proj.get(b.wkt.projection):f;for(var A=new a.format.WKT,B=[],C=0;C-1)return a.source[b.type][d]}return null},v=function(b){var c=new a.layer.Group;return c.set("name",b),c},w=function(b,c){var d;return angular.forEach(b,function(b){if(b instanceof a.layer.Group&&b.get("name")===c)return void(d=b)}),d},x=function(a,b){for(var c,d=0;d'); + element = $compile(element)(scope); + scope.$digest(); + expect(function() { scope.$destroy(); }).not.toThrow(); + }); +}); From 2a8dab8c60197c5045498880636b86237cb0bf03 Mon Sep 17 00:00:00 2001 From: Sathish Kesavaperumal Date: Wed, 7 Mar 2018 15:42:49 +0530 Subject: [PATCH 43/53] Removed the Junk file --- node_modules/.bin/grunt-open | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 node_modules/.bin/grunt-open diff --git a/node_modules/.bin/grunt-open b/node_modules/.bin/grunt-open deleted file mode 100644 index b6035be1..00000000 --- a/node_modules/.bin/grunt-open +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh -basedir=`dirname "$0"` - -case `uname` in - *CYGWIN*) basedir=`cygpath -w "$basedir"`;; -esac - -if [ -x "$basedir/node" ]; then - "$basedir/node" "$basedir/../grunt-open/bin/grunt-open" "$@" - ret=$? -else - node "$basedir/../grunt-open/bin/grunt-open" "$@" - ret=$? -fi -exit $ret From 8e76819f85edca25627f7264b5a64332f76f66cb Mon Sep 17 00:00:00 2001 From: Sathish Kesavaperumal Date: Wed, 7 Mar 2018 15:43:48 +0530 Subject: [PATCH 44/53] Removed the compiled output files --- dist/angular-openlayers-directive.css | 58 - dist/angular-openlayers-directive.js | 2567 ----------------- dist/angular-openlayers-directive.min.js | 32 - ...ular-openlayers-directive.min.no-header.js | 3 - dist/angular-openlayers-directive.pre.js | 2567 ----------------- 5 files changed, 5227 deletions(-) delete mode 100644 dist/angular-openlayers-directive.css delete mode 100644 dist/angular-openlayers-directive.js delete mode 100644 dist/angular-openlayers-directive.min.js delete mode 100644 dist/angular-openlayers-directive.min.no-header.js delete mode 100644 dist/angular-openlayers-directive.pre.js diff --git a/dist/angular-openlayers-directive.css b/dist/angular-openlayers-directive.css deleted file mode 100644 index fd9933e0..00000000 --- a/dist/angular-openlayers-directive.css +++ /dev/null @@ -1,58 +0,0 @@ -.popup-label { - background-color: #fff; - border: 2px #444 solid; - border-radius: 7px; - -webkit-box-shadow: 4px 4px 5px 0px rgba(50, 50, 50, 0.75); - -moz-box-shadow: 4px 4px 5px 0px rgba(50, 50, 50, 0.75); - box-shadow: 4px 4px 5px 0px rgba(50, 50, 50, 0.75); - color: #111; - font: 12px/20px "Helvetica Neue", Arial, Helvetica, sans-serif; - font-weight: bold; - padding: 3px 6px; - position: absolute; - white-space: nowrap; - top: -35px; - left: 20px; - display: none; -} - -.popup-label img { - vertical-align: middle; -} - -.popup-label.marker:before { - border-top: 6px solid transparent; - border-bottom: 6px solid transparent; - content: ""; - border-right: 6px solid black; - border-right-color: inherit; - position: absolute; - left: -8px; - top: 5px; -} - -.angular-openlayers-map:-moz-full-screen { - height: 100%; -} -.angular-openlayers-map:-webkit-full-screen { - height: 100%; -} -.angular-openlayers-map:full-screen { - height: 100%; -} - -.angular-openlayers-map:not(-moz-full-screen) { - height: 400px; -} - -.angular-openlayers-map:not(-webkit-full-screen) { - height: 400px; -} - -.angular-openlayers-map:not(full-screen) { - height: 400px; -} -.ol-full-screen { - position: absolute; - top: 50%; -} diff --git a/dist/angular-openlayers-directive.js b/dist/angular-openlayers-directive.js deleted file mode 100644 index bfe8bf36..00000000 --- a/dist/angular-openlayers-directive.js +++ /dev/null @@ -1,2567 +0,0 @@ -(function (root, factory) { - if (typeof require === 'function' && typeof exports === 'object') { - // CommonJS - var ol = require('openlayers-prebuilt'); - var ngSanitize = require('angular-sanitize'); - exports.angularOpenlayersDirective = factory(ol); - } else if (typeof define === 'function' && define.amd) { - // AMD. - define(['ol'], function (ol) { - return root.angularOpenlayersDirective = factory(ol); - }); - } else { - // Browser globals - root.angularOpenlayersDirective = factory(root.ol); - } -}(this, function (ol) { -angular.module('openlayers-directive', ['ngSanitize']).directive('openlayers', ["$log", "$q", "$compile", "olHelpers", "olMapDefaults", "olData", function($log, $q, $compile, olHelpers, - olMapDefaults, olData) { - return { - restrict: 'EA', - transclude: true, - replace: true, - scope: { - center: '=olCenter', - defaults: '=olDefaults', - view: '=olView', - events: '=olEvents' - }, - template: '
', - controller: ["$scope", function($scope) { - var _map = $q.defer(); - $scope.getMap = function() { - return _map.promise; - }; - - $scope.setMap = function(map) { - _map.resolve(map); - }; - - this.getOpenlayersScope = function() { - return $scope; - }; - }], - link: function(scope, element, attrs) { - var isDefined = olHelpers.isDefined; - var createLayer = olHelpers.createLayer; - var setMapEvents = olHelpers.setMapEvents; - var setViewEvents = olHelpers.setViewEvents; - var createView = olHelpers.createView; - var defaults = olMapDefaults.setDefaults(scope); - - // Set width and height if they are defined - if (isDefined(attrs.width)) { - if (isNaN(attrs.width)) { - element.css('width', attrs.width); - } else { - element.css('width', attrs.width + 'px'); - } - } - - if (isDefined(attrs.height)) { - if (isNaN(attrs.height)) { - element.css('height', attrs.height); - } else { - element.css('height', attrs.height + 'px'); - } - } - - if (isDefined(attrs.lat)) { - defaults.center.lat = parseFloat(attrs.lat); - } - - if (isDefined(attrs.lon)) { - defaults.center.lon = parseFloat(attrs.lon); - } - - if (isDefined(attrs.zoom)) { - defaults.center.zoom = parseFloat(attrs.zoom); - } - - var controls = ol.control.defaults(defaults.controls); - var interactions = ol.interaction.defaults(defaults.interactions); - var view = createView(defaults.view); - - // Create the Openlayers Map Object with the options - var map = new ol.Map({ - target: element[0], - controls: controls, - interactions: interactions, - renderer: defaults.renderer, - view: view, - loadTilesWhileAnimating: defaults.loadTilesWhileAnimating, - loadTilesWhileInteracting: defaults.loadTilesWhileInteracting - }); - - scope.$on('$destroy', function() { - olData.resetMap(attrs.id); - map.setTarget(null); - }); - - // If no layer is defined, set the default tileLayer - if (!attrs.customLayers) { - var l = { - type: 'Tile', - source: { - type: 'OSM' - } - }; - var layer = createLayer(l, view.getProjection(), 'default'); - map.addLayer(layer); - map.set('default', true); - } - - if (!isDefined(attrs.olCenter)) { - var c = ol.proj.transform([defaults.center.lon, - defaults.center.lat - ], - defaults.center.projection, view.getProjection() - ); - view.setCenter(c); - view.setZoom(defaults.center.zoom); - } - - // Set the Default events for the map - setMapEvents(defaults.events, map, scope); - - //Set the Default events for the map view - setViewEvents(defaults.events, map, scope); - - // Resolve the map object to the promises - scope.setMap(map); - olData.setMap(map, attrs.id); - - } - }; - }]); - -angular.module('openlayers-directive').directive('olCenter', ["$log", "$location", "olMapDefaults", "olHelpers", function($log, $location, olMapDefaults, olHelpers) { - - return { - restrict: 'A', - scope: false, - replace: false, - require: 'openlayers', - - link: function(scope, element, attrs, controller) { - var safeApply = olHelpers.safeApply; - var isValidCenter = olHelpers.isValidCenter; - var isDefined = olHelpers.isDefined; - var isArray = olHelpers.isArray; - var isNumber = olHelpers.isNumber; - var isSameCenterOnMap = olHelpers.isSameCenterOnMap; - var setCenter = olHelpers.setCenter; - var setZoom = olHelpers.setZoom; - var olScope = controller.getOpenlayersScope(); - - olScope.getMap().then(function(map) { - var defaults = olMapDefaults.getDefaults(olScope); - var view = map.getView(); - var center = olScope.center; - - if (attrs.olCenter.search('-') !== -1) { - $log.error('[AngularJS - Openlayers] The "center" variable can\'t use ' + - 'a "-" on his key name: "' + attrs.center + '".'); - setCenter(view, defaults.view.projection, defaults.center, map); - return; - } - - if (!isDefined(center)) { - center = {}; - } - - if (!isValidCenter(center)) { - $log.warn('[AngularJS - Openlayers] invalid \'center\''); - center.lat = defaults.center.lat; - center.lon = defaults.center.lon; - center.zoom = defaults.center.zoom; - center.projection = defaults.center.projection; - } - - if (!center.projection) { - if (defaults.view.projection !== 'pixel') { - center.projection = defaults.center.projection; - } else { - center.projection = 'pixel'; - } - } - - if (!isNumber(center.zoom)) { - center.zoom = 1; - } - - setCenter(view, defaults.view.projection, center, map); - view.setZoom(center.zoom); - - var centerUrlHash; - if (center.centerUrlHash === true) { - var extractCenterFromUrl = function() { - var search = $location.search(); - var centerParam; - if (isDefined(search.c)) { - var cParam = search.c.split(':'); - if (cParam.length === 3) { - centerParam = { - lat: parseFloat(cParam[0]), - lon: parseFloat(cParam[1]), - zoom: parseInt(cParam[2], 10) - }; - } - } - return centerParam; - }; - centerUrlHash = extractCenterFromUrl(); - - olScope.$on('$locationChangeSuccess', function() { - var urlCenter = extractCenterFromUrl(); - if (urlCenter && !isSameCenterOnMap(urlCenter, map)) { - safeApply(olScope, function(scope) { - scope.center.lat = urlCenter.lat; - scope.center.lon = urlCenter.lon; - scope.center.zoom = urlCenter.zoom; - }); - } - }); - } - - var geolocation; - olScope.$watchCollection('center', function(center) { - - if (!center) { - return; - } - - if (!center.projection) { - center.projection = defaults.center.projection; - } - - if (center.autodiscover) { - if (!geolocation) { - geolocation = new ol.Geolocation({ - projection: ol.proj.get(center.projection) - }); - - geolocation.on('change', function() { - if (center.autodiscover) { - var location = geolocation.getPosition(); - safeApply(olScope, function(scope) { - scope.center.lat = location[1]; - scope.center.lon = location[0]; - scope.center.zoom = 12; - scope.center.autodiscover = false; - geolocation.setTracking(false); - }); - } - }); - } - geolocation.setTracking(true); - return; - } - - if (!isValidCenter(center)) { - $log.warn('[AngularJS - Openlayers] invalid \'center\''); - center = defaults.center; - } - - var viewCenter = view.getCenter(); - if (viewCenter) { - if (defaults.view.projection === 'pixel' || center.projection === 'pixel') { - view.setCenter(center.coord); - } else { - var actualCenter = - ol.proj.transform(viewCenter, defaults.view.projection, center.projection); - if (!(actualCenter[1] === center.lat && actualCenter[0] === center.lon)) { - setCenter(view, defaults.view.projection, center, map); - } - } - } - - if (view.getZoom() !== center.zoom) { - setZoom(view, center.zoom, map); - } - }); - - var moveEndEventKey = map.on('moveend', function() { - safeApply(olScope, function(scope) { - - if (!isDefined(scope.center)) { - return; - } - - var center = map.getView().getCenter(); - scope.center.zoom = view.getZoom(); - - if (defaults.view.projection === 'pixel' || scope.center.projection === 'pixel') { - scope.center.coord = center; - return; - } - - if (scope.center) { - var proj = ol.proj.transform(center, defaults.view.projection, scope.center.projection); - scope.center.lat = proj[1]; - scope.center.lon = proj[0]; - - // Notify the controller about a change in the center position - olHelpers.notifyCenterUrlHashChanged(olScope, scope.center, $location.search()); - - // Calculate the bounds if needed - if (isArray(scope.center.bounds)) { - var extent = view.calculateExtent(map.getSize()); - var centerProjection = scope.center.projection; - var viewProjection = defaults.view.projection; - scope.center.bounds = ol.proj.transformExtent(extent, viewProjection, centerProjection); - } - } - }); - }); - - olScope.$on('$destroy', function() { - map.unByKey(moveEndEventKey); - }); - }); - } - }; -}]); - -angular.module('openlayers-directive').directive('olLayer', ["$log", "$q", "olMapDefaults", "olHelpers", function($log, $q, olMapDefaults, olHelpers) { - - return { - restrict: 'E', - scope: { - properties: '=olLayerProperties', - onLayerCreated: '&' - }, - replace: false, - require: '^openlayers', - link: function(scope, element, attrs, controller) { - var isDefined = olHelpers.isDefined; - var equals = olHelpers.equals; - var olScope = controller.getOpenlayersScope(); - var createLayer = olHelpers.createLayer; - var setVectorLayerEvents = olHelpers.setVectorLayerEvents; - var detectLayerType = olHelpers.detectLayerType; - var createStyle = olHelpers.createStyle; - var isBoolean = olHelpers.isBoolean; - var addLayerBeforeMarkers = olHelpers.addLayerBeforeMarkers; - var isNumber = olHelpers.isNumber; - var insertLayer = olHelpers.insertLayer; - var removeLayer = olHelpers.removeLayer; - var addLayerToGroup = olHelpers.addLayerToGroup; - var removeLayerFromGroup = olHelpers.removeLayerFromGroup; - var getGroup = olHelpers.getGroup; - - olScope.getMap().then(function(map) { - var projection = map.getView().getProjection(); - var defaults = olMapDefaults.setDefaults(olScope); - var layerCollection = map.getLayers(); - var olLayer; - - scope.$on('$destroy', function() { - if (scope.properties.group) { - removeLayerFromGroup(layerCollection, olLayer, scope.properties.group); - } else { - removeLayer(layerCollection, olLayer.index); - } - - map.removeLayer(olLayer); - }); - - if (!isDefined(scope.properties)) { - if (isDefined(attrs.sourceType) && isDefined(attrs.sourceUrl)) { - var l = { - source: { - url: attrs.sourceUrl, - type: attrs.sourceType - } - }; - - olLayer = createLayer(l, projection, attrs.layerName, scope.onLayerCreated); - if (detectLayerType(l) === 'Vector') { - setVectorLayerEvents(defaults.events, map, scope, attrs.name); - } - addLayerBeforeMarkers(layerCollection, olLayer); - } - return; - } - - scope.$watch('properties', function(properties, oldProperties) { - if (!isDefined(properties.source) || !isDefined(properties.source.type)) { - return; - } - - if (!isDefined(properties.visible)) { - properties.visible = true; - return; - } - - if (!isDefined(properties.opacity)) { - properties.opacity = 1; - return; - } - - var style; - var group; - var collection; - if (!isDefined(olLayer)) { - olLayer = createLayer(properties, projection, scope.onLayerCreated); - if (isDefined(properties.group)) { - addLayerToGroup(layerCollection, olLayer, properties.group); - } else if (isDefined(properties.index)) { - insertLayer(layerCollection, properties.index, olLayer); - } else { - addLayerBeforeMarkers(layerCollection, olLayer); - } - - if (detectLayerType(properties) === 'Vector') { - setVectorLayerEvents(defaults.events, map, scope, properties.name); - } - - if (isBoolean(properties.visible)) { - olLayer.setVisible(properties.visible); - } - - if (properties.opacity) { - olLayer.setOpacity(properties.opacity); - } - - if (angular.isArray(properties.extent)) { - olLayer.setExtent(properties.extent); - } - - if (properties.style) { - if (!angular.isFunction(properties.style)) { - style = createStyle(properties.style); - } else { - style = properties.style; - } - // not every layer has a setStyle method - if (olLayer.setStyle && angular.isFunction(olLayer.setStyle)) { - olLayer.setStyle(style); - } - } - - if (properties.minResolution) { - olLayer.setMinResolution(properties.minResolution); - } - - if (properties.maxResolution) { - olLayer.setMaxResolution(properties.maxResolution); - } - - } else { - var isNewLayer = (function(olLayer) { - // this function can be used to verify whether a new layer instance has - // been created. This is needed in order to re-assign styles, opacity - // etc... - return function(layer) { - return layer !== olLayer; - }; - })(olLayer); - - // set source properties - if (isDefined(oldProperties) && !equals(properties.source, oldProperties.source)) { - var idx = olLayer.index; - collection = layerCollection; - group = olLayer.get('group'); - - if (group) { - collection = getGroup(layerCollection, group).getLayers(); - } - - collection.removeAt(idx); - - olLayer = createLayer(properties, projection, scope.onLayerCreated); - olLayer.set('group', group); - - if (isDefined(olLayer)) { - insertLayer(collection, idx, olLayer); - - if (detectLayerType(properties) === 'Vector') { - setVectorLayerEvents(defaults.events, map, scope, properties.name); - } - } - } - - // set opacity - if (isDefined(oldProperties) && - properties.opacity !== oldProperties.opacity || isNewLayer(olLayer)) { - if (isNumber(properties.opacity) || isNumber(parseFloat(properties.opacity))) { - olLayer.setOpacity(properties.opacity); - } - } - - // set index - if (isDefined(properties.index) && properties.index !== olLayer.index) { - collection = layerCollection; - group = olLayer.get('group'); - - if (group) { - collection = getGroup(layerCollection, group).getLayers(); - } - - removeLayer(collection, olLayer.index); - insertLayer(collection, properties.index, olLayer); - } - - // set group - if (isDefined(properties.group) && properties.group !== oldProperties.group) { - removeLayerFromGroup(layerCollection, olLayer, oldProperties.group); - addLayerToGroup(layerCollection, olLayer, properties.group); - } - - // set visibility - if (isDefined(oldProperties) && - isBoolean(properties.visible) && - properties.visible !== oldProperties.visible || isNewLayer(olLayer)) { - olLayer.setVisible(properties.visible); - } - - // set style - if (isDefined(properties.style) && - !equals(properties.style, oldProperties.style) || isNewLayer(olLayer)) { - if (!angular.isFunction(properties.style)) { - style = createStyle(properties.style); - } else { - style = properties.style; - } - // not every layer has a setStyle method - if (olLayer.setStyle && angular.isFunction(olLayer.setStyle)) { - olLayer.setStyle(style); - } - } - - //set min resolution - if (!equals(properties.minResolution, oldProperties.minResolution) || isNewLayer(olLayer)) { - if (isDefined(properties.minResolution)) { - olLayer.setMinResolution(properties.minResolution); - } - } - - //set max resolution - if (!equals(properties.maxResolution, oldProperties.maxResolution) || isNewLayer(olLayer)) { - if (isDefined(properties.maxResolution)) { - olLayer.setMaxResolution(properties.maxResolution); - } - } - } - }, true); - }); - } - }; -}]); - -angular.module('openlayers-directive').directive('olPath', ["$log", "$q", "olMapDefaults", "olHelpers", function($log, $q, olMapDefaults, olHelpers) { - - return { - restrict: 'E', - scope: { - properties: '=olGeomProperties', - style: '=olStyle' - }, - require: '^openlayers', - replace: true, - template: '', - - link: function(scope, element, attrs, controller) { - var isDefined = olHelpers.isDefined; - var createFeature = olHelpers.createFeature; - var createOverlay = olHelpers.createOverlay; - var createVectorLayer = olHelpers.createVectorLayer; - var insertLayer = olHelpers.insertLayer; - var removeLayer = olHelpers.removeLayer; - var olScope = controller.getOpenlayersScope(); - - olScope.getMap().then(function(map) { - var mapDefaults = olMapDefaults.getDefaults(olScope); - var viewProjection = mapDefaults.view.projection; - - var layer = createVectorLayer(); - var layerCollection = map.getLayers(); - - insertLayer(layerCollection, layerCollection.getLength(), layer); - - scope.$on('$destroy', function() { - removeLayer(layerCollection, layer.index); - }); - - if (isDefined(attrs.coords)) { - var proj = attrs.proj || 'EPSG:4326'; - var coords = JSON.parse(attrs.coords); - var data = { - type: 'Polygon', - coords: coords, - projection: proj, - style: scope.style ? scope.style : mapDefaults.styles.path - }; - var feature = createFeature(data, viewProjection); - layer.getSource().addFeature(feature); - - if (attrs.message) { - scope.message = attrs.message; - var extent = feature.getGeometry().getExtent(); - var label = createOverlay(element, extent); - map.addOverlay(label); - } - return; - } - }); - } - }; -}]); - -angular.module('openlayers-directive').directive('olView', ["$log", "$q", "olData", "olMapDefaults", "olHelpers", function($log, $q, olData, olMapDefaults, olHelpers) { - return { - restrict: 'A', - scope: false, - replace: false, - require: 'openlayers', - link: function(scope, element, attrs, controller) { - var olScope = controller.getOpenlayersScope(); - var isNumber = olHelpers.isNumber; - var safeApply = olHelpers.safeApply; - var createView = olHelpers.createView; - - olScope.getMap().then(function(map) { - var defaults = olMapDefaults.getDefaults(olScope); - var view = olScope.view; - - if (!view.projection) { - view.projection = defaults.view.projection; - } - - if (!view.maxZoom) { - view.maxZoom = defaults.view.maxZoom; - } - - if (!view.minZoom) { - view.minZoom = defaults.view.minZoom; - } - - if (!view.rotation) { - view.rotation = defaults.view.rotation; - } - - var mapView = createView(view); - map.setView(mapView); - - olScope.$watchCollection('view', function(view) { - if (isNumber(view.rotation)) { - mapView.setRotation(view.rotation); - } - }); - - var rotationEventKey = mapView.on('change:rotation', function() { - safeApply(olScope, function(scope) { - scope.view.rotation = map.getView().getRotation(); - }); - }); - - olScope.$on('$destroy', function() { - map.unByKey(rotationEventKey); - }); - - }); - } - }; -}]); - -angular.module('openlayers-directive') -.directive('olControl', ["$log", "$q", "olData", "olMapDefaults", "olHelpers", function($log, $q, olData, olMapDefaults, olHelpers) { - return { - restrict: 'E', - scope: { - properties: '=olControlProperties' - }, - replace: false, - require: '^openlayers', - link: function(scope, element, attrs, controller) { - var isDefined = olHelpers.isDefined; - var olScope = controller.getOpenlayersScope(); - var olControl; - var olControlOps; - var getControlClasses = olHelpers.getControlClasses; - var controlClasses = getControlClasses(); - - olScope.getMap().then(function(map) { - - scope.$on('$destroy', function() { - map.removeControl(olControl); - }); - - scope.$watch('properties', function(properties) { - if (!isDefined(properties)) { - return; - } - - initCtrls(properties); - }); - - function initCtrls(properties) { - if (properties && properties.control) { - // the control instance is already defined, - // so simply use it and go ahead - - // is there already a control, so destroy and recreate it? - if (olControl) { - map.removeControl(olControl); - } - - olControl = properties.control; - map.addControl(olControl); - } else { - - // the name is the key to instantiate an ol3 control - if (attrs.name) { - if (isDefined(properties)) { - olControlOps = properties; - } - - // is there already a control, so destroy and recreate it? - if (olControl) { - map.removeControl(olControl); - } - - olControl = new controlClasses[attrs.name](olControlOps); - map.addControl(olControl); - } - } - } - - initCtrls(scope.properties); - - }); - - } - }; -}]); - -angular.module('openlayers-directive').directive('olMarker', ["$log", "$q", "olMapDefaults", "olHelpers", function($log, $q, olMapDefaults, olHelpers) { - - var getMarkerDefaults = function() { - return { - projection: 'EPSG:4326', - lat: 0, - lon: 0, - coord: [], - show: true, - showOnMouseOver: false, - showOnMouseClick: false, - keepOneOverlayVisible: false - }; - }; - - var markerLayerManager = (function() { - var mapDict = []; - - function getMapIndex(map) { - return mapDict.map(function(record) { - return record.map; - }).indexOf(map); - } - - return { - getInst: function getMarkerLayerInst(scope, map) { - var mapIndex = getMapIndex(map); - - if (mapIndex === -1) { - var markerLayer = olHelpers.createVectorLayer(); - markerLayer.set('markers', true); - map.addLayer(markerLayer); - mapDict.push({ - map: map, - markerLayer: markerLayer, - instScopes: [] - }); - mapIndex = mapDict.length - 1; - } - - mapDict[mapIndex].instScopes.push(scope); - - return mapDict[mapIndex].markerLayer; - }, - deregisterScope: function deregisterScope(scope, map) { - var mapIndex = getMapIndex(map); - if (mapIndex === -1) { - throw Error('This map has no markers'); - } - - var scopes = mapDict[mapIndex].instScopes; - var scopeIndex = scopes.indexOf(scope); - if (scopeIndex === -1) { - throw Error('Scope wan\'t registered'); - } - - scopes.splice(scopeIndex, 1); - - if (!scopes.length) { - map.removeLayer(mapDict[mapIndex].markerLayer); - delete mapDict[mapIndex].markerLayer; - delete mapDict[mapIndex]; - } - } - }; - })(); - return { - restrict: 'E', - scope: { - lat: '=lat', - lon: '=lon', - label: '=label', - properties: '=olMarkerProperties', - style: '=olStyle' - }, - transclude: true, - require: '^openlayers', - replace: true, - template: - '', - - link: function(scope, element, attrs, controller) { - var isDefined = olHelpers.isDefined; - var olScope = controller.getOpenlayersScope(); - var createFeature = olHelpers.createFeature; - var createOverlay = olHelpers.createOverlay; - - var hasTranscluded = element.find('ng-transclude').children().length > 0; - - olScope.getMap().then(function(map) { - var markerLayer = markerLayerManager.getInst(scope, map); - var data = getMarkerDefaults(); - - var mapDefaults = olMapDefaults.getDefaults(olScope); - var viewProjection = mapDefaults.view.projection; - var label; - var pos; - var marker; - - // This function handles dragging a marker - var pickOffset = null; - var pickProperties = null; - scope.handleDrag = function(evt) { - var coord = evt.coordinate; - var proj = map.getView().getProjection().getCode(); - if (proj === 'pixel') { - coord = coord.map(function(v) { - return parseInt(v, 10); - }); - } else { - coord = ol.proj.transform(coord, proj, 'EPSG:4326'); - } - - if (evt.type === 'pointerdown') { - // Get feature under mouse if any - var feature = map.forEachFeatureAtPixel(evt.pixel, function(feature) { - return feature; - }); - // Get associated marker properties - pickProperties = (feature ? feature.get('marker') : null); - if (!pickProperties || !pickProperties.draggable) { - pickProperties = null; - return; - } - map.getTarget().style.cursor = 'pointer'; - if (proj === 'pixel') { - pickOffset = [coord[0] - pickProperties.coord[0], coord[1] - pickProperties.coord[1]]; - } else { - pickOffset = [coord[0] - pickProperties.lon, coord[1] - pickProperties.lat]; - } - evt.preventDefault(); - } else if (pickOffset && pickProperties) { - if (evt.type === 'pointerup') { - map.getTarget().style.cursor = ''; - pickOffset = null; - pickProperties = null; - evt.preventDefault(); - } else if (evt.type === 'pointerdrag') { - evt.preventDefault(); - scope.$apply(function() { - // Add current delta to marker initial position - if (proj === 'pixel') { - pickProperties.coord[0] = coord[0] - pickOffset[0]; - pickProperties.coord[1] = coord[1] - pickOffset[1]; - } else { - pickProperties.lon = coord[0] - pickOffset[0]; - pickProperties.lat = coord[1] - pickOffset[1]; - } - }); - } - } - }; - - function unregisterHandlers() { - if (!scope.properties) { return ; } - // Remove previous listeners if any - map.getViewport().removeEventListener('mousemove', scope.properties.handleInteraction); - map.getViewport().removeEventListener('click', scope.properties.handleTapInteraction); - map.getViewport().querySelector('canvas.ol-unselectable').removeEventListener( - 'touchend', scope.properties.handleTapInteraction); - map.getViewport().removeEventListener('mousemove', scope.properties.showAtLeastOneOverlay); - map.getViewport().removeEventListener('click', scope.properties.removeAllOverlays); - map.getViewport().querySelector('canvas.ol-unselectable').removeEventListener( - 'touchmove', scope.properties.activateCooldown); - } - - // Setup generic handlers for marker drag - map.on('pointerdown', scope.handleDrag); - map.on('pointerup', scope.handleDrag); - map.on('pointerdrag', scope.handleDrag); - - scope.$on('$destroy', function() { - markerLayer.getSource().removeFeature(marker); - if (isDefined(label)) { - map.removeOverlay(label); - } - markerLayerManager.deregisterScope(scope, map); - map.un('pointerdown', scope.handleDrag); - map.un('pointerup', scope.handleDrag); - map.un('pointerdrag', scope.handleDrag); - unregisterHandlers(); - }); - - if (!isDefined(scope.properties)) { - data.lat = scope.lat ? scope.lat : data.lat; - data.lon = scope.lon ? scope.lon : data.lon; - data.message = attrs.message; - data.style = scope.style ? scope.style : mapDefaults.styles.marker; - - marker = createFeature(data, viewProjection); - if (!isDefined(marker)) { - $log.error('[AngularJS - Openlayers] Received invalid data on ' + - 'the marker.'); - } - // Add a link between the feature and the marker properties - marker.set('marker', scope); - markerLayer.getSource().addFeature(marker); - - if (data.message || hasTranscluded) { - scope.message = attrs.message; - pos = ol.proj.transform([data.lon, data.lat], data.projection, - viewProjection); - label = createOverlay(element, pos); - map.addOverlay(label); - } - return; - } - - scope.$watch('properties', function(properties) { - - unregisterHandlers(); - - // This function handles popup on mouse over/click - properties.handleInteraction = function(evt) { - var ngClick = false; - if (attrs.hasOwnProperty('ngClick')) { - ngClick = true; - } - - if (properties.label.show && !ngClick) { - return; - } - var found = false; - var pixel = map.getEventPixel(evt); - var feature = map.forEachFeatureAtPixel(pixel, function(feature) { - return feature; - }); - - var actionTaken = false; - if (feature === marker) { - actionTaken = true; - found = true; - if (ngClick && (evt.type === 'click' || evt.type === 'touchend')) { - element.triggerHandler('click'); - evt.preventDefault(); - evt.stopPropagation(); - return; - } - if (!isDefined(label)) { - if (data.projection === 'pixel') { - pos = properties.coord; - } else { - pos = ol.proj.transform([properties.lon, properties.lat], - data.projection, viewProjection); - } - label = createOverlay(element, pos); - map.addOverlay(label); - } - map.getTarget().style.cursor = 'pointer'; - } - - if (!found && label) { - actionTaken = true; - map.removeOverlay(label); - label = undefined; - map.getTarget().style.cursor = ''; - } - - if (actionTaken) { - evt.preventDefault(); - } - }; - - // Made to filter out click/tap events if both are being triggered on this platform - properties.handleTapInteraction = (function() { - var cooldownActive = false; - var prevTimeout; - - // Sets the cooldown flag to filter out any subsequent events within 500 ms - properties.activateCooldown = function() { - cooldownActive = true; - if (prevTimeout) { - clearTimeout(prevTimeout); - } - prevTimeout = setTimeout(function() { - cooldownActive = false; - prevTimeout = null; - }, 500); - }; - - // Preventing from 'touchend' to be considered a tap, if fired immediately after 'touchmove' - if (properties.activateCooldown) { - map.getViewport().querySelector('canvas.ol-unselectable').removeEventListener( - 'touchmove', properties.activateCooldown); - } - map.getViewport().querySelector('canvas.ol-unselectable').addEventListener( - 'touchmove', properties.activateCooldown); - - return function() { - if (!cooldownActive) { - properties.handleInteraction.apply(null, arguments); - properties.activateCooldown(); - } - }; - })(); - - properties.showAtLeastOneOverlay = function(evt) { - if (properties.label.show) { - return; - } - var found = false; - var pixel = map.getEventPixel(evt); - var feature = map.forEachFeatureAtPixel(pixel, function(feature) { - return feature; - }); - - var actionTaken = false; - if (feature === marker) { - actionTaken = true; - found = true; - if (!isDefined(label)) { - if (data.projection === 'pixel') { - pos = data.coord; - } else { - pos = ol.proj.transform([data.lon, data.lat], - data.projection, viewProjection); - } - label = createOverlay(element, pos); - angular.forEach(map.getOverlays(), function(value) { - map.removeOverlay(value); - }); - map.addOverlay(label); - } - map.getTarget().style.cursor = 'pointer'; - } - - if (!found && label) { - actionTaken = true; - label = undefined; - map.getTarget().style.cursor = ''; - } - - if (actionTaken) { - evt.preventDefault(); - } - }; - - properties.removeAllOverlays = function(evt) { - angular.forEach(map.getOverlays(), function(value) { - map.removeOverlay(value); - }); - evt.preventDefault(); - }; - - if (!isDefined(marker)) { - data.projection = properties.projection ? properties.projection : - data.projection; - data.coord = properties.coord ? properties.coord : data.coord; - data.lat = properties.lat ? properties.lat : data.lat; - data.lon = properties.lon ? properties.lon : data.lon; - - if (isDefined(properties.style)) { - data.style = properties.style; - } else { - data.style = mapDefaults.styles.marker; - } - - marker = createFeature(data, viewProjection); - if (!isDefined(marker)) { - $log.error('[AngularJS - Openlayers] Received invalid data on ' + - 'the marker.'); - } - // Add a link between the feature and the marker properties - marker.set('marker', properties); - markerLayer.getSource().addFeature(marker); - } else { - var requestedPosition; - if (properties.projection === 'pixel') { - requestedPosition = properties.coord; - } else { - requestedPosition = ol.proj.transform([properties.lon, properties.lat], data.projection, - map.getView().getProjection()); - } - - if (!angular.equals(marker.getGeometry().getCoordinates(), requestedPosition)) { - var geometry = new ol.geom.Point(requestedPosition); - marker.setGeometry(geometry); - } - } - - if (isDefined(label)) { - map.removeOverlay(label); - } - - if (!isDefined(properties.label)) { - return; - } - - scope.message = properties.label.message; - if (!hasTranscluded && (!isDefined(scope.message) || scope.message.length === 0)) { - return; - } - - if (properties.label && properties.label.show === true) { - if (data.projection === 'pixel') { - pos = data.coord; - } else { - pos = ol.proj.transform([properties.lon, properties.lat], data.projection, - viewProjection); - } - label = createOverlay(element, pos); - map.addOverlay(label); - } - - if (label && properties.label && properties.label.show === false) { - map.removeOverlay(label); - label = undefined; - } - - // Then setup new ones according to properties - if (properties.label && properties.label.show === false && - properties.label.showOnMouseOver) { - map.getViewport().addEventListener('mousemove', properties.handleInteraction); - } - - if ((properties.label && properties.label.show === false && - properties.label.showOnMouseClick) || - attrs.hasOwnProperty('ngClick')) { - map.getViewport().addEventListener('click', properties.handleTapInteraction); - map.getViewport().querySelector('canvas.ol-unselectable').addEventListener( - 'touchend', properties.handleTapInteraction); - } - - if ((properties.label && properties.label.show === false && - properties.label.keepOneOverlayVisible)) { - map.getViewport().addEventListener('mousemove', properties.showAtLeastOneOverlay); - map.getViewport().addEventListener('click', properties.removeAllOverlays); - } - }, true); - }); - } - }; -}]); - -angular.module('openlayers-directive').service('olData', ["$log", "$q", function($log, $q) { - - var maps = {}; - - var setResolvedDefer = function(d, mapId) { - var id = obtainEffectiveMapId(d, mapId); - d[id].resolvedDefer = true; - }; - - var getUnresolvedDefer = function(d, mapId) { - var id = obtainEffectiveMapId(d, mapId); - var defer; - - if (!angular.isDefined(d[id]) || d[id].resolvedDefer === true) { - defer = $q.defer(); - d[id] = { - defer: defer, - resolvedDefer: false - }; - } else { - defer = d[id].defer; - } - return defer; - }; - - var getDefer = function(d, mapId) { - var id = obtainEffectiveMapId(d, mapId); - var defer; - - if (!angular.isDefined(d[id]) || d[id].resolvedDefer === false) { - defer = getUnresolvedDefer(d, mapId); - } else { - defer = d[id].defer; - } - return defer; - }; - - this.setMap = function(olMap, scopeId) { - var defer = getUnresolvedDefer(maps, scopeId); - defer.resolve(olMap); - setResolvedDefer(maps, scopeId); - }; - - this.getMap = function(scopeId) { - var defer = getDefer(maps, scopeId); - return defer.promise; - }; - - function obtainEffectiveMapId(d, mapId) { - var id; - var i; - if (!angular.isDefined(mapId)) { - if (Object.keys(d).length === 1) { - for (i in d) { - if (d.hasOwnProperty(i)) { - id = i; - } - } - } else if (Object.keys(d).length === 0) { - id = 'main'; - } else { - $log.error('[AngularJS - Openlayers] - You have more than 1 map on the DOM, ' + - 'you must provide the map ID to the olData.getXXX call'); - } - } else { - id = mapId; - } - return id; - } - - this.resetMap = function(scopeId) { - if (angular.isDefined(maps[scopeId])) { - delete maps[scopeId]; - } - }; - -}]); - -angular.module('openlayers-directive').factory('olHelpers', ["$q", "$log", "$http", function($q, $log, $http) { - - var isDefined = function(value) { - return angular.isDefined(value); - }; - - var isDefinedAndNotNull = function(value) { - return angular.isDefined(value) && value !== null; - }; - - var setEvent = function(map, eventType, scope) { - map.on(eventType, function(event) { - var coord = event.coordinate; - var proj = map.getView().getProjection().getCode(); - if (proj === 'pixel') { - coord = coord.map(function(v) { - return parseInt(v, 10); - }); - } - scope.$emit('openlayers.map.' + eventType, { - 'coord': coord, - 'projection': proj, - 'event': event - }); - }); - }; - - var bingImagerySets = [ - 'Road', - 'Aerial', - 'AerialWithLabels', - 'collinsBart', - 'ordnanceSurvey' - ]; - - var getControlClasses = function() { - return { - attribution: ol.control.Attribution, - fullscreen: ol.control.FullScreen, - mouseposition: ol.control.MousePosition, - overviewmap: ol.control.OverviewMap, - rotate: ol.control.Rotate, - scaleline: ol.control.ScaleLine, - zoom: ol.control.Zoom, - zoomslider: ol.control.ZoomSlider, - zoomtoextent: ol.control.ZoomToExtent - }; - }; - - var mapQuestLayers = ['osm', 'sat', 'hyb']; - - var esriBaseLayers = ['World_Imagery', 'World_Street_Map', 'World_Topo_Map', - 'World_Physical_Map', 'World_Terrain_Base', - 'Ocean_Basemap', 'NatGeo_World_Map', - 'World_Light_Gray_Base', 'World_Dark_Gray_Base']; - - var styleMap = { - 'style': ol.style.Style, - 'fill': ol.style.Fill, - 'stroke': ol.style.Stroke, - 'circle': ol.style.Circle, - 'icon': ol.style.Icon, - 'image': ol.style.Image, - 'regularshape': ol.style.RegularShape, - 'text': ol.style.Text - }; - - var optionalFactory = function(style, Constructor) { - if (Constructor && style instanceof Constructor) { - return style; - } else if (Constructor) { - return new Constructor(style); - } else { - return style; - } - }; - - //Parse the style tree calling the appropriate constructors. - //The keys in styleMap can be used and the OpenLayers constructors can be - //used directly. - var createStyle = function recursiveStyle(data, styleName) { - var style; - if (!styleName) { - styleName = 'style'; - style = data; - } else { - style = data[styleName]; - } - //Instead of defining one style for the layer, we've been given a style function - //to apply to each feature. - if (styleName === 'style' && data instanceof Function) { - return data; - } - - if (!(style instanceof Object)) { - return style; - } - - var styleObject; - if (Object.prototype.toString.call(style) === '[object Object]') { - styleObject = {}; - var styleConstructor = styleMap[styleName]; - if (styleConstructor && style instanceof styleConstructor) { - return style; - } - Object.getOwnPropertyNames(style).forEach(function(val, idx, array) { - //Consider the case - //image: { - // circle: { - // fill: { - // color: 'red' - // } - // } - // - //An ol.style.Circle is an instance of ol.style.Image, so we do not want to construct - //an Image and then construct a Circle. We assume that if we have an instanceof - //relationship, that the JSON parent has exactly one child. - //We check to see if an inheritance relationship exists. - //If it does, then for the parent we create an instance of the child. - var valConstructor = styleMap[val]; - if (styleConstructor && valConstructor && - valConstructor.prototype instanceof styleMap[styleName]) { - console.assert(array.length === 1, 'Extra parameters for ' + styleName); - styleObject = recursiveStyle(style, val); - return optionalFactory(styleObject, valConstructor); - } else { - styleObject[val] = recursiveStyle(style, val); - - // if the value is 'text' and it contains a String, then it should be interpreted - // as such, 'cause the text style might effectively contain a text to display - if (val !== 'text' && typeof styleObject[val] !== 'string') { - styleObject[val] = optionalFactory(styleObject[val], styleMap[val]); - } - } - }); - } else { - styleObject = style; - } - return optionalFactory(styleObject, styleMap[styleName]); - }; - - var detectLayerType = function(layer) { - if (layer.type) { - return layer.type; - } else { - switch (layer.source.type) { - case 'ImageWMS': - return 'Image'; - case 'ImageStatic': - return 'Image'; - case 'GeoJSON': - case 'JSONP': - case 'TopoJSON': - case 'KML': - case 'WKT': - return 'Vector'; - case 'TileVector': - case 'MVT': - return 'TileVector'; - default: - return 'Tile'; - } - } - }; - - var createProjection = function(view) { - var oProjection; - - switch (view.projection) { - case 'pixel': - if (!isDefined(view.extent)) { - $log.error('[AngularJS - Openlayers] - You must provide the extent of the image ' + - 'if using pixel projection'); - return; - } - oProjection = new ol.proj.Projection({ - code: 'pixel', - units: 'pixels', - extent: view.extent - }); - break; - default: - oProjection = new ol.proj.get(view.projection); - break; - } - - return oProjection; - }; - - var isValidStamenLayer = function(layer) { - return ['watercolor', 'terrain', 'toner'].indexOf(layer) !== -1; - }; - - var createSource = function(source, projection) { - var oSource; - var pixelRatio; - var url; - var geojsonFormat = new ol.format.GeoJSON(); // used in various switch stmnts below - - switch (source.type) { - case 'MapBox': - if (!source.mapId || !source.accessToken) { - $log.error('[AngularJS - Openlayers] - MapBox layer requires the map id and the access token'); - return; - } - url = 'https://api.tiles.mapbox.com/v4/' + source.mapId + '/{z}/{x}/{y}.png?access_token=' + - source.accessToken; - - pixelRatio = window.devicePixelRatio; - - if (pixelRatio > 1) { - url = url.replace('.png', '@2x.png'); - } - - oSource = new ol.source.XYZ({ - url: url, - tileLoadFunction: source.tileLoadFunction, - attributions: createAttribution(source), - tilePixelRatio: pixelRatio > 1 ? 2 : 1, - wrapX: source.wrapX !== undefined ? source.wrapX : true - }); - break; - case 'MapBoxStudio': - if (!source.mapId || !source.accessToken || !source.userId) { - $log.error('[AngularJS - Openlayers] - MapBox Studio layer requires the map id' + - ', user id and the access token'); - return; - } - url = 'https://api.mapbox.com/styles/v1/' + source.userId + - '/' + source.mapId + '/tiles/{z}/{x}/{y}?access_token=' + - source.accessToken; - - pixelRatio = window.devicePixelRatio; - - if (pixelRatio > 1) { - url = url.replace('{y}?access_token', '{y}@2x?access_token'); - } - - oSource = new ol.source.XYZ({ - url: url, - tileLoadFunction: source.tileLoadFunction, - attributions: createAttribution(source), - tilePixelRatio: pixelRatio > 1 ? 2 : 1, - tileSize: source.tileSize || [512, 512], - wrapX: source.wrapX !== undefined ? source.wrapX : true - }); - break; - case 'MVT': - if (!source.url) { - $log.error('[AngularJS - Openlayers] - MVT layer requires the source url'); - return; - } - oSource = new ol.source.VectorTile({ - attributions: source.attributions || '', - format: new ol.format.MVT(), - tileGrid: ol.tilegrid.createXYZ({maxZoom: source.maxZoom || 22}), - tilePixelRatio: source.tilePixelRatio || 16, - url: source.url - }); - break; - case 'ImageWMS': - if (!source.url || !source.params) { - $log.error('[AngularJS - Openlayers] - ImageWMS Layer needs ' + - 'valid server url and params properties'); - } - oSource = new ol.source.ImageWMS({ - url: source.url, - imageLoadFunction: source.imageLoadFunction, - attributions: createAttribution(source), - crossOrigin: (typeof source.crossOrigin === 'undefined') ? 'anonymous' : source.crossOrigin, - params: deepCopy(source.params), - ratio: source.ratio - }); - break; - - case 'TileWMS': - if ((!source.url && !source.urls) || !source.params) { - $log.error('[AngularJS - Openlayers] - TileWMS Layer needs ' + - 'valid url (or urls) and params properties'); - } - - var wmsConfiguration = { - tileLoadFunction: source.tileLoadFunction, - crossOrigin: (typeof source.crossOrigin === 'undefined') ? 'anonymous' : source.crossOrigin, - params: deepCopy(source.params), - attributions: createAttribution(source), - wrapX: source.wrapX !== undefined ? source.wrapX : true - }; - - if (source.projection) { - wmsConfiguration.projection = new ol.proj.get(source.projection); - } - - if (source.serverType) { - wmsConfiguration.serverType = source.serverType; - } - - if (source.url) { - wmsConfiguration.url = source.url; - } - - if (source.urls) { - wmsConfiguration.urls = source.urls; - } - - oSource = new ol.source.TileWMS(wmsConfiguration); - break; - - case 'WMTS': - if ((!source.url && !source.urls) || !source.tileGrid) { - $log.error('[AngularJS - Openlayers] - WMTS Layer needs valid url ' + - '(or urls) and tileGrid properties'); - } - - var wmtsConfiguration = { - tileLoadFunction: source.tileLoadFunction, - projection: projection, - layer: source.layer, - attributions: createAttribution(source), - matrixSet: (source.matrixSet === 'undefined') ? projection : source.matrixSet, - format: (source.format === 'undefined') ? 'image/jpeg' : source.format, - requestEncoding: (source.requestEncoding === 'undefined') ? - 'KVP' : source.requestEncoding, - tileGrid: new ol.tilegrid.WMTS({ - origin: source.tileGrid.origin, - resolutions: source.tileGrid.resolutions, - matrixIds: source.tileGrid.matrixIds - }), - style: (source.style === 'undefined') ? 'normal' : source.style, - wrapX: source.wrapX !== undefined ? source.wrapX : true - }; - - if (isDefined(source.url)) { - wmtsConfiguration.url = source.url; - } - - if (isDefined(source.urls)) { - wmtsConfiguration.urls = source.urls; - } - - oSource = new ol.source.WMTS(wmtsConfiguration); - break; - - case 'OSM': - oSource = new ol.source.OSM({ - tileLoadFunction: source.tileLoadFunction, - attributions: createAttribution(source), - wrapX: source.wrapX !== undefined ? source.wrapX : true - }); - - if (source.url) { - oSource.setUrl(source.url); - } - - break; - case 'BingMaps': - if (!source.key) { - $log.error('[AngularJS - Openlayers] - You need an API key to show the Bing Maps.'); - return; - } - - var bingConfiguration = { - key: source.key, - tileLoadFunction: source.tileLoadFunction, - attributions: createAttribution(source), - imagerySet: source.imagerySet ? source.imagerySet : bingImagerySets[0], - culture: source.culture, - wrapX: source.wrapX !== undefined ? source.wrapX : true - }; - - if (source.maxZoom) { - bingConfiguration.maxZoom = source.maxZoom; - } - - oSource = new ol.source.BingMaps(bingConfiguration); - break; - - case 'MapQuest': - if (!source.layer || mapQuestLayers.indexOf(source.layer) === -1) { - $log.error('[AngularJS - Openlayers] - MapQuest layers needs a valid \'layer\' property.'); - return; - } - - oSource = new ol.source.MapQuest({ - attributions: createAttribution(source), - layer: source.layer, - wrapX: source.wrapX !== undefined ? source.wrapX : true - }); - - break; - - case 'EsriBaseMaps': - if (!source.layer || esriBaseLayers.indexOf(source.layer) === -1) { - $log.error('[AngularJS - Openlayers] - ESRI layers needs a valid \'layer\' property.'); - return; - } - - var _urlBase = 'http://services.arcgisonline.com/ArcGIS/rest/services/'; - if (source.layer === 'World_Light_Gray_Base' || source.layer === 'World_Dark_Gray_Base') { - _urlBase = _urlBase + 'Canvas/'; - } - var _url = _urlBase + source.layer + '/MapServer/tile/{z}/{y}/{x}'; - - oSource = new ol.source.XYZ({ - attributions: createAttribution(source), - tileLoadFunction: source.tileLoadFunction, - url: _url, - wrapX: source.wrapX !== undefined ? source.wrapX : true - }); - - break; - - case 'TileArcGISRest': - if (!source.url) { - $log.error('[AngularJS - Openlayers] - TileArcGISRest Layer needs valid url'); - } - - oSource = new ol.source.TileArcGISRest({ - attributions: createAttribution(source), - tileLoadFunction: source.tileLoadFunction, - url: source.url, - wrapX: source.wrapX !== undefined ? source.wrapX : true - }); - - break; - - case 'GeoJSON': - if (!(source.geojson || source.url)) { - $log.error('[AngularJS - Openlayers] - You need a geojson ' + - 'property to add a GeoJSON layer.'); - return; - } - - if (isDefined(source.url)) { - oSource = new ol.source.Vector({ - format: new ol.format.GeoJSON(), - url: source.url - }); - } else { - oSource = new ol.source.Vector(); - - var projectionToUse = projection; - var dataProjection; // Projection of geojson data - if (isDefined(source.geojson.projection)) { - dataProjection = new ol.proj.get(source.geojson.projection); - } else { - dataProjection = projection; // If not defined, features will not be reprojected. - } - - var features = geojsonFormat.readFeatures( - source.geojson.object, { - featureProjection: projectionToUse.getCode(), - dataProjection: dataProjection.getCode() - }); - - oSource.addFeatures(features); - } - break; - case 'WKT': - if (!(source.wkt || source.url)) { - $log.error('[AngularJS - Openlayers] - You need a WKT ' + - 'property to add a GeoJSON layer.'); - return; - } - if (isDefined(source.url)) { - oSource = new ol.source.Vector({ - format: new ol.format.WKT(), - url: source.url, - wrapX: source.wrapX !== undefined ? source.wrapX : true - }); - } else { - oSource = new ol.source.Vector(); - var featureProjection = projection; - var wktProjection; - if (isDefined(source.wkt.projection)) { - wktProjection = new ol.proj.get(source.wkt.projection); - } else { - wktProjection = projection; - } - - var wktFormat = new ol.format.WKT(); - var wktFeatures = []; - for (var k = 0; k < source.wkt.object.length; k++) { - var feature = wktFormat.readFeature( - source.wkt.object[k].data, {dataProjection: wktProjection.getCode() , - featureProjection: featureProjection.getCode() }); - if (source.wkt.object[k].properties) { - feature.properties = source.wkt.object[k].properties; - } - wktFeatures.push(feature); - } - oSource.addFeatures(wktFeatures); - } - - break; - case 'JSONP': - if (!(source.url)) { - $log.error('[AngularJS - Openlayers] - You need an url properly configured to add a JSONP layer.'); - return; - } - - if (isDefined(source.url)) { - oSource = new ol.source.ServerVector({ - format: geojsonFormat, - loader: function(/*extent, resolution, projection*/) { - var url = source.url + - '&outputFormat=text/javascript&format_options=callback:JSON_CALLBACK'; - $http.jsonp(url, { cache: source.cache}) - .success(function(response) { - oSource.addFeatures(geojsonFormat.readFeatures(response)); - }) - .error(function(response) { - $log(response); - }); - }, - projection: projection - }); - } - break; - case 'TopoJSON': - if (!(source.topojson || source.url)) { - $log.error('[AngularJS - Openlayers] - You need a topojson ' + - 'property to add a TopoJSON layer.'); - return; - } - - if (source.url) { - oSource = new ol.source.Vector({ - format: new ol.format.TopoJSON(), - url: source.url - }); - } else { - oSource = new ol.source.Vector(angular.extend(source.topojson, { - format: new ol.format.TopoJSON() - })); - } - break; - case 'TileJSON': - oSource = new ol.source.TileJSON({ - url: source.url, - attributions: createAttribution(source), - tileLoadFunction: source.tileLoadFunction, - crossOrigin: 'anonymous', - wrapX: source.wrapX !== undefined ? source.wrapX : true - }); - break; - - case 'TileVector': - if (!source.url || !source.format) { - $log.error('[AngularJS - Openlayers] - TileVector Layer needs valid url and format properties'); - } - oSource = new ol.source.VectorTile({ - url: source.url, - projection: projection, - attributions: createAttribution(source), - tileLoadFunction: source.tileLoadFunction, - format: source.format, - tileGrid: new ol.tilegrid.createXYZ({ - maxZoom: source.maxZoom || 19 - }), - wrapX: source.wrapX !== undefined ? source.wrapX : true - }); - break; - - case 'TileTMS': - if (!source.url || !source.tileGrid) { - $log.error('[AngularJS - Openlayers] - TileTMS Layer needs valid url and tileGrid properties'); - } - oSource = new ol.source.TileImage({ - url: source.url, - maxExtent: source.maxExtent, - attributions: createAttribution(source), - tileLoadFunction: source.tileLoadFunction, - tileGrid: new ol.tilegrid.TileGrid({ - origin: source.tileGrid.origin, - resolutions: source.tileGrid.resolutions - }), - tileUrlFunction: function(tileCoord) { - - var z = tileCoord[0]; - var x = tileCoord[1]; - var y = tileCoord[2]; //(1 << z) - tileCoord[2] - 1; - - if (x < 0 || y < 0) { - return ''; - } - - var url = source.url + z + '/' + x + '/' + y + '.png'; - - return url; - }, - wrapX: source.wrapX !== undefined ? source.wrapX : true - }); - break; - case 'TileImage': - oSource = new ol.source.TileImage({ - url: source.url, - attributions: createAttribution(source), - tileLoadFunction: source.tileLoadFunction, - tileGrid: new ol.tilegrid.TileGrid({ - origin: source.tileGrid.origin, // top left corner of the pixel projection's extent - resolutions: source.tileGrid.resolutions - }), - tileUrlFunction: function(tileCoord/*, pixelRatio, projection*/) { - var z = tileCoord[0]; - var x = tileCoord[1]; - var y = -tileCoord[2] - 1; - var url = source.url - .replace('{z}', z.toString()) - .replace('{x}', x.toString()) - .replace('{y}', y.toString()); - return url; - }, - wrapX: source.wrapX !== undefined ? source.wrapX : true - }); - break; - case 'KML': - var extractStyles = source.extractStyles || false; - oSource = new ol.source.Vector({ - url: source.url, - format: new ol.format.KML({ - extractStyles: extractStyles - }), - radius: source.radius - }); - break; - case 'Stamen': - if (!source.layer || !isValidStamenLayer(source.layer)) { - $log.error('[AngularJS - Openlayers] - You need a valid Stamen layer.'); - return; - } - oSource = new ol.source.Stamen({ - tileLoadFunction: source.tileLoadFunction, - layer: source.layer, - wrapX: source.wrapX !== undefined ? source.wrapX : true - }); - break; - case 'ImageStatic': - if (!source.url || !angular.isArray(source.imageSize) || source.imageSize.length !== 2) { - $log.error('[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.'); - return; - } - - oSource = new ol.source.ImageStatic({ - url: source.url, - attributions: createAttribution(source), - imageSize: source.imageSize, - projection: projection, - imageExtent: source.imageExtent ? source.imageExtent : projection.getExtent(), - imageLoadFunction: source.imageLoadFunction - }); - break; - case 'XYZ': - if (!source.url && !source.urls && !source.tileUrlFunction) { - $log.error('[AngularJS - Openlayers] - XYZ Layer needs valid urls or tileUrlFunction properties'); - } - oSource = new ol.source.XYZ({ - url: source.url, - urls: source.urls, - attributions: createAttribution(source), - minZoom: source.minZoom, - maxZoom: source.maxZoom, - projection: source.projection, - tileUrlFunction: source.tileUrlFunction, - tileLoadFunction: source.tileLoadFunction, - wrapX: source.wrapX !== undefined ? source.wrapX : true - }); - break; - case 'Zoomify': - if (!source.url || !angular.isArray(source.imageSize) || source.imageSize.length !== 2) { - $log.error('[AngularJS - Openlayers] - Zoomify Layer needs valid url and imageSize properties'); - } - oSource = new ol.source.Zoomify({ - url: source.url, - size: source.imageSize, - wrapX: source.wrapX !== undefined ? source.wrapX : true - }); - break; - } - - // log a warning when no source could be created for the given type - if (!oSource) { - $log.warn('[AngularJS - Openlayers] - No source could be found for type "' + source.type + '"'); - } - - return oSource; - }; - - var deepCopy = function(oldObj) { - var newObj = oldObj; - if (oldObj && typeof oldObj === 'object') { - newObj = Object.prototype.toString.call(oldObj) === '[object Array]' ? [] : {}; - for (var i in oldObj) { - newObj[i] = deepCopy(oldObj[i]); - } - } - return newObj; - }; - - var createAttribution = function(source) { - var attributions = []; - if (isDefined(source.attribution)) { - attributions.unshift(new ol.Attribution({html: source.attribution})); - } - return attributions; - }; - - var createGroup = function(name) { - var olGroup = new ol.layer.Group(); - olGroup.set('name', name); - - return olGroup; - }; - - var getGroup = function(layers, name) { - var layer; - - angular.forEach(layers, function(l) { - if (l instanceof ol.layer.Group && l.get('name') === name) { - layer = l; - return; - } - }); - - return layer; - }; - - var addLayerBeforeMarkers = function(layers, layer) { - var markersIndex; - for (var i = 0; i < layers.getLength(); i++) { - var l = layers.item(i); - - if (l.get('markers')) { - markersIndex = i; - break; - } - } - - if (isDefined(markersIndex)) { - var markers = layers.item(markersIndex); - layer.index = markersIndex; - layers.setAt(markersIndex, layer); - markers.index = layers.getLength(); - layers.push(markers); - } else { - layer.index = layers.getLength(); - layers.push(layer); - } - - }; - - var removeLayer = function(layers, index) { - layers.removeAt(index); - for (var i = index; i < layers.getLength(); i++) { - var l = layers.item(i); - if (l === null) { - layers.insertAt(i, null); - break; - } else { - l.index = i; - } - } - }; - - return { - // Determine if a reference is defined - isDefined: isDefined, - - // Determine if a reference is a number - isNumber: function(value) { - return angular.isNumber(value); - }, - - createView: function(view) { - var projection = createProjection(view); - - var viewConfig = { - projection: projection, - maxZoom: view.maxZoom, - minZoom: view.minZoom - }; - - if (view.center) { - viewConfig.center = view.center; - } - if (view.extent) { - viewConfig.extent = view.extent; - } - if (view.zoom) { - viewConfig.zoom = view.zoom; - } - if (view.resolutions) { - viewConfig.resolutions = view.resolutions; - } - - return new ol.View(viewConfig); - }, - - // Determine if a reference is defined and not null - isDefinedAndNotNull: isDefinedAndNotNull, - - // Determine if a reference is a string - isString: function(value) { - return angular.isString(value); - }, - - // Determine if a reference is an array - isArray: function(value) { - return angular.isArray(value); - }, - - // Determine if a reference is an object - isObject: function(value) { - return angular.isObject(value); - }, - - // Determine if two objects have the same properties - equals: function(o1, o2) { - return angular.equals(o1, o2); - }, - - isValidCenter: function(center) { - return angular.isDefined(center) && - (typeof center.autodiscover === 'boolean' || - angular.isNumber(center.lat) && angular.isNumber(center.lon) || - (angular.isArray(center.coord) && center.coord.length === 2 && - angular.isNumber(center.coord[0]) && angular.isNumber(center.coord[1])) || - (angular.isArray(center.bounds) && center.bounds.length === 4 && - angular.isNumber(center.bounds[0]) && angular.isNumber(center.bounds[1]) && - angular.isNumber(center.bounds[1]) && angular.isNumber(center.bounds[2]))); - }, - - safeApply: function($scope, fn) { - var phase = $scope.$root.$$phase; - if (phase === '$apply' || phase === '$digest') { - $scope.$eval(fn); - } else { - $scope.$apply(fn); - } - }, - - isSameCenterOnMap: function(center, map) { - var urlProj = center.projection || 'EPSG:4326'; - var urlCenter = [center.lon, center.lat]; - var mapProj = map.getView().getProjection(); - var mapCenter = ol.proj.transform(map.getView().getCenter(), mapProj, urlProj); - var zoom = map.getView().getZoom(); - if (mapCenter[1].toFixed(4) === urlCenter[1].toFixed(4) && - mapCenter[0].toFixed(4) === urlCenter[0].toFixed(4) && - zoom === center.zoom) { - return true; - } - return false; - }, - - setCenter: function(view, projection, newCenter, map) { - - if (map && view.getCenter()) { - var pan = ol.animation.pan({ - duration: 150, - source: (view.getCenter()) - }); - map.beforeRender(pan); - } - - if (newCenter.projection === projection) { - view.setCenter([newCenter.lon, newCenter.lat]); - } else { - var coord = [newCenter.lon, newCenter.lat]; - view.setCenter(ol.proj.transform(coord, newCenter.projection, projection)); - } - }, - - setZoom: function(view, zoom, map) { - var z = ol.animation.zoom({ - duration: 150, - resolution: map.getView().getResolution() - }); - map.beforeRender(z); - view.setZoom(zoom); - }, - - isBoolean: function(value) { - return typeof value === 'boolean'; - }, - - createStyle: createStyle, - - setMapEvents: function(events, map, scope) { - if (isDefined(events) && angular.isArray(events.map)) { - for (var i in events.map) { - var event = events.map[i]; - setEvent(map, event, scope); - } - } - }, - - setVectorLayerEvents: function(events, map, scope, layerName) { - if (isDefined(events) && angular.isArray(events.layers)) { - angular.forEach(events.layers, function(eventType) { - angular.element(map.getViewport()).on(eventType, function(evt) { - var pixel = map.getEventPixel(evt); - var feature = map.forEachFeatureAtPixel(pixel, function(feature, olLayer) { - // only return the feature if it is in this layer (based on the name) - return (isDefinedAndNotNull(olLayer) && olLayer.get('name') === layerName) ? feature : null; - }); - if (isDefinedAndNotNull(feature)) { - scope.$emit('openlayers.layers.' + layerName + '.' + eventType, feature, evt); - } - }); - }); - } - }, - - setViewEvents: function(events, map, scope) { - if (isDefined(events) && angular.isArray(events.view)) { - var view = map.getView(); - angular.forEach(events.view, function(eventType) { - view.on(eventType, function(event) { - scope.$emit('openlayers.view.' + eventType, view, event); - }); - }); - } - }, - - detectLayerType: detectLayerType, - - createLayer: function(layer, projection, name, onLayerCreatedFn) { - var oLayer; - var type = detectLayerType(layer); - var oSource = createSource(layer.source, projection); - if (!oSource) { - return; - } - - // handle function overloading. 'name' argument may be - // our onLayerCreateFn since name is optional - if (typeof(name) === 'function' && !onLayerCreatedFn) { - onLayerCreatedFn = name; - name = undefined; // reset, otherwise it'll be used later on - } - - // Manage clustering - if ((type === 'Vector') && layer.clustering) { - oSource = new ol.source.Cluster({ - source: oSource, - distance: layer.clusteringDistance - }); - } - - var layerConfig = {}; - - // copy over eventual properties set on the passed layerconfig which - // can later be retrieved via layer.get('propName'); - for (var property in layer) { - if (layer.hasOwnProperty(property) && - // ignore props like source or those angular might add (starting with $) - // don't use startsWith as it is not supported in IE - property.indexOf('$', 0) !== 0 && - property.indexOf('source', 0) !== 0 && - property.indexOf('style', 0) !== 0 - ) { - layerConfig[property] = layer[property]; - } - } - - layerConfig.source = oSource; - - // ol.layer.Layer configuration options - if (isDefinedAndNotNull(layer.opacity)) { - layerConfig.opacity = layer.opacity; - } - if (isDefinedAndNotNull(layer.visible)) { - layerConfig.visible = layer.visible; - } - if (isDefinedAndNotNull(layer.extent)) { - layerConfig.extent = layer.extent; - } - if (isDefinedAndNotNull(layer.zIndex)) { - layerConfig.zIndex = layer.zIndex; - } - if (isDefinedAndNotNull(layer.minResolution)) { - layerConfig.minResolution = layer.minResolution; - } - if (isDefinedAndNotNull(layer.maxResolution)) { - layerConfig.maxResolution = layer.maxResolution; - } - if (isDefinedAndNotNull(layer.style) && type === 'TileVector') { - layerConfig.style = layer.style; - } - - switch (type) { - case 'Image': - oLayer = new ol.layer.Image(layerConfig); - break; - case 'Tile': - oLayer = new ol.layer.Tile(layerConfig); - break; - case 'Heatmap': - oLayer = new ol.layer.Heatmap(layerConfig); - break; - case 'Vector': - oLayer = new ol.layer.Vector(layerConfig); - break; - case 'TileVector': - oLayer = new ol.layer.VectorTile(layerConfig); - break; - } - - // set a layer name if given - if (isDefined(name)) { - oLayer.set('name', name); - } else if (isDefined(layer.name)) { - oLayer.set('name', layer.name); - } - - // set custom layer properties if given - if (isDefined(layer.customAttributes)) { - for (var key in layer.customAttributes) { - oLayer.set(key, layer.customAttributes[key]); - } - } - - // invoke the onSourceCreated callback - if (onLayerCreatedFn) { - onLayerCreatedFn({ - oLayer: oLayer - }); - } - - return oLayer; - }, - - createVectorLayer: function() { - return new ol.layer.Vector({ - source: new ol.source.Vector() - }); - }, - - notifyCenterUrlHashChanged: function(scope, center, search) { - if (center.centerUrlHash) { - var centerUrlHash = center.lat.toFixed(4) + ':' + center.lon.toFixed(4) + ':' + center.zoom; - if (!isDefined(search.c) || search.c !== centerUrlHash) { - scope.$emit('centerUrlHash', centerUrlHash); - } - } - }, - - getControlClasses: getControlClasses, - - detectControls: function(controls) { - var actualControls = {}; - var controlClasses = getControlClasses(); - - controls.forEach(function(control) { - for (var i in controlClasses) { - if (control instanceof controlClasses[i]) { - actualControls[i] = control; - } - } - }); - - return actualControls; - }, - - createFeature: function(data, viewProjection) { - var geometry; - - switch (data.type) { - case 'Polygon': - geometry = new ol.geom.Polygon(data.coords); - break; - default: - if (isDefined(data.coord) && data.projection === 'pixel') { - geometry = new ol.geom.Point(data.coord); - } else { - geometry = new ol.geom.Point([data.lon, data.lat]); - } - break; - } - - if (isDefined(data.projection) && data.projection !== 'pixel') { - geometry = geometry.transform(data.projection, viewProjection); - } - - var feature = new ol.Feature({ - geometry: geometry - }); - - if (isDefined(data.style)) { - var style = createStyle(data.style); - feature.setStyle(style); - } - return feature; - }, - - addLayerBeforeMarkers: addLayerBeforeMarkers, - - getGroup: getGroup, - - addLayerToGroup: function(layers, layer, name) { - var groupLayer = getGroup(layers, name); - - if (!isDefined(groupLayer)) { - groupLayer = createGroup(name); - addLayerBeforeMarkers(layers, groupLayer); - } - - layer.set('group', name); - addLayerBeforeMarkers(groupLayer.getLayers(), layer); - }, - - removeLayerFromGroup: function(layers, layer, name) { - var groupLayer = getGroup(layers, name); - layer.set('group'); - removeLayer(groupLayer.getLayers(), layer.index); - }, - - removeLayer: removeLayer, - - insertLayer: function(layers, index, layer) { - if (layers.getLength() < index) { - // fill up with "null layers" till we get to the desired index - while (layers.getLength() < index) { - var nullLayer = new ol.layer.Image(); - nullLayer.index = layers.getLength(); // add index which will be equal to the length in this case - nullLayer.name = '(null-layer)'; // we need a marker somehow - layers.push(nullLayer); - } - layer.index = index; - layers.push(layer); - } else { - layer.index = index; - layers.insertAt(layer.index, layer); - - // remove eventual null layers - for (var i = index + 1; i < layers.getLength(); i++) { - var l = layers.item(i); - if (l.name === '(null-layer)') { - layers.removeAt(i); - break; - } else { - l.index = i; - } - } - } - }, - - createOverlay: function(element, pos) { - element.css('display', 'block'); - var ov = new ol.Overlay({ - position: pos, - element: element[0], - positioning: 'center-left' - }); - - return ov; - } - }; -}]); - -angular.module('openlayers-directive').factory('olMapDefaults', ["$q", "olHelpers", function($q, olHelpers) { - - var base64icon = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAApCAYAAADAk4LOAAAGmklEQVRYw' + - '7VXeUyTZxjvNnfELFuyIzOabermMZEeQC/OclkO49CpOHXOLJl/CAURuYbQi3KLgEhbrhZ1aDwmaoGq' + - 'KII6odATmH/scDFbdC7LvFqOCc+e95s2VG50X/LLm/f4/Z7neY/ne18aANCmAr5E/xZf1uDOkTcGcWR' + - '6hl9247tT5U7Y6SNvWsKT63P58qbfeLJG8M5qcgTknrvvrdDbsT7Ml+tv82X6vVxJE33aRmgSyYtcWV' + - 'MqX97Yv2JvW39UhRE2HuyBL+t+gK1116ly06EeWFNlAmHxlQE0OMiV6mQCScusKRlhS3QLeVJdl1+23' + - 'h5dY4FNB3thrbYboqptEFlphTC1hSpJnbRvxP4NWgsE5Jyz86QNNi/5qSUTGuFk1gu54tN9wuK2wc3o' + - '+Wc13RCmsoBwEqzGcZsxsvCSy/9wJKf7UWf1mEY8JWfewc67UUoDbDjQC+FqK4QqLVMGGR9d2wurKzq' + - 'Bk3nqIT/9zLxRRjgZ9bqQgub+DdoeCC03Q8j+0QhFhBHR/eP3U/zCln7Uu+hihJ1+bBNffLIvmkyP0g' + - 'pBZWYXhKussK6mBz5HT6M1Nqpcp+mBCPXosYQfrekGvrjewd59/GvKCE7TbK/04/ZV5QZYVWmDwH1mF' + - '3xa2Q3ra3DBC5vBT1oP7PTj4C0+CcL8c7C2CtejqhuCnuIQHaKHzvcRfZpnylFfXsYJx3pNLwhKzRAw' + - 'AhEqG0SpusBHfAKkxw3w4627MPhoCH798z7s0ZnBJ/MEJbZSbXPhER2ih7p2ok/zSj2cEJDd4CAe+5W' + - 'YnBCgR2uruyEw6zRoW6/DWJ/OeAP8pd/BGtzOZKpG8oke0SX6GMmRk6GFlyAc59K32OTEinILRJRcha' + - 'h8HQwND8N435Z9Z0FY1EqtxUg+0SO6RJ/mmXz4VuS+DpxXC3gXmZwIL7dBSH4zKE50wESf8qwVgrP1E' + - 'IlTO5JP9Igu0aexdh28F1lmAEGJGfh7jE6ElyM5Rw/FDcYJjWhbeiBYoYNIpc2FT/SILivp0F1ipDWk' + - '4BIEo2VuodEJUifhbiltnNBIXPUFCMpthtAyqws/BPlEF/VbaIxErdxPphsU7rcCp8DohC+GvBIPJS/' + - 'tW2jtvTmmAeuNO8BNOYQeG8G/2OzCJ3q+soYB5i6NhMaKr17FSal7GIHheuV3uSCY8qYVuEm1cOzqdW' + - 'r7ku/R0BDoTT+DT+ohCM6/CCvKLKO4RI+dXPeAuaMqksaKrZ7L3FE5FIFbkIceeOZ2OcHO6wIhTkNo0' + - 'ffgjRGxEqogXHYUPHfWAC/lADpwGcLRY3aeK4/oRGCKYcZXPVoeX/kelVYY8dUGf8V5EBRbgJXT5QIP' + - 'hP9ePJi428JKOiEYhYXFBqou2Guh+p/mEB1/RfMw6rY7cxcjTrneI1FrDyuzUSRm9miwEJx8E/gUmql' + - 'yvHGkneiwErR21F3tNOK5Tf0yXaT+O7DgCvALTUBXdM4YhC/IawPU+2PduqMvuaR6eoxSwUk75ggqsY' + - 'J7VicsnwGIkZBSXKOUww73WGXyqP+J2/b9c+gi1YAg/xpwck3gJuucNrh5JvDPvQr0WFXf0piyt8f8/' + - 'WI0hV4pRxxkQZdJDfDJNOAmM0Ag8jyT6hz0WGXWuP94Yh2jcfjmXAGvHCMslRimDHYuHuDsy2QtHuIa' + - 'vznhbYURq5R57KpzBBRZKPJi8eQg48h4j8SDdowifdIrEVdU+gbO6QNvRRt4ZBthUaZhUnjlYObNagV' + - '3keoeru3rU7rcuceqU1mJBxy+BWZYlNEBH+0eH4vRiB+OYybU2hnblYlTvkHinM4m54YnxSyaZYSF6R' + - '3jwgP7udKLGIX6r/lbNa9N6y5MFynjWDtrHd75ZvTYAPO/6RgF0k76mQla3FGq7dO+cH8sKn0Vo7nDl' + - 'lwAhqwLPkxrHwWmHJOo+AKJ4rab5OgrM7rVu8eWb2Pu0Dh4eDgXoOfvp7Y7QeqknRmvcTBEyq9m/HQQ' + - 'SCSz6LHq3z0yzsNySRfMS253wl2KyRDbcZPcfJKjZmSEOjcxyi+Y8dUOtsIEH6R2wNykdqrkYJ0RV92' + - 'H0W58pkfQk7cKevsLK10Py8SdMGfXNXATY+pPbyJR/ET6n9nIfztNtZYRV9XniQu9IA2vOVgy4ir7GC' + - 'LVmmd+zjkH0eAF9Po6K61pmCXHxU5rHMYd1ftc3owjwRSVRzLjKvqZEty6cRUD7jGqiOdu5HG6MdHjN' + - 'cNYGqfDm5YRzLBBCCDl/2bk8a8gdbqcfwECu62Fg/HrggAAAABJRU5ErkJggg=='; - - var _getDefaults = function() { - return { - view: { - projection: 'EPSG:3857', - minZoom: undefined, - maxZoom: undefined, - rotation: 0, - extent: undefined - }, - center: { - lat: 0, - lon: 0, - zoom: 1, - autodiscover: false, - bounds: [], - centerUrlHash: false, - projection: 'EPSG:4326' - }, - styles: { - path: { - stroke: { - color: 'blue', - width: 8 - } - }, - marker: { - image: new ol.style.Icon({ - anchor: [0.5, 1], - anchorXUnits: 'fraction', - anchorYUnits: 'fraction', - opacity: 0.90, - src: base64icon - }) - } - }, - events: { - map: [], - markers: [], - layers: [] - }, - controls: { - attribution: true, - rotate: false, - zoom: true - }, - interactions: { - mouseWheelZoom: false - }, - renderer: 'canvas' - }; - }; - - var isDefined = olHelpers.isDefined; - var defaults = {}; - - // Get the _defaults dictionary, and override the properties defined by the user - return { - getDefaults: function(scope) { - if (!isDefined(scope)) { - for (var i in defaults) { - return defaults[i]; - } - } - return defaults[scope.$id]; - }, - - setDefaults: function(scope) { - var userDefaults = scope.defaults; - var scopeId = scope.$id; - var newDefaults = _getDefaults(); - - if (isDefined(userDefaults)) { - - if (isDefined(userDefaults.layers)) { - newDefaults.layers = angular.copy(userDefaults.layers); - } - - if (isDefined(userDefaults.controls)) { - newDefaults.controls = angular.copy(userDefaults.controls); - } - - if (isDefined(userDefaults.events)) { - newDefaults.events = angular.copy(userDefaults.events); - } - - if (isDefined(userDefaults.interactions)) { - newDefaults.interactions = angular.copy(userDefaults.interactions); - } - - if (isDefined(userDefaults.renderer)) { - newDefaults.renderer = userDefaults.renderer; - } - - if (isDefined(userDefaults.view)) { - newDefaults.view.maxZoom = userDefaults.view.maxZoom || newDefaults.view.maxZoom; - newDefaults.view.minZoom = userDefaults.view.minZoom || newDefaults.view.minZoom; - newDefaults.view.projection = userDefaults.view.projection || newDefaults.view.projection; - newDefaults.view.extent = userDefaults.view.extent || newDefaults.view.extent; - newDefaults.view.resolutions = userDefaults.view.resolutions || newDefaults.view.resolutions; - } - - if (isDefined(userDefaults.styles)) { - newDefaults.styles = angular.extend(newDefaults.styles, userDefaults.styles); - } - - if (isDefined(userDefaults.loadTilesWhileAnimating)) { - newDefaults.loadTilesWhileAnimating = userDefaults.loadTilesWhileAnimating; - } - - if (isDefined(userDefaults.loadTilesWhileInteracting)) { - newDefaults.loadTilesWhileInteracting = userDefaults.loadTilesWhileInteracting; - } - } - - defaults[scopeId] = newDefaults; - return newDefaults; - } - }; -}]); -return angular.module('openlayers-directive'); -})); \ No newline at end of file diff --git a/dist/angular-openlayers-directive.min.js b/dist/angular-openlayers-directive.min.js deleted file mode 100644 index f301c7a9..00000000 --- a/dist/angular-openlayers-directive.min.js +++ /dev/null @@ -1,32 +0,0 @@ -/**! - * The MIT License - * - * Copyright (c) 2013 the angular-openlayers-directive Team, http://tombatossals.github.io/angular-openlayers-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-google-maps - * https://github.com/tombatossals/angular-openlayers-directive - * - * @authors https://github.com/tombatossals/angular-openlayers-directive/graphs/contributors - */ - -/*! angular-openlayers-directive 03-08-2017 */ -!function(a,b){if("function"==typeof require&&"object"==typeof exports){var c=require("openlayers-prebuilt");require("angular-sanitize");exports.angularOpenlayersDirective=b(c)}else"function"==typeof define&&define.amd?define(["ol"],function(c){return a.angularOpenlayersDirective=b(c)}):a.angularOpenlayersDirective=b(a.ol)}(this,function(a){return angular.module("openlayers-directive",["ngSanitize"]).directive("openlayers",["$log","$q","$compile","olHelpers","olMapDefaults","olData",function(b,c,d,e,f,g){return{restrict:"EA",transclude:!0,replace:!0,scope:{center:"=olCenter",defaults:"=olDefaults",view:"=olView",events:"=olEvents"},template:'
',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id),q.setTarget(null)}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);if(!0===s.centerUrlHash){var t=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t(),r.$on("$locationChangeSuccess",function(){var a=t();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var u;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return u||(u=new a.Geolocation({projection:a.proj.get(c.projection)}),u.on("change",function(){if(c.autodiscover){var a=u.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,u.setTracking(!1)})}})),void u.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}});var v=f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})});r.$on("$destroy",function(){f.unByKey(v)})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)});var f=e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})});g.$on("$destroy",function(){a.unByKey(f)})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope(),j=e.getControlClasses,k=j();i.getMap().then(function(b){function d(a){a&&a.control?(f&&b.removeControl(f),f=a.control,b.addControl(f)):c.name&&(h(a)&&(g=a),f&&b.removeControl(f),f=new k[c.name](g),b.addControl(f))}a.$on("$destroy",function(){b.removeControl(f)}),a.$watch("properties",function(a){h(a)&&d(a)}),d(a.properties)})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e].markerLayer,delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(){c.properties&&(e.getViewport().removeEventListener("mousemove",c.properties.handleInteraction),e.getViewport().removeEventListener("click",c.properties.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",c.properties.handleTapInteraction),e.getViewport().removeEventListener("mousemove",c.properties.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",c.properties.removeAllOverlays),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",c.properties.activateCooldown))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;if(c.handleDrag=function(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(!(x=g?g.get("marker"):null)||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))},e.on("pointerdown",c.handleDrag),e.on("pointerup",c.handleDrag),e.on("pointerdrag",c.handleDrag),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e),e.un("pointerdown",c.handleDrag),e.un("pointerup",c.handleDrag),e.un("pointerdrag",c.handleDrag),j()}),!k(c.properties))return t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p)));c.$watch("properties",function(d){if(j(),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){var a,b=!1;return d.activateCooldown=function(){b=!0,a&&clearTimeout(a),a=setTimeout(function(){b=!1,a=null},500)},d.activateCooldown&&e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",d.activateCooldown),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",d.activateCooldown),function(){b||(d.handleInteraction.apply(null,arguments),d.activateCooldown())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&!0===d.label.show&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&!1===d.label.show&&(e.removeOverlay(p),p=void 0),d.label&&!1===d.label.show&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&!1===d.label.show&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&!1===d.label.show&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0)})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){a[c(a,b)].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&!0!==a[f].resolvedDefer?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d=c(a,b);return angular.isDefined(a[d])&&!1!==a[d].resolvedDefer?a[d].defer:f(a,b)};this.setMap=function(a,b){f(d,b).resolve(a),e(d,b)},this.getMap=function(a){return g(d,a).promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map","World_Light_Gray_Base","World_Dark_Gray_Base"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function a(b,c){var d;if(c?d=b[c]:(c="style",d=b),"style"===c&&b instanceof Function)return b;if(!(d instanceof Object))return d;var e;if("[object Object]"===Object.prototype.toString.call(d)){e={};var f=l[c];if(f&&d instanceof f)return d;Object.getOwnPropertyNames(d).forEach(function(b,g,h){var i=l[b];if(f&&i&&i.prototype instanceof l[c])return console.assert(1===h.length,"Extra parameters for "+c),e=a(d,b),m(e,i);e[b]=a(d,b),"text"!==b&&"string"!=typeof e[b]&&(e[b]=m(e[b],l[b]))})}else e=d;return m(e,l[c])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":return"Vector";case"TileVector":case"MVT":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g,i,l,m=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");l="https://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace(".png","@2x.png")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,wrapX:void 0===b.wrapX||b.wrapX});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");l="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace("{y}?access_token","{y}@2x?access_token")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,tileSize:b.tileSize||[512,512],wrapX:void 0===b.wrapX||b.wrapX});break;case"MVT":if(!b.url)return void c.error("[AngularJS - Openlayers] - MVT layer requires the source url");g=new a.source.VectorTile({attributions:b.attributions||"",format:new a.format.MVT,tileGrid:a.tilegrid.createXYZ({maxZoom:b.maxZoom||22}),tilePixelRatio:b.tilePixelRatio||16,url:b.url});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,imageLoadFunction:b.imageLoadFunction,attributions:t(b),crossOrigin:void 0===b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={tileLoadFunction:b.tileLoadFunction,crossOrigin:void 0===b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX};b.projection&&(n.projection=new a.proj.get(b.projection)),b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={tileLoadFunction:b.tileLoadFunction,projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),style:"undefined"===b.style?"normal":b.style,wrapX:void 0===b.wrapX||b.wrapX};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({tileLoadFunction:b.tileLoadFunction,attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,tileLoadFunction:b.tileLoadFunction,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX||b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer,wrapX:void 0===b.wrapX||b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="http://services.arcgisonline.com/ArcGIS/rest/services/";"World_Light_Gray_Base"!==b.layer&&"World_Dark_Gray_Base"!==b.layer||(r+="Canvas/");var u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:u,wrapX:void 0===b.wrapX||b.wrapX});break;case"TileArcGISRest":b.url||c.error("[AngularJS - Openlayers] - TileArcGISRest Layer needs valid url"),g=new a.source.TileArcGISRest({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=m.readFeatures(b.geojson.object,{featureProjection:w.getCode(),dataProjection:v.getCode()});g.addFeatures(x)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});else{g=new a.source.Vector;var y,z=f;y=e(b.wkt.projection)?new a.proj.get(b.wkt.projection):f;for(var A=new a.format.WKT,B=[],C=0;C',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id),q.setTarget(null)}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);if(!0===s.centerUrlHash){var t=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t(),r.$on("$locationChangeSuccess",function(){var a=t();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var u;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return u||(u=new a.Geolocation({projection:a.proj.get(c.projection)}),u.on("change",function(){if(c.autodiscover){var a=u.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,u.setTracking(!1)})}})),void u.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}});var v=f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})});r.$on("$destroy",function(){f.unByKey(v)})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),(g(e)&&n(c.visible)&&c.visible!==e.visible||z(d))&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(a,b,c,f){var g=f.getOpenlayersScope(),h=e.isNumber,i=e.safeApply,j=e.createView;g.getMap().then(function(a){var b=d.getDefaults(g),c=g.view;c.projection||(c.projection=b.view.projection),c.maxZoom||(c.maxZoom=b.view.maxZoom),c.minZoom||(c.minZoom=b.view.minZoom),c.rotation||(c.rotation=b.view.rotation);var e=j(c);a.setView(e),g.$watchCollection("view",function(a){h(a.rotation)&&e.setRotation(a.rotation)});var f=e.on("change:rotation",function(){i(g,function(b){b.view.rotation=a.getView().getRotation()})});g.$on("$destroy",function(){a.unByKey(f)})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope(),j=e.getControlClasses,k=j();i.getMap().then(function(b){function d(a){a&&a.control?(f&&b.removeControl(f),f=a.control,b.addControl(f)):c.name&&(h(a)&&(g=a),f&&b.removeControl(f),f=new k[c.name](g),b.addControl(f))}a.$on("$destroy",function(){b.removeControl(f)}),a.$watch("properties",function(a){h(a)&&d(a)}),d(a.properties)})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e].markerLayer,delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(){c.properties&&(e.getViewport().removeEventListener("mousemove",c.properties.handleInteraction),e.getViewport().removeEventListener("click",c.properties.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",c.properties.handleTapInteraction),e.getViewport().removeEventListener("mousemove",c.properties.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",c.properties.removeAllOverlays),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",c.properties.activateCooldown))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;if(c.handleDrag=function(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(!(x=g?g.get("marker"):null)||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))},e.on("pointerdown",c.handleDrag),e.on("pointerup",c.handleDrag),e.on("pointerdrag",c.handleDrag),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e),e.un("pointerdown",c.handleDrag),e.un("pointerup",c.handleDrag),e.un("pointerdrag",c.handleDrag),j()}),!k(c.properties))return t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p)));c.$watch("properties",function(d){if(j(),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){var a,b=!1;return d.activateCooldown=function(){b=!0,a&&clearTimeout(a),a=setTimeout(function(){b=!1,a=null},500)},d.activateCooldown&&e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",d.activateCooldown),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",d.activateCooldown),function(){b||(d.handleInteraction.apply(null,arguments),d.activateCooldown())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&!0===d.label.show&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&!1===d.label.show&&(e.removeOverlay(p),p=void 0),d.label&&!1===d.label.show&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&!1===d.label.show&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&!1===d.label.show&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0)})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){a[c(a,b)].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&!0!==a[f].resolvedDefer?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d=c(a,b);return angular.isDefined(a[d])&&!1!==a[d].resolvedDefer?a[d].defer:f(a,b)};this.setMap=function(a,b){f(d,b).resolve(a),e(d,b)},this.getMap=function(a){return g(d,a).promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map","World_Light_Gray_Base","World_Dark_Gray_Base"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function a(b,c){var d;if(c?d=b[c]:(c="style",d=b),"style"===c&&b instanceof Function)return b;if(!(d instanceof Object))return d;var e;if("[object Object]"===Object.prototype.toString.call(d)){e={};var f=l[c];if(f&&d instanceof f)return d;Object.getOwnPropertyNames(d).forEach(function(b,g,h){var i=l[b];if(f&&i&&i.prototype instanceof l[c])return console.assert(1===h.length,"Extra parameters for "+c),e=a(d,b),m(e,i);e[b]=a(d,b),"text"!==b&&"string"!=typeof e[b]&&(e[b]=m(e[b],l[b]))})}else e=d;return m(e,l[c])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":return"Vector";case"TileVector":case"MVT":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g,i,l,m=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");l="https://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace(".png","@2x.png")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,wrapX:void 0===b.wrapX||b.wrapX});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");l="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace("{y}?access_token","{y}@2x?access_token")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,tileSize:b.tileSize||[512,512],wrapX:void 0===b.wrapX||b.wrapX});break;case"MVT":if(!b.url)return void c.error("[AngularJS - Openlayers] - MVT layer requires the source url");g=new a.source.VectorTile({attributions:b.attributions||"",format:new a.format.MVT,tileGrid:a.tilegrid.createXYZ({maxZoom:b.maxZoom||22}),tilePixelRatio:b.tilePixelRatio||16,url:b.url});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,imageLoadFunction:b.imageLoadFunction,attributions:t(b),crossOrigin:void 0===b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={tileLoadFunction:b.tileLoadFunction,crossOrigin:void 0===b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX};b.projection&&(n.projection=new a.proj.get(b.projection)),b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={tileLoadFunction:b.tileLoadFunction,projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),style:"undefined"===b.style?"normal":b.style,wrapX:void 0===b.wrapX||b.wrapX};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({tileLoadFunction:b.tileLoadFunction,attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,tileLoadFunction:b.tileLoadFunction,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX||b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer,wrapX:void 0===b.wrapX||b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="http://services.arcgisonline.com/ArcGIS/rest/services/";"World_Light_Gray_Base"!==b.layer&&"World_Dark_Gray_Base"!==b.layer||(r+="Canvas/");var u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:u,wrapX:void 0===b.wrapX||b.wrapX});break;case"TileArcGISRest":b.url||c.error("[AngularJS - Openlayers] - TileArcGISRest Layer needs valid url"),g=new a.source.TileArcGISRest({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=m.readFeatures(b.geojson.object,{featureProjection:w.getCode(),dataProjection:v.getCode()});g.addFeatures(x)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});else{g=new a.source.Vector;var y,z=f;y=e(b.wkt.projection)?new a.proj.get(b.wkt.projection):f;for(var A=new a.format.WKT,B=[],C=0;C', - controller: function($scope) { - var _map = $q.defer(); - $scope.getMap = function() { - return _map.promise; - }; - - $scope.setMap = function(map) { - _map.resolve(map); - }; - - this.getOpenlayersScope = function() { - return $scope; - }; - }, - link: function(scope, element, attrs) { - var isDefined = olHelpers.isDefined; - var createLayer = olHelpers.createLayer; - var setMapEvents = olHelpers.setMapEvents; - var setViewEvents = olHelpers.setViewEvents; - var createView = olHelpers.createView; - var defaults = olMapDefaults.setDefaults(scope); - - // Set width and height if they are defined - if (isDefined(attrs.width)) { - if (isNaN(attrs.width)) { - element.css('width', attrs.width); - } else { - element.css('width', attrs.width + 'px'); - } - } - - if (isDefined(attrs.height)) { - if (isNaN(attrs.height)) { - element.css('height', attrs.height); - } else { - element.css('height', attrs.height + 'px'); - } - } - - if (isDefined(attrs.lat)) { - defaults.center.lat = parseFloat(attrs.lat); - } - - if (isDefined(attrs.lon)) { - defaults.center.lon = parseFloat(attrs.lon); - } - - if (isDefined(attrs.zoom)) { - defaults.center.zoom = parseFloat(attrs.zoom); - } - - var controls = ol.control.defaults(defaults.controls); - var interactions = ol.interaction.defaults(defaults.interactions); - var view = createView(defaults.view); - - // Create the Openlayers Map Object with the options - var map = new ol.Map({ - target: element[0], - controls: controls, - interactions: interactions, - renderer: defaults.renderer, - view: view, - loadTilesWhileAnimating: defaults.loadTilesWhileAnimating, - loadTilesWhileInteracting: defaults.loadTilesWhileInteracting - }); - - scope.$on('$destroy', function() { - olData.resetMap(attrs.id); - map.setTarget(null); - }); - - // If no layer is defined, set the default tileLayer - if (!attrs.customLayers) { - var l = { - type: 'Tile', - source: { - type: 'OSM' - } - }; - var layer = createLayer(l, view.getProjection(), 'default'); - map.addLayer(layer); - map.set('default', true); - } - - if (!isDefined(attrs.olCenter)) { - var c = ol.proj.transform([defaults.center.lon, - defaults.center.lat - ], - defaults.center.projection, view.getProjection() - ); - view.setCenter(c); - view.setZoom(defaults.center.zoom); - } - - // Set the Default events for the map - setMapEvents(defaults.events, map, scope); - - //Set the Default events for the map view - setViewEvents(defaults.events, map, scope); - - // Resolve the map object to the promises - scope.setMap(map); - olData.setMap(map, attrs.id); - - } - }; - }); - -angular.module('openlayers-directive').directive('olCenter', function($log, $location, olMapDefaults, olHelpers) { - - return { - restrict: 'A', - scope: false, - replace: false, - require: 'openlayers', - - link: function(scope, element, attrs, controller) { - var safeApply = olHelpers.safeApply; - var isValidCenter = olHelpers.isValidCenter; - var isDefined = olHelpers.isDefined; - var isArray = olHelpers.isArray; - var isNumber = olHelpers.isNumber; - var isSameCenterOnMap = olHelpers.isSameCenterOnMap; - var setCenter = olHelpers.setCenter; - var setZoom = olHelpers.setZoom; - var olScope = controller.getOpenlayersScope(); - - olScope.getMap().then(function(map) { - var defaults = olMapDefaults.getDefaults(olScope); - var view = map.getView(); - var center = olScope.center; - - if (attrs.olCenter.search('-') !== -1) { - $log.error('[AngularJS - Openlayers] The "center" variable can\'t use ' + - 'a "-" on his key name: "' + attrs.center + '".'); - setCenter(view, defaults.view.projection, defaults.center, map); - return; - } - - if (!isDefined(center)) { - center = {}; - } - - if (!isValidCenter(center)) { - $log.warn('[AngularJS - Openlayers] invalid \'center\''); - center.lat = defaults.center.lat; - center.lon = defaults.center.lon; - center.zoom = defaults.center.zoom; - center.projection = defaults.center.projection; - } - - if (!center.projection) { - if (defaults.view.projection !== 'pixel') { - center.projection = defaults.center.projection; - } else { - center.projection = 'pixel'; - } - } - - if (!isNumber(center.zoom)) { - center.zoom = 1; - } - - setCenter(view, defaults.view.projection, center, map); - view.setZoom(center.zoom); - - var centerUrlHash; - if (center.centerUrlHash === true) { - var extractCenterFromUrl = function() { - var search = $location.search(); - var centerParam; - if (isDefined(search.c)) { - var cParam = search.c.split(':'); - if (cParam.length === 3) { - centerParam = { - lat: parseFloat(cParam[0]), - lon: parseFloat(cParam[1]), - zoom: parseInt(cParam[2], 10) - }; - } - } - return centerParam; - }; - centerUrlHash = extractCenterFromUrl(); - - olScope.$on('$locationChangeSuccess', function() { - var urlCenter = extractCenterFromUrl(); - if (urlCenter && !isSameCenterOnMap(urlCenter, map)) { - safeApply(olScope, function(scope) { - scope.center.lat = urlCenter.lat; - scope.center.lon = urlCenter.lon; - scope.center.zoom = urlCenter.zoom; - }); - } - }); - } - - var geolocation; - olScope.$watchCollection('center', function(center) { - - if (!center) { - return; - } - - if (!center.projection) { - center.projection = defaults.center.projection; - } - - if (center.autodiscover) { - if (!geolocation) { - geolocation = new ol.Geolocation({ - projection: ol.proj.get(center.projection) - }); - - geolocation.on('change', function() { - if (center.autodiscover) { - var location = geolocation.getPosition(); - safeApply(olScope, function(scope) { - scope.center.lat = location[1]; - scope.center.lon = location[0]; - scope.center.zoom = 12; - scope.center.autodiscover = false; - geolocation.setTracking(false); - }); - } - }); - } - geolocation.setTracking(true); - return; - } - - if (!isValidCenter(center)) { - $log.warn('[AngularJS - Openlayers] invalid \'center\''); - center = defaults.center; - } - - var viewCenter = view.getCenter(); - if (viewCenter) { - if (defaults.view.projection === 'pixel' || center.projection === 'pixel') { - view.setCenter(center.coord); - } else { - var actualCenter = - ol.proj.transform(viewCenter, defaults.view.projection, center.projection); - if (!(actualCenter[1] === center.lat && actualCenter[0] === center.lon)) { - setCenter(view, defaults.view.projection, center, map); - } - } - } - - if (view.getZoom() !== center.zoom) { - setZoom(view, center.zoom, map); - } - }); - - var moveEndEventKey = map.on('moveend', function() { - safeApply(olScope, function(scope) { - - if (!isDefined(scope.center)) { - return; - } - - var center = map.getView().getCenter(); - scope.center.zoom = view.getZoom(); - - if (defaults.view.projection === 'pixel' || scope.center.projection === 'pixel') { - scope.center.coord = center; - return; - } - - if (scope.center) { - var proj = ol.proj.transform(center, defaults.view.projection, scope.center.projection); - scope.center.lat = proj[1]; - scope.center.lon = proj[0]; - - // Notify the controller about a change in the center position - olHelpers.notifyCenterUrlHashChanged(olScope, scope.center, $location.search()); - - // Calculate the bounds if needed - if (isArray(scope.center.bounds)) { - var extent = view.calculateExtent(map.getSize()); - var centerProjection = scope.center.projection; - var viewProjection = defaults.view.projection; - scope.center.bounds = ol.proj.transformExtent(extent, viewProjection, centerProjection); - } - } - }); - }); - - olScope.$on('$destroy', function() { - map.unByKey(moveEndEventKey); - }); - }); - } - }; -}); - -angular.module('openlayers-directive').directive('olLayer', function($log, $q, olMapDefaults, olHelpers) { - - return { - restrict: 'E', - scope: { - properties: '=olLayerProperties', - onLayerCreated: '&' - }, - replace: false, - require: '^openlayers', - link: function(scope, element, attrs, controller) { - var isDefined = olHelpers.isDefined; - var equals = olHelpers.equals; - var olScope = controller.getOpenlayersScope(); - var createLayer = olHelpers.createLayer; - var setVectorLayerEvents = olHelpers.setVectorLayerEvents; - var detectLayerType = olHelpers.detectLayerType; - var createStyle = olHelpers.createStyle; - var isBoolean = olHelpers.isBoolean; - var addLayerBeforeMarkers = olHelpers.addLayerBeforeMarkers; - var isNumber = olHelpers.isNumber; - var insertLayer = olHelpers.insertLayer; - var removeLayer = olHelpers.removeLayer; - var addLayerToGroup = olHelpers.addLayerToGroup; - var removeLayerFromGroup = olHelpers.removeLayerFromGroup; - var getGroup = olHelpers.getGroup; - - olScope.getMap().then(function(map) { - var projection = map.getView().getProjection(); - var defaults = olMapDefaults.setDefaults(olScope); - var layerCollection = map.getLayers(); - var olLayer; - - scope.$on('$destroy', function() { - if (scope.properties.group) { - removeLayerFromGroup(layerCollection, olLayer, scope.properties.group); - } else { - removeLayer(layerCollection, olLayer.index); - } - - map.removeLayer(olLayer); - }); - - if (!isDefined(scope.properties)) { - if (isDefined(attrs.sourceType) && isDefined(attrs.sourceUrl)) { - var l = { - source: { - url: attrs.sourceUrl, - type: attrs.sourceType - } - }; - - olLayer = createLayer(l, projection, attrs.layerName, scope.onLayerCreated); - if (detectLayerType(l) === 'Vector') { - setVectorLayerEvents(defaults.events, map, scope, attrs.name); - } - addLayerBeforeMarkers(layerCollection, olLayer); - } - return; - } - - scope.$watch('properties', function(properties, oldProperties) { - if (!isDefined(properties.source) || !isDefined(properties.source.type)) { - return; - } - - if (!isDefined(properties.visible)) { - properties.visible = true; - return; - } - - if (!isDefined(properties.opacity)) { - properties.opacity = 1; - return; - } - - var style; - var group; - var collection; - if (!isDefined(olLayer)) { - olLayer = createLayer(properties, projection, scope.onLayerCreated); - if (isDefined(properties.group)) { - addLayerToGroup(layerCollection, olLayer, properties.group); - } else if (isDefined(properties.index)) { - insertLayer(layerCollection, properties.index, olLayer); - } else { - addLayerBeforeMarkers(layerCollection, olLayer); - } - - if (detectLayerType(properties) === 'Vector') { - setVectorLayerEvents(defaults.events, map, scope, properties.name); - } - - if (isBoolean(properties.visible)) { - olLayer.setVisible(properties.visible); - } - - if (properties.opacity) { - olLayer.setOpacity(properties.opacity); - } - - if (angular.isArray(properties.extent)) { - olLayer.setExtent(properties.extent); - } - - if (properties.style) { - if (!angular.isFunction(properties.style)) { - style = createStyle(properties.style); - } else { - style = properties.style; - } - // not every layer has a setStyle method - if (olLayer.setStyle && angular.isFunction(olLayer.setStyle)) { - olLayer.setStyle(style); - } - } - - if (properties.minResolution) { - olLayer.setMinResolution(properties.minResolution); - } - - if (properties.maxResolution) { - olLayer.setMaxResolution(properties.maxResolution); - } - - } else { - var isNewLayer = (function(olLayer) { - // this function can be used to verify whether a new layer instance has - // been created. This is needed in order to re-assign styles, opacity - // etc... - return function(layer) { - return layer !== olLayer; - }; - })(olLayer); - - // set source properties - if (isDefined(oldProperties) && !equals(properties.source, oldProperties.source)) { - var idx = olLayer.index; - collection = layerCollection; - group = olLayer.get('group'); - - if (group) { - collection = getGroup(layerCollection, group).getLayers(); - } - - collection.removeAt(idx); - - olLayer = createLayer(properties, projection, scope.onLayerCreated); - olLayer.set('group', group); - - if (isDefined(olLayer)) { - insertLayer(collection, idx, olLayer); - - if (detectLayerType(properties) === 'Vector') { - setVectorLayerEvents(defaults.events, map, scope, properties.name); - } - } - } - - // set opacity - if (isDefined(oldProperties) && - properties.opacity !== oldProperties.opacity || isNewLayer(olLayer)) { - if (isNumber(properties.opacity) || isNumber(parseFloat(properties.opacity))) { - olLayer.setOpacity(properties.opacity); - } - } - - // set index - if (isDefined(properties.index) && properties.index !== olLayer.index) { - collection = layerCollection; - group = olLayer.get('group'); - - if (group) { - collection = getGroup(layerCollection, group).getLayers(); - } - - removeLayer(collection, olLayer.index); - insertLayer(collection, properties.index, olLayer); - } - - // set group - if (isDefined(properties.group) && properties.group !== oldProperties.group) { - removeLayerFromGroup(layerCollection, olLayer, oldProperties.group); - addLayerToGroup(layerCollection, olLayer, properties.group); - } - - // set visibility - if (isDefined(oldProperties) && - isBoolean(properties.visible) && - properties.visible !== oldProperties.visible || isNewLayer(olLayer)) { - olLayer.setVisible(properties.visible); - } - - // set style - if (isDefined(properties.style) && - !equals(properties.style, oldProperties.style) || isNewLayer(olLayer)) { - if (!angular.isFunction(properties.style)) { - style = createStyle(properties.style); - } else { - style = properties.style; - } - // not every layer has a setStyle method - if (olLayer.setStyle && angular.isFunction(olLayer.setStyle)) { - olLayer.setStyle(style); - } - } - - //set min resolution - if (!equals(properties.minResolution, oldProperties.minResolution) || isNewLayer(olLayer)) { - if (isDefined(properties.minResolution)) { - olLayer.setMinResolution(properties.minResolution); - } - } - - //set max resolution - if (!equals(properties.maxResolution, oldProperties.maxResolution) || isNewLayer(olLayer)) { - if (isDefined(properties.maxResolution)) { - olLayer.setMaxResolution(properties.maxResolution); - } - } - } - }, true); - }); - } - }; -}); - -angular.module('openlayers-directive').directive('olPath', function($log, $q, olMapDefaults, olHelpers) { - - return { - restrict: 'E', - scope: { - properties: '=olGeomProperties', - style: '=olStyle' - }, - require: '^openlayers', - replace: true, - template: '', - - link: function(scope, element, attrs, controller) { - var isDefined = olHelpers.isDefined; - var createFeature = olHelpers.createFeature; - var createOverlay = olHelpers.createOverlay; - var createVectorLayer = olHelpers.createVectorLayer; - var insertLayer = olHelpers.insertLayer; - var removeLayer = olHelpers.removeLayer; - var olScope = controller.getOpenlayersScope(); - - olScope.getMap().then(function(map) { - var mapDefaults = olMapDefaults.getDefaults(olScope); - var viewProjection = mapDefaults.view.projection; - - var layer = createVectorLayer(); - var layerCollection = map.getLayers(); - - insertLayer(layerCollection, layerCollection.getLength(), layer); - - scope.$on('$destroy', function() { - removeLayer(layerCollection, layer.index); - }); - - if (isDefined(attrs.coords)) { - var proj = attrs.proj || 'EPSG:4326'; - var coords = JSON.parse(attrs.coords); - var data = { - type: 'Polygon', - coords: coords, - projection: proj, - style: scope.style ? scope.style : mapDefaults.styles.path - }; - var feature = createFeature(data, viewProjection); - layer.getSource().addFeature(feature); - - if (attrs.message) { - scope.message = attrs.message; - var extent = feature.getGeometry().getExtent(); - var label = createOverlay(element, extent); - map.addOverlay(label); - } - return; - } - }); - } - }; -}); - -angular.module('openlayers-directive').directive('olView', function($log, $q, olData, olMapDefaults, olHelpers) { - return { - restrict: 'A', - scope: false, - replace: false, - require: 'openlayers', - link: function(scope, element, attrs, controller) { - var olScope = controller.getOpenlayersScope(); - var isNumber = olHelpers.isNumber; - var safeApply = olHelpers.safeApply; - var createView = olHelpers.createView; - - olScope.getMap().then(function(map) { - var defaults = olMapDefaults.getDefaults(olScope); - var view = olScope.view; - - if (!view.projection) { - view.projection = defaults.view.projection; - } - - if (!view.maxZoom) { - view.maxZoom = defaults.view.maxZoom; - } - - if (!view.minZoom) { - view.minZoom = defaults.view.minZoom; - } - - if (!view.rotation) { - view.rotation = defaults.view.rotation; - } - - var mapView = createView(view); - map.setView(mapView); - - olScope.$watchCollection('view', function(view) { - if (isNumber(view.rotation)) { - mapView.setRotation(view.rotation); - } - }); - - var rotationEventKey = mapView.on('change:rotation', function() { - safeApply(olScope, function(scope) { - scope.view.rotation = map.getView().getRotation(); - }); - }); - - olScope.$on('$destroy', function() { - map.unByKey(rotationEventKey); - }); - - }); - } - }; -}); - -angular.module('openlayers-directive') -.directive('olControl', function($log, $q, olData, olMapDefaults, olHelpers) { - return { - restrict: 'E', - scope: { - properties: '=olControlProperties' - }, - replace: false, - require: '^openlayers', - link: function(scope, element, attrs, controller) { - var isDefined = olHelpers.isDefined; - var olScope = controller.getOpenlayersScope(); - var olControl; - var olControlOps; - var getControlClasses = olHelpers.getControlClasses; - var controlClasses = getControlClasses(); - - olScope.getMap().then(function(map) { - - scope.$on('$destroy', function() { - map.removeControl(olControl); - }); - - scope.$watch('properties', function(properties) { - if (!isDefined(properties)) { - return; - } - - initCtrls(properties); - }); - - function initCtrls(properties) { - if (properties && properties.control) { - // the control instance is already defined, - // so simply use it and go ahead - - // is there already a control, so destroy and recreate it? - if (olControl) { - map.removeControl(olControl); - } - - olControl = properties.control; - map.addControl(olControl); - } else { - - // the name is the key to instantiate an ol3 control - if (attrs.name) { - if (isDefined(properties)) { - olControlOps = properties; - } - - // is there already a control, so destroy and recreate it? - if (olControl) { - map.removeControl(olControl); - } - - olControl = new controlClasses[attrs.name](olControlOps); - map.addControl(olControl); - } - } - } - - initCtrls(scope.properties); - - }); - - } - }; -}); - -angular.module('openlayers-directive').directive('olMarker', function($log, $q, olMapDefaults, olHelpers) { - - var getMarkerDefaults = function() { - return { - projection: 'EPSG:4326', - lat: 0, - lon: 0, - coord: [], - show: true, - showOnMouseOver: false, - showOnMouseClick: false, - keepOneOverlayVisible: false - }; - }; - - var markerLayerManager = (function() { - var mapDict = []; - - function getMapIndex(map) { - return mapDict.map(function(record) { - return record.map; - }).indexOf(map); - } - - return { - getInst: function getMarkerLayerInst(scope, map) { - var mapIndex = getMapIndex(map); - - if (mapIndex === -1) { - var markerLayer = olHelpers.createVectorLayer(); - markerLayer.set('markers', true); - map.addLayer(markerLayer); - mapDict.push({ - map: map, - markerLayer: markerLayer, - instScopes: [] - }); - mapIndex = mapDict.length - 1; - } - - mapDict[mapIndex].instScopes.push(scope); - - return mapDict[mapIndex].markerLayer; - }, - deregisterScope: function deregisterScope(scope, map) { - var mapIndex = getMapIndex(map); - if (mapIndex === -1) { - throw Error('This map has no markers'); - } - - var scopes = mapDict[mapIndex].instScopes; - var scopeIndex = scopes.indexOf(scope); - if (scopeIndex === -1) { - throw Error('Scope wan\'t registered'); - } - - scopes.splice(scopeIndex, 1); - - if (!scopes.length) { - map.removeLayer(mapDict[mapIndex].markerLayer); - delete mapDict[mapIndex].markerLayer; - delete mapDict[mapIndex]; - } - } - }; - })(); - return { - restrict: 'E', - scope: { - lat: '=lat', - lon: '=lon', - label: '=label', - properties: '=olMarkerProperties', - style: '=olStyle' - }, - transclude: true, - require: '^openlayers', - replace: true, - template: - '', - - link: function(scope, element, attrs, controller) { - var isDefined = olHelpers.isDefined; - var olScope = controller.getOpenlayersScope(); - var createFeature = olHelpers.createFeature; - var createOverlay = olHelpers.createOverlay; - - var hasTranscluded = element.find('ng-transclude').children().length > 0; - - olScope.getMap().then(function(map) { - var markerLayer = markerLayerManager.getInst(scope, map); - var data = getMarkerDefaults(); - - var mapDefaults = olMapDefaults.getDefaults(olScope); - var viewProjection = mapDefaults.view.projection; - var label; - var pos; - var marker; - - // This function handles dragging a marker - var pickOffset = null; - var pickProperties = null; - scope.handleDrag = function(evt) { - var coord = evt.coordinate; - var proj = map.getView().getProjection().getCode(); - if (proj === 'pixel') { - coord = coord.map(function(v) { - return parseInt(v, 10); - }); - } else { - coord = ol.proj.transform(coord, proj, 'EPSG:4326'); - } - - if (evt.type === 'pointerdown') { - // Get feature under mouse if any - var feature = map.forEachFeatureAtPixel(evt.pixel, function(feature) { - return feature; - }); - // Get associated marker properties - pickProperties = (feature ? feature.get('marker') : null); - if (!pickProperties || !pickProperties.draggable) { - pickProperties = null; - return; - } - map.getTarget().style.cursor = 'pointer'; - if (proj === 'pixel') { - pickOffset = [coord[0] - pickProperties.coord[0], coord[1] - pickProperties.coord[1]]; - } else { - pickOffset = [coord[0] - pickProperties.lon, coord[1] - pickProperties.lat]; - } - evt.preventDefault(); - } else if (pickOffset && pickProperties) { - if (evt.type === 'pointerup') { - map.getTarget().style.cursor = ''; - pickOffset = null; - pickProperties = null; - evt.preventDefault(); - } else if (evt.type === 'pointerdrag') { - evt.preventDefault(); - scope.$apply(function() { - // Add current delta to marker initial position - if (proj === 'pixel') { - pickProperties.coord[0] = coord[0] - pickOffset[0]; - pickProperties.coord[1] = coord[1] - pickOffset[1]; - } else { - pickProperties.lon = coord[0] - pickOffset[0]; - pickProperties.lat = coord[1] - pickOffset[1]; - } - }); - } - } - }; - - function unregisterHandlers() { - if (!scope.properties) { return ; } - // Remove previous listeners if any - map.getViewport().removeEventListener('mousemove', scope.properties.handleInteraction); - map.getViewport().removeEventListener('click', scope.properties.handleTapInteraction); - map.getViewport().querySelector('canvas.ol-unselectable').removeEventListener( - 'touchend', scope.properties.handleTapInteraction); - map.getViewport().removeEventListener('mousemove', scope.properties.showAtLeastOneOverlay); - map.getViewport().removeEventListener('click', scope.properties.removeAllOverlays); - map.getViewport().querySelector('canvas.ol-unselectable').removeEventListener( - 'touchmove', scope.properties.activateCooldown); - } - - // Setup generic handlers for marker drag - map.on('pointerdown', scope.handleDrag); - map.on('pointerup', scope.handleDrag); - map.on('pointerdrag', scope.handleDrag); - - scope.$on('$destroy', function() { - markerLayer.getSource().removeFeature(marker); - if (isDefined(label)) { - map.removeOverlay(label); - } - markerLayerManager.deregisterScope(scope, map); - map.un('pointerdown', scope.handleDrag); - map.un('pointerup', scope.handleDrag); - map.un('pointerdrag', scope.handleDrag); - unregisterHandlers(); - }); - - if (!isDefined(scope.properties)) { - data.lat = scope.lat ? scope.lat : data.lat; - data.lon = scope.lon ? scope.lon : data.lon; - data.message = attrs.message; - data.style = scope.style ? scope.style : mapDefaults.styles.marker; - - marker = createFeature(data, viewProjection); - if (!isDefined(marker)) { - $log.error('[AngularJS - Openlayers] Received invalid data on ' + - 'the marker.'); - } - // Add a link between the feature and the marker properties - marker.set('marker', scope); - markerLayer.getSource().addFeature(marker); - - if (data.message || hasTranscluded) { - scope.message = attrs.message; - pos = ol.proj.transform([data.lon, data.lat], data.projection, - viewProjection); - label = createOverlay(element, pos); - map.addOverlay(label); - } - return; - } - - scope.$watch('properties', function(properties) { - - unregisterHandlers(); - - // This function handles popup on mouse over/click - properties.handleInteraction = function(evt) { - var ngClick = false; - if (attrs.hasOwnProperty('ngClick')) { - ngClick = true; - } - - if (properties.label.show && !ngClick) { - return; - } - var found = false; - var pixel = map.getEventPixel(evt); - var feature = map.forEachFeatureAtPixel(pixel, function(feature) { - return feature; - }); - - var actionTaken = false; - if (feature === marker) { - actionTaken = true; - found = true; - if (ngClick && (evt.type === 'click' || evt.type === 'touchend')) { - element.triggerHandler('click'); - evt.preventDefault(); - evt.stopPropagation(); - return; - } - if (!isDefined(label)) { - if (data.projection === 'pixel') { - pos = properties.coord; - } else { - pos = ol.proj.transform([properties.lon, properties.lat], - data.projection, viewProjection); - } - label = createOverlay(element, pos); - map.addOverlay(label); - } - map.getTarget().style.cursor = 'pointer'; - } - - if (!found && label) { - actionTaken = true; - map.removeOverlay(label); - label = undefined; - map.getTarget().style.cursor = ''; - } - - if (actionTaken) { - evt.preventDefault(); - } - }; - - // Made to filter out click/tap events if both are being triggered on this platform - properties.handleTapInteraction = (function() { - var cooldownActive = false; - var prevTimeout; - - // Sets the cooldown flag to filter out any subsequent events within 500 ms - properties.activateCooldown = function() { - cooldownActive = true; - if (prevTimeout) { - clearTimeout(prevTimeout); - } - prevTimeout = setTimeout(function() { - cooldownActive = false; - prevTimeout = null; - }, 500); - }; - - // Preventing from 'touchend' to be considered a tap, if fired immediately after 'touchmove' - if (properties.activateCooldown) { - map.getViewport().querySelector('canvas.ol-unselectable').removeEventListener( - 'touchmove', properties.activateCooldown); - } - map.getViewport().querySelector('canvas.ol-unselectable').addEventListener( - 'touchmove', properties.activateCooldown); - - return function() { - if (!cooldownActive) { - properties.handleInteraction.apply(null, arguments); - properties.activateCooldown(); - } - }; - })(); - - properties.showAtLeastOneOverlay = function(evt) { - if (properties.label.show) { - return; - } - var found = false; - var pixel = map.getEventPixel(evt); - var feature = map.forEachFeatureAtPixel(pixel, function(feature) { - return feature; - }); - - var actionTaken = false; - if (feature === marker) { - actionTaken = true; - found = true; - if (!isDefined(label)) { - if (data.projection === 'pixel') { - pos = data.coord; - } else { - pos = ol.proj.transform([data.lon, data.lat], - data.projection, viewProjection); - } - label = createOverlay(element, pos); - angular.forEach(map.getOverlays(), function(value) { - map.removeOverlay(value); - }); - map.addOverlay(label); - } - map.getTarget().style.cursor = 'pointer'; - } - - if (!found && label) { - actionTaken = true; - label = undefined; - map.getTarget().style.cursor = ''; - } - - if (actionTaken) { - evt.preventDefault(); - } - }; - - properties.removeAllOverlays = function(evt) { - angular.forEach(map.getOverlays(), function(value) { - map.removeOverlay(value); - }); - evt.preventDefault(); - }; - - if (!isDefined(marker)) { - data.projection = properties.projection ? properties.projection : - data.projection; - data.coord = properties.coord ? properties.coord : data.coord; - data.lat = properties.lat ? properties.lat : data.lat; - data.lon = properties.lon ? properties.lon : data.lon; - - if (isDefined(properties.style)) { - data.style = properties.style; - } else { - data.style = mapDefaults.styles.marker; - } - - marker = createFeature(data, viewProjection); - if (!isDefined(marker)) { - $log.error('[AngularJS - Openlayers] Received invalid data on ' + - 'the marker.'); - } - // Add a link between the feature and the marker properties - marker.set('marker', properties); - markerLayer.getSource().addFeature(marker); - } else { - var requestedPosition; - if (properties.projection === 'pixel') { - requestedPosition = properties.coord; - } else { - requestedPosition = ol.proj.transform([properties.lon, properties.lat], data.projection, - map.getView().getProjection()); - } - - if (!angular.equals(marker.getGeometry().getCoordinates(), requestedPosition)) { - var geometry = new ol.geom.Point(requestedPosition); - marker.setGeometry(geometry); - } - } - - if (isDefined(label)) { - map.removeOverlay(label); - } - - if (!isDefined(properties.label)) { - return; - } - - scope.message = properties.label.message; - if (!hasTranscluded && (!isDefined(scope.message) || scope.message.length === 0)) { - return; - } - - if (properties.label && properties.label.show === true) { - if (data.projection === 'pixel') { - pos = data.coord; - } else { - pos = ol.proj.transform([properties.lon, properties.lat], data.projection, - viewProjection); - } - label = createOverlay(element, pos); - map.addOverlay(label); - } - - if (label && properties.label && properties.label.show === false) { - map.removeOverlay(label); - label = undefined; - } - - // Then setup new ones according to properties - if (properties.label && properties.label.show === false && - properties.label.showOnMouseOver) { - map.getViewport().addEventListener('mousemove', properties.handleInteraction); - } - - if ((properties.label && properties.label.show === false && - properties.label.showOnMouseClick) || - attrs.hasOwnProperty('ngClick')) { - map.getViewport().addEventListener('click', properties.handleTapInteraction); - map.getViewport().querySelector('canvas.ol-unselectable').addEventListener( - 'touchend', properties.handleTapInteraction); - } - - if ((properties.label && properties.label.show === false && - properties.label.keepOneOverlayVisible)) { - map.getViewport().addEventListener('mousemove', properties.showAtLeastOneOverlay); - map.getViewport().addEventListener('click', properties.removeAllOverlays); - } - }, true); - }); - } - }; -}); - -angular.module('openlayers-directive').service('olData', function($log, $q) { - - var maps = {}; - - var setResolvedDefer = function(d, mapId) { - var id = obtainEffectiveMapId(d, mapId); - d[id].resolvedDefer = true; - }; - - var getUnresolvedDefer = function(d, mapId) { - var id = obtainEffectiveMapId(d, mapId); - var defer; - - if (!angular.isDefined(d[id]) || d[id].resolvedDefer === true) { - defer = $q.defer(); - d[id] = { - defer: defer, - resolvedDefer: false - }; - } else { - defer = d[id].defer; - } - return defer; - }; - - var getDefer = function(d, mapId) { - var id = obtainEffectiveMapId(d, mapId); - var defer; - - if (!angular.isDefined(d[id]) || d[id].resolvedDefer === false) { - defer = getUnresolvedDefer(d, mapId); - } else { - defer = d[id].defer; - } - return defer; - }; - - this.setMap = function(olMap, scopeId) { - var defer = getUnresolvedDefer(maps, scopeId); - defer.resolve(olMap); - setResolvedDefer(maps, scopeId); - }; - - this.getMap = function(scopeId) { - var defer = getDefer(maps, scopeId); - return defer.promise; - }; - - function obtainEffectiveMapId(d, mapId) { - var id; - var i; - if (!angular.isDefined(mapId)) { - if (Object.keys(d).length === 1) { - for (i in d) { - if (d.hasOwnProperty(i)) { - id = i; - } - } - } else if (Object.keys(d).length === 0) { - id = 'main'; - } else { - $log.error('[AngularJS - Openlayers] - You have more than 1 map on the DOM, ' + - 'you must provide the map ID to the olData.getXXX call'); - } - } else { - id = mapId; - } - return id; - } - - this.resetMap = function(scopeId) { - if (angular.isDefined(maps[scopeId])) { - delete maps[scopeId]; - } - }; - -}); - -angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $http) { - - var isDefined = function(value) { - return angular.isDefined(value); - }; - - var isDefinedAndNotNull = function(value) { - return angular.isDefined(value) && value !== null; - }; - - var setEvent = function(map, eventType, scope) { - map.on(eventType, function(event) { - var coord = event.coordinate; - var proj = map.getView().getProjection().getCode(); - if (proj === 'pixel') { - coord = coord.map(function(v) { - return parseInt(v, 10); - }); - } - scope.$emit('openlayers.map.' + eventType, { - 'coord': coord, - 'projection': proj, - 'event': event - }); - }); - }; - - var bingImagerySets = [ - 'Road', - 'Aerial', - 'AerialWithLabels', - 'collinsBart', - 'ordnanceSurvey' - ]; - - var getControlClasses = function() { - return { - attribution: ol.control.Attribution, - fullscreen: ol.control.FullScreen, - mouseposition: ol.control.MousePosition, - overviewmap: ol.control.OverviewMap, - rotate: ol.control.Rotate, - scaleline: ol.control.ScaleLine, - zoom: ol.control.Zoom, - zoomslider: ol.control.ZoomSlider, - zoomtoextent: ol.control.ZoomToExtent - }; - }; - - var mapQuestLayers = ['osm', 'sat', 'hyb']; - - var esriBaseLayers = ['World_Imagery', 'World_Street_Map', 'World_Topo_Map', - 'World_Physical_Map', 'World_Terrain_Base', - 'Ocean_Basemap', 'NatGeo_World_Map', - 'World_Light_Gray_Base', 'World_Dark_Gray_Base']; - - var styleMap = { - 'style': ol.style.Style, - 'fill': ol.style.Fill, - 'stroke': ol.style.Stroke, - 'circle': ol.style.Circle, - 'icon': ol.style.Icon, - 'image': ol.style.Image, - 'regularshape': ol.style.RegularShape, - 'text': ol.style.Text - }; - - var optionalFactory = function(style, Constructor) { - if (Constructor && style instanceof Constructor) { - return style; - } else if (Constructor) { - return new Constructor(style); - } else { - return style; - } - }; - - //Parse the style tree calling the appropriate constructors. - //The keys in styleMap can be used and the OpenLayers constructors can be - //used directly. - var createStyle = function recursiveStyle(data, styleName) { - var style; - if (!styleName) { - styleName = 'style'; - style = data; - } else { - style = data[styleName]; - } - //Instead of defining one style for the layer, we've been given a style function - //to apply to each feature. - if (styleName === 'style' && data instanceof Function) { - return data; - } - - if (!(style instanceof Object)) { - return style; - } - - var styleObject; - if (Object.prototype.toString.call(style) === '[object Object]') { - styleObject = {}; - var styleConstructor = styleMap[styleName]; - if (styleConstructor && style instanceof styleConstructor) { - return style; - } - Object.getOwnPropertyNames(style).forEach(function(val, idx, array) { - //Consider the case - //image: { - // circle: { - // fill: { - // color: 'red' - // } - // } - // - //An ol.style.Circle is an instance of ol.style.Image, so we do not want to construct - //an Image and then construct a Circle. We assume that if we have an instanceof - //relationship, that the JSON parent has exactly one child. - //We check to see if an inheritance relationship exists. - //If it does, then for the parent we create an instance of the child. - var valConstructor = styleMap[val]; - if (styleConstructor && valConstructor && - valConstructor.prototype instanceof styleMap[styleName]) { - console.assert(array.length === 1, 'Extra parameters for ' + styleName); - styleObject = recursiveStyle(style, val); - return optionalFactory(styleObject, valConstructor); - } else { - styleObject[val] = recursiveStyle(style, val); - - // if the value is 'text' and it contains a String, then it should be interpreted - // as such, 'cause the text style might effectively contain a text to display - if (val !== 'text' && typeof styleObject[val] !== 'string') { - styleObject[val] = optionalFactory(styleObject[val], styleMap[val]); - } - } - }); - } else { - styleObject = style; - } - return optionalFactory(styleObject, styleMap[styleName]); - }; - - var detectLayerType = function(layer) { - if (layer.type) { - return layer.type; - } else { - switch (layer.source.type) { - case 'ImageWMS': - return 'Image'; - case 'ImageStatic': - return 'Image'; - case 'GeoJSON': - case 'JSONP': - case 'TopoJSON': - case 'KML': - case 'WKT': - return 'Vector'; - case 'TileVector': - case 'MVT': - return 'TileVector'; - default: - return 'Tile'; - } - } - }; - - var createProjection = function(view) { - var oProjection; - - switch (view.projection) { - case 'pixel': - if (!isDefined(view.extent)) { - $log.error('[AngularJS - Openlayers] - You must provide the extent of the image ' + - 'if using pixel projection'); - return; - } - oProjection = new ol.proj.Projection({ - code: 'pixel', - units: 'pixels', - extent: view.extent - }); - break; - default: - oProjection = new ol.proj.get(view.projection); - break; - } - - return oProjection; - }; - - var isValidStamenLayer = function(layer) { - return ['watercolor', 'terrain', 'toner'].indexOf(layer) !== -1; - }; - - var createSource = function(source, projection) { - var oSource; - var pixelRatio; - var url; - var geojsonFormat = new ol.format.GeoJSON(); // used in various switch stmnts below - - switch (source.type) { - case 'MapBox': - if (!source.mapId || !source.accessToken) { - $log.error('[AngularJS - Openlayers] - MapBox layer requires the map id and the access token'); - return; - } - url = 'https://api.tiles.mapbox.com/v4/' + source.mapId + '/{z}/{x}/{y}.png?access_token=' + - source.accessToken; - - pixelRatio = window.devicePixelRatio; - - if (pixelRatio > 1) { - url = url.replace('.png', '@2x.png'); - } - - oSource = new ol.source.XYZ({ - url: url, - tileLoadFunction: source.tileLoadFunction, - attributions: createAttribution(source), - tilePixelRatio: pixelRatio > 1 ? 2 : 1, - wrapX: source.wrapX !== undefined ? source.wrapX : true - }); - break; - case 'MapBoxStudio': - if (!source.mapId || !source.accessToken || !source.userId) { - $log.error('[AngularJS - Openlayers] - MapBox Studio layer requires the map id' + - ', user id and the access token'); - return; - } - url = 'https://api.mapbox.com/styles/v1/' + source.userId + - '/' + source.mapId + '/tiles/{z}/{x}/{y}?access_token=' + - source.accessToken; - - pixelRatio = window.devicePixelRatio; - - if (pixelRatio > 1) { - url = url.replace('{y}?access_token', '{y}@2x?access_token'); - } - - oSource = new ol.source.XYZ({ - url: url, - tileLoadFunction: source.tileLoadFunction, - attributions: createAttribution(source), - tilePixelRatio: pixelRatio > 1 ? 2 : 1, - tileSize: source.tileSize || [512, 512], - wrapX: source.wrapX !== undefined ? source.wrapX : true - }); - break; - case 'MVT': - if (!source.url) { - $log.error('[AngularJS - Openlayers] - MVT layer requires the source url'); - return; - } - oSource = new ol.source.VectorTile({ - attributions: source.attributions || '', - format: new ol.format.MVT(), - tileGrid: ol.tilegrid.createXYZ({maxZoom: source.maxZoom || 22}), - tilePixelRatio: source.tilePixelRatio || 16, - url: source.url - }); - break; - case 'ImageWMS': - if (!source.url || !source.params) { - $log.error('[AngularJS - Openlayers] - ImageWMS Layer needs ' + - 'valid server url and params properties'); - } - oSource = new ol.source.ImageWMS({ - url: source.url, - imageLoadFunction: source.imageLoadFunction, - attributions: createAttribution(source), - crossOrigin: (typeof source.crossOrigin === 'undefined') ? 'anonymous' : source.crossOrigin, - params: deepCopy(source.params), - ratio: source.ratio - }); - break; - - case 'TileWMS': - if ((!source.url && !source.urls) || !source.params) { - $log.error('[AngularJS - Openlayers] - TileWMS Layer needs ' + - 'valid url (or urls) and params properties'); - } - - var wmsConfiguration = { - tileLoadFunction: source.tileLoadFunction, - crossOrigin: (typeof source.crossOrigin === 'undefined') ? 'anonymous' : source.crossOrigin, - params: deepCopy(source.params), - attributions: createAttribution(source), - wrapX: source.wrapX !== undefined ? source.wrapX : true - }; - - if (source.projection) { - wmsConfiguration.projection = new ol.proj.get(source.projection); - } - - if (source.serverType) { - wmsConfiguration.serverType = source.serverType; - } - - if (source.url) { - wmsConfiguration.url = source.url; - } - - if (source.urls) { - wmsConfiguration.urls = source.urls; - } - - oSource = new ol.source.TileWMS(wmsConfiguration); - break; - - case 'WMTS': - if ((!source.url && !source.urls) || !source.tileGrid) { - $log.error('[AngularJS - Openlayers] - WMTS Layer needs valid url ' + - '(or urls) and tileGrid properties'); - } - - var wmtsConfiguration = { - tileLoadFunction: source.tileLoadFunction, - projection: projection, - layer: source.layer, - attributions: createAttribution(source), - matrixSet: (source.matrixSet === 'undefined') ? projection : source.matrixSet, - format: (source.format === 'undefined') ? 'image/jpeg' : source.format, - requestEncoding: (source.requestEncoding === 'undefined') ? - 'KVP' : source.requestEncoding, - tileGrid: new ol.tilegrid.WMTS({ - origin: source.tileGrid.origin, - resolutions: source.tileGrid.resolutions, - matrixIds: source.tileGrid.matrixIds - }), - style: (source.style === 'undefined') ? 'normal' : source.style, - wrapX: source.wrapX !== undefined ? source.wrapX : true - }; - - if (isDefined(source.url)) { - wmtsConfiguration.url = source.url; - } - - if (isDefined(source.urls)) { - wmtsConfiguration.urls = source.urls; - } - - oSource = new ol.source.WMTS(wmtsConfiguration); - break; - - case 'OSM': - oSource = new ol.source.OSM({ - tileLoadFunction: source.tileLoadFunction, - attributions: createAttribution(source), - wrapX: source.wrapX !== undefined ? source.wrapX : true - }); - - if (source.url) { - oSource.setUrl(source.url); - } - - break; - case 'BingMaps': - if (!source.key) { - $log.error('[AngularJS - Openlayers] - You need an API key to show the Bing Maps.'); - return; - } - - var bingConfiguration = { - key: source.key, - tileLoadFunction: source.tileLoadFunction, - attributions: createAttribution(source), - imagerySet: source.imagerySet ? source.imagerySet : bingImagerySets[0], - culture: source.culture, - wrapX: source.wrapX !== undefined ? source.wrapX : true - }; - - if (source.maxZoom) { - bingConfiguration.maxZoom = source.maxZoom; - } - - oSource = new ol.source.BingMaps(bingConfiguration); - break; - - case 'MapQuest': - if (!source.layer || mapQuestLayers.indexOf(source.layer) === -1) { - $log.error('[AngularJS - Openlayers] - MapQuest layers needs a valid \'layer\' property.'); - return; - } - - oSource = new ol.source.MapQuest({ - attributions: createAttribution(source), - layer: source.layer, - wrapX: source.wrapX !== undefined ? source.wrapX : true - }); - - break; - - case 'EsriBaseMaps': - if (!source.layer || esriBaseLayers.indexOf(source.layer) === -1) { - $log.error('[AngularJS - Openlayers] - ESRI layers needs a valid \'layer\' property.'); - return; - } - - var _urlBase = 'http://services.arcgisonline.com/ArcGIS/rest/services/'; - if (source.layer === 'World_Light_Gray_Base' || source.layer === 'World_Dark_Gray_Base') { - _urlBase = _urlBase + 'Canvas/'; - } - var _url = _urlBase + source.layer + '/MapServer/tile/{z}/{y}/{x}'; - - oSource = new ol.source.XYZ({ - attributions: createAttribution(source), - tileLoadFunction: source.tileLoadFunction, - url: _url, - wrapX: source.wrapX !== undefined ? source.wrapX : true - }); - - break; - - case 'TileArcGISRest': - if (!source.url) { - $log.error('[AngularJS - Openlayers] - TileArcGISRest Layer needs valid url'); - } - - oSource = new ol.source.TileArcGISRest({ - attributions: createAttribution(source), - tileLoadFunction: source.tileLoadFunction, - url: source.url, - wrapX: source.wrapX !== undefined ? source.wrapX : true - }); - - break; - - case 'GeoJSON': - if (!(source.geojson || source.url)) { - $log.error('[AngularJS - Openlayers] - You need a geojson ' + - 'property to add a GeoJSON layer.'); - return; - } - - if (isDefined(source.url)) { - oSource = new ol.source.Vector({ - format: new ol.format.GeoJSON(), - url: source.url - }); - } else { - oSource = new ol.source.Vector(); - - var projectionToUse = projection; - var dataProjection; // Projection of geojson data - if (isDefined(source.geojson.projection)) { - dataProjection = new ol.proj.get(source.geojson.projection); - } else { - dataProjection = projection; // If not defined, features will not be reprojected. - } - - var features = geojsonFormat.readFeatures( - source.geojson.object, { - featureProjection: projectionToUse.getCode(), - dataProjection: dataProjection.getCode() - }); - - oSource.addFeatures(features); - } - break; - case 'WKT': - if (!(source.wkt || source.url)) { - $log.error('[AngularJS - Openlayers] - You need a WKT ' + - 'property to add a GeoJSON layer.'); - return; - } - if (isDefined(source.url)) { - oSource = new ol.source.Vector({ - format: new ol.format.WKT(), - url: source.url, - wrapX: source.wrapX !== undefined ? source.wrapX : true - }); - } else { - oSource = new ol.source.Vector(); - var featureProjection = projection; - var wktProjection; - if (isDefined(source.wkt.projection)) { - wktProjection = new ol.proj.get(source.wkt.projection); - } else { - wktProjection = projection; - } - - var wktFormat = new ol.format.WKT(); - var wktFeatures = []; - for (var k = 0; k < source.wkt.object.length; k++) { - var feature = wktFormat.readFeature( - source.wkt.object[k].data, {dataProjection: wktProjection.getCode() , - featureProjection: featureProjection.getCode() }); - if (source.wkt.object[k].properties) { - feature.properties = source.wkt.object[k].properties; - } - wktFeatures.push(feature); - } - oSource.addFeatures(wktFeatures); - } - - break; - case 'JSONP': - if (!(source.url)) { - $log.error('[AngularJS - Openlayers] - You need an url properly configured to add a JSONP layer.'); - return; - } - - if (isDefined(source.url)) { - oSource = new ol.source.ServerVector({ - format: geojsonFormat, - loader: function(/*extent, resolution, projection*/) { - var url = source.url + - '&outputFormat=text/javascript&format_options=callback:JSON_CALLBACK'; - $http.jsonp(url, { cache: source.cache}) - .success(function(response) { - oSource.addFeatures(geojsonFormat.readFeatures(response)); - }) - .error(function(response) { - $log(response); - }); - }, - projection: projection - }); - } - break; - case 'TopoJSON': - if (!(source.topojson || source.url)) { - $log.error('[AngularJS - Openlayers] - You need a topojson ' + - 'property to add a TopoJSON layer.'); - return; - } - - if (source.url) { - oSource = new ol.source.Vector({ - format: new ol.format.TopoJSON(), - url: source.url - }); - } else { - oSource = new ol.source.Vector(angular.extend(source.topojson, { - format: new ol.format.TopoJSON() - })); - } - break; - case 'TileJSON': - oSource = new ol.source.TileJSON({ - url: source.url, - attributions: createAttribution(source), - tileLoadFunction: source.tileLoadFunction, - crossOrigin: 'anonymous', - wrapX: source.wrapX !== undefined ? source.wrapX : true - }); - break; - - case 'TileVector': - if (!source.url || !source.format) { - $log.error('[AngularJS - Openlayers] - TileVector Layer needs valid url and format properties'); - } - oSource = new ol.source.VectorTile({ - url: source.url, - projection: projection, - attributions: createAttribution(source), - tileLoadFunction: source.tileLoadFunction, - format: source.format, - tileGrid: new ol.tilegrid.createXYZ({ - maxZoom: source.maxZoom || 19 - }), - wrapX: source.wrapX !== undefined ? source.wrapX : true - }); - break; - - case 'TileTMS': - if (!source.url || !source.tileGrid) { - $log.error('[AngularJS - Openlayers] - TileTMS Layer needs valid url and tileGrid properties'); - } - oSource = new ol.source.TileImage({ - url: source.url, - maxExtent: source.maxExtent, - attributions: createAttribution(source), - tileLoadFunction: source.tileLoadFunction, - tileGrid: new ol.tilegrid.TileGrid({ - origin: source.tileGrid.origin, - resolutions: source.tileGrid.resolutions - }), - tileUrlFunction: function(tileCoord) { - - var z = tileCoord[0]; - var x = tileCoord[1]; - var y = tileCoord[2]; //(1 << z) - tileCoord[2] - 1; - - if (x < 0 || y < 0) { - return ''; - } - - var url = source.url + z + '/' + x + '/' + y + '.png'; - - return url; - }, - wrapX: source.wrapX !== undefined ? source.wrapX : true - }); - break; - case 'TileImage': - oSource = new ol.source.TileImage({ - url: source.url, - attributions: createAttribution(source), - tileLoadFunction: source.tileLoadFunction, - tileGrid: new ol.tilegrid.TileGrid({ - origin: source.tileGrid.origin, // top left corner of the pixel projection's extent - resolutions: source.tileGrid.resolutions - }), - tileUrlFunction: function(tileCoord/*, pixelRatio, projection*/) { - var z = tileCoord[0]; - var x = tileCoord[1]; - var y = -tileCoord[2] - 1; - var url = source.url - .replace('{z}', z.toString()) - .replace('{x}', x.toString()) - .replace('{y}', y.toString()); - return url; - }, - wrapX: source.wrapX !== undefined ? source.wrapX : true - }); - break; - case 'KML': - var extractStyles = source.extractStyles || false; - oSource = new ol.source.Vector({ - url: source.url, - format: new ol.format.KML({ - extractStyles: extractStyles - }), - radius: source.radius - }); - break; - case 'Stamen': - if (!source.layer || !isValidStamenLayer(source.layer)) { - $log.error('[AngularJS - Openlayers] - You need a valid Stamen layer.'); - return; - } - oSource = new ol.source.Stamen({ - tileLoadFunction: source.tileLoadFunction, - layer: source.layer, - wrapX: source.wrapX !== undefined ? source.wrapX : true - }); - break; - case 'ImageStatic': - if (!source.url || !angular.isArray(source.imageSize) || source.imageSize.length !== 2) { - $log.error('[AngularJS - Openlayers] - You need a image URL to create a ImageStatic layer.'); - return; - } - - oSource = new ol.source.ImageStatic({ - url: source.url, - attributions: createAttribution(source), - imageSize: source.imageSize, - projection: projection, - imageExtent: source.imageExtent ? source.imageExtent : projection.getExtent(), - imageLoadFunction: source.imageLoadFunction - }); - break; - case 'XYZ': - if (!source.url && !source.urls && !source.tileUrlFunction) { - $log.error('[AngularJS - Openlayers] - XYZ Layer needs valid urls or tileUrlFunction properties'); - } - oSource = new ol.source.XYZ({ - url: source.url, - urls: source.urls, - attributions: createAttribution(source), - minZoom: source.minZoom, - maxZoom: source.maxZoom, - projection: source.projection, - tileUrlFunction: source.tileUrlFunction, - tileLoadFunction: source.tileLoadFunction, - wrapX: source.wrapX !== undefined ? source.wrapX : true - }); - break; - case 'Zoomify': - if (!source.url || !angular.isArray(source.imageSize) || source.imageSize.length !== 2) { - $log.error('[AngularJS - Openlayers] - Zoomify Layer needs valid url and imageSize properties'); - } - oSource = new ol.source.Zoomify({ - url: source.url, - size: source.imageSize, - wrapX: source.wrapX !== undefined ? source.wrapX : true - }); - break; - } - - // log a warning when no source could be created for the given type - if (!oSource) { - $log.warn('[AngularJS - Openlayers] - No source could be found for type "' + source.type + '"'); - } - - return oSource; - }; - - var deepCopy = function(oldObj) { - var newObj = oldObj; - if (oldObj && typeof oldObj === 'object') { - newObj = Object.prototype.toString.call(oldObj) === '[object Array]' ? [] : {}; - for (var i in oldObj) { - newObj[i] = deepCopy(oldObj[i]); - } - } - return newObj; - }; - - var createAttribution = function(source) { - var attributions = []; - if (isDefined(source.attribution)) { - attributions.unshift(new ol.Attribution({html: source.attribution})); - } - return attributions; - }; - - var createGroup = function(name) { - var olGroup = new ol.layer.Group(); - olGroup.set('name', name); - - return olGroup; - }; - - var getGroup = function(layers, name) { - var layer; - - angular.forEach(layers, function(l) { - if (l instanceof ol.layer.Group && l.get('name') === name) { - layer = l; - return; - } - }); - - return layer; - }; - - var addLayerBeforeMarkers = function(layers, layer) { - var markersIndex; - for (var i = 0; i < layers.getLength(); i++) { - var l = layers.item(i); - - if (l.get('markers')) { - markersIndex = i; - break; - } - } - - if (isDefined(markersIndex)) { - var markers = layers.item(markersIndex); - layer.index = markersIndex; - layers.setAt(markersIndex, layer); - markers.index = layers.getLength(); - layers.push(markers); - } else { - layer.index = layers.getLength(); - layers.push(layer); - } - - }; - - var removeLayer = function(layers, index) { - layers.removeAt(index); - for (var i = index; i < layers.getLength(); i++) { - var l = layers.item(i); - if (l === null) { - layers.insertAt(i, null); - break; - } else { - l.index = i; - } - } - }; - - return { - // Determine if a reference is defined - isDefined: isDefined, - - // Determine if a reference is a number - isNumber: function(value) { - return angular.isNumber(value); - }, - - createView: function(view) { - var projection = createProjection(view); - - var viewConfig = { - projection: projection, - maxZoom: view.maxZoom, - minZoom: view.minZoom - }; - - if (view.center) { - viewConfig.center = view.center; - } - if (view.extent) { - viewConfig.extent = view.extent; - } - if (view.zoom) { - viewConfig.zoom = view.zoom; - } - if (view.resolutions) { - viewConfig.resolutions = view.resolutions; - } - - return new ol.View(viewConfig); - }, - - // Determine if a reference is defined and not null - isDefinedAndNotNull: isDefinedAndNotNull, - - // Determine if a reference is a string - isString: function(value) { - return angular.isString(value); - }, - - // Determine if a reference is an array - isArray: function(value) { - return angular.isArray(value); - }, - - // Determine if a reference is an object - isObject: function(value) { - return angular.isObject(value); - }, - - // Determine if two objects have the same properties - equals: function(o1, o2) { - return angular.equals(o1, o2); - }, - - isValidCenter: function(center) { - return angular.isDefined(center) && - (typeof center.autodiscover === 'boolean' || - angular.isNumber(center.lat) && angular.isNumber(center.lon) || - (angular.isArray(center.coord) && center.coord.length === 2 && - angular.isNumber(center.coord[0]) && angular.isNumber(center.coord[1])) || - (angular.isArray(center.bounds) && center.bounds.length === 4 && - angular.isNumber(center.bounds[0]) && angular.isNumber(center.bounds[1]) && - angular.isNumber(center.bounds[1]) && angular.isNumber(center.bounds[2]))); - }, - - safeApply: function($scope, fn) { - var phase = $scope.$root.$$phase; - if (phase === '$apply' || phase === '$digest') { - $scope.$eval(fn); - } else { - $scope.$apply(fn); - } - }, - - isSameCenterOnMap: function(center, map) { - var urlProj = center.projection || 'EPSG:4326'; - var urlCenter = [center.lon, center.lat]; - var mapProj = map.getView().getProjection(); - var mapCenter = ol.proj.transform(map.getView().getCenter(), mapProj, urlProj); - var zoom = map.getView().getZoom(); - if (mapCenter[1].toFixed(4) === urlCenter[1].toFixed(4) && - mapCenter[0].toFixed(4) === urlCenter[0].toFixed(4) && - zoom === center.zoom) { - return true; - } - return false; - }, - - setCenter: function(view, projection, newCenter, map) { - - if (map && view.getCenter()) { - var pan = ol.animation.pan({ - duration: 150, - source: (view.getCenter()) - }); - map.beforeRender(pan); - } - - if (newCenter.projection === projection) { - view.setCenter([newCenter.lon, newCenter.lat]); - } else { - var coord = [newCenter.lon, newCenter.lat]; - view.setCenter(ol.proj.transform(coord, newCenter.projection, projection)); - } - }, - - setZoom: function(view, zoom, map) { - var z = ol.animation.zoom({ - duration: 150, - resolution: map.getView().getResolution() - }); - map.beforeRender(z); - view.setZoom(zoom); - }, - - isBoolean: function(value) { - return typeof value === 'boolean'; - }, - - createStyle: createStyle, - - setMapEvents: function(events, map, scope) { - if (isDefined(events) && angular.isArray(events.map)) { - for (var i in events.map) { - var event = events.map[i]; - setEvent(map, event, scope); - } - } - }, - - setVectorLayerEvents: function(events, map, scope, layerName) { - if (isDefined(events) && angular.isArray(events.layers)) { - angular.forEach(events.layers, function(eventType) { - angular.element(map.getViewport()).on(eventType, function(evt) { - var pixel = map.getEventPixel(evt); - var feature = map.forEachFeatureAtPixel(pixel, function(feature, olLayer) { - // only return the feature if it is in this layer (based on the name) - return (isDefinedAndNotNull(olLayer) && olLayer.get('name') === layerName) ? feature : null; - }); - if (isDefinedAndNotNull(feature)) { - scope.$emit('openlayers.layers.' + layerName + '.' + eventType, feature, evt); - } - }); - }); - } - }, - - setViewEvents: function(events, map, scope) { - if (isDefined(events) && angular.isArray(events.view)) { - var view = map.getView(); - angular.forEach(events.view, function(eventType) { - view.on(eventType, function(event) { - scope.$emit('openlayers.view.' + eventType, view, event); - }); - }); - } - }, - - detectLayerType: detectLayerType, - - createLayer: function(layer, projection, name, onLayerCreatedFn) { - var oLayer; - var type = detectLayerType(layer); - var oSource = createSource(layer.source, projection); - if (!oSource) { - return; - } - - // handle function overloading. 'name' argument may be - // our onLayerCreateFn since name is optional - if (typeof(name) === 'function' && !onLayerCreatedFn) { - onLayerCreatedFn = name; - name = undefined; // reset, otherwise it'll be used later on - } - - // Manage clustering - if ((type === 'Vector') && layer.clustering) { - oSource = new ol.source.Cluster({ - source: oSource, - distance: layer.clusteringDistance - }); - } - - var layerConfig = {}; - - // copy over eventual properties set on the passed layerconfig which - // can later be retrieved via layer.get('propName'); - for (var property in layer) { - if (layer.hasOwnProperty(property) && - // ignore props like source or those angular might add (starting with $) - // don't use startsWith as it is not supported in IE - property.indexOf('$', 0) !== 0 && - property.indexOf('source', 0) !== 0 && - property.indexOf('style', 0) !== 0 - ) { - layerConfig[property] = layer[property]; - } - } - - layerConfig.source = oSource; - - // ol.layer.Layer configuration options - if (isDefinedAndNotNull(layer.opacity)) { - layerConfig.opacity = layer.opacity; - } - if (isDefinedAndNotNull(layer.visible)) { - layerConfig.visible = layer.visible; - } - if (isDefinedAndNotNull(layer.extent)) { - layerConfig.extent = layer.extent; - } - if (isDefinedAndNotNull(layer.zIndex)) { - layerConfig.zIndex = layer.zIndex; - } - if (isDefinedAndNotNull(layer.minResolution)) { - layerConfig.minResolution = layer.minResolution; - } - if (isDefinedAndNotNull(layer.maxResolution)) { - layerConfig.maxResolution = layer.maxResolution; - } - if (isDefinedAndNotNull(layer.style) && type === 'TileVector') { - layerConfig.style = layer.style; - } - - switch (type) { - case 'Image': - oLayer = new ol.layer.Image(layerConfig); - break; - case 'Tile': - oLayer = new ol.layer.Tile(layerConfig); - break; - case 'Heatmap': - oLayer = new ol.layer.Heatmap(layerConfig); - break; - case 'Vector': - oLayer = new ol.layer.Vector(layerConfig); - break; - case 'TileVector': - oLayer = new ol.layer.VectorTile(layerConfig); - break; - } - - // set a layer name if given - if (isDefined(name)) { - oLayer.set('name', name); - } else if (isDefined(layer.name)) { - oLayer.set('name', layer.name); - } - - // set custom layer properties if given - if (isDefined(layer.customAttributes)) { - for (var key in layer.customAttributes) { - oLayer.set(key, layer.customAttributes[key]); - } - } - - // invoke the onSourceCreated callback - if (onLayerCreatedFn) { - onLayerCreatedFn({ - oLayer: oLayer - }); - } - - return oLayer; - }, - - createVectorLayer: function() { - return new ol.layer.Vector({ - source: new ol.source.Vector() - }); - }, - - notifyCenterUrlHashChanged: function(scope, center, search) { - if (center.centerUrlHash) { - var centerUrlHash = center.lat.toFixed(4) + ':' + center.lon.toFixed(4) + ':' + center.zoom; - if (!isDefined(search.c) || search.c !== centerUrlHash) { - scope.$emit('centerUrlHash', centerUrlHash); - } - } - }, - - getControlClasses: getControlClasses, - - detectControls: function(controls) { - var actualControls = {}; - var controlClasses = getControlClasses(); - - controls.forEach(function(control) { - for (var i in controlClasses) { - if (control instanceof controlClasses[i]) { - actualControls[i] = control; - } - } - }); - - return actualControls; - }, - - createFeature: function(data, viewProjection) { - var geometry; - - switch (data.type) { - case 'Polygon': - geometry = new ol.geom.Polygon(data.coords); - break; - default: - if (isDefined(data.coord) && data.projection === 'pixel') { - geometry = new ol.geom.Point(data.coord); - } else { - geometry = new ol.geom.Point([data.lon, data.lat]); - } - break; - } - - if (isDefined(data.projection) && data.projection !== 'pixel') { - geometry = geometry.transform(data.projection, viewProjection); - } - - var feature = new ol.Feature({ - geometry: geometry - }); - - if (isDefined(data.style)) { - var style = createStyle(data.style); - feature.setStyle(style); - } - return feature; - }, - - addLayerBeforeMarkers: addLayerBeforeMarkers, - - getGroup: getGroup, - - addLayerToGroup: function(layers, layer, name) { - var groupLayer = getGroup(layers, name); - - if (!isDefined(groupLayer)) { - groupLayer = createGroup(name); - addLayerBeforeMarkers(layers, groupLayer); - } - - layer.set('group', name); - addLayerBeforeMarkers(groupLayer.getLayers(), layer); - }, - - removeLayerFromGroup: function(layers, layer, name) { - var groupLayer = getGroup(layers, name); - layer.set('group'); - removeLayer(groupLayer.getLayers(), layer.index); - }, - - removeLayer: removeLayer, - - insertLayer: function(layers, index, layer) { - if (layers.getLength() < index) { - // fill up with "null layers" till we get to the desired index - while (layers.getLength() < index) { - var nullLayer = new ol.layer.Image(); - nullLayer.index = layers.getLength(); // add index which will be equal to the length in this case - nullLayer.name = '(null-layer)'; // we need a marker somehow - layers.push(nullLayer); - } - layer.index = index; - layers.push(layer); - } else { - layer.index = index; - layers.insertAt(layer.index, layer); - - // remove eventual null layers - for (var i = index + 1; i < layers.getLength(); i++) { - var l = layers.item(i); - if (l.name === '(null-layer)') { - layers.removeAt(i); - break; - } else { - l.index = i; - } - } - } - }, - - createOverlay: function(element, pos) { - element.css('display', 'block'); - var ov = new ol.Overlay({ - position: pos, - element: element[0], - positioning: 'center-left' - }); - - return ov; - } - }; -}); - -angular.module('openlayers-directive').factory('olMapDefaults', function($q, olHelpers) { - - var base64icon = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAApCAYAAADAk4LOAAAGmklEQVRYw' + - '7VXeUyTZxjvNnfELFuyIzOabermMZEeQC/OclkO49CpOHXOLJl/CAURuYbQi3KLgEhbrhZ1aDwmaoGq' + - 'KII6odATmH/scDFbdC7LvFqOCc+e95s2VG50X/LLm/f4/Z7neY/ne18aANCmAr5E/xZf1uDOkTcGcWR' + - '6hl9247tT5U7Y6SNvWsKT63P58qbfeLJG8M5qcgTknrvvrdDbsT7Ml+tv82X6vVxJE33aRmgSyYtcWV' + - 'MqX97Yv2JvW39UhRE2HuyBL+t+gK1116ly06EeWFNlAmHxlQE0OMiV6mQCScusKRlhS3QLeVJdl1+23' + - 'h5dY4FNB3thrbYboqptEFlphTC1hSpJnbRvxP4NWgsE5Jyz86QNNi/5qSUTGuFk1gu54tN9wuK2wc3o' + - '+Wc13RCmsoBwEqzGcZsxsvCSy/9wJKf7UWf1mEY8JWfewc67UUoDbDjQC+FqK4QqLVMGGR9d2wurKzq' + - 'Bk3nqIT/9zLxRRjgZ9bqQgub+DdoeCC03Q8j+0QhFhBHR/eP3U/zCln7Uu+hihJ1+bBNffLIvmkyP0g' + - 'pBZWYXhKussK6mBz5HT6M1Nqpcp+mBCPXosYQfrekGvrjewd59/GvKCE7TbK/04/ZV5QZYVWmDwH1mF' + - '3xa2Q3ra3DBC5vBT1oP7PTj4C0+CcL8c7C2CtejqhuCnuIQHaKHzvcRfZpnylFfXsYJx3pNLwhKzRAw' + - 'AhEqG0SpusBHfAKkxw3w4627MPhoCH798z7s0ZnBJ/MEJbZSbXPhER2ih7p2ok/zSj2cEJDd4CAe+5W' + - 'YnBCgR2uruyEw6zRoW6/DWJ/OeAP8pd/BGtzOZKpG8oke0SX6GMmRk6GFlyAc59K32OTEinILRJRcha' + - 'h8HQwND8N435Z9Z0FY1EqtxUg+0SO6RJ/mmXz4VuS+DpxXC3gXmZwIL7dBSH4zKE50wESf8qwVgrP1E' + - 'IlTO5JP9Igu0aexdh28F1lmAEGJGfh7jE6ElyM5Rw/FDcYJjWhbeiBYoYNIpc2FT/SILivp0F1ipDWk' + - '4BIEo2VuodEJUifhbiltnNBIXPUFCMpthtAyqws/BPlEF/VbaIxErdxPphsU7rcCp8DohC+GvBIPJS/' + - 'tW2jtvTmmAeuNO8BNOYQeG8G/2OzCJ3q+soYB5i6NhMaKr17FSal7GIHheuV3uSCY8qYVuEm1cOzqdW' + - 'r7ku/R0BDoTT+DT+ohCM6/CCvKLKO4RI+dXPeAuaMqksaKrZ7L3FE5FIFbkIceeOZ2OcHO6wIhTkNo0' + - 'ffgjRGxEqogXHYUPHfWAC/lADpwGcLRY3aeK4/oRGCKYcZXPVoeX/kelVYY8dUGf8V5EBRbgJXT5QIP' + - 'hP9ePJi428JKOiEYhYXFBqou2Guh+p/mEB1/RfMw6rY7cxcjTrneI1FrDyuzUSRm9miwEJx8E/gUmql' + - 'yvHGkneiwErR21F3tNOK5Tf0yXaT+O7DgCvALTUBXdM4YhC/IawPU+2PduqMvuaR6eoxSwUk75ggqsY' + - 'J7VicsnwGIkZBSXKOUww73WGXyqP+J2/b9c+gi1YAg/xpwck3gJuucNrh5JvDPvQr0WFXf0piyt8f8/' + - 'WI0hV4pRxxkQZdJDfDJNOAmM0Ag8jyT6hz0WGXWuP94Yh2jcfjmXAGvHCMslRimDHYuHuDsy2QtHuIa' + - 'vznhbYURq5R57KpzBBRZKPJi8eQg48h4j8SDdowifdIrEVdU+gbO6QNvRRt4ZBthUaZhUnjlYObNagV' + - '3keoeru3rU7rcuceqU1mJBxy+BWZYlNEBH+0eH4vRiB+OYybU2hnblYlTvkHinM4m54YnxSyaZYSF6R' + - '3jwgP7udKLGIX6r/lbNa9N6y5MFynjWDtrHd75ZvTYAPO/6RgF0k76mQla3FGq7dO+cH8sKn0Vo7nDl' + - 'lwAhqwLPkxrHwWmHJOo+AKJ4rab5OgrM7rVu8eWb2Pu0Dh4eDgXoOfvp7Y7QeqknRmvcTBEyq9m/HQQ' + - 'SCSz6LHq3z0yzsNySRfMS253wl2KyRDbcZPcfJKjZmSEOjcxyi+Y8dUOtsIEH6R2wNykdqrkYJ0RV92' + - 'H0W58pkfQk7cKevsLK10Py8SdMGfXNXATY+pPbyJR/ET6n9nIfztNtZYRV9XniQu9IA2vOVgy4ir7GC' + - 'LVmmd+zjkH0eAF9Po6K61pmCXHxU5rHMYd1ftc3owjwRSVRzLjKvqZEty6cRUD7jGqiOdu5HG6MdHjN' + - 'cNYGqfDm5YRzLBBCCDl/2bk8a8gdbqcfwECu62Fg/HrggAAAABJRU5ErkJggg=='; - - var _getDefaults = function() { - return { - view: { - projection: 'EPSG:3857', - minZoom: undefined, - maxZoom: undefined, - rotation: 0, - extent: undefined - }, - center: { - lat: 0, - lon: 0, - zoom: 1, - autodiscover: false, - bounds: [], - centerUrlHash: false, - projection: 'EPSG:4326' - }, - styles: { - path: { - stroke: { - color: 'blue', - width: 8 - } - }, - marker: { - image: new ol.style.Icon({ - anchor: [0.5, 1], - anchorXUnits: 'fraction', - anchorYUnits: 'fraction', - opacity: 0.90, - src: base64icon - }) - } - }, - events: { - map: [], - markers: [], - layers: [] - }, - controls: { - attribution: true, - rotate: false, - zoom: true - }, - interactions: { - mouseWheelZoom: false - }, - renderer: 'canvas' - }; - }; - - var isDefined = olHelpers.isDefined; - var defaults = {}; - - // Get the _defaults dictionary, and override the properties defined by the user - return { - getDefaults: function(scope) { - if (!isDefined(scope)) { - for (var i in defaults) { - return defaults[i]; - } - } - return defaults[scope.$id]; - }, - - setDefaults: function(scope) { - var userDefaults = scope.defaults; - var scopeId = scope.$id; - var newDefaults = _getDefaults(); - - if (isDefined(userDefaults)) { - - if (isDefined(userDefaults.layers)) { - newDefaults.layers = angular.copy(userDefaults.layers); - } - - if (isDefined(userDefaults.controls)) { - newDefaults.controls = angular.copy(userDefaults.controls); - } - - if (isDefined(userDefaults.events)) { - newDefaults.events = angular.copy(userDefaults.events); - } - - if (isDefined(userDefaults.interactions)) { - newDefaults.interactions = angular.copy(userDefaults.interactions); - } - - if (isDefined(userDefaults.renderer)) { - newDefaults.renderer = userDefaults.renderer; - } - - if (isDefined(userDefaults.view)) { - newDefaults.view.maxZoom = userDefaults.view.maxZoom || newDefaults.view.maxZoom; - newDefaults.view.minZoom = userDefaults.view.minZoom || newDefaults.view.minZoom; - newDefaults.view.projection = userDefaults.view.projection || newDefaults.view.projection; - newDefaults.view.extent = userDefaults.view.extent || newDefaults.view.extent; - newDefaults.view.resolutions = userDefaults.view.resolutions || newDefaults.view.resolutions; - } - - if (isDefined(userDefaults.styles)) { - newDefaults.styles = angular.extend(newDefaults.styles, userDefaults.styles); - } - - if (isDefined(userDefaults.loadTilesWhileAnimating)) { - newDefaults.loadTilesWhileAnimating = userDefaults.loadTilesWhileAnimating; - } - - if (isDefined(userDefaults.loadTilesWhileInteracting)) { - newDefaults.loadTilesWhileInteracting = userDefaults.loadTilesWhileInteracting; - } - } - - defaults[scopeId] = newDefaults; - return newDefaults; - } - }; -}); -return angular.module('openlayers-directive'); -})); \ No newline at end of file From 255a25619bc5d60b31609a5c48ac0a1fd7b1a922 Mon Sep 17 00:00:00 2001 From: Sathish Kesavaperumal Date: Wed, 7 Mar 2018 15:47:04 +0530 Subject: [PATCH 45/53] Synced concat.js file --- grunt/concat.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/grunt/concat.js b/grunt/concat.js index a0aaa9c0..31e34c2f 100644 --- a/grunt/concat.js +++ b/grunt/concat.js @@ -3,8 +3,7 @@ var banner = '(function (root, factory) {\n' + ' if (typeof require === \'function\' && typeof exports === \'object\') {\n' + ' // CommonJS\n' + - ' var ol = require(\'openlayers-prebuilt\');\n' + - ' var ngSanitize = require(\'angular-sanitize\');\n' + + ' var ol = require(\'openlayers\');\n' + ' exports.angularOpenlayersDirective = factory(ol);\n' + ' } else if (typeof define === \'function\' && define.amd) {\n' + ' // AMD.\n' + @@ -16,15 +15,13 @@ var banner = '(function (root, factory) {\n' + ' root.angularOpenlayersDirective = factory(root.ol);\n' + ' }\n' + '}(this, function (ol) {\n'; -var footer = 'return angular.module(\'openlayers-directive\');' + - '\n}));'; module.exports = function (grunt, options) { return { dist: { options: { banner: banner, - footer: footer + footer: '\n}));' }, src: [ 'src/directives/openlayers.js', From 4674a1b0260a3617eabf79a500b8f685fc76b2ad Mon Sep 17 00:00:00 2001 From: Sathish Kesavaperumal Date: Wed, 7 Mar 2018 15:49:19 +0530 Subject: [PATCH 46/53] Sycned CONTRIBUTING.md file --- CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6935b503..6524ac4e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -129,7 +129,7 @@ Once you have the development dependencies installed, we can use our predefined * **grunt test**. Executes the karma unitary tests and the protractor e2e tests, reporting the actual state of the project. * **grunt test:unit**. Executes only the karma unitary tests. * **grunt test:e2e**. Executes only the protractor e2e tests. -* **grunt coverage**. Generates a "coverage" folder with an [istanbul](https://github.com/gotwarlost/istanbul) report of which part of the code is covered by the actual tests. +* **grunt coverage**. Generates a "coverage" folder with an [istanbul](https://github.com/gotwarlost/istanbul) report of wich part of the code is covered by the actual tests. * **grunt**. The default task watches for project files changes and when a change is detected, tries to build the library file passing the jshint filter and the tests. Let's see an example: ``` @@ -150,7 +150,7 @@ Running "jshint:grunt" (jshint) task Running "concat:dist" (concat) task File "dist/angular-openlayers-directive.js" created. -Running "ngAnnotate" (ngAnnotate) task +Running "ngmin:directives" (ngmin) task ngminifying dist/angular-openlayers-directive.js Running "uglify:dist" (uglify) task From 17e28975107611947cbf10800a33337c5806ed7e Mon Sep 17 00:00:00 2001 From: Sathish Kesavaperumal Date: Wed, 7 Mar 2018 15:55:33 +0530 Subject: [PATCH 47/53] Synced olHelpers.js file --- src/services/olHelpers.js | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/services/olHelpers.js b/src/services/olHelpers.js index 36ab2a58..d10ffd1a 100644 --- a/src/services/olHelpers.js +++ b/src/services/olHelpers.js @@ -51,8 +51,7 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ var esriBaseLayers = ['World_Imagery', 'World_Street_Map', 'World_Topo_Map', 'World_Physical_Map', 'World_Terrain_Base', - 'Ocean_Basemap', 'NatGeo_World_Map', - 'World_Light_Gray_Base', 'World_Dark_Gray_Base']; + 'Ocean_Basemap', 'NatGeo_World_Map']; var styleMap = { 'style': ol.style.Style, @@ -396,9 +395,6 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ } var _urlBase = 'https://services.arcgisonline.com/ArcGIS/rest/services/'; - if (source.layer === 'World_Light_Gray_Base' || source.layer === 'World_Dark_Gray_Base') { - _urlBase = _urlBase + 'Canvas/'; - } var _url = _urlBase + source.layer + '/MapServer/tile/{z}/{y}/{x}'; oSource = new ol.source.XYZ({ @@ -618,10 +614,9 @@ angular.module('openlayers-directive').factory('olHelpers', function($q, $log, $ var extractStyles = source.extractStyles || false; oSource = new ol.source.Vector({ url: source.url, - format: new ol.format.KML({ - extractStyles: extractStyles - }), - radius: source.radius + format: new ol.format.KML(), + radius: source.radius, + extractStyles: extractStyles }); break; case 'Stamen': From 0e26d843db92bbcf8f48283bde6f251a225a3493 Mon Sep 17 00:00:00 2001 From: Sathish Kesavaperumal Date: Thu, 8 Mar 2018 14:51:47 +0530 Subject: [PATCH 48/53] ES6 support for Angular module --- dist/angular-openlayers-directive.js | 2 +- dist/angular-openlayers-directive.min.js | 6 +++--- dist/angular-openlayers-directive.min.no-header.js | 6 +++--- dist/angular-openlayers-directive.pre.js | 2 +- grunt/concat.js | 5 ++++- 5 files changed, 12 insertions(+), 9 deletions(-) diff --git a/dist/angular-openlayers-directive.js b/dist/angular-openlayers-directive.js index 39f3a712..d612617a 100644 --- a/dist/angular-openlayers-directive.js +++ b/dist/angular-openlayers-directive.js @@ -2593,5 +2593,5 @@ angular.module('openlayers-directive').factory('olMapDefaults', ["$q", "olHelper } }; }]); - +return angular.module('openlayers-directive'); })); \ No newline at end of file diff --git a/dist/angular-openlayers-directive.min.js b/dist/angular-openlayers-directive.min.js index 2528bb86..49411d41 100644 --- a/dist/angular-openlayers-directive.min.js +++ b/dist/angular-openlayers-directive.min.js @@ -27,6 +27,6 @@ * @authors https://github.com/tombatossals/angular-openlayers-directive/graphs/contributors */ -/*! angular-openlayers-directive 07-03-2018 */ -!function(a,b){if("function"==typeof require&&"object"==typeof exports){var c=require("openlayers");exports.angularOpenlayersDirective=b(c)}else"function"==typeof define&&define.amd?define(["ol"],function(c){return a.angularOpenlayersDirective=b(c)}):a.angularOpenlayersDirective=b(a.ol)}(this,function(a){angular.module("openlayers-directive",["ngSanitize"]).directive("openlayers",["$log","$q","$compile","olHelpers","olMapDefaults","olData",function(b,c,d,e,f,g){return{restrict:"EA",transclude:!0,replace:!0,scope:{center:"=olCenter",defaults:"=olDefaults",view:"=olView",events:"=olEvents"},template:'
',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id),q.setTarget(null),q=null}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);if(!0===s.centerUrlHash){var t=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t(),r.$on("$locationChangeSuccess",function(){var a=t();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var u;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return u||(u=new a.Geolocation({projection:a.proj.get(c.projection)}),u.on("change",function(){if(c.autodiscover){var a=u.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,u.setTracking(!1)})}})),void u.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}});var v=f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})});r.$on("$destroy",function(){a.Observable.unByKey(v)})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),g(e)&&n(c.visible)&&(c.visible!==e.visible||z(d)||d.getVisible()!==c.visible)&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(b,c,d,e,f){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(b,c,d,g){var h=g.getOpenlayersScope(),i=f.isNumber,j=f.safeApply,k=f.createView;h.getMap().then(function(b){var c=e.getDefaults(h),d=h.view;d.projection||(d.projection=c.view.projection),d.maxZoom||(d.maxZoom=c.view.maxZoom),d.minZoom||(d.minZoom=c.view.minZoom),d.rotation||(d.rotation=c.view.rotation);var f=k(d);b.setView(f),h.$watchCollection("view",function(a){i(a.rotation)&&f.setRotation(a.rotation)});var g=f.on("change:rotation",function(){j(h,function(a){a.view.rotation=b.getView().getRotation()})});h.$on("$destroy",function(){a.Observable.unByKey(g)})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope(),j=e.getControlClasses,k=j();i.getMap().then(function(b){function d(a){a&&a.control?(f&&b.removeControl(f),f=a.control,b.addControl(f)):c.name&&(h(a)&&(g=a),f&&b.removeControl(f),f=new k[c.name](g),b.addControl(f))}a.$on("$destroy",function(){b.removeControl(f)}),a.$watch("properties",function(a){h(a)&&d(a)}),d(a.properties)})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e].markerLayer,delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(){c.properties&&(e.getViewport().removeEventListener("mousemove",c.properties.handleInteraction),e.getViewport().removeEventListener("click",c.properties.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",c.properties.handleTapInteraction),e.getViewport().removeEventListener("mousemove",c.properties.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",c.properties.removeAllOverlays),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",c.properties.activateCooldown))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;if(c.handleDrag=function(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(!(x=g?g.get("marker"):null)||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))},e.on("pointerdown",c.handleDrag),e.on("pointerup",c.handleDrag),e.on("pointerdrag",c.handleDrag),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e),e.un("pointerdown",c.handleDrag),e.un("pointerup",c.handleDrag),e.un("pointerdrag",c.handleDrag),j()}),!k(c.properties))return t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p)));c.$watch("properties",function(d){if(j(),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){var a,b=!1;return d.activateCooldown=function(){b=!0,a&&clearTimeout(a),a=setTimeout(function(){b=!1,a=null},500)},d.activateCooldown&&e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",d.activateCooldown),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",d.activateCooldown),function(){b||(d.handleInteraction.apply(null,arguments),d.activateCooldown())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&!0===d.label.show&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&!1===d.label.show&&(e.removeOverlay(p),p=void 0),d.label&&!1===d.label.show&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&!1===d.label.show&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&!1===d.label.show&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0)})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){a[c(a,b)].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&!0!==a[f].resolvedDefer?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d=c(a,b);return angular.isDefined(a[d])&&!1!==a[d].resolvedDefer?a[d].defer:f(a,b)};this.setMap=function(a,b){f(d,b).resolve(a),e(d,b)},this.getMap=function(a){return g(d,a).promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function a(b,c){var d;if(c?d=b[c]:(c="style",d=b),"style"===c&&b instanceof Function)return b;if(!(d instanceof Object))return d;var e;if("[object Object]"===Object.prototype.toString.call(d)){e={};var f=l[c];if(f&&d instanceof f)return d;Object.getOwnPropertyNames(d).forEach(function(b,g,h){var i=l[b];if(f&&i&&i.prototype instanceof l[c])return console.assert(1===h.length,"Extra parameters for "+c),e=a(d,b),m(e,i);e[b]=a(d,b),"text"!==b&&"string"!=typeof e[b]&&(e[b]=m(e[b],l[b]))})}else e=d;return m(e,l[c])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":return"Vector";case"TileVector":case"MVT":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g,i,l,m=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");l="https://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace(".png","@2x.png")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,wrapX:void 0===b.wrapX||b.wrapX});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");l="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace("{y}?access_token","{y}@2x?access_token")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,tileSize:b.tileSize||[512,512],wrapX:void 0===b.wrapX||b.wrapX});break;case"MVT":if(!b.url)return void c.error("[AngularJS - Openlayers] - MVT layer requires the source url");g=new a.source.VectorTile({attributions:b.attributions||"",format:new a.format.MVT,tileGrid:a.tilegrid.createXYZ({maxZoom:b.maxZoom||22}),tilePixelRatio:b.tilePixelRatio||16,url:b.url});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,imageLoadFunction:b.imageLoadFunction,attributions:t(b),crossOrigin:void 0===b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={tileLoadFunction:b.tileLoadFunction,crossOrigin:void 0===b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX};b.projection&&(n.projection=new a.proj.get(b.projection)),b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={tileLoadFunction:b.tileLoadFunction,projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),style:"undefined"===b.style?"normal":b.style,wrapX:void 0===b.wrapX||b.wrapX};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({tileLoadFunction:b.tileLoadFunction,attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,tileLoadFunction:b.tileLoadFunction,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX||b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer,wrapX:void 0===b.wrapX||b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="https://services.arcgisonline.com/ArcGIS/rest/services/",u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:u,wrapX:void 0===b.wrapX||b.wrapX});break;case"TileArcGISRest":b.url||c.error("[AngularJS - Openlayers] - TileArcGISRest Layer needs valid url"),g=new a.source.TileArcGISRest({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=m.readFeatures(b.geojson.object,{featureProjection:w.getCode(),dataProjection:v.getCode()});g.addFeatures(x)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});else{g=new a.source.Vector;var y,z=f;y=e(b.wkt.projection)?new a.proj.get(b.wkt.projection):f;for(var A=new a.format.WKT,B=[],C=0;C-1)return a.source[b.type][d]}return null},v=function(b){var c=new a.layer.Group;return c.set("name",b),c},w=function(b,c){var d;return angular.forEach(b,function(b){if(b instanceof a.layer.Group&&b.get("name")===c)return void(d=b)}),d},x=function(a,b){for(var c,d=0;d',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id),q.setTarget(null),q=null}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);if(!0===s.centerUrlHash){var t=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t(),r.$on("$locationChangeSuccess",function(){var a=t();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var u;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return u||(u=new a.Geolocation({projection:a.proj.get(c.projection)}),u.on("change",function(){if(c.autodiscover){var a=u.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,u.setTracking(!1)})}})),void u.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}});var v=f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})});r.$on("$destroy",function(){a.Observable.unByKey(v)})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),g(e)&&n(c.visible)&&(c.visible!==e.visible||z(d)||d.getVisible()!==c.visible)&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(b,c,d,e,f){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(b,c,d,g){var h=g.getOpenlayersScope(),i=f.isNumber,j=f.safeApply,k=f.createView;h.getMap().then(function(b){var c=e.getDefaults(h),d=h.view;d.projection||(d.projection=c.view.projection),d.maxZoom||(d.maxZoom=c.view.maxZoom),d.minZoom||(d.minZoom=c.view.minZoom),d.rotation||(d.rotation=c.view.rotation);var f=k(d);b.setView(f),h.$watchCollection("view",function(a){i(a.rotation)&&f.setRotation(a.rotation)});var g=f.on("change:rotation",function(){j(h,function(a){a.view.rotation=b.getView().getRotation()})});h.$on("$destroy",function(){a.Observable.unByKey(g)})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope(),j=e.getControlClasses,k=j();i.getMap().then(function(b){function d(a){a&&a.control?(f&&b.removeControl(f),f=a.control,b.addControl(f)):c.name&&(h(a)&&(g=a),f&&b.removeControl(f),f=new k[c.name](g),b.addControl(f))}a.$on("$destroy",function(){b.removeControl(f)}),a.$watch("properties",function(a){h(a)&&d(a)}),d(a.properties)})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e].markerLayer,delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(){c.properties&&(e.getViewport().removeEventListener("mousemove",c.properties.handleInteraction),e.getViewport().removeEventListener("click",c.properties.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",c.properties.handleTapInteraction),e.getViewport().removeEventListener("mousemove",c.properties.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",c.properties.removeAllOverlays),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",c.properties.activateCooldown))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;if(c.handleDrag=function(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(!(x=g?g.get("marker"):null)||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))},e.on("pointerdown",c.handleDrag),e.on("pointerup",c.handleDrag),e.on("pointerdrag",c.handleDrag),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e),e.un("pointerdown",c.handleDrag),e.un("pointerup",c.handleDrag),e.un("pointerdrag",c.handleDrag),j()}),!k(c.properties))return t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p)));c.$watch("properties",function(d){if(j(),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){var a,b=!1;return d.activateCooldown=function(){b=!0,a&&clearTimeout(a),a=setTimeout(function(){b=!1,a=null},500)},d.activateCooldown&&e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",d.activateCooldown),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",d.activateCooldown),function(){b||(d.handleInteraction.apply(null,arguments),d.activateCooldown())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&!0===d.label.show&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&!1===d.label.show&&(e.removeOverlay(p),p=void 0),d.label&&!1===d.label.show&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&!1===d.label.show&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&!1===d.label.show&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0)})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){a[c(a,b)].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&!0!==a[f].resolvedDefer?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d=c(a,b);return angular.isDefined(a[d])&&!1!==a[d].resolvedDefer?a[d].defer:f(a,b)};this.setMap=function(a,b){f(d,b).resolve(a),e(d,b)},this.getMap=function(a){return g(d,a).promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function a(b,c){var d;if(c?d=b[c]:(c="style",d=b),"style"===c&&b instanceof Function)return b;if(!(d instanceof Object))return d;var e;if("[object Object]"===Object.prototype.toString.call(d)){e={};var f=l[c];if(f&&d instanceof f)return d;Object.getOwnPropertyNames(d).forEach(function(b,g,h){var i=l[b];if(f&&i&&i.prototype instanceof l[c])return console.assert(1===h.length,"Extra parameters for "+c),e=a(d,b),m(e,i);e[b]=a(d,b),"text"!==b&&"string"!=typeof e[b]&&(e[b]=m(e[b],l[b]))})}else e=d;return m(e,l[c])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":return"Vector";case"TileVector":case"MVT":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g,i,l,m=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");l="https://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace(".png","@2x.png")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,wrapX:void 0===b.wrapX||b.wrapX});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");l="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace("{y}?access_token","{y}@2x?access_token")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,tileSize:b.tileSize||[512,512],wrapX:void 0===b.wrapX||b.wrapX});break;case"MVT":if(!b.url)return void c.error("[AngularJS - Openlayers] - MVT layer requires the source url");g=new a.source.VectorTile({attributions:b.attributions||"",format:new a.format.MVT,tileGrid:a.tilegrid.createXYZ({maxZoom:b.maxZoom||22}),tilePixelRatio:b.tilePixelRatio||16,url:b.url});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,imageLoadFunction:b.imageLoadFunction,attributions:t(b),crossOrigin:void 0===b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={tileLoadFunction:b.tileLoadFunction,crossOrigin:void 0===b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX};b.projection&&(n.projection=new a.proj.get(b.projection)),b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={tileLoadFunction:b.tileLoadFunction,projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),style:"undefined"===b.style?"normal":b.style,wrapX:void 0===b.wrapX||b.wrapX};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({tileLoadFunction:b.tileLoadFunction,attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,tileLoadFunction:b.tileLoadFunction,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX||b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer,wrapX:void 0===b.wrapX||b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="https://services.arcgisonline.com/ArcGIS/rest/services/",u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:u,wrapX:void 0===b.wrapX||b.wrapX});break;case"TileArcGISRest":b.url||c.error("[AngularJS - Openlayers] - TileArcGISRest Layer needs valid url"),g=new a.source.TileArcGISRest({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=m.readFeatures(b.geojson.object,{featureProjection:w.getCode(),dataProjection:v.getCode()});g.addFeatures(x)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});else{g=new a.source.Vector;var y,z=f;y=e(b.wkt.projection)?new a.proj.get(b.wkt.projection):f;for(var A=new a.format.WKT,B=[],C=0;C-1)return a.source[b.type][d]}return null},v=function(b){var c=new a.layer.Group;return c.set("name",b),c},w=function(b,c){var d;return angular.forEach(b,function(b){if(b instanceof a.layer.Group&&b.get("name")===c)return void(d=b)}),d},x=function(a,b){for(var c,d=0;d',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id),q.setTarget(null),q=null}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);if(!0===s.centerUrlHash){var t=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t(),r.$on("$locationChangeSuccess",function(){var a=t();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var u;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return u||(u=new a.Geolocation({projection:a.proj.get(c.projection)}),u.on("change",function(){if(c.autodiscover){var a=u.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,u.setTracking(!1)})}})),void u.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}});var v=f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})});r.$on("$destroy",function(){a.Observable.unByKey(v)})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),g(e)&&n(c.visible)&&(c.visible!==e.visible||z(d)||d.getVisible()!==c.visible)&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(b,c,d,e,f){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(b,c,d,g){var h=g.getOpenlayersScope(),i=f.isNumber,j=f.safeApply,k=f.createView;h.getMap().then(function(b){var c=e.getDefaults(h),d=h.view;d.projection||(d.projection=c.view.projection),d.maxZoom||(d.maxZoom=c.view.maxZoom),d.minZoom||(d.minZoom=c.view.minZoom),d.rotation||(d.rotation=c.view.rotation);var f=k(d);b.setView(f),h.$watchCollection("view",function(a){i(a.rotation)&&f.setRotation(a.rotation)});var g=f.on("change:rotation",function(){j(h,function(a){a.view.rotation=b.getView().getRotation()})});h.$on("$destroy",function(){a.Observable.unByKey(g)})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope(),j=e.getControlClasses,k=j();i.getMap().then(function(b){function d(a){a&&a.control?(f&&b.removeControl(f),f=a.control,b.addControl(f)):c.name&&(h(a)&&(g=a),f&&b.removeControl(f),f=new k[c.name](g),b.addControl(f))}a.$on("$destroy",function(){b.removeControl(f)}),a.$watch("properties",function(a){h(a)&&d(a)}),d(a.properties)})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e].markerLayer,delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(){c.properties&&(e.getViewport().removeEventListener("mousemove",c.properties.handleInteraction),e.getViewport().removeEventListener("click",c.properties.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",c.properties.handleTapInteraction),e.getViewport().removeEventListener("mousemove",c.properties.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",c.properties.removeAllOverlays),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",c.properties.activateCooldown))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;if(c.handleDrag=function(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(!(x=g?g.get("marker"):null)||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))},e.on("pointerdown",c.handleDrag),e.on("pointerup",c.handleDrag),e.on("pointerdrag",c.handleDrag),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e),e.un("pointerdown",c.handleDrag),e.un("pointerup",c.handleDrag),e.un("pointerdrag",c.handleDrag),j()}),!k(c.properties))return t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p)));c.$watch("properties",function(d){if(j(),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){var a,b=!1;return d.activateCooldown=function(){b=!0,a&&clearTimeout(a),a=setTimeout(function(){b=!1,a=null},500)},d.activateCooldown&&e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",d.activateCooldown),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",d.activateCooldown),function(){b||(d.handleInteraction.apply(null,arguments),d.activateCooldown())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&!0===d.label.show&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&!1===d.label.show&&(e.removeOverlay(p),p=void 0),d.label&&!1===d.label.show&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&!1===d.label.show&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&!1===d.label.show&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0)})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){a[c(a,b)].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&!0!==a[f].resolvedDefer?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d=c(a,b);return angular.isDefined(a[d])&&!1!==a[d].resolvedDefer?a[d].defer:f(a,b)};this.setMap=function(a,b){f(d,b).resolve(a),e(d,b)},this.getMap=function(a){return g(d,a).promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function a(b,c){var d;if(c?d=b[c]:(c="style",d=b),"style"===c&&b instanceof Function)return b;if(!(d instanceof Object))return d;var e;if("[object Object]"===Object.prototype.toString.call(d)){e={};var f=l[c];if(f&&d instanceof f)return d;Object.getOwnPropertyNames(d).forEach(function(b,g,h){var i=l[b];if(f&&i&&i.prototype instanceof l[c])return console.assert(1===h.length,"Extra parameters for "+c),e=a(d,b),m(e,i);e[b]=a(d,b),"text"!==b&&"string"!=typeof e[b]&&(e[b]=m(e[b],l[b]))})}else e=d;return m(e,l[c])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":return"Vector";case"TileVector":case"MVT":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g,i,l,m=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");l="https://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace(".png","@2x.png")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,wrapX:void 0===b.wrapX||b.wrapX});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");l="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace("{y}?access_token","{y}@2x?access_token")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,tileSize:b.tileSize||[512,512],wrapX:void 0===b.wrapX||b.wrapX});break;case"MVT":if(!b.url)return void c.error("[AngularJS - Openlayers] - MVT layer requires the source url");g=new a.source.VectorTile({attributions:b.attributions||"",format:new a.format.MVT,tileGrid:a.tilegrid.createXYZ({maxZoom:b.maxZoom||22}),tilePixelRatio:b.tilePixelRatio||16,url:b.url});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,imageLoadFunction:b.imageLoadFunction,attributions:t(b),crossOrigin:void 0===b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={tileLoadFunction:b.tileLoadFunction,crossOrigin:void 0===b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX};b.projection&&(n.projection=new a.proj.get(b.projection)),b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={tileLoadFunction:b.tileLoadFunction,projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),style:"undefined"===b.style?"normal":b.style,wrapX:void 0===b.wrapX||b.wrapX};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({tileLoadFunction:b.tileLoadFunction,attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,tileLoadFunction:b.tileLoadFunction,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX||b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer,wrapX:void 0===b.wrapX||b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="https://services.arcgisonline.com/ArcGIS/rest/services/",u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:u,wrapX:void 0===b.wrapX||b.wrapX});break;case"TileArcGISRest":b.url||c.error("[AngularJS - Openlayers] - TileArcGISRest Layer needs valid url"),g=new a.source.TileArcGISRest({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=m.readFeatures(b.geojson.object,{featureProjection:w.getCode(),dataProjection:v.getCode()});g.addFeatures(x)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});else{g=new a.source.Vector;var y,z=f;y=e(b.wkt.projection)?new a.proj.get(b.wkt.projection):f;for(var A=new a.format.WKT,B=[],C=0;C-1)return a.source[b.type][d]}return null},v=function(b){var c=new a.layer.Group;return c.set("name",b),c},w=function(b,c){var d;return angular.forEach(b,function(b){if(b instanceof a.layer.Group&&b.get("name")===c)return void(d=b)}),d},x=function(a,b){for(var c,d=0;d',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id),q.setTarget(null),q=null}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);if(!0===s.centerUrlHash){var t=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t(),r.$on("$locationChangeSuccess",function(){var a=t();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var u;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return u||(u=new a.Geolocation({projection:a.proj.get(c.projection)}),u.on("change",function(){if(c.autodiscover){var a=u.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,u.setTracking(!1)})}})),void u.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}});var v=f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})});r.$on("$destroy",function(){a.Observable.unByKey(v)})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),g(e)&&n(c.visible)&&(c.visible!==e.visible||z(d)||d.getVisible()!==c.visible)&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(b,c,d,e,f){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(b,c,d,g){var h=g.getOpenlayersScope(),i=f.isNumber,j=f.safeApply,k=f.createView;h.getMap().then(function(b){var c=e.getDefaults(h),d=h.view;d.projection||(d.projection=c.view.projection),d.maxZoom||(d.maxZoom=c.view.maxZoom),d.minZoom||(d.minZoom=c.view.minZoom),d.rotation||(d.rotation=c.view.rotation);var f=k(d);b.setView(f),h.$watchCollection("view",function(a){i(a.rotation)&&f.setRotation(a.rotation)});var g=f.on("change:rotation",function(){j(h,function(a){a.view.rotation=b.getView().getRotation()})});h.$on("$destroy",function(){a.Observable.unByKey(g)})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope(),j=e.getControlClasses,k=j();i.getMap().then(function(b){function d(a){a&&a.control?(f&&b.removeControl(f),f=a.control,b.addControl(f)):c.name&&(h(a)&&(g=a),f&&b.removeControl(f),f=new k[c.name](g),b.addControl(f))}a.$on("$destroy",function(){b.removeControl(f)}),a.$watch("properties",function(a){h(a)&&d(a)}),d(a.properties)})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e].markerLayer,delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(){c.properties&&(e.getViewport().removeEventListener("mousemove",c.properties.handleInteraction),e.getViewport().removeEventListener("click",c.properties.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",c.properties.handleTapInteraction),e.getViewport().removeEventListener("mousemove",c.properties.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",c.properties.removeAllOverlays),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",c.properties.activateCooldown))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;if(c.handleDrag=function(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(!(x=g?g.get("marker"):null)||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))},e.on("pointerdown",c.handleDrag),e.on("pointerup",c.handleDrag),e.on("pointerdrag",c.handleDrag),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e),e.un("pointerdown",c.handleDrag),e.un("pointerup",c.handleDrag),e.un("pointerdrag",c.handleDrag),j()}),!k(c.properties))return t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p)));c.$watch("properties",function(d){if(j(),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){var a,b=!1;return d.activateCooldown=function(){b=!0,a&&clearTimeout(a),a=setTimeout(function(){b=!1,a=null},500)},d.activateCooldown&&e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",d.activateCooldown),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",d.activateCooldown),function(){b||(d.handleInteraction.apply(null,arguments),d.activateCooldown())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&!0===d.label.show&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&!1===d.label.show&&(e.removeOverlay(p),p=void 0),d.label&&!1===d.label.show&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&!1===d.label.show&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&!1===d.label.show&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0)})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){a[c(a,b)].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&!0!==a[f].resolvedDefer?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d=c(a,b);return angular.isDefined(a[d])&&!1!==a[d].resolvedDefer?a[d].defer:f(a,b)};this.setMap=function(a,b){f(d,b).resolve(a),e(d,b)},this.getMap=function(a){return g(d,a).promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function a(b,c){var d;if(c?d=b[c]:(c="style",d=b),"style"===c&&b instanceof Function)return b;if(!(d instanceof Object))return d;var e;if("[object Object]"===Object.prototype.toString.call(d)){e={};var f=l[c];if(f&&d instanceof f)return d;Object.getOwnPropertyNames(d).forEach(function(b,g,h){var i=l[b];if(f&&i&&i.prototype instanceof l[c])return console.assert(1===h.length,"Extra parameters for "+c),e=a(d,b),m(e,i);e[b]=a(d,b),"text"!==b&&"string"!=typeof e[b]&&(e[b]=m(e[b],l[b]))})}else e=d;return m(e,l[c])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":return"Vector";case"TileVector":case"MVT":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g,i,l,m=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");l="https://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace(".png","@2x.png")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,wrapX:void 0===b.wrapX||b.wrapX});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");l="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace("{y}?access_token","{y}@2x?access_token")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,tileSize:b.tileSize||[512,512],wrapX:void 0===b.wrapX||b.wrapX});break;case"MVT":if(!b.url)return void c.error("[AngularJS - Openlayers] - MVT layer requires the source url");g=new a.source.VectorTile({attributions:b.attributions||"",format:new a.format.MVT,tileGrid:a.tilegrid.createXYZ({maxZoom:b.maxZoom||22}),tilePixelRatio:b.tilePixelRatio||16,url:b.url});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,imageLoadFunction:b.imageLoadFunction,attributions:t(b),crossOrigin:void 0===b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={tileLoadFunction:b.tileLoadFunction,crossOrigin:void 0===b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX};b.projection&&(n.projection=new a.proj.get(b.projection)),b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={tileLoadFunction:b.tileLoadFunction,projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),style:"undefined"===b.style?"normal":b.style,wrapX:void 0===b.wrapX||b.wrapX};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({tileLoadFunction:b.tileLoadFunction,attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,tileLoadFunction:b.tileLoadFunction,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX||b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer,wrapX:void 0===b.wrapX||b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="https://services.arcgisonline.com/ArcGIS/rest/services/",u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:u,wrapX:void 0===b.wrapX||b.wrapX});break;case"TileArcGISRest":b.url||c.error("[AngularJS - Openlayers] - TileArcGISRest Layer needs valid url"),g=new a.source.TileArcGISRest({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=m.readFeatures(b.geojson.object,{featureProjection:w.getCode(),dataProjection:v.getCode()});g.addFeatures(x)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});else{g=new a.source.Vector;var y,z=f;y=e(b.wkt.projection)?new a.proj.get(b.wkt.projection):f;for(var A=new a.format.WKT,B=[],C=0;C-1)return a.source[b.type][d]}return null},v=function(b){var c=new a.layer.Group;return c.set("name",b),c},w=function(b,c){var d;return angular.forEach(b,function(b){if(b instanceof a.layer.Group&&b.get("name")===c)return void(d=b)}),d},x=function(a,b){for(var c,d=0;d Date: Thu, 8 Mar 2018 14:57:30 +0530 Subject: [PATCH 49/53] CommonJS - Injecting angular-sanitize to angular module --- dist/angular-openlayers-directive.js | 1 + dist/angular-openlayers-directive.min.js | 4 ++-- dist/angular-openlayers-directive.min.no-header.js | 4 ++-- dist/angular-openlayers-directive.pre.js | 1 + grunt/concat.js | 1 + 5 files changed, 7 insertions(+), 4 deletions(-) diff --git a/dist/angular-openlayers-directive.js b/dist/angular-openlayers-directive.js index d612617a..6410cb37 100644 --- a/dist/angular-openlayers-directive.js +++ b/dist/angular-openlayers-directive.js @@ -2,6 +2,7 @@ if (typeof require === 'function' && typeof exports === 'object') { // CommonJS var ol = require('openlayers'); + var ngSanitize = require('angular-sanitize'); exports.angularOpenlayersDirective = factory(ol); } else if (typeof define === 'function' && define.amd) { // AMD. diff --git a/dist/angular-openlayers-directive.min.js b/dist/angular-openlayers-directive.min.js index 49411d41..92e55cb4 100644 --- a/dist/angular-openlayers-directive.min.js +++ b/dist/angular-openlayers-directive.min.js @@ -28,5 +28,5 @@ */ /*! angular-openlayers-directive 08-03-2018 */ -!function(a,b){if("function"==typeof require&&"object"==typeof exports){var c=require("openlayers");exports.angularOpenlayersDirective=b(c)}else"function"==typeof define&&define.amd?define(["ol"],function(c){return a.angularOpenlayersDirective=b(c)}):a.angularOpenlayersDirective=b(a.ol)}(this,function(a){return angular.module("openlayers-directive",["ngSanitize"]).directive("openlayers",["$log","$q","$compile","olHelpers","olMapDefaults","olData",function(b,c,d,e,f,g){return{restrict:"EA",transclude:!0,replace:!0,scope:{center:"=olCenter",defaults:"=olDefaults",view:"=olView",events:"=olEvents"},template:'
',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id),q.setTarget(null),q=null}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);if(!0===s.centerUrlHash){var t=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t(),r.$on("$locationChangeSuccess",function(){var a=t();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var u;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return u||(u=new a.Geolocation({projection:a.proj.get(c.projection)}),u.on("change",function(){if(c.autodiscover){var a=u.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,u.setTracking(!1)})}})),void u.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}});var v=f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})});r.$on("$destroy",function(){a.Observable.unByKey(v)})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),g(e)&&n(c.visible)&&(c.visible!==e.visible||z(d)||d.getVisible()!==c.visible)&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(b,c,d,e,f){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(b,c,d,g){var h=g.getOpenlayersScope(),i=f.isNumber,j=f.safeApply,k=f.createView;h.getMap().then(function(b){var c=e.getDefaults(h),d=h.view;d.projection||(d.projection=c.view.projection),d.maxZoom||(d.maxZoom=c.view.maxZoom),d.minZoom||(d.minZoom=c.view.minZoom),d.rotation||(d.rotation=c.view.rotation);var f=k(d);b.setView(f),h.$watchCollection("view",function(a){i(a.rotation)&&f.setRotation(a.rotation)});var g=f.on("change:rotation",function(){j(h,function(a){a.view.rotation=b.getView().getRotation()})});h.$on("$destroy",function(){a.Observable.unByKey(g)})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope(),j=e.getControlClasses,k=j();i.getMap().then(function(b){function d(a){a&&a.control?(f&&b.removeControl(f),f=a.control,b.addControl(f)):c.name&&(h(a)&&(g=a),f&&b.removeControl(f),f=new k[c.name](g),b.addControl(f))}a.$on("$destroy",function(){b.removeControl(f)}),a.$watch("properties",function(a){h(a)&&d(a)}),d(a.properties)})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e].markerLayer,delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(){c.properties&&(e.getViewport().removeEventListener("mousemove",c.properties.handleInteraction),e.getViewport().removeEventListener("click",c.properties.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",c.properties.handleTapInteraction),e.getViewport().removeEventListener("mousemove",c.properties.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",c.properties.removeAllOverlays),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",c.properties.activateCooldown))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;if(c.handleDrag=function(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(!(x=g?g.get("marker"):null)||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))},e.on("pointerdown",c.handleDrag),e.on("pointerup",c.handleDrag),e.on("pointerdrag",c.handleDrag),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e),e.un("pointerdown",c.handleDrag),e.un("pointerup",c.handleDrag),e.un("pointerdrag",c.handleDrag),j()}),!k(c.properties))return t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p)));c.$watch("properties",function(d){if(j(),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){var a,b=!1;return d.activateCooldown=function(){b=!0,a&&clearTimeout(a),a=setTimeout(function(){b=!1,a=null},500)},d.activateCooldown&&e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",d.activateCooldown),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",d.activateCooldown),function(){b||(d.handleInteraction.apply(null,arguments),d.activateCooldown())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&!0===d.label.show&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&!1===d.label.show&&(e.removeOverlay(p),p=void 0),d.label&&!1===d.label.show&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&!1===d.label.show&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&!1===d.label.show&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0)})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){a[c(a,b)].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&!0!==a[f].resolvedDefer?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d=c(a,b);return angular.isDefined(a[d])&&!1!==a[d].resolvedDefer?a[d].defer:f(a,b)};this.setMap=function(a,b){f(d,b).resolve(a),e(d,b)},this.getMap=function(a){return g(d,a).promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function a(b,c){var d;if(c?d=b[c]:(c="style",d=b),"style"===c&&b instanceof Function)return b;if(!(d instanceof Object))return d;var e;if("[object Object]"===Object.prototype.toString.call(d)){e={};var f=l[c];if(f&&d instanceof f)return d;Object.getOwnPropertyNames(d).forEach(function(b,g,h){var i=l[b];if(f&&i&&i.prototype instanceof l[c])return console.assert(1===h.length,"Extra parameters for "+c),e=a(d,b),m(e,i);e[b]=a(d,b),"text"!==b&&"string"!=typeof e[b]&&(e[b]=m(e[b],l[b]))})}else e=d;return m(e,l[c])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":return"Vector";case"TileVector":case"MVT":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g,i,l,m=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");l="https://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace(".png","@2x.png")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,wrapX:void 0===b.wrapX||b.wrapX});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");l="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace("{y}?access_token","{y}@2x?access_token")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,tileSize:b.tileSize||[512,512],wrapX:void 0===b.wrapX||b.wrapX});break;case"MVT":if(!b.url)return void c.error("[AngularJS - Openlayers] - MVT layer requires the source url");g=new a.source.VectorTile({attributions:b.attributions||"",format:new a.format.MVT,tileGrid:a.tilegrid.createXYZ({maxZoom:b.maxZoom||22}),tilePixelRatio:b.tilePixelRatio||16,url:b.url});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,imageLoadFunction:b.imageLoadFunction,attributions:t(b),crossOrigin:void 0===b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={tileLoadFunction:b.tileLoadFunction,crossOrigin:void 0===b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX};b.projection&&(n.projection=new a.proj.get(b.projection)),b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={tileLoadFunction:b.tileLoadFunction,projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),style:"undefined"===b.style?"normal":b.style,wrapX:void 0===b.wrapX||b.wrapX};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({tileLoadFunction:b.tileLoadFunction,attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,tileLoadFunction:b.tileLoadFunction,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX||b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer,wrapX:void 0===b.wrapX||b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="https://services.arcgisonline.com/ArcGIS/rest/services/",u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:u,wrapX:void 0===b.wrapX||b.wrapX});break;case"TileArcGISRest":b.url||c.error("[AngularJS - Openlayers] - TileArcGISRest Layer needs valid url"),g=new a.source.TileArcGISRest({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=m.readFeatures(b.geojson.object,{featureProjection:w.getCode(),dataProjection:v.getCode()});g.addFeatures(x)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});else{g=new a.source.Vector;var y,z=f;y=e(b.wkt.projection)?new a.proj.get(b.wkt.projection):f;for(var A=new a.format.WKT,B=[],C=0;C-1)return a.source[b.type][d]}return null},v=function(b){var c=new a.layer.Group;return c.set("name",b),c},w=function(b,c){var d;return angular.forEach(b,function(b){if(b instanceof a.layer.Group&&b.get("name")===c)return void(d=b)}),d},x=function(a,b){for(var c,d=0;d',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id),q.setTarget(null),q=null}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);if(!0===s.centerUrlHash){var t=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t(),r.$on("$locationChangeSuccess",function(){var a=t();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var u;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return u||(u=new a.Geolocation({projection:a.proj.get(c.projection)}),u.on("change",function(){if(c.autodiscover){var a=u.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,u.setTracking(!1)})}})),void u.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}});var v=f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})});r.$on("$destroy",function(){a.Observable.unByKey(v)})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),g(e)&&n(c.visible)&&(c.visible!==e.visible||z(d)||d.getVisible()!==c.visible)&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(b,c,d,e,f){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(b,c,d,g){var h=g.getOpenlayersScope(),i=f.isNumber,j=f.safeApply,k=f.createView;h.getMap().then(function(b){var c=e.getDefaults(h),d=h.view;d.projection||(d.projection=c.view.projection),d.maxZoom||(d.maxZoom=c.view.maxZoom),d.minZoom||(d.minZoom=c.view.minZoom),d.rotation||(d.rotation=c.view.rotation);var f=k(d);b.setView(f),h.$watchCollection("view",function(a){i(a.rotation)&&f.setRotation(a.rotation)});var g=f.on("change:rotation",function(){j(h,function(a){a.view.rotation=b.getView().getRotation()})});h.$on("$destroy",function(){a.Observable.unByKey(g)})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope(),j=e.getControlClasses,k=j();i.getMap().then(function(b){function d(a){a&&a.control?(f&&b.removeControl(f),f=a.control,b.addControl(f)):c.name&&(h(a)&&(g=a),f&&b.removeControl(f),f=new k[c.name](g),b.addControl(f))}a.$on("$destroy",function(){b.removeControl(f)}),a.$watch("properties",function(a){h(a)&&d(a)}),d(a.properties)})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e].markerLayer,delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(){c.properties&&(e.getViewport().removeEventListener("mousemove",c.properties.handleInteraction),e.getViewport().removeEventListener("click",c.properties.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",c.properties.handleTapInteraction),e.getViewport().removeEventListener("mousemove",c.properties.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",c.properties.removeAllOverlays),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",c.properties.activateCooldown))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;if(c.handleDrag=function(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(!(x=g?g.get("marker"):null)||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))},e.on("pointerdown",c.handleDrag),e.on("pointerup",c.handleDrag),e.on("pointerdrag",c.handleDrag),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e),e.un("pointerdown",c.handleDrag),e.un("pointerup",c.handleDrag),e.un("pointerdrag",c.handleDrag),j()}),!k(c.properties))return t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p)));c.$watch("properties",function(d){if(j(),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){var a,b=!1;return d.activateCooldown=function(){b=!0,a&&clearTimeout(a),a=setTimeout(function(){b=!1,a=null},500)},d.activateCooldown&&e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",d.activateCooldown),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",d.activateCooldown),function(){b||(d.handleInteraction.apply(null,arguments),d.activateCooldown())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&!0===d.label.show&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&!1===d.label.show&&(e.removeOverlay(p),p=void 0),d.label&&!1===d.label.show&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&!1===d.label.show&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&!1===d.label.show&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0)})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){a[c(a,b)].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&!0!==a[f].resolvedDefer?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d=c(a,b);return angular.isDefined(a[d])&&!1!==a[d].resolvedDefer?a[d].defer:f(a,b)};this.setMap=function(a,b){f(d,b).resolve(a),e(d,b)},this.getMap=function(a){return g(d,a).promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function a(b,c){var d;if(c?d=b[c]:(c="style",d=b),"style"===c&&b instanceof Function)return b;if(!(d instanceof Object))return d;var e;if("[object Object]"===Object.prototype.toString.call(d)){e={};var f=l[c];if(f&&d instanceof f)return d;Object.getOwnPropertyNames(d).forEach(function(b,g,h){var i=l[b];if(f&&i&&i.prototype instanceof l[c])return console.assert(1===h.length,"Extra parameters for "+c),e=a(d,b),m(e,i);e[b]=a(d,b),"text"!==b&&"string"!=typeof e[b]&&(e[b]=m(e[b],l[b]))})}else e=d;return m(e,l[c])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":return"Vector";case"TileVector":case"MVT":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g,i,l,m=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");l="https://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace(".png","@2x.png")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,wrapX:void 0===b.wrapX||b.wrapX});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");l="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace("{y}?access_token","{y}@2x?access_token")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,tileSize:b.tileSize||[512,512],wrapX:void 0===b.wrapX||b.wrapX});break;case"MVT":if(!b.url)return void c.error("[AngularJS - Openlayers] - MVT layer requires the source url");g=new a.source.VectorTile({attributions:b.attributions||"",format:new a.format.MVT,tileGrid:a.tilegrid.createXYZ({maxZoom:b.maxZoom||22}),tilePixelRatio:b.tilePixelRatio||16,url:b.url});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,imageLoadFunction:b.imageLoadFunction,attributions:t(b),crossOrigin:void 0===b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={tileLoadFunction:b.tileLoadFunction,crossOrigin:void 0===b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX};b.projection&&(n.projection=new a.proj.get(b.projection)),b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={tileLoadFunction:b.tileLoadFunction,projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),style:"undefined"===b.style?"normal":b.style,wrapX:void 0===b.wrapX||b.wrapX};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({tileLoadFunction:b.tileLoadFunction,attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,tileLoadFunction:b.tileLoadFunction,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX||b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer,wrapX:void 0===b.wrapX||b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="https://services.arcgisonline.com/ArcGIS/rest/services/",u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:u,wrapX:void 0===b.wrapX||b.wrapX});break;case"TileArcGISRest":b.url||c.error("[AngularJS - Openlayers] - TileArcGISRest Layer needs valid url"),g=new a.source.TileArcGISRest({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=m.readFeatures(b.geojson.object,{featureProjection:w.getCode(),dataProjection:v.getCode()});g.addFeatures(x)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});else{g=new a.source.Vector;var y,z=f;y=e(b.wkt.projection)?new a.proj.get(b.wkt.projection):f;for(var A=new a.format.WKT,B=[],C=0;C-1)return a.source[b.type][d]}return null},v=function(b){var c=new a.layer.Group;return c.set("name",b),c},w=function(b,c){var d;return angular.forEach(b,function(b){if(b instanceof a.layer.Group&&b.get("name")===c)return void(d=b)}),d},x=function(a,b){for(var c,d=0;d',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id),q.setTarget(null),q=null}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);if(!0===s.centerUrlHash){var t=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t(),r.$on("$locationChangeSuccess",function(){var a=t();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var u;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return u||(u=new a.Geolocation({projection:a.proj.get(c.projection)}),u.on("change",function(){if(c.autodiscover){var a=u.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,u.setTracking(!1)})}})),void u.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}});var v=f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})});r.$on("$destroy",function(){a.Observable.unByKey(v)})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),g(e)&&n(c.visible)&&(c.visible!==e.visible||z(d)||d.getVisible()!==c.visible)&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(b,c,d,e,f){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(b,c,d,g){var h=g.getOpenlayersScope(),i=f.isNumber,j=f.safeApply,k=f.createView;h.getMap().then(function(b){var c=e.getDefaults(h),d=h.view;d.projection||(d.projection=c.view.projection),d.maxZoom||(d.maxZoom=c.view.maxZoom),d.minZoom||(d.minZoom=c.view.minZoom),d.rotation||(d.rotation=c.view.rotation);var f=k(d);b.setView(f),h.$watchCollection("view",function(a){i(a.rotation)&&f.setRotation(a.rotation)});var g=f.on("change:rotation",function(){j(h,function(a){a.view.rotation=b.getView().getRotation()})});h.$on("$destroy",function(){a.Observable.unByKey(g)})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope(),j=e.getControlClasses,k=j();i.getMap().then(function(b){function d(a){a&&a.control?(f&&b.removeControl(f),f=a.control,b.addControl(f)):c.name&&(h(a)&&(g=a),f&&b.removeControl(f),f=new k[c.name](g),b.addControl(f))}a.$on("$destroy",function(){b.removeControl(f)}),a.$watch("properties",function(a){h(a)&&d(a)}),d(a.properties)})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e].markerLayer,delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(){c.properties&&(e.getViewport().removeEventListener("mousemove",c.properties.handleInteraction),e.getViewport().removeEventListener("click",c.properties.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",c.properties.handleTapInteraction),e.getViewport().removeEventListener("mousemove",c.properties.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",c.properties.removeAllOverlays),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",c.properties.activateCooldown))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;if(c.handleDrag=function(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(!(x=g?g.get("marker"):null)||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))},e.on("pointerdown",c.handleDrag),e.on("pointerup",c.handleDrag),e.on("pointerdrag",c.handleDrag),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e),e.un("pointerdown",c.handleDrag),e.un("pointerup",c.handleDrag),e.un("pointerdrag",c.handleDrag),j()}),!k(c.properties))return t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p)));c.$watch("properties",function(d){if(j(),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){var a,b=!1;return d.activateCooldown=function(){b=!0,a&&clearTimeout(a),a=setTimeout(function(){b=!1,a=null},500)},d.activateCooldown&&e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",d.activateCooldown),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",d.activateCooldown),function(){b||(d.handleInteraction.apply(null,arguments),d.activateCooldown())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&!0===d.label.show&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&!1===d.label.show&&(e.removeOverlay(p),p=void 0),d.label&&!1===d.label.show&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&!1===d.label.show&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&!1===d.label.show&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0)})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){a[c(a,b)].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&!0!==a[f].resolvedDefer?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d=c(a,b);return angular.isDefined(a[d])&&!1!==a[d].resolvedDefer?a[d].defer:f(a,b)};this.setMap=function(a,b){f(d,b).resolve(a),e(d,b)},this.getMap=function(a){return g(d,a).promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function a(b,c){var d;if(c?d=b[c]:(c="style",d=b),"style"===c&&b instanceof Function)return b;if(!(d instanceof Object))return d;var e;if("[object Object]"===Object.prototype.toString.call(d)){e={};var f=l[c];if(f&&d instanceof f)return d;Object.getOwnPropertyNames(d).forEach(function(b,g,h){var i=l[b];if(f&&i&&i.prototype instanceof l[c])return console.assert(1===h.length,"Extra parameters for "+c),e=a(d,b),m(e,i);e[b]=a(d,b),"text"!==b&&"string"!=typeof e[b]&&(e[b]=m(e[b],l[b]))})}else e=d;return m(e,l[c])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":return"Vector";case"TileVector":case"MVT":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g,i,l,m=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");l="https://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace(".png","@2x.png")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,wrapX:void 0===b.wrapX||b.wrapX});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");l="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace("{y}?access_token","{y}@2x?access_token")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,tileSize:b.tileSize||[512,512],wrapX:void 0===b.wrapX||b.wrapX});break;case"MVT":if(!b.url)return void c.error("[AngularJS - Openlayers] - MVT layer requires the source url");g=new a.source.VectorTile({attributions:b.attributions||"",format:new a.format.MVT,tileGrid:a.tilegrid.createXYZ({maxZoom:b.maxZoom||22}),tilePixelRatio:b.tilePixelRatio||16,url:b.url});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,imageLoadFunction:b.imageLoadFunction,attributions:t(b),crossOrigin:void 0===b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={tileLoadFunction:b.tileLoadFunction,crossOrigin:void 0===b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX};b.projection&&(n.projection=new a.proj.get(b.projection)),b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={tileLoadFunction:b.tileLoadFunction,projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),style:"undefined"===b.style?"normal":b.style,wrapX:void 0===b.wrapX||b.wrapX};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({tileLoadFunction:b.tileLoadFunction,attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,tileLoadFunction:b.tileLoadFunction,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX||b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer,wrapX:void 0===b.wrapX||b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="https://services.arcgisonline.com/ArcGIS/rest/services/",u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:u,wrapX:void 0===b.wrapX||b.wrapX});break;case"TileArcGISRest":b.url||c.error("[AngularJS - Openlayers] - TileArcGISRest Layer needs valid url"),g=new a.source.TileArcGISRest({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=m.readFeatures(b.geojson.object,{featureProjection:w.getCode(),dataProjection:v.getCode()});g.addFeatures(x)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});else{g=new a.source.Vector;var y,z=f;y=e(b.wkt.projection)?new a.proj.get(b.wkt.projection):f;for(var A=new a.format.WKT,B=[],C=0;C-1)return a.source[b.type][d]}return null},v=function(b){var c=new a.layer.Group;return c.set("name",b),c},w=function(b,c){var d;return angular.forEach(b,function(b){if(b instanceof a.layer.Group&&b.get("name")===c)return void(d=b)}),d},x=function(a,b){for(var c,d=0;d',controller:["$scope",function(a){var b=c.defer();a.getMap=function(){return b.promise},a.setMap=function(a){b.resolve(a)},this.getOpenlayersScope=function(){return a}}],link:function(b,c,d){var h=e.isDefined,i=e.createLayer,j=e.setMapEvents,k=e.setViewEvents,l=e.createView,m=f.setDefaults(b);h(d.width)&&(isNaN(d.width)?c.css("width",d.width):c.css("width",d.width+"px")),h(d.height)&&(isNaN(d.height)?c.css("height",d.height):c.css("height",d.height+"px")),h(d.lat)&&(m.center.lat=parseFloat(d.lat)),h(d.lon)&&(m.center.lon=parseFloat(d.lon)),h(d.zoom)&&(m.center.zoom=parseFloat(d.zoom));var n=a.control.defaults(m.controls),o=a.interaction.defaults(m.interactions),p=l(m.view),q=new a.Map({target:c[0],controls:n,interactions:o,renderer:m.renderer,view:p,loadTilesWhileAnimating:m.loadTilesWhileAnimating,loadTilesWhileInteracting:m.loadTilesWhileInteracting});if(b.$on("$destroy",function(){g.resetMap(d.id),q.setTarget(null),q=null}),!d.customLayers){var r={type:"Tile",source:{type:"OSM"}},s=i(r,p.getProjection(),"default");q.addLayer(s),q.set("default",!0)}if(!h(d.olCenter)){var t=a.proj.transform([m.center.lon,m.center.lat],m.center.projection,p.getProjection());p.setCenter(t),p.setZoom(m.center.zoom)}j(m.events,q,b),k(m.events,q,b),b.setMap(q),g.setMap(q,d.id)}}}]),angular.module("openlayers-directive").directive("olCenter",["$log","$location","olMapDefaults","olHelpers",function(b,c,d,e){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(f,g,h,i){var j=e.safeApply,k=e.isValidCenter,l=e.isDefined,m=e.isArray,n=e.isNumber,o=e.isSameCenterOnMap,p=e.setCenter,q=e.setZoom,r=i.getOpenlayersScope();r.getMap().then(function(f){var g=d.getDefaults(r),i=f.getView(),s=r.center;if(-1!==h.olCenter.search("-"))return b.error('[AngularJS - Openlayers] The "center" variable can\'t use a "-" on his key name: "'+h.center+'".'),void p(i,g.view.projection,g.center,f);l(s)||(s={}),k(s)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),s.lat=g.center.lat,s.lon=g.center.lon,s.zoom=g.center.zoom,s.projection=g.center.projection),s.projection||("pixel"!==g.view.projection?s.projection=g.center.projection:s.projection="pixel"),n(s.zoom)||(s.zoom=1),p(i,g.view.projection,s,f),i.setZoom(s.zoom);if(!0===s.centerUrlHash){var t=function(){var a,b=c.search();if(l(b.c)){var d=b.c.split(":");3===d.length&&(a={lat:parseFloat(d[0]),lon:parseFloat(d[1]),zoom:parseInt(d[2],10)})}return a};t(),r.$on("$locationChangeSuccess",function(){var a=t();a&&!o(a,f)&&j(r,function(b){b.center.lat=a.lat,b.center.lon=a.lon,b.center.zoom=a.zoom})})}var u;r.$watchCollection("center",function(c){if(c){if(c.projection||(c.projection=g.center.projection),c.autodiscover)return u||(u=new a.Geolocation({projection:a.proj.get(c.projection)}),u.on("change",function(){if(c.autodiscover){var a=u.getPosition();j(r,function(b){b.center.lat=a[1],b.center.lon=a[0],b.center.zoom=12,b.center.autodiscover=!1,u.setTracking(!1)})}})),void u.setTracking(!0);k(c)||(b.warn("[AngularJS - Openlayers] invalid 'center'"),c=g.center);var d=i.getCenter();if(d)if("pixel"===g.view.projection||"pixel"===c.projection)i.setCenter(c.coord);else{var e=a.proj.transform(d,g.view.projection,c.projection);e[1]===c.lat&&e[0]===c.lon||p(i,g.view.projection,c,f)}i.getZoom()!==c.zoom&&q(i,c.zoom,f)}});var v=f.on("moveend",function(){j(r,function(b){if(l(b.center)){var d=f.getView().getCenter();if(b.center.zoom=i.getZoom(),"pixel"===g.view.projection||"pixel"===b.center.projection)return void(b.center.coord=d);if(b.center){var h=a.proj.transform(d,g.view.projection,b.center.projection);if(b.center.lat=h[1],b.center.lon=h[0],e.notifyCenterUrlHashChanged(r,b.center,c.search()),m(b.center.bounds)){var j=i.calculateExtent(f.getSize()),k=b.center.projection,n=g.view.projection;b.center.bounds=a.proj.transformExtent(j,n,k)}}}})});r.$on("$destroy",function(){a.Observable.unByKey(v)})})}}}]),angular.module("openlayers-directive").directive("olLayer",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olLayerProperties",onLayerCreated:"&"},replace:!1,require:"^openlayers",link:function(a,b,e,f){var g=d.isDefined,h=d.equals,i=f.getOpenlayersScope(),j=d.createLayer,k=d.setVectorLayerEvents,l=d.detectLayerType,m=d.createStyle,n=d.isBoolean,o=d.addLayerBeforeMarkers,p=d.isNumber,q=d.insertLayer,r=d.removeLayer,s=d.addLayerToGroup,t=d.removeLayerFromGroup,u=d.getGroup;i.getMap().then(function(b){var d,f=b.getView().getProjection(),v=c.setDefaults(i),w=b.getLayers();if(a.$on("$destroy",function(){a.properties.group?t(w,d,a.properties.group):r(w,d.index),b.removeLayer(d)}),g(a.properties))a.$watch("properties",function(c,e){if(g(c.source)&&g(c.source.type)){if(!g(c.visible))return void(c.visible=!0);if(!g(c.opacity))return void(c.opacity=1);var i,x,y;if(g(d)){var z=function(a){return function(b){return b!==a}}(d);if(g(e)&&!h(c.source,e.source)){var A=d.index;y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),y.removeAt(A),d=j(c,f,a.onLayerCreated),d.set("group",x),g(d)&&(q(y,A,d),"Vector"===l(c)&&k(v.events,b,a,c.name))}(g(e)&&c.opacity!==e.opacity||z(d))&&(p(c.opacity)||p(parseFloat(c.opacity)))&&d.setOpacity(c.opacity),g(c.index)&&c.index!==d.index&&(y=w,x=d.get("group"),x&&(y=u(w,x).getLayers()),r(y,d.index),q(y,c.index,d)),g(c.group)&&c.group!==e.group&&(t(w,d,e.group),s(w,d,c.group)),g(e)&&n(c.visible)&&(c.visible!==e.visible||z(d)||d.getVisible()!==c.visible)&&d.setVisible(c.visible),(g(c.style)&&!h(c.style,e.style)||z(d))&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),h(c.minResolution,e.minResolution)&&!z(d)||g(c.minResolution)&&d.setMinResolution(c.minResolution),h(c.maxResolution,e.maxResolution)&&!z(d)||g(c.maxResolution)&&d.setMaxResolution(c.maxResolution)}else d=j(c,f,a.onLayerCreated),g(c.group)?s(w,d,c.group):g(c.index)?q(w,c.index,d):o(w,d),"Vector"===l(c)&&k(v.events,b,a,c.name),n(c.visible)&&d.setVisible(c.visible),c.opacity&&d.setOpacity(c.opacity),angular.isArray(c.extent)&&d.setExtent(c.extent),c.style&&(i=angular.isFunction(c.style)?c.style:m(c.style),d.setStyle&&angular.isFunction(d.setStyle)&&d.setStyle(i)),c.minResolution&&d.setMinResolution(c.minResolution),c.maxResolution&&d.setMaxResolution(c.maxResolution)}},!0);else if(g(e.sourceType)&&g(e.sourceUrl)){var x={source:{url:e.sourceUrl,type:e.sourceType}};d=j(x,f,e.layerName,a.onLayerCreated),"Vector"===l(x)&&k(v.events,b,a,e.name),o(w,d)}})}}}]),angular.module("openlayers-directive").directive("olPath",["$log","$q","olMapDefaults","olHelpers",function(a,b,c,d){return{restrict:"E",scope:{properties:"=olGeomProperties",style:"=olStyle"},require:"^openlayers",replace:!0,template:'',link:function(a,b,e,f){var g=d.isDefined,h=d.createFeature,i=d.createOverlay,j=d.createVectorLayer,k=d.insertLayer,l=d.removeLayer,m=f.getOpenlayersScope();m.getMap().then(function(d){var f=c.getDefaults(m),n=f.view.projection,o=j(),p=d.getLayers();if(k(p,p.getLength(),o),a.$on("$destroy",function(){l(p,o.index)}),g(e.coords)){var q=e.proj||"EPSG:4326",r=JSON.parse(e.coords),s={type:"Polygon",coords:r,projection:q,style:a.style?a.style:f.styles.path},t=h(s,n);if(o.getSource().addFeature(t),e.message){a.message=e.message;var u=t.getGeometry().getExtent(),v=i(b,u);d.addOverlay(v)}}else;})}}}]),angular.module("openlayers-directive").directive("olView",["$log","$q","olData","olMapDefaults","olHelpers",function(b,c,d,e,f){return{restrict:"A",scope:!1,replace:!1,require:"openlayers",link:function(b,c,d,g){var h=g.getOpenlayersScope(),i=f.isNumber,j=f.safeApply,k=f.createView;h.getMap().then(function(b){var c=e.getDefaults(h),d=h.view;d.projection||(d.projection=c.view.projection),d.maxZoom||(d.maxZoom=c.view.maxZoom),d.minZoom||(d.minZoom=c.view.minZoom),d.rotation||(d.rotation=c.view.rotation);var f=k(d);b.setView(f),h.$watchCollection("view",function(a){i(a.rotation)&&f.setRotation(a.rotation)});var g=f.on("change:rotation",function(){j(h,function(a){a.view.rotation=b.getView().getRotation()})});h.$on("$destroy",function(){a.Observable.unByKey(g)})})}}}]),angular.module("openlayers-directive").directive("olControl",["$log","$q","olData","olMapDefaults","olHelpers",function(a,b,c,d,e){return{restrict:"E",scope:{properties:"=olControlProperties"},replace:!1,require:"^openlayers",link:function(a,b,c,d){var f,g,h=e.isDefined,i=d.getOpenlayersScope(),j=e.getControlClasses,k=j();i.getMap().then(function(b){function d(a){a&&a.control?(f&&b.removeControl(f),f=a.control,b.addControl(f)):c.name&&(h(a)&&(g=a),f&&b.removeControl(f),f=new k[c.name](g),b.addControl(f))}a.$on("$destroy",function(){b.removeControl(f)}),a.$watch("properties",function(a){h(a)&&d(a)}),d(a.properties)})}}}]),angular.module("openlayers-directive").directive("olMarker",["$log","$q","olMapDefaults","olHelpers",function(b,c,d,e){var f=function(){return{projection:"EPSG:4326",lat:0,lon:0,coord:[],show:!0,showOnMouseOver:!1,showOnMouseClick:!1,keepOneOverlayVisible:!1}},g=function(){function a(a){return b.map(function(a){return a.map}).indexOf(a)}var b=[];return{getInst:function(c,d){var f=a(d);if(-1===f){var g=e.createVectorLayer();g.set("markers",!0),d.addLayer(g),b.push({map:d,markerLayer:g,instScopes:[]}),f=b.length-1}return b[f].instScopes.push(c),b[f].markerLayer},deregisterScope:function(c,d){var e=a(d);if(-1===e)throw Error("This map has no markers");var f=b[e].instScopes,g=f.indexOf(c);if(-1===g)throw Error("Scope wan't registered");f.splice(g,1),f.length||(d.removeLayer(b[e].markerLayer),delete b[e].markerLayer,delete b[e])}}}();return{restrict:"E",scope:{lat:"=lat",lon:"=lon",label:"=label",properties:"=olMarkerProperties",style:"=olStyle"},transclude:!0,require:"^openlayers",replace:!0,template:'',link:function(c,h,i,j){var k=e.isDefined,l=j.getOpenlayersScope(),m=e.createFeature,n=e.createOverlay,o=h.find("ng-transclude").children().length>0;l.getMap().then(function(e){function j(){c.properties&&(e.getViewport().removeEventListener("mousemove",c.properties.handleInteraction),e.getViewport().removeEventListener("click",c.properties.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchend",c.properties.handleTapInteraction),e.getViewport().removeEventListener("mousemove",c.properties.showAtLeastOneOverlay),e.getViewport().removeEventListener("click",c.properties.removeAllOverlays),e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",c.properties.activateCooldown))}var p,q,r,s=g.getInst(c,e),t=f(),u=d.getDefaults(l),v=u.view.projection,w=null,x=null;if(c.handleDrag=function(b){var d=b.coordinate,f=e.getView().getProjection().getCode();if(d="pixel"===f?d.map(function(a){return parseInt(a,10)}):a.proj.transform(d,f,"EPSG:4326"),"pointerdown"===b.type){var g=e.forEachFeatureAtPixel(b.pixel,function(a){return a});if(!(x=g?g.get("marker"):null)||!x.draggable)return void(x=null);e.getTarget().style.cursor="pointer",w="pixel"===f?[d[0]-x.coord[0],d[1]-x.coord[1]]:[d[0]-x.lon,d[1]-x.lat],b.preventDefault()}else w&&x&&("pointerup"===b.type?(e.getTarget().style.cursor="",w=null,x=null,b.preventDefault()):"pointerdrag"===b.type&&(b.preventDefault(),c.$apply(function(){"pixel"===f?(x.coord[0]=d[0]-w[0],x.coord[1]=d[1]-w[1]):(x.lon=d[0]-w[0],x.lat=d[1]-w[1])})))},e.on("pointerdown",c.handleDrag),e.on("pointerup",c.handleDrag),e.on("pointerdrag",c.handleDrag),c.$on("$destroy",function(){s.getSource().removeFeature(r),k(p)&&e.removeOverlay(p),g.deregisterScope(c,e),e.un("pointerdown",c.handleDrag),e.un("pointerup",c.handleDrag),e.un("pointerdrag",c.handleDrag),j()}),!k(c.properties))return t.lat=c.lat?c.lat:t.lat,t.lon=c.lon?c.lon:t.lon,t.message=i.message,t.style=c.style?c.style:u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",c),s.getSource().addFeature(r),void((t.message||o)&&(c.message=i.message,q=a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),e.addOverlay(p)));c.$watch("properties",function(d){if(j(),d.handleInteraction=function(b){var c=!1;if(i.hasOwnProperty("ngClick")&&(c=!0),!d.label.show||c){var f=!1,g=e.getEventPixel(b),j=e.forEachFeatureAtPixel(g,function(a){return a}),l=!1;if(j===r){if(l=!0,f=!0,c&&("click"===b.type||"touchend"===b.type))return h.triggerHandler("click"),b.preventDefault(),void b.stopPropagation();k(p)||(q="pixel"===t.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),e.getTarget().style.cursor="pointer"}!f&&p&&(l=!0,e.removeOverlay(p),p=void 0,e.getTarget().style.cursor=""),l&&b.preventDefault()}},d.handleTapInteraction=function(){var a,b=!1;return d.activateCooldown=function(){b=!0,a&&clearTimeout(a),a=setTimeout(function(){b=!1,a=null},500)},d.activateCooldown&&e.getViewport().querySelector("canvas.ol-unselectable").removeEventListener("touchmove",d.activateCooldown),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchmove",d.activateCooldown),function(){b||(d.handleInteraction.apply(null,arguments),d.activateCooldown())}}(),d.showAtLeastOneOverlay=function(b){if(!d.label.show){var c=!1,f=e.getEventPixel(b),g=e.forEachFeatureAtPixel(f,function(a){return a}),i=!1;g===r&&(i=!0,c=!0,k(p)||(q="pixel"===t.projection?t.coord:a.proj.transform([t.lon,t.lat],t.projection,v),p=n(h,q),angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),e.addOverlay(p)),e.getTarget().style.cursor="pointer"),!c&&p&&(i=!0,p=void 0,e.getTarget().style.cursor=""),i&&b.preventDefault()}},d.removeAllOverlays=function(a){angular.forEach(e.getOverlays(),function(a){e.removeOverlay(a)}),a.preventDefault()},k(r)){var f;if(f="pixel"===d.projection?d.coord:a.proj.transform([d.lon,d.lat],t.projection,e.getView().getProjection()),!angular.equals(r.getGeometry().getCoordinates(),f)){var g=new a.geom.Point(f);r.setGeometry(g)}}else t.projection=d.projection?d.projection:t.projection,t.coord=d.coord?d.coord:t.coord,t.lat=d.lat?d.lat:t.lat,t.lon=d.lon?d.lon:t.lon,k(d.style)?t.style=d.style:t.style=u.styles.marker,r=m(t,v),k(r)||b.error("[AngularJS - Openlayers] Received invalid data on the marker."),r.set("marker",d),s.getSource().addFeature(r);k(p)&&e.removeOverlay(p),k(d.label)&&(c.message=d.label.message,(o||k(c.message)&&0!==c.message.length)&&(d.label&&!0===d.label.show&&(q="pixel"===t.projection?t.coord:a.proj.transform([d.lon,d.lat],t.projection,v),p=n(h,q),e.addOverlay(p)),p&&d.label&&!1===d.label.show&&(e.removeOverlay(p),p=void 0),d.label&&!1===d.label.show&&d.label.showOnMouseOver&&e.getViewport().addEventListener("mousemove",d.handleInteraction),(d.label&&!1===d.label.show&&d.label.showOnMouseClick||i.hasOwnProperty("ngClick"))&&(e.getViewport().addEventListener("click",d.handleTapInteraction),e.getViewport().querySelector("canvas.ol-unselectable").addEventListener("touchend",d.handleTapInteraction)),d.label&&!1===d.label.show&&d.label.keepOneOverlayVisible&&(e.getViewport().addEventListener("mousemove",d.showAtLeastOneOverlay),e.getViewport().addEventListener("click",d.removeAllOverlays))))},!0)})}}}]),angular.module("openlayers-directive").service("olData",["$log","$q",function(a,b){function c(b,c){var d,e;if(angular.isDefined(c))d=c;else if(1===Object.keys(b).length)for(e in b)b.hasOwnProperty(e)&&(d=e);else 0===Object.keys(b).length?d="main":a.error("[AngularJS - Openlayers] - You have more than 1 map on the DOM, you must provide the map ID to the olData.getXXX call");return d}var d={},e=function(a,b){a[c(a,b)].resolvedDefer=!0},f=function(a,d){var e,f=c(a,d);return angular.isDefined(a[f])&&!0!==a[f].resolvedDefer?e=a[f].defer:(e=b.defer(),a[f]={defer:e,resolvedDefer:!1}),e},g=function(a,b){var d=c(a,b);return angular.isDefined(a[d])&&!1!==a[d].resolvedDefer?a[d].defer:f(a,b)};this.setMap=function(a,b){f(d,b).resolve(a),e(d,b)},this.getMap=function(a){return g(d,a).promise},this.resetMap=function(a){angular.isDefined(d[a])&&delete d[a]}}]),angular.module("openlayers-directive").factory("olHelpers",["$q","$log","$http",function(b,c,d){var e=function(a){return angular.isDefined(a)},f=function(a){return angular.isDefined(a)&&null!==a},g=function(a,b,c){a.on(b,function(d){var e=d.coordinate,f=a.getView().getProjection().getCode();"pixel"===f&&(e=e.map(function(a){return parseInt(a,10)})),c.$emit("openlayers.map."+b,{coord:e,projection:f,event:d})})},h=["Road","Aerial","AerialWithLabels","collinsBart","ordnanceSurvey"],i=function(){return{attribution:a.control.Attribution,fullscreen:a.control.FullScreen,mouseposition:a.control.MousePosition,overviewmap:a.control.OverviewMap,rotate:a.control.Rotate,scaleline:a.control.ScaleLine,zoom:a.control.Zoom,zoomslider:a.control.ZoomSlider,zoomtoextent:a.control.ZoomToExtent}},j=["osm","sat","hyb"],k=["World_Imagery","World_Street_Map","World_Topo_Map","World_Physical_Map","World_Terrain_Base","Ocean_Basemap","NatGeo_World_Map"],l={style:a.style.Style,fill:a.style.Fill,stroke:a.style.Stroke,circle:a.style.Circle,icon:a.style.Icon,image:a.style.Image,regularshape:a.style.RegularShape,text:a.style.Text},m=function(a,b){return b&&a instanceof b?a:b?new b(a):a},n=function a(b,c){var d;if(c?d=b[c]:(c="style",d=b),"style"===c&&b instanceof Function)return b;if(!(d instanceof Object))return d;var e;if("[object Object]"===Object.prototype.toString.call(d)){e={};var f=l[c];if(f&&d instanceof f)return d;Object.getOwnPropertyNames(d).forEach(function(b,g,h){var i=l[b];if(f&&i&&i.prototype instanceof l[c])return console.assert(1===h.length,"Extra parameters for "+c),e=a(d,b),m(e,i);e[b]=a(d,b),"text"!==b&&"string"!=typeof e[b]&&(e[b]=m(e[b],l[b]))})}else e=d;return m(e,l[c])},o=function(a){if(a.type)return a.type;switch(a.source.type){case"ImageWMS":case"ImageStatic":return"Image";case"GeoJSON":case"JSONP":case"TopoJSON":case"KML":case"WKT":return"Vector";case"TileVector":case"MVT":return"TileVector";default:return"Tile"}},p=function(b){var d;switch(b.projection){case"pixel":if(!e(b.extent))return void c.error("[AngularJS - Openlayers] - You must provide the extent of the image if using pixel projection");d=new a.proj.Projection({code:"pixel",units:"pixels",extent:b.extent});break;default:d=new a.proj.get(b.projection)}return d},q=function(a){return-1!==["watercolor","terrain","toner"].indexOf(a)},r=function(b,f){var g,i,l,m=new a.format.GeoJSON;switch(b.type){case"MapBox":if(!b.mapId||!b.accessToken)return void c.error("[AngularJS - Openlayers] - MapBox layer requires the map id and the access token");l="https://api.tiles.mapbox.com/v4/"+b.mapId+"/{z}/{x}/{y}.png?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace(".png","@2x.png")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,wrapX:void 0===b.wrapX||b.wrapX});break;case"MapBoxStudio":if(!b.mapId||!b.accessToken||!b.userId)return void c.error("[AngularJS - Openlayers] - MapBox Studio layer requires the map id, user id and the access token");l="https://api.mapbox.com/styles/v1/"+b.userId+"/"+b.mapId+"/tiles/{z}/{x}/{y}?access_token="+b.accessToken,i=window.devicePixelRatio,i>1&&(l=l.replace("{y}?access_token","{y}@2x?access_token")),g=new a.source.XYZ({url:l,tileLoadFunction:b.tileLoadFunction,attributions:t(b),tilePixelRatio:i>1?2:1,tileSize:b.tileSize||[512,512],wrapX:void 0===b.wrapX||b.wrapX});break;case"MVT":if(!b.url)return void c.error("[AngularJS - Openlayers] - MVT layer requires the source url");g=new a.source.VectorTile({attributions:b.attributions||"",format:new a.format.MVT,tileGrid:a.tilegrid.createXYZ({maxZoom:b.maxZoom||22}),tilePixelRatio:b.tilePixelRatio||16,url:b.url});break;case"ImageWMS":b.url&&b.params||c.error("[AngularJS - Openlayers] - ImageWMS Layer needs valid server url and params properties"),g=new a.source.ImageWMS({url:b.url,imageLoadFunction:b.imageLoadFunction,attributions:t(b),crossOrigin:void 0===b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),ratio:b.ratio});break;case"TileWMS":(b.url||b.urls)&&b.params||c.error("[AngularJS - Openlayers] - TileWMS Layer needs valid url (or urls) and params properties");var n={tileLoadFunction:b.tileLoadFunction,crossOrigin:void 0===b.crossOrigin?"anonymous":b.crossOrigin,params:s(b.params),attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX};b.projection&&(n.projection=new a.proj.get(b.projection)),b.serverType&&(n.serverType=b.serverType),b.url&&(n.url=b.url),b.urls&&(n.urls=b.urls),g=new a.source.TileWMS(n);break;case"WMTS":(b.url||b.urls)&&b.tileGrid||c.error("[AngularJS - Openlayers] - WMTS Layer needs valid url (or urls) and tileGrid properties");var o={tileLoadFunction:b.tileLoadFunction,projection:f,layer:b.layer,attributions:t(b),matrixSet:"undefined"===b.matrixSet?f:b.matrixSet,format:"undefined"===b.format?"image/jpeg":b.format,requestEncoding:"undefined"===b.requestEncoding?"KVP":b.requestEncoding,tileGrid:new a.tilegrid.WMTS({origin:b.tileGrid.origin,resolutions:b.tileGrid.resolutions,matrixIds:b.tileGrid.matrixIds}),style:"undefined"===b.style?"normal":b.style,wrapX:void 0===b.wrapX||b.wrapX};e(b.url)&&(o.url=b.url),e(b.urls)&&(o.urls=b.urls),g=new a.source.WMTS(o);break;case"OSM":g=new a.source.OSM({tileLoadFunction:b.tileLoadFunction,attributions:t(b),wrapX:void 0===b.wrapX||b.wrapX}),b.url&&g.setUrl(b.url);break;case"BingMaps":if(!b.key)return void c.error("[AngularJS - Openlayers] - You need an API key to show the Bing Maps.");var p={key:b.key,tileLoadFunction:b.tileLoadFunction,attributions:t(b),imagerySet:b.imagerySet?b.imagerySet:h[0],culture:b.culture,wrapX:void 0===b.wrapX||b.wrapX};b.maxZoom&&(p.maxZoom=b.maxZoom),g=new a.source.BingMaps(p);break;case"MapQuest":if(!b.layer||-1===j.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - MapQuest layers needs a valid 'layer' property.");g=new a.source.MapQuest({attributions:t(b),layer:b.layer,wrapX:void 0===b.wrapX||b.wrapX});break;case"EsriBaseMaps":if(!b.layer||-1===k.indexOf(b.layer))return void c.error("[AngularJS - Openlayers] - ESRI layers needs a valid 'layer' property.");var r="https://services.arcgisonline.com/ArcGIS/rest/services/",u=r+b.layer+"/MapServer/tile/{z}/{y}/{x}";g=new a.source.XYZ({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:u,wrapX:void 0===b.wrapX||b.wrapX});break;case"TileArcGISRest":b.url||c.error("[AngularJS - Openlayers] - TileArcGISRest Layer needs valid url"),g=new a.source.TileArcGISRest({attributions:t(b),tileLoadFunction:b.tileLoadFunction,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});break;case"GeoJSON":if(!b.geojson&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a geojson property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.GeoJSON,url:b.url});else{g=new a.source.Vector;var v,w=f;v=e(b.geojson.projection)?new a.proj.get(b.geojson.projection):f;var x=m.readFeatures(b.geojson.object,{featureProjection:w.getCode(),dataProjection:v.getCode()});g.addFeatures(x)}break;case"WKT":if(!b.wkt&&!b.url)return void c.error("[AngularJS - Openlayers] - You need a WKT property to add a GeoJSON layer.");if(e(b.url))g=new a.source.Vector({format:new a.format.WKT,url:b.url,wrapX:void 0===b.wrapX||b.wrapX});else{g=new a.source.Vector;var y,z=f;y=e(b.wkt.projection)?new a.proj.get(b.wkt.projection):f;for(var A=new a.format.WKT,B=[],C=0;C-1)return a.source[b.type][d]}return null},v=function(b){var c=new a.layer.Group;return c.set("name",b),c},w=function(b,c){var d;return angular.forEach(b,function(b){if(b instanceof a.layer.Group&&b.get("name")===c)return void(d=b)}),d},x=function(a,b){for(var c,d=0;d Date: Thu, 8 Mar 2018 15:00:51 +0530 Subject: [PATCH 50/53] Common JS Changes - To Support Angular Module --- grunt/concat.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/grunt/concat.js b/grunt/concat.js index 31e34c2f..ddad09bd 100644 --- a/grunt/concat.js +++ b/grunt/concat.js @@ -4,6 +4,7 @@ var banner = '(function (root, factory) {\n' + ' if (typeof require === \'function\' && typeof exports === \'object\') {\n' + ' // CommonJS\n' + ' var ol = require(\'openlayers\');\n' + + ' var ngSanitize = require(\'angular-sanitize\');\n' + ' exports.angularOpenlayersDirective = factory(ol);\n' + ' } else if (typeof define === \'function\' && define.amd) {\n' + ' // AMD.\n' + @@ -16,12 +17,15 @@ var banner = '(function (root, factory) {\n' + ' }\n' + '}(this, function (ol) {\n'; +var footer = 'return angular.module(\'openlayers-directive\');' + + '\n}));'; + module.exports = function (grunt, options) { return { dist: { options: { banner: banner, - footer: '\n}));' + footer: footer }, src: [ 'src/directives/openlayers.js', From 7e424ddf8565b64697f4ff3c688be3360d0456aa Mon Sep 17 00:00:00 2001 From: Sathish Kesavaperumal Date: Thu, 8 Mar 2018 18:53:32 +0530 Subject: [PATCH 51/53] feat(concat.js): compatibility with commonjs for angular module support --- grunt/concat.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/grunt/concat.js b/grunt/concat.js index 31e34c2f..78351f28 100644 --- a/grunt/concat.js +++ b/grunt/concat.js @@ -4,7 +4,8 @@ var banner = '(function (root, factory) {\n' + ' if (typeof require === \'function\' && typeof exports === \'object\') {\n' + ' // CommonJS\n' + ' var ol = require(\'openlayers\');\n' + - ' exports.angularOpenlayersDirective = factory(ol);\n' + + ' var ngSanitize = require(\'angular-sanitize\');\n' + + ' module.exports = factory(ol);\n' + ' } else if (typeof define === \'function\' && define.amd) {\n' + ' // AMD.\n' + ' define([\'ol\'], function (ol) {\n' + @@ -16,12 +17,15 @@ var banner = '(function (root, factory) {\n' + ' }\n' + '}(this, function (ol) {\n'; +var footer = 'return angular.module(\'openlayers-directive\');' + + '\n}));'; + module.exports = function (grunt, options) { return { dist: { options: { banner: banner, - footer: '\n}));' + footer: footer }, src: [ 'src/directives/openlayers.js', From 13cf9f978de2a625375b683f215281a5dbf1752e Mon Sep 17 00:00:00 2001 From: vdevara Date: Thu, 4 Jun 2020 20:16:51 +0530 Subject: [PATCH 52/53] Updated angular-sanitize version. --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 1053ed32..91f01f22 100644 --- a/package.json +++ b/package.json @@ -18,11 +18,11 @@ "license": "MIT", "dependencies": { "angular": "~1.4.8", - "angular-sanitize": "~1.4.8", + "angular-sanitize": "1.7.9", "openlayers": "4.3.4" }, "devDependencies": { - "grunt": "~0.4.5", + "grunt": "^0.4.5", "grunt-bower-task": "~0.4.0", "grunt-bump": "^0.3.0", "grunt-contrib-concat": "~0.5.0", @@ -67,4 +67,4 @@ }, "main": "dist/angular-openlayers-directive", "version": "2.1.0" -} \ No newline at end of file +} From c6d9170bb788da49f013d744257a9f6ab2622f8a Mon Sep 17 00:00:00 2001 From: vdevara Date: Fri, 5 Jun 2020 10:36:53 +0530 Subject: [PATCH 53/53] Updated angular-sanitize version. --- package.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 91f01f22..15951a91 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "openlayers": "4.3.4" }, "devDependencies": { - "grunt": "^0.4.5", + "grunt": "~0.4.5", "grunt-bower-task": "~0.4.0", "grunt-bump": "^0.3.0", "grunt-contrib-concat": "~0.5.0", @@ -55,7 +55,9 @@ "phantomjs": "^2.1.0", "protractor": "~2.5.0", "publish-latest": "^1.1.2", - "semantic-release": "^4.3.5" + "semantic-release": "^4.3.5", + "bower": "^1.8.8", + "requirejs": "^2.3.6" }, "scripts": { "test": "grunt build && grunt karma:unit",