Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

esri-leaflet

Package Overview
Dependencies
Maintainers
1
Versions
71
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

esri-leaflet - npm Package Compare versions

Comparing version 1.0.0 to 2.0.0-beta.1

dist/esri-leaflet-v2.0.0-beta.1

2

bower.json
{
"name": "esri-leaflet",
"version": "v1.0.0",
"version": "v2.0.0-beta.1",
"main": "dist/esri-leaflet.js",

@@ -5,0 +5,0 @@ "ignore": [

@@ -1,5 +0,49 @@

# Changelog
# Change Log
## 1.0.0
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).
[Upcoming changes][unreleased]
## [2.0.0-beta.1](v2.0.0-beta.1)
This release is the first release that supports [Leaflet 1.0.0-beta.1](http://leafletjs.com/2015/07/15/leaflet-1.0-beta1-released.html).
### Added
* New `featureLayer.resetFeatureStyle(id, style)` for reseting the styles on a specific feature to their original style.
### Changed
* By default basemap layers `GrayLabels`, `DarkGrayLabels`, `OceansLabels`, `ImageryLabels`, `ImageryTransportation`, `ShadedReliefLabels`, `TerrainLabels` will now be rendered on top of polygons and polylines if the browser supports [CSS Pointer Events](https://developer.mozilla.org/en-US/docs/Web/CSS/pointer-events). You can disable this behavior by passing `{pane: "tilePane"}` in the `L.esri.basemapLayer` options.
* Now relies on the [Leaflet 1.0.0-beta.1 release](http://leafletjs.com/2015/07/15/leaflet-1.0-beta1-released.html)
* Rewritten build and test systems to rely on ES 2015 Modules specification
* More build and release automation
* `featureLayer.resetStyle` no longer takes and id and will reset the style of all features. Use the new `featureLayer.resetFeatureStyle(id, style)` method.
* Styling point feature layers using vector markers like `L.circleMarker` should now also use the `style` option to set the styles of the vector markers as opposed to setting it in the `L.circleMarker` options. This enables the `setStyle`, `resetStyle`, `setFeatureStyle` and `resetFeatureStyle` options to work properly.
```js
L.esri.featureLayer({
url: 'http://...',
// define how to convert your point into a layer
pointToLayer: function(latlng, feature){
return L.circleMarker(latlng);
},
// style that vector layer
style: {
radius: 10,
color: 'red'
}
})
```
### Removed
* All alternate/compact builds have been removed. They will be replaced with a new system for generating custom builds soon.
* `L.esri.Request` has been removed. Please use `L.esri.get`, `L.esri.get.CORS`, `L.esri.get.JSONP`, `L.esri.post` or `L.esri.request` directly.
## [1.0.0](v1.0.0)
This represents the stable release of Esri Leaflet compatible with Leaflet 0.7.3. All future 1.0.X releases will be compatible with Leaflet 0.7.3 and contain only bug fixes. New features will only be added in Esri Leaflet 2.0.0 which will require Leaflet 1.0.0.

@@ -11,3 +55,3 @@

#### Breaking Changes
### Breaking Changes

@@ -39,3 +83,3 @@ * `L.esri.Services.FeatureLayer` has been renamed to `L.esri.Services.FeatureLayerService`. It should be initialized with `L.esri.Services.featureLayerService(options)`.

#### Changes
### Changes

@@ -48,9 +92,9 @@ * Added support for the `dynamicLayers` option to `L.esri.DynamicMapLayer` https://github.com/Esri/esri-leaflet/issues/566

## Release Candidate 8
## [Release Candidate 8](v1.0.0-rc.8)
#### Breaking Changes
### Breaking Changes
* CDN moved to JS Delivr http://www.jsdelivr.com/#!leaflet.esri
#### Changes
### Changes

@@ -63,9 +107,9 @@ * Non standard scale levels from tile services published in web mercator are now remapped to the standard scale levels https://github.com/Esri/esri-leaflet/pull/548 https://github.com/Esri/esri-leaflet/issues/530

## Release Candidate 7
## [Release Candidate 7](v1.0.0-rc.7)
#### Breaking Changes
### Breaking Changes
* DynamicMapLayer will now request `json` by default to better expose the authentication process. If you are using ArcGIS Server 10.0 or have disabled CORS on your server you will need to add `useCors: false` to your options.
#### Changes
### Changes
* refactor of `FeatureLayer.resetStyle()` behavior. https://github.com/Esri/esri-leaflet/issues/488

@@ -85,23 +129,23 @@ * improvement of `DynamicMapLayer` image loading logic. https://github.com/Esri/esri-leaflet/issues/498

## Release Candidate 6
## [Release Candidate 6](v1.0.0-rc.6)
#### Breaking Changes
### Breaking Changes
None
#### Changes
### Changes
* `f:'json'` will now be used automatically when a proxy is set for `L.esri.DynamicMapLayer`. https://github.com/Esri/esri-leaflet/issues/464
* Callback functions will now only be run once when there is a CORS error. https://github.com/Esri/esri-leaflet/issues/465
* Layer ids will now beinlucded with the GeoJSON response from `identify()` and `L.esri.Tasks.Identify`. https://github.com/Esri/esri-leaflet/issues/443
* Layer ids will now be included with the GeoJSON response from `identify()` and `L.esri.Tasks.Identify`. https://github.com/Esri/esri-leaflet/issues/443
* Bugfix for adding/removing certain basemap layers. https://github.com/Esri/esri-leaflet/issues/455
## Release Candidate 5
## [Release Candidate 5](v1.0.0-rc.5)
#### Breaking Changes
### Breaking Changes
* All `Task` and `Service` constructors now accept `url` as a value within options, rather than as a seperate parameter. [#420](https://github.com/Esri/esri-leaflet/issues/420)
* 'Layer' objects continue to expect a `url' string to be supplied as the first parameter, but afterwards, the property is now accessible via Layer.options.url instead of Layer.url
* All `Task` and `Service` constructors now accept `url` as a value within options, rather than as a separate parameter. [#420](https://github.com/Esri/esri-leaflet/issues/420)
* 'Layer' objects continue to expect a `url` string to be supplied as the first parameter, but afterwards, the property is now accessible via Layer.options.url instead of Layer.url
#### Changes
### Changes

@@ -115,5 +159,5 @@ * Fixed duplicate Esri logo bug [#427](https://github.com/Esri/esri-leaflet/issues/427)

## Release Candidate 4
## [Release Candidate 4](v1.0.0-rc.4)
#### Changes
### Changes

@@ -124,5 +168,5 @@ * Fixed a bug where resetStyle would not work with MultiPolygon and MultiPolyline features [#390](https://github.com/Esri/esri-leaflet/issues/390)

## Release Candidate 3
## [Release Candidate 3](v1.0.0-rc.3)
#### Changes
### Changes

@@ -136,5 +180,5 @@ * Removed hardcoded http call in `L.esri.Controls.Logo` [#383](https://github.com/Esri/esri-leaflet/issues/383)

## Release Candidate 2
## [Release Candidate 2](v1.0.0-rc.2)
#### Changes
### Changes

@@ -146,15 +190,15 @@ * Fixed IE 8 and 9 support that was broken in RC 1.

* Added `contains`, `overlaps` and `intersects` to `L.esri.Tasks.Query`.
* Spatial methods on `L.esri.Tasks.Query` can now accept the follwoing Leaflet types, `L.Marker`, `L.Polygon`, `L.Polyline`, `L.LatLng`, `L.LatLngBounds` and `L.GeoJSON`. It can also accept valid GeoJSON Point, Polyline, Polygon and GeoJSON Feautre objects containing Point, Polyline, Polygon.
* Spatial methods on `L.esri.Tasks.Query` can now accept the following Leaflet types, `L.Marker`, `L.Polygon`, `L.Polyline`, `L.LatLng`, `L.LatLngBounds` and `L.GeoJSON`. It can also accept valid GeoJSON Point, Polyline, Polygon and GeoJSON Feature objects containing Point, Polyline, Polygon.
* Most methods that accept `L.LatLng` and `L.LatLngBounds` now accept the simple [lat,lng] or [[lat,lng], [lat,lng]] forms.
## Release Candidate 1
## [Release Candidate 1](v1.0.0-rc.1)
#### Changes
### Changes
* `L.esri.Task` now accepts `proxy` and `useCors` like `L.esri.Service`. https://github.com/Esri/esri-leaflet/pull/359
* Esri Leaflet can now be used in Common JS (browserify) and AMD (Dojo, RequierJS) module loaders. Examples will be coming soon.
* Esri Leaflet can now be used in Common JS (browserify) and AMD (Dojo, RequireJS) module loaders. Examples will be coming soon.
* Source maps are now built and distributed along with the distribution files to aid in debugging. To learn how to use the source maps [Treehouse](http://blog.teamtreehouse.com/introduction-source-maps) and [HTML5Rocks](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/) have excellent resources.
* `L.esri.ClusteredFeatureLayer` has been moved to its own repository. https://github.com/Esri/esri-leaflet-clustered-feature-layer
* `L.esri.HeatmapFeatureLayer` has been moved to its own repository. https://github.com/Esri/esri-leaflet-heatmap-feature-layer
* An edgecase when converting ArcGIS > GeoJSON has been resolved https://github.com/Esri/esri-leaflet/pull/340
* `popupOptions` are now properly presvered https://github.com/Esri/esri-leaflet/pull/348
* An edge case when converting ArcGIS > GeoJSON has been resolved https://github.com/Esri/esri-leaflet/pull/340
* `popupOptions` are now properly persevered https://github.com/Esri/esri-leaflet/pull/348
* `setStyle` now permanently overrides the style in `options.style`. https://github.com/Esri/esri-leaflet/pull/349

@@ -165,4 +209,5 @@ * `setWhere` and `setTimeRange` now take callbacks. https://github.com/Esri/esri-leaflet/pull/354

* a sample.html file was added to help jumpstart debugging local source files. https://github.com/Esri/esri-leaflet/pull/364
#### Breaking Changes
### Breaking Changes
* Task methods that accept callbacks (like `run` or `bounds`) now return an instance of `XMLHttpRequest` as opposed to the task or service.

@@ -172,11 +217,11 @@ * `bindPopup` on `L.esri.DynamicMapLayer` now identifies only visible features by default rather then all features.

#### Changes
### Changes
## Beta 6
## [Beta 6](v0.0.1-beta.6)
#### Breaking Changes
### Breaking Changes
* `L.esri.Tasks.Identify` has been renamed to `L.esri.Tasks.IdentifyFeatures`. This is to reduce confusion with `L.esri.Tasks.IdentifyImage` and to clearly delineate what these 2 classes do.
#### Changes
### Changes
* Logo position can now be controlled by using the `logoPosition` option on `L.esri.BasemapLayer` https://github.com/Esri/esri-leaflet/issues/210

@@ -193,3 +238,3 @@ * Logo can now be hidden entirely and re-added to the map with the `L.esri.Controls.Logo` class. **If you use Esri map tiles you must display the Esri Logo!**

#### Misc
### Misc
* [New example](esri.github.io/esri-leaflet/examples/parse-feature-collection.html) for parsing [Feature Collections](http://resources.arcgis.com/en/help/arcgis-rest-api/#/featureCollection/02r30000003m000000/) from ArcGIS Online.

@@ -201,5 +246,5 @@ * [New example]() for labeling points with [Leaflet.label](https://github.com/Leaflet/Leaflet.label).

## Beta 5
## [Beta 5](v0.0.1-beta.5)
#### Breaking Changes
### Breaking Changes

@@ -217,3 +262,3 @@ * `Oceans` no longer contains map labels, labels have been added as another key `OceansLabels`.

#### Changes
### Changes

@@ -223,3 +268,3 @@ * Added `OceansLabels` to `L.esri.BasemapLayer`.

* `L.esri.FeatureLayer` has been refactored into several classes. `L.esri.FeatureGrid` and `L.esri.FeatureManager` now handle loading and querying features from the service.
* `L.esri.ClusteredFeatureLayer` and `L.esri.HeatMapFeatureLayer` now inherit from `L.`L.esri.FeatureManager` so they share many new methods and options.
* `L.esri.ClusteredFeatureLayer` and `L.esri.HeatMapFeatureLayer` now inherit from `L.esri.FeatureManager` so they share many new methods and options.
* `L.esri.FeatureLayer`, `L.esri.ClusteredFeatureLayer` and `L.esri.HeatMapFeatureLayer` now support time enabled service via `from`, `to`, `timeFields` and `timeFilterMode` options and `setTimeRange(from, to)` and `getTimeRange()` methods.

@@ -241,5 +286,5 @@ * `L.esri.FeatureLayer`, `L.esri.ClusteredFeatureLayer` and `L.esri.HeatMapFeatureLayer` now support `where` options and have new methods for `setWhere()` and `getWhere()` to perform filtering.

## Beta 4 Patch 1
## [Beta 4 Patch 1](v0.0.1-beta.4-patch-1)
#### Changes
### Changes

@@ -249,9 +294,9 @@ * Patches a bug with identifying features on DynamicMapLayer

## Beta 4
## [Beta 4](v0.0.1-beta.4)
#### New Demos
### New Demos
* Heat map layer - http://esri.github.io/esri-leaflet/heatmaplayer.html
* Geocoder - http://esri.github.io/esri-leaflet/findplaces.html
#### Changes
### Changes

@@ -266,3 +311,3 @@ * Authentication for ClusteredFeatureLayer https://github.com/Esri/esri-leaflet/commit/d23ddd99ee86bb7255e4d89b6cf3f339a441c88b

# Beta 3
## [Beta 3](v0.0.1-beta.3)

@@ -274,1 +319,18 @@ * Improve DynamicMapLayer panning and zooming performance. #137

* An attributionControl on maps is now required when using BasemapLayer. #159
[unreleased]: https://github.com/esri/esri-leaflet/compare/v2.0.0-beta.1...HEAD
[v2.0.0-beta.1]: https://github.com/esri/esri-leaflet/compare/v1.0.0...v2.0.0-beta.1
[v1.0.0]: https://github.com/esri/esri-leaflet/compare/v1.0.0-rc.8...v1.0.0
[v1.0.0-rc.8]: https://github.com/esri/esri-leaflet/compare/v1.0.0-rc.7...v1.0.0-rc.8
[v1.0.0-rc.7]: https://github.com/esri/esri-leaflet/compare/v1.0.0-rc.6...v1.0.0-rc.7
[v1.0.0-rc.6]: https://github.com/esri/esri-leaflet/compare/v1.0.0-rc.5...v1.0.0-rc.6
[v1.0.0-rc.5]: https://github.com/esri/esri-leaflet/compare/v1.0.0-rc.4...v1.0.0-rc.5
[v1.0.0-rc.4]: https://github.com/esri/esri-leaflet/compare/v1.0.0-rc.3...v1.0.0-rc.4
[v1.0.0-rc.3]: https://github.com/esri/esri-leaflet/compare/v1.0.0-rc.2...v1.0.0-rc.3
[v1.0.0-rc.2]: https://github.com/esri/esri-leaflet/compare/v1.0.0-rc.1...v1.0.0-rc.2
[v1.0.0-rc.1]: https://github.com/esri/esri-leaflet/compare/v0.0.1-beta.6...v1.0.0-rc.1
[v0.0.1-beta.6]: https://github.com/esri/esri-leaflet/compare/v0.0.1-beta.5...v0.0.1-beta.6
[v0.0.1-beta.5]: https://github.com/esri/esri-leaflet/compare/v0.0.1-beta.4-patch-1...v0.0.1-beta.5
[v0.0.1-beta.4-patch-1]: https://github.com/esri/esri-leaflet/compare/v0.0.1-beta.4...v0.0.1-beta.4-patch-1
[v0.0.1-beta.4]: https://github.com/esri/esri-leaflet/compare/v0.0.1-beta.3...v0.0.1-beta.4
[v0.0.1-beta.3]: https://github.com/esri/esri-leaflet/compare/v0.0.1-beta.2...v0.0.1-beta.3

@@ -1,25 +0,6 @@

/*! esri-leaflet - v1.0.0 - 2015-07-10
/*! esri-leaflet - v2.0.0-beta.1 - Sun Jul 19 2015
* Copyright (c) 2015 Environmental Systems Research Institute, Inc.
* Apache License*/
(function (factory) {
//define an AMD module that relies on 'leaflet'
if (typeof define === 'function' && define.amd) {
define(['leaflet'], function (L) {
return factory(L);
});
//define a common js module that relies on 'leaflet'
} else if (typeof module === 'object' && typeof module.exports === 'object') {
module.exports = factory(require('leaflet'));
}
if(typeof window !== 'undefined' && window.L){
factory(window.L);
}
}(function (L) {
var EsriLeaflet={VERSION:"1.0.0",Layers:{},Services:{},Controls:{},Tasks:{},Util:{},Support:{CORS:!!(window.XMLHttpRequest&&"withCredentials"in new XMLHttpRequest),pointerEvents:""===document.documentElement.style.pointerEvents}};"undefined"!=typeof window&&window.L&&(window.L.esri=EsriLeaflet),function(a){function b(a){var b={};for(var c in a)a.hasOwnProperty(c)&&(b[c]=a[c]);return b}function c(a,b){for(var c=0;c<a.length;c++)if(a[c]!==b[c])return!1;return!0}function d(a){return c(a[0],a[a.length-1])||a.push(a[0]),a}function e(a){var b,c=0,d=0,e=a.length,f=a[d];for(d;e-1>d;d++)b=a[d+1],c+=(b[0]-f[0])*(b[1]+f[1]),f=b;return c>=0}function f(a,b,c,d){var e=(d[0]-c[0])*(a[1]-c[1])-(d[1]-c[1])*(a[0]-c[0]),f=(b[0]-a[0])*(a[1]-c[1])-(b[1]-a[1])*(a[0]-c[0]),g=(d[1]-c[1])*(b[0]-a[0])-(d[0]-c[0])*(b[1]-a[1]);if(0!==g){var h=e/g,i=f/g;if(h>=0&&1>=h&&i>=0&&1>=i)return!0}return!1}function g(a,b){for(var c=0;c<a.length-1;c++)for(var d=0;d<b.length-1;d++)if(f(a[c],a[c+1],b[d],b[d+1]))return!0;return!1}function h(a,b){for(var c=!1,d=-1,e=a.length,f=e-1;++d<e;f=d)(a[d][1]<=b[1]&&b[1]<a[f][1]||a[f][1]<=b[1]&&b[1]<a[d][1])&&b[0]<(a[f][0]-a[d][0])*(b[1]-a[d][1])/(a[f][1]-a[d][1])+a[d][0]&&(c=!c);return c}function i(a,b){var c=g(a,b),d=h(a,b[0]);return!c&&d?!0:!1}function j(a){for(var b,c,f,h=[],j=[],k=0;k<a.length;k++){var l=d(a[k].slice(0));if(!(l.length<4))if(e(l)){var m=[l];h.push(m)}else j.push(l)}for(var n=[];j.length;){f=j.pop();var o=!1;for(b=h.length-1;b>=0;b--)if(c=h[b][0],i(c,f)){h[b].push(f),o=!0;break}o||n.push(f)}for(;n.length;){f=n.pop();var p=!1;for(b=h.length-1;b>=0;b--)if(c=h[b][0],g(c,f)){h[b].push(f),p=!0;break}p||h.push([f.reverse()])}return 1===h.length?{type:"Polygon",coordinates:h[0]}:{type:"MultiPolygon",coordinates:h}}function k(a){var b=[],c=a.slice(0),f=d(c.shift().slice(0));if(f.length>=4){e(f)||f.reverse(),b.push(f);for(var g=0;g<c.length;g++){var h=d(c[g].slice(0));h.length>=4&&(e(h)&&h.reverse(),b.push(h))}}return b}function l(a){for(var b=[],c=0;c<a.length;c++)for(var d=k(a[c]),e=d.length-1;e>=0;e--){var f=d[e].slice(0);b.push(f)}return b}var m=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.msRequestAnimationFrame||function(a){return window.setTimeout(a,1e3/60)};a.Util.extentToBounds=function(a){var b=new L.LatLng(a.ymin,a.xmin),c=new L.LatLng(a.ymax,a.xmax);return new L.LatLngBounds(b,c)},a.Util.boundsToExtent=function(a){return a=L.latLngBounds(a),{xmin:a.getSouthWest().lng,ymin:a.getSouthWest().lat,xmax:a.getNorthEast().lng,ymax:a.getNorthEast().lat,spatialReference:{wkid:4326}}},a.Util.arcgisToGeojson=function(c,d){var e={};return"number"==typeof c.x&&"number"==typeof c.y&&(e.type="Point",e.coordinates=[c.x,c.y]),c.points&&(e.type="MultiPoint",e.coordinates=c.points.slice(0)),c.paths&&(1===c.paths.length?(e.type="LineString",e.coordinates=c.paths[0].slice(0)):(e.type="MultiLineString",e.coordinates=c.paths.slice(0))),c.rings&&(e=j(c.rings.slice(0))),(c.geometry||c.attributes)&&(e.type="Feature",e.geometry=c.geometry?a.Util.arcgisToGeojson(c.geometry):null,e.properties=c.attributes?b(c.attributes):null,c.attributes&&(e.id=c.attributes[d]||c.attributes.OBJECTID||c.attributes.FID)),e},a.Util.geojsonToArcGIS=function(c,d){d=d||"OBJECTID";var e,f={wkid:4326},g={};switch(c.type){case"Point":g.x=c.coordinates[0],g.y=c.coordinates[1],g.spatialReference=f;break;case"MultiPoint":g.points=c.coordinates.slice(0),g.spatialReference=f;break;case"LineString":g.paths=[c.coordinates.slice(0)],g.spatialReference=f;break;case"MultiLineString":g.paths=c.coordinates.slice(0),g.spatialReference=f;break;case"Polygon":g.rings=k(c.coordinates.slice(0)),g.spatialReference=f;break;case"MultiPolygon":g.rings=l(c.coordinates.slice(0)),g.spatialReference=f;break;case"Feature":c.geometry&&(g.geometry=a.Util.geojsonToArcGIS(c.geometry,d)),g.attributes=c.properties?b(c.properties):{},c.id&&(g.attributes[d]=c.id);break;case"FeatureCollection":for(g=[],e=0;e<c.features.length;e++)g.push(a.Util.geojsonToArcGIS(c.features[e],d));break;case"GeometryCollection":for(g=[],e=0;e<c.geometries.length;e++)g.push(a.Util.geojsonToArcGIS(c.geometries[e],d))}return g},a.Util.responseToFeatureCollection=function(b,c){var d;if(c)d=c;else if(b.objectIdFieldName)d=b.objectIdFieldName;else if(b.fields){for(var e=0;e<=b.fields.length-1;e++)if("esriFieldTypeOID"===b.fields[e].type){d=b.fields[e].name;break}}else d="OBJECTID";var f={type:"FeatureCollection",features:[]},g=b.features||b.results;if(g.length)for(var h=g.length-1;h>=0;h--)f.features.push(a.Util.arcgisToGeojson(g[h],d));return f},a.Util.cleanUrl=function(a){return a=a.replace(/^\s+|\s+$|\A\s+|\s+\z/g,""),"/"!==a[a.length-1]&&(a+="/"),a},a.Util.isArcgisOnline=function(a){return/\.arcgis\.com.*?FeatureServer/g.test(a)},a.Util.geojsonTypeToArcGIS=function(a){var b;switch(a){case"Point":b="esriGeometryPoint";break;case"MultiPoint":b="esriGeometryMultipoint";break;case"LineString":b="esriGeometryPolyline";break;case"MultiLineString":b="esriGeometryPolyline";break;case"Polygon":b="esriGeometryPolygon";break;case"MultiPolygon":b="esriGeometryPolygon"}return b},a.Util.requestAnimationFrame=L.Util.bind(m,window),a.Util.warn=function(a){console&&console.warn&&console.warn(a)}}(EsriLeaflet),function(a){function b(a){var b="";a.f=a.f||"json";for(var c in a)if(a.hasOwnProperty(c)){var d,e=a[c],f=Object.prototype.toString.call(e);b.length&&(b+="&"),d="[object Array]"===f?"[object Object]"===Object.prototype.toString.call(e[0])?JSON.stringify(e):e.join(","):"[object Object]"===f?JSON.stringify(e):"[object Date]"===f?e.valueOf():e,b+=encodeURIComponent(c)+"="+encodeURIComponent(d)}return b}function c(a,b){var c=new XMLHttpRequest;return c.onerror=function(d){c.onreadystatechange=L.Util.falseFn,a.call(b,{error:{code:500,message:"XMLHttpRequest error"}},null)},c.onreadystatechange=function(){var d,e;if(4===c.readyState){try{d=JSON.parse(c.responseText)}catch(f){d=null,e={code:500,message:"Could not parse response as JSON. This could also be caused by a CORS or XMLHttpRequest error."}}!e&&d.error&&(e=d.error,d=null),c.onerror=L.Util.falseFn,a.call(b,e,d)}},c}var d=0;window._EsriLeafletCallbacks={},a.Request={request:function(d,e,f,g){var h=b(e),i=c(f,g),j=(d+"?"+h).length;if(2e3>=j&&L.esri.Support.CORS)i.open("GET",d+"?"+h),i.send(null);else{if(!(j>2e3&&L.esri.Support.CORS))return 2e3>=j&&!L.esri.Support.CORS?L.esri.Request.get.JSONP(d,e,f,g):void a.Util.warn("a request to "+d+" was longer then 2000 characters and this browser cannot make a cross-domain post request. Please use a proxy http://esri.github.io/esri-leaflet/api-reference/request.html");i.open("POST",d),i.setRequestHeader("Content-Type","application/x-www-form-urlencoded"),i.send(h)}return i},post:{XMLHTTP:function(a,d,e,f){var g=c(e,f);return g.open("POST",a),g.setRequestHeader("Content-Type","application/x-www-form-urlencoded"),g.send(b(d)),g}},get:{CORS:function(a,d,e,f){var g=c(e,f);return g.open("GET",a+"?"+b(d),!0),g.send(null),g},JSONP:function(a,c,e,f){var g="c"+d;c.callback="window._EsriLeafletCallbacks."+g;var h=L.DomUtil.create("script",null,document.body);return h.type="text/javascript",h.src=a+"?"+b(c),h.id=g,window._EsriLeafletCallbacks[g]=function(a){if(window._EsriLeafletCallbacks[g]!==!0){var b,c=Object.prototype.toString.call(a);"[object Object]"!==c&&"[object Array]"!==c&&(b={error:{code:500,message:"Expected array or object as JSONP response"}},a=null),!b&&a.error&&(b=a,a=null),e.call(f,b,a),window._EsriLeafletCallbacks[g]=!0}},d++,{id:g,url:h.src,abort:function(){window._EsriLeafletCallbacks._callback[g]({code:0,message:"Request aborted."})}}}}},a.get=a.Support.CORS?a.Request.get.CORS:a.Request.get.JSONP,a.post=a.Request.post.XMLHTTP,a.request=a.Request.request}(EsriLeaflet),EsriLeaflet.Services.Service=L.Class.extend({includes:L.Mixin.Events,options:{proxy:!1,useCors:EsriLeaflet.Support.CORS},initialize:function(a){a=a||{},this._requestQueue=[],this._authenticating=!1,L.Util.setOptions(this,a),this.options.url=EsriLeaflet.Util.cleanUrl(this.options.url)},get:function(a,b,c,d){return this._request("get",a,b,c,d)},post:function(a,b,c,d){return this._request("post",a,b,c,d)},request:function(a,b,c,d){return this._request("request",a,b,c,d)},metadata:function(a,b){return this._request("get","",{},a,b)},authenticate:function(a){return this._authenticating=!1,this.options.token=a,this._runQueue(),this},_request:function(a,b,c,d,e){this.fire("requeststart",{url:this.options.url+b,params:c,method:a});var f=this._createServiceCallback(a,b,c,d,e);if(this.options.token&&(c.token=this.options.token),this._authenticating)return void this._requestQueue.push([a,b,c,d,e]);var g=this.options.proxy?this.options.proxy+"?"+this.options.url+b:this.options.url+b;return"get"!==a&&"request"!==a||this.options.useCors?EsriLeaflet[a](g,c,f):EsriLeaflet.Request.get.JSONP(g,c,f)},_createServiceCallback:function(a,b,c,d,e){return L.Util.bind(function(f,g){!f||499!==f.code&&498!==f.code||(this._authenticating=!0,this._requestQueue.push([a,b,c,d,e]),this.fire("authenticationrequired",{authenticate:L.Util.bind(this.authenticate,this)}),f.authenticate=L.Util.bind(this.authenticate,this)),d.call(e,f,g),f?this.fire("requesterror",{url:this.options.url+b,params:c,message:f.message,code:f.code,method:a}):this.fire("requestsuccess",{url:this.options.url+b,params:c,response:g,method:a}),this.fire("requestend",{url:this.options.url+b,params:c,method:a})},this)},_runQueue:function(){for(var a=this._requestQueue.length-1;a>=0;a--){var b=this._requestQueue[a],c=b.shift();this[c].apply(this,b)}this._requestQueue=[]}}),EsriLeaflet.Services.service=function(a){return new EsriLeaflet.Services.Service(a)},EsriLeaflet.Services.FeatureLayerService=EsriLeaflet.Services.Service.extend({options:{idAttribute:"OBJECTID"},query:function(){return new EsriLeaflet.Tasks.Query(this)},addFeature:function(a,b,c){return delete a.id,a=EsriLeaflet.Util.geojsonToArcGIS(a),this.post("addFeatures",{features:[a]},function(a,d){var e=d&&d.addResults?d.addResults[0]:void 0;b&&b.call(c,a||d.addResults[0].error,e)},c)},updateFeature:function(a,b,c){return a=EsriLeaflet.Util.geojsonToArcGIS(a,this.options.idAttribute),this.post("updateFeatures",{features:[a]},function(a,d){var e=d&&d.updateResults?d.updateResults[0]:void 0;b&&b.call(c,a||d.updateResults[0].error,e)},c)},deleteFeature:function(a,b,c){return this.post("deleteFeatures",{objectIds:a},function(a,d){var e=d&&d.deleteResults?d.deleteResults[0]:void 0;b&&b.call(c,a||d.deleteResults[0].error,e)},c)},deleteFeatures:function(a,b,c){return this.post("deleteFeatures",{objectIds:a},function(a,d){var e=d&&d.deleteResults?d.deleteResults:void 0;b&&b.call(c,a||d.deleteResults[0].error,e)},c)}}),EsriLeaflet.Services.featureLayerService=function(a){return new EsriLeaflet.Services.FeatureLayerService(a)},EsriLeaflet.Services.MapService=EsriLeaflet.Services.Service.extend({identify:function(){return new EsriLeaflet.Tasks.identifyFeatures(this)},find:function(){return new EsriLeaflet.Tasks.Find(this)},query:function(){return new EsriLeaflet.Tasks.Query(this)}}),EsriLeaflet.Services.mapService=function(a){return new EsriLeaflet.Services.MapService(a)},EsriLeaflet.Services.ImageService=EsriLeaflet.Services.Service.extend({query:function(){return new EsriLeaflet.Tasks.Query(this)},identify:function(){return new EsriLeaflet.Tasks.IdentifyImage(this)}}),EsriLeaflet.Services.imageService=function(a){return new EsriLeaflet.Services.ImageService(a)},EsriLeaflet.Tasks.Task=L.Class.extend({options:{proxy:!1,useCors:EsriLeaflet.Support.CORS},generateSetter:function(a,b){return L.Util.bind(function(b){return this.params[a]=b,this},b)},initialize:function(a){if(a.request&&a.options?(this._service=a,L.Util.setOptions(this,a.options)):(L.Util.setOptions(this,a),this.options.url=L.esri.Util.cleanUrl(a.url)),this.params=L.Util.extend({},this.params||{}),this.setters)for(var b in this.setters){var c=this.setters[b];this[b]=this.generateSetter(c,this)}},token:function(a){return this._service?this._service.authenticate(a):this.params.token=a,this},request:function(a,b){return this._service?this._service.request(this.path,this.params,a,b):this._request("request",this.path,this.params,a,b)},_request:function(a,b,c,d,e){var f=this.options.proxy?this.options.proxy+"?"+this.options.url+b:this.options.url+b;return"get"!==a&&"request"!==a||this.options.useCors?EsriLeaflet[a](f,c,d,e):EsriLeaflet.Request.get.JSONP(f,c,d,e)}}),EsriLeaflet.Tasks.Query=EsriLeaflet.Tasks.Task.extend({setters:{offset:"offset",limit:"limit",fields:"outFields",precision:"geometryPrecision",featureIds:"objectIds",returnGeometry:"returnGeometry",token:"token"},path:"query",params:{returnGeometry:!0,where:"1=1",outSr:4326,outFields:"*"},within:function(a){return this._setGeometry(a),this.params.spatialRel="esriSpatialRelContains",this},intersects:function(a){return this._setGeometry(a),this.params.spatialRel="esriSpatialRelIntersects",this},contains:function(a){return this._setGeometry(a),this.params.spatialRel="esriSpatialRelWithin",this},overlaps:function(a){return this._setGeometry(a),this.params.spatialRel="esriSpatialRelOverlaps",this},nearby:function(a,b){return a=L.latLng(a),this.params.geometry=[a.lng,a.lat],this.params.geometryType="esriGeometryPoint",this.params.spatialRel="esriSpatialRelIntersects",this.params.units="esriSRUnit_Meter",this.params.distance=b,this.params.inSr=4326,this},where:function(a){return this.params.where=a,this},between:function(a,b){return this.params.time=[a.valueOf(),b.valueOf()],this},simplify:function(a,b){var c=Math.abs(a.getBounds().getWest()-a.getBounds().getEast());return this.params.maxAllowableOffset=c/a.getSize().y*b,this},orderBy:function(a,b){return b=b||"ASC",this.params.orderByFields=this.params.orderByFields?this.params.orderByFields+",":"",this.params.orderByFields+=[a,b].join(" "),this},run:function(a,b){return this._cleanParams(),EsriLeaflet.Util.isArcgisOnline(this.options.url)?(this.params.f="geojson",this.request(function(c,d){this._trapSQLerrors(c),a.call(b,c,d,d)},this)):this.request(function(c,d){this._trapSQLerrors(c),a.call(b,c,d&&EsriLeaflet.Util.responseToFeatureCollection(d),d)},this)},count:function(a,b){return this._cleanParams(),this.params.returnCountOnly=!0,this.request(function(b,c){a.call(this,b,c&&c.count,c)},b)},ids:function(a,b){return this._cleanParams(),this.params.returnIdsOnly=!0,this.request(function(b,c){a.call(this,b,c&&c.objectIds,c)},b)},bounds:function(a,b){return this._cleanParams(),this.params.returnExtentOnly=!0,this.request(function(c,d){a.call(b,c,d&&d.extent&&EsriLeaflet.Util.extentToBounds(d.extent),d)},b)},pixelSize:function(a){return a=L.point(a),this.params.pixelSize=[a.x,a.y],this},layer:function(a){return this.path=a+"/query",this},_trapSQLerrors:function(a){a&&"400"===a.code&&EsriLeaflet.Util.warn("one common syntax error in query requests is encasing string values in double quotes instead of single quotes")},_cleanParams:function(){delete this.params.returnIdsOnly,delete this.params.returnExtentOnly,delete this.params.returnCountOnly},_setGeometry:function(a){return this.params.inSr=4326,a instanceof L.LatLngBounds?(this.params.geometry=EsriLeaflet.Util.boundsToExtent(a),void(this.params.geometryType="esriGeometryEnvelope")):(a.getLatLng&&(a=a.getLatLng()),a instanceof L.LatLng&&(a={type:"Point",coordinates:[a.lng,a.lat]}),a instanceof L.GeoJSON&&(a=a.getLayers()[0].feature.geometry,this.params.geometry=EsriLeaflet.Util.geojsonToArcGIS(a),this.params.geometryType=EsriLeaflet.Util.geojsonTypeToArcGIS(a.type)),a.toGeoJSON&&(a=a.toGeoJSON()),"Feature"===a.type&&(a=a.geometry),"Point"===a.type||"LineString"===a.type||"Polygon"===a.type?(this.params.geometry=EsriLeaflet.Util.geojsonToArcGIS(a),void(this.params.geometryType=EsriLeaflet.Util.geojsonTypeToArcGIS(a.type))):void EsriLeaflet.Util.warn("invalid geometry passed to spatial query. Should be an L.LatLng, L.LatLngBounds or L.Marker or a GeoJSON Point Line or Polygon object"))}}),EsriLeaflet.Tasks.query=function(a){return new EsriLeaflet.Tasks.Query(a)},EsriLeaflet.Tasks.Find=EsriLeaflet.Tasks.Task.extend({setters:{contains:"contains",text:"searchText",fields:"searchFields",spatialReference:"sr",sr:"sr",layers:"layers",returnGeometry:"returnGeometry",maxAllowableOffset:"maxAllowableOffset",precision:"geometryPrecision",dynamicLayers:"dynamicLayers",returnZ:"returnZ",returnM:"returnM",gdbVersion:"gdbVersion",token:"token"},path:"find",params:{sr:4326,contains:!0,returnGeometry:!0,returnZ:!0,returnM:!1},layerDefs:function(a,b){return this.params.layerDefs=this.params.layerDefs?this.params.layerDefs+";":"",this.params.layerDefs+=[a,b].join(":"),this},simplify:function(a,b){var c=Math.abs(a.getBounds().getWest()-a.getBounds().getEast());return this.params.maxAllowableOffset=c/a.getSize().y*b,this},run:function(a,b){return this.request(function(c,d){a.call(b,c,d&&EsriLeaflet.Util.responseToFeatureCollection(d),d)},b)}}),EsriLeaflet.Tasks.find=function(a){return new EsriLeaflet.Tasks.Find(a)},EsriLeaflet.Tasks.Identify=EsriLeaflet.Tasks.Task.extend({path:"identify",between:function(a,b){return this.params.time=[a.valueOf(),b.valueOf()],this}}),EsriLeaflet.Tasks.IdentifyImage=EsriLeaflet.Tasks.Identify.extend({setters:{setMosaicRule:"mosaicRule",setRenderingRule:"renderingRule",setPixelSize:"pixelSize",returnCatalogItems:"returnCatalogItems",returnGeometry:"returnGeometry"},params:{returnGeometry:!1},at:function(a){return a=L.latLng(a),this.params.geometry=JSON.stringify({x:a.lng,y:a.lat,spatialReference:{wkid:4326}}),this.params.geometryType="esriGeometryPoint",this},getMosaicRule:function(){return this.params.mosaicRule},getRenderingRule:function(){return this.params.renderingRule},getPixelSize:function(){return this.params.pixelSize},run:function(a,b){return this.request(function(c,d){a.call(b,c,d&&this._responseToGeoJSON(d),d)},this)},_responseToGeoJSON:function(a){var b=a.location,c=a.catalogItems,d=a.catalogItemVisibilities,e={pixel:{type:"Feature",geometry:{type:"Point",coordinates:[b.x,b.y]},crs:{type:"EPSG",properties:{code:b.spatialReference.wkid}},properties:{OBJECTID:a.objectId,name:a.name,value:a.value},id:a.objectId}};if(a.properties&&a.properties.Values&&(e.pixel.properties.values=a.properties.Values),c&&c.features&&(e.catalogItems=EsriLeaflet.Util.responseToFeatureCollection(c),d&&d.length===e.catalogItems.features.length))for(var f=d.length-1;f>=0;f--)e.catalogItems.features[f].properties.catalogItemVisibility=d[f];return e}}),EsriLeaflet.Tasks.identifyImage=function(a){return new EsriLeaflet.Tasks.IdentifyImage(a)},EsriLeaflet.Tasks.IdentifyFeatures=EsriLeaflet.Tasks.Identify.extend({setters:{layers:"layers",precision:"geometryPrecision",tolerance:"tolerance",returnGeometry:"returnGeometry"},params:{sr:4326,layers:"all",tolerance:3,returnGeometry:!0},on:function(a){var b=EsriLeaflet.Util.boundsToExtent(a.getBounds()),c=a.getSize();return this.params.imageDisplay=[c.x,c.y,96],this.params.mapExtent=[b.xmin,b.ymin,b.xmax,b.ymax],this},at:function(a){return a=L.latLng(a),this.params.geometry=[a.lng,a.lat],this.params.geometryType="esriGeometryPoint",this},layerDef:function(a,b){return this.params.layerDefs=this.params.layerDefs?this.params.layerDefs+";":"",this.params.layerDefs+=[a,b].join(":"),this},simplify:function(a,b){var c=Math.abs(a.getBounds().getWest()-a.getBounds().getEast());return this.params.maxAllowableOffset=c/a.getSize().y*(1-b),this},run:function(a,b){return this.request(function(c,d){if(c)return void a.call(b,c,void 0,d);var e=EsriLeaflet.Util.responseToFeatureCollection(d);d.results=d.results.reverse();for(var f=0;f<e.features.length;f++){var g=e.features[f];g.layerId=d.results[f].layerId}a.call(b,void 0,e,d)})}}),EsriLeaflet.Tasks.identifyFeatures=function(a){return new EsriLeaflet.Tasks.IdentifyFeatures(a)},function(a){var b="https:"!==window.location.protocol?"http:":"https:";a.Layers.BasemapLayer=L.TileLayer.extend({statics:{TILES:{Streets:{urlTemplate:b+"//{s}.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}",attributionUrl:"https://static.arcgis.com/attribution/World_Street_Map",options:{hideLogo:!1,logoPosition:"bottomright",minZoom:1,maxZoom:19,subdomains:["server","services"],attribution:"Esri"}},Topographic:{urlTemplate:b+"//{s}.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}",attributionUrl:"https://static.arcgis.com/attribution/World_Topo_Map",options:{hideLogo:!1,logoPosition:"bottomright",minZoom:1,maxZoom:19,subdomains:["server","services"],attribution:"Esri"}},Oceans:{urlTemplate:b+"//{s}.arcgisonline.com/arcgis/rest/services/Ocean/World_Ocean_Base/MapServer/tile/{z}/{y}/{x}",attributionUrl:"https://static.arcgis.com/attribution/Ocean_Basemap",options:{hideLogo:!1,logoPosition:"bottomright",minZoom:1,maxZoom:16,subdomains:["server","services"],attribution:"Esri"}},OceansLabels:{urlTemplate:b+"//{s}.arcgisonline.com/arcgis/rest/services/Ocean/World_Ocean_Reference/MapServer/tile/{z}/{y}/{x}",options:{hideLogo:!0,logoPosition:"bottomright",minZoom:1,maxZoom:16,subdomains:["server","services"]}},NationalGeographic:{urlTemplate:b+"//{s}.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer/tile/{z}/{y}/{x}",options:{hideLogo:!1,logoPosition:"bottomright",minZoom:1,maxZoom:16,subdomains:["server","services"],attribution:"Esri"}},DarkGray:{urlTemplate:b+"//{s}.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Dark_Gray_Base/MapServer/tile/{z}/{y}/{x}",options:{hideLogo:!1,logoPosition:"bottomright",minZoom:1,maxZoom:16,subdomains:["server","services"],attribution:"Esri, DeLorme, HERE"}},DarkGrayLabels:{urlTemplate:b+"//{s}.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Dark_Gray_Reference/MapServer/tile/{z}/{y}/{x}",options:{hideLogo:!0,logoPosition:"bottomright",minZoom:1,maxZoom:16,subdomains:["server","services"]}},Gray:{urlTemplate:b+"//{s}.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer/tile/{z}/{y}/{x}",options:{hideLogo:!1,logoPosition:"bottomright",minZoom:1,maxZoom:16,subdomains:["server","services"],attribution:"Esri, NAVTEQ, DeLorme"}},GrayLabels:{urlTemplate:b+"//{s}.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Reference/MapServer/tile/{z}/{y}/{x}",options:{hideLogo:!0,logoPosition:"bottomright",minZoom:1,maxZoom:16,subdomains:["server","services"]}},Imagery:{urlTemplate:b+"//{s}.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}",options:{hideLogo:!1,logoPosition:"bottomright",minZoom:1,maxZoom:19,subdomains:["server","services"],attribution:"Esri, DigitalGlobe, GeoEye, i-cubed, USDA, USGS, AEX, Getmapping, Aerogrid, IGN, IGP, swisstopo, and the GIS User Community"}},ImageryLabels:{urlTemplate:b+"//{s}.arcgisonline.com/ArcGIS/rest/services/Reference/World_Boundaries_and_Places/MapServer/tile/{z}/{y}/{x}",options:{hideLogo:!0,logoPosition:"bottomright",minZoom:1,maxZoom:19,subdomains:["server","services"]}},ImageryTransportation:{urlTemplate:b+"//{s}.arcgisonline.com/ArcGIS/rest/services/Reference/World_Transportation/MapServer/tile/{z}/{y}/{x}",options:{hideLogo:!0,logoPosition:"bottomright",minZoom:1,maxZoom:19,subdomains:["server","services"]}},ShadedRelief:{urlTemplate:b+"//{s}.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer/tile/{z}/{y}/{x}",options:{hideLogo:!1,logoPosition:"bottomright",minZoom:1,maxZoom:13,subdomains:["server","services"],attribution:"Esri, NAVTEQ, DeLorme"}},ShadedReliefLabels:{urlTemplate:b+"//{s}.arcgisonline.com/ArcGIS/rest/services/Reference/World_Boundaries_and_Places_Alternate/MapServer/tile/{z}/{y}/{x}",options:{hideLogo:!0,logoPosition:"bottomright",minZoom:1,maxZoom:12,subdomains:["server","services"]}},Terrain:{urlTemplate:b+"//{s}.arcgisonline.com/ArcGIS/rest/services/World_Terrain_Base/MapServer/tile/{z}/{y}/{x}",options:{hideLogo:!1,logoPosition:"bottomright",minZoom:1,maxZoom:13,subdomains:["server","services"],attribution:"Esri, USGS, NOAA"}},TerrainLabels:{urlTemplate:b+"//{s}.arcgisonline.com/ArcGIS/rest/services/Reference/World_Reference_Overlay/MapServer/tile/{z}/{y}/{x}",options:{hideLogo:!0,logoPosition:"bottomright",minZoom:1,maxZoom:13,subdomains:["server","services"]}}}},initialize:function(b,c){var d;if("object"==typeof b&&b.urlTemplate&&b.options)d=b;else{if("string"!=typeof b||!a.BasemapLayer.TILES[b])throw new Error('L.esri.BasemapLayer: Invalid parameter. Use one of "Streets", "Topographic", "Oceans", "OceansLabels", "NationalGeographic", "Gray", "GrayLabels", "DarkGray", "DarkGrayLabels", "Imagery", "ImageryLabels", "ImageryTransportation", "ShadedRelief", "ShadedReliefLabels", "Terrain" or "TerrainLabels"');d=a.BasemapLayer.TILES[b]}var e=L.Util.extend(d.options,c);L.TileLayer.prototype.initialize.call(this,d.urlTemplate,L.Util.setOptions(this,e)),d.attributionUrl&&this._getAttributionData(d.attributionUrl),this._logo=new a.Controls.Logo({position:this.options.logoPosition})},onAdd:function(a){this.options.hideLogo||a._hasEsriLogo||(this._logo.addTo(a),a._hasEsriLogo=!0),L.TileLayer.prototype.onAdd.call(this,a),a.on("moveend",this._updateMapAttribution,this)},onRemove:function(a){this._logo&&this._logo._container&&(a.removeControl(this._logo),a._hasEsriLogo=!1),L.TileLayer.prototype.onRemove.call(this,a),a.off("moveend",this._updateMapAttribution,this)},getAttribution:function(){var a='<span class="esri-attributions" style="line-height:14px; vertical-align: -3px; text-overflow:ellipsis; white-space:nowrap; overflow:hidden; display:inline-block;">'+this.options.attribution+"</span>";return a},_getAttributionData:function(a){L.esri.Request.get.JSONP(a,{},L.Util.bind(function(a,b){this._attributions=[];for(var c=0;c<b.contributors.length;c++)for(var d=b.contributors[c],e=0;e<d.coverageAreas.length;e++){var f=d.coverageAreas[e],g=new L.LatLng(f.bbox[0],f.bbox[1]),h=new L.LatLng(f.bbox[2],f.bbox[3]);this._attributions.push({attribution:d.attribution,score:f.score,bounds:new L.LatLngBounds(g,h),minZoom:f.zoomMin,maxZoom:f.zoomMax})}this._attributions.sort(function(a,b){return b.score-a.score}),this._updateMapAttribution()},this))},_updateMapAttribution:function(){if(this._map&&this._map.attributionControl&&this._attributions){for(var a="",b=this._map.getBounds(),c=this._map.getZoom(),d=0;d<this._attributions.length;d++){var e=this._attributions[d],f=e.attribution;!a.match(f)&&b.intersects(e.bounds)&&c>=e.minZoom&&c<=e.maxZoom&&(a+=", "+f)}a=a.substr(2);var g=this._map.attributionControl._container.querySelector(".esri-attributions");g.innerHTML=a,g.style.maxWidth=.65*this._map.getSize().x+"px",this.fire("attributionupdated",{attribution:a})}}}),a.BasemapLayer=a.Layers.BasemapLayer,a.Layers.basemapLayer=function(b,c){return new a.Layers.BasemapLayer(b,c)},a.basemapLayer=function(b,c){return new a.Layers.BasemapLayer(b,c)}}(EsriLeaflet),EsriLeaflet.Layers.RasterLayer=L.Class.extend({includes:L.Mixin.Events,options:{opacity:1,position:"front",f:"image"},onAdd:function(a){if(this._map=a,this._update=L.Util.limitExecByInterval(this._update,this.options.updateInterval,this),a.options.crs&&a.options.crs.code){var b=a.options.crs.code.split(":")[1];this.options.bboxSR=b,this.options.imageSR=b}a.on("moveend",this._update,this),this._currentImage&&this._currentImage._bounds.equals(this._map.getBounds())?a.addLayer(this._currentImage):this._currentImage&&(this._map.removeLayer(this._currentImage),this._currentImage=null),this._update(),this._popup&&(this._map.on("click",this._getPopupData,this),this._map.on("dblclick",this._resetPopupState,this))},bindPopup:function(a,b){return this._shouldRenderPopup=!1,this._lastClick=!1,this._popup=L.popup(b),this._popupFunction=a,this._map&&(this._map.on("click",this._getPopupData,this),this._map.on("dblclick",this._resetPopupState,this)),this},unbindPopup:function(){return this._map&&(this._map.closePopup(this._popup),this._map.off("click",this._getPopupData,this),this._map.off("dblclick",this._resetPopupState,this)),this._popup=!1,this},onRemove:function(a){this._currentImage&&this._map.removeLayer(this._currentImage),this._popup&&(this._map.off("click",this._getPopupData,this),this._map.off("dblclick",this._resetPopupState,this)),this._map.off("moveend",this._update,this),this._map=null},addTo:function(a){return a.addLayer(this),this},removeFrom:function(a){return a.removeLayer(this),this},bringToFront:function(){return this.options.position="front",this._currentImage&&this._currentImage.bringToFront(),this},bringToBack:function(){return this.options.position="back",this._currentImage&&this._currentImage.bringToBack(),this},getAttribution:function(){return this.options.attribution},getOpacity:function(){return this.options.opacity},setOpacity:function(a){return this.options.opacity=a,this._currentImage.setOpacity(a),this},getTimeRange:function(){return[this.options.from,this.options.to]},setTimeRange:function(a,b){return this.options.from=a,this.options.to=b,this._update(),this},metadata:function(a,b){return this._service.metadata(a,b),this},authenticate:function(a){return this._service.authenticate(a),this},_renderImage:function(a,b){if(this._map){var c=new L.ImageOverlay(a,b,{opacity:0}).addTo(this._map);c.once("load",function(a){var c=a.target,d=this._currentImage;c._bounds.equals(b)&&c._bounds.equals(this._map.getBounds())?(this._currentImage=c,"front"===this.options.position?this.bringToFront():this.bringToBack(),this._map&&this._currentImage._map?this._currentImage.setOpacity(this.options.opacity):this._currentImage._map.removeLayer(this._currentImage),d&&this._map&&this._map.removeLayer(d),d&&d._map&&d._map.removeLayer(d)):this._map.removeLayer(c),this.fire("load",{bounds:b})},this),this.fire("loading",{bounds:b})}},_update:function(){if(this._map){var a=this._map.getZoom(),b=this._map.getBounds();if(!this._animatingZoom&&!(this._map._panTransition&&this._map._panTransition._inProgress||a>this.options.maxZoom||a<this.options.minZoom)){var c=this._buildExportParams();this._requestExport(c,b)}}},_renderPopup:function(a,b,c,d){if(a=L.latLng(a),this._shouldRenderPopup&&this._lastClick.equals(a)){var e=this._popupFunction(b,c,d);e&&this._popup.setLatLng(a).setContent(e).openOn(this._map)}},_resetPopupState:function(a){this._shouldRenderPopup=!1,this._lastClick=a.latlng},_propagateEvent:function(a){a=L.extend({layer:a.target,target:this},a),this.fire(a.type,a)}}),EsriLeaflet.Layers.DynamicMapLayer=EsriLeaflet.Layers.RasterLayer.extend({options:{updateInterval:150,layers:!1,layerDefs:!1,timeOptions:!1,format:"png24",transparent:!0,f:"json"},initialize:function(a){a.url=EsriLeaflet.Util.cleanUrl(a.url),this._service=new EsriLeaflet.Services.MapService(a),this._service.on("authenticationrequired requeststart requestend requesterror requestsuccess",this._propagateEvent,this),(a.proxy||a.token)&&"json"!==a.f&&(a.f="json"),L.Util.setOptions(this,a)},getDynamicLayers:function(){return this.options.dynamicLayers},setDynamicLayers:function(a){return this.options.dynamicLayers=a,this._update(),this},getLayers:function(){return this.options.layers},setLayers:function(a){return this.options.layers=a,this._update(),this},getLayerDefs:function(){return this.options.layerDefs},setLayerDefs:function(a){return this.options.layerDefs=a,this._update(),this},getTimeOptions:function(){return this.options.timeOptions},setTimeOptions:function(a){return this.options.timeOptions=a,this._update(),this},query:function(){return this._service.query()},identify:function(){return this._service.identify()},find:function(){return this._service.find()},_getPopupData:function(a){var b=L.Util.bind(function(b,c,d){b||setTimeout(L.Util.bind(function(){this._renderPopup(a.latlng,b,c,d)},this),300)},this),c=this.identify().on(this._map).at(a.latlng);this.options.layers?c.layers("visible:"+this.options.layers.join(",")):c.layers("visible"),c.run(b),this._shouldRenderPopup=!0,this._lastClick=a.latlng},_buildExportParams:function(){var a=this._map.getBounds(),b=this._map.getSize(),c=this._map.options.crs.project(a._northEast),d=this._map.options.crs.project(a._southWest),e=this._map.latLngToLayerPoint(a._northEast),f=this._map.latLngToLayerPoint(a._southWest);
(e.y>0||f.y<b.y)&&(b.y=f.y-e.y);var g={bbox:[d.x,d.y,c.x,c.y].join(","),size:b.x+","+b.y,dpi:96,format:this.options.format,transparent:this.options.transparent,bboxSR:this.options.bboxSR,imageSR:this.options.imageSR};return this.options.dynamicLayers&&(g.dynamicLayers=this.options.dynamicLayers),this.options.layers&&(g.layers="show:"+this.options.layers.join(",")),this.options.layerDefs&&(g.layerDefs=JSON.stringify(this.options.layerDefs)),this.options.timeOptions&&(g.timeOptions=JSON.stringify(this.options.timeOptions)),this.options.from&&this.options.to&&(g.time=this.options.from.valueOf()+","+this.options.to.valueOf()),this._service.options.token&&(g.token=this._service.options.token),g},_requestExport:function(a,b){"json"===this.options.f?this._service.request("export",a,function(a,c){a||this._renderImage(c.href,b)},this):(a.f="image",this._renderImage(this.options.url+"export"+L.Util.getParamString(a),b))}}),EsriLeaflet.DynamicMapLayer=EsriLeaflet.Layers.DynamicMapLayer,EsriLeaflet.Layers.dynamicMapLayer=function(a){return new EsriLeaflet.Layers.DynamicMapLayer(a)},EsriLeaflet.dynamicMapLayer=function(a){return new EsriLeaflet.Layers.DynamicMapLayer(a)},EsriLeaflet.Layers.ImageMapLayer=EsriLeaflet.Layers.RasterLayer.extend({options:{updateInterval:150,format:"jpgpng",transparent:!0,f:"json"},query:function(){return this._service.query()},identify:function(){return this._service.identify()},initialize:function(a){a.url=EsriLeaflet.Util.cleanUrl(a.url),this._service=new EsriLeaflet.Services.ImageService(a),this._service.on("authenticationrequired requeststart requestend requesterror requestsuccess",this._propagateEvent,this),L.Util.setOptions(this,a)},setPixelType:function(a){return this.options.pixelType=a,this._update(),this},getPixelType:function(){return this.options.pixelType},setBandIds:function(a){return L.Util.isArray(a)?this.options.bandIds=a.join(","):this.options.bandIds=a.toString(),this._update(),this},getBandIds:function(){return this.options.bandIds},setNoData:function(a,b){return L.Util.isArray(a)?this.options.noData=a.join(","):this.options.noData=a.toString(),b&&(this.options.noDataInterpretation=b),this._update(),this},getNoData:function(){return this.options.noData},getNoDataInterpretation:function(){return this.options.noDataInterpretation},setRenderingRule:function(a){this.options.renderingRule=a,this._update()},getRenderingRule:function(){return this.options.renderingRule},setMosaicRule:function(a){this.options.mosaicRule=a,this._update()},getMosaicRule:function(){return this.options.mosaicRule},_getPopupData:function(a){var b=L.Util.bind(function(b,c,d){b||setTimeout(L.Util.bind(function(){this._renderPopup(a.latlng,b,c,d)},this),300)},this),c=this.identify().at(a.latlng);this.options.mosaicRule&&c.setMosaicRule(this.options.mosaicRule),c.run(b),this._shouldRenderPopup=!0,this._lastClick=a.latlng},_buildExportParams:function(){var a=this._map.getBounds(),b=this._map.getSize(),c=this._map.options.crs.project(a._northEast),d=this._map.options.crs.project(a._southWest),e={bbox:[d.x,d.y,c.x,c.y].join(","),size:b.x+","+b.y,format:this.options.format,transparent:this.options.transparent,bboxSR:this.options.bboxSR,imageSR:this.options.imageSR};return this.options.from&&this.options.to&&(e.time=this.options.from.valueOf()+","+this.options.to.valueOf()),this.options.pixelType&&(e.pixelType=this.options.pixelType),this.options.interpolation&&(e.interpolation=this.options.interpolation),this.options.compressionQuality&&(e.compressionQuality=this.options.compressionQuality),this.options.bandIds&&(e.bandIds=this.options.bandIds),this.options.noData&&(e.noData=this.options.noData),this.options.noDataInterpretation&&(e.noDataInterpretation=this.options.noDataInterpretation),this._service.options.token&&(e.token=this._service.options.token),this.options.renderingRule&&(e.renderingRule=JSON.stringify(this.options.renderingRule)),this.options.mosaicRule&&(e.mosaicRule=JSON.stringify(this.options.mosaicRule)),e},_requestExport:function(a,b){"json"===this.options.f?this._service.request("exportImage",a,function(a,c){a||this._renderImage(c.href,b)},this):(a.f="image",this._renderImage(this.options.url+"exportImage"+L.Util.getParamString(a),b))}}),EsriLeaflet.ImageMapLayer=EsriLeaflet.Layers.ImageMapLayer,EsriLeaflet.Layers.imageMapLayer=function(a){return new EsriLeaflet.Layers.ImageMapLayer(a)},EsriLeaflet.imageMapLayer=function(a){return new EsriLeaflet.Layers.ImageMapLayer(a)},EsriLeaflet.Layers.TiledMapLayer=L.TileLayer.extend({options:{zoomOffsetAllowance:.1,correctZoomLevels:!0},statics:{MercatorZoomLevels:{0:156543.033928,1:78271.5169639999,2:39135.7584820001,3:19567.8792409999,4:9783.93962049996,5:4891.96981024998,6:2445.98490512499,7:1222.99245256249,8:611.49622628138,9:305.748113140558,10:152.874056570411,11:76.4370282850732,12:38.2185141425366,13:19.1092570712683,14:9.55462853563415,15:4.77731426794937,16:2.38865713397468,17:1.19432856685505,18:.597164283559817,19:.298582141647617,20:.14929107082381,21:.07464553541191,22:.0373227677059525,23:.0186613838529763}},initialize:function(a){a.url=EsriLeaflet.Util.cleanUrl(a.url),a=L.Util.setOptions(this,a),this.tileUrl=L.esri.Util.cleanUrl(a.url)+"tile/{z}/{y}/{x}",this._service=new L.esri.Services.MapService(a),this._service.on("authenticationrequired requeststart requestend requesterror requestsuccess",this._propagateEvent,this),this.tileUrl.match("://tiles.arcgisonline.com")&&(this.tileUrl=this.tileUrl.replace("://tiles.arcgisonline.com","://tiles{s}.arcgisonline.com"),a.subdomains=["1","2","3","4"]),this.options.token&&(this.tileUrl+="?token="+this.options.token),L.TileLayer.prototype.initialize.call(this,this.tileUrl,a)},getTileUrl:function(a){return L.Util.template(this.tileUrl,L.extend({s:this._getSubdomain(a),z:this._lodMap[a.z]||a.z,x:a.x,y:a.y},this.options))},onAdd:function(a){!this._lodMap&&this.options.correctZoomLevels?(this._lodMap={},this.metadata(function(b,c){if(!b){var d=c.spatialReference.latestWkid||c.spatialReference.wkid;if(102100===d||3857===d)for(var e=c.tileInfo.lods,f=EsriLeaflet.Layers.TiledMapLayer.MercatorZoomLevels,g=0;g<e.length;g++){var h=e[g];for(var i in f){var j=f[i];if(this._withinPercentage(h.resolution,j,this.options.zoomOffsetAllowance)){this._lodMap[i]=h.level;break}}}else EsriLeaflet.Util.warn("L.esri.TiledMapLayer is using a non-mercator spatial reference. Support may be available through Proj4Leaflet http://esri.github.io/esri-leaflet/examples/non-mercator-projection.html")}L.TileLayer.prototype.onAdd.call(this,a)},this)):L.TileLayer.prototype.onAdd.call(this,a)},metadata:function(a,b){return this._service.metadata(a,b),this},identify:function(){return this._service.identify()},authenticate:function(a){var b="?token="+a;return this.tileUrl=this.options.token?this.tileUrl.replace(/\?token=(.+)/g,b):this.tileUrl+b,this.options.token=a,this._service.authenticate(a),this},_propagateEvent:function(a){a=L.extend({layer:a.target,target:this},a),this.fire(a.type,a)},_withinPercentage:function(a,b,c){var d=Math.abs(a/b-1);return c>d}}),L.esri.TiledMapLayer=L.esri.Layers.tiledMapLayer,L.esri.Layers.tiledMapLayer=function(a){return new L.esri.Layers.TiledMapLayer(a)},L.esri.tiledMapLayer=function(a){return new L.esri.Layers.TiledMapLayer(a)},EsriLeaflet.Layers.FeatureGrid=L.Class.extend({includes:L.Mixin.Events,options:{cellSize:512,updateInterval:150},initialize:function(a){a=L.setOptions(this,a)},onAdd:function(a){this._map=a,this._update=L.Util.limitExecByInterval(this._update,this.options.updateInterval,this),this._map.addEventListener(this.getEvents(),this),this._reset(),this._update()},onRemove:function(){this._map.removeEventListener(this.getEvents(),this),this._removeCells()},getEvents:function(){var a={viewreset:this._reset,moveend:this._update,zoomend:this._onZoom};return a},addTo:function(a){return a.addLayer(this),this},removeFrom:function(a){return a.removeLayer(this),this},_onZoom:function(){var a=this._map.getZoom();a>this.options.maxZoom||a<this.options.minZoom?(this.removeFrom(this._map),this._map.addEventListener("zoomend",this.getEvents().zoomend,this)):this._map.hasLayer(this)||(this._map.removeEventListener("zoomend",this.getEvents().zoomend,this),this.addTo(this._map))},_reset:function(){this._removeCells(),this._cells={},this._activeCells={},this._cellsToLoad=0,this._cellsTotal=0,this._resetWrap()},_resetWrap:function(){var a=this._map,b=a.options.crs;if(!b.infinite){var c=this._getCellSize();b.wrapLng&&(this._wrapLng=[Math.floor(a.project([0,b.wrapLng[0]]).x/c),Math.ceil(a.project([0,b.wrapLng[1]]).x/c)]),b.wrapLat&&(this._wrapLat=[Math.floor(a.project([b.wrapLat[0],0]).y/c),Math.ceil(a.project([b.wrapLat[1],0]).y/c)])}},_getCellSize:function(){return this.options.cellSize},_update:function(){if(this._map){var a=this._map.getPixelBounds(),b=this._map.getZoom(),c=this._getCellSize(),d=[c/2,c/2];if(!(b>this.options.maxZoom||b<this.options.minZoom)){var e=a.min.subtract(d).divideBy(c).floor();e.x=Math.max(e.x,0),e.y=Math.max(e.y,0);var f=L.bounds(e,a.max.add(d).divideBy(c).floor());this._removeOtherCells(f),this._addCells(f)}}},_addCells:function(a){var b,c,d,e=[],f=a.getCenter(),g=this._map.getZoom();for(b=a.min.y;b<=a.max.y;b++)for(c=a.min.x;c<=a.max.x;c++)d=new L.Point(c,b),d.z=g,e.push(d);var h=e.length;if(0!==h)for(this._cellsToLoad+=h,this._cellsTotal+=h,e.sort(function(a,b){return a.distanceTo(f)-b.distanceTo(f)}),c=0;h>c;c++)this._addCell(e[c])},_cellCoordsToBounds:function(a){var b=this._map,c=this.options.cellSize,d=a.multiplyBy(c),e=d.add([c,c]),f=b.unproject(d,a.z).wrap(),g=b.unproject(e,a.z).wrap();return new L.LatLngBounds(f,g)},_cellCoordsToKey:function(a){return a.x+":"+a.y},_keyToCellCoords:function(a){var b=a.split(":"),c=parseInt(b[0],10),d=parseInt(b[1],10);return new L.Point(c,d)},_removeOtherCells:function(a){for(var b in this._cells)a.contains(this._keyToCellCoords(b))||this._removeCell(b)},_removeCell:function(a){var b=this._activeCells[a];b&&(delete this._activeCells[a],this.cellLeave&&this.cellLeave(b.bounds,b.coords),this.fire("cellleave",{bounds:b.bounds,coords:b.coords}))},_removeCells:function(){for(var a in this._cells){var b=this._cells[a].bounds,c=this._cells[a].coords;this.cellLeave&&this.cellLeave(b,c),this.fire("cellleave",{bounds:b,coords:c})}},_addCell:function(a){this._wrapCoords(a);var b=this._cellCoordsToKey(a),c=this._cells[b];c&&!this._activeCells[b]&&(this.cellEnter&&this.cellEnter(c.bounds,a),this.fire("cellenter",{bounds:c.bounds,coords:a}),this._activeCells[b]=c),c||(c={coords:a,bounds:this._cellCoordsToBounds(a)},this._cells[b]=c,this._activeCells[b]=c,this.createCell&&this.createCell(c.bounds,a),this.fire("cellcreate",{bounds:c.bounds,coords:a}))},_wrapCoords:function(a){a.x=this._wrapLng?L.Util.wrapNum(a.x,this._wrapLng):a.x,a.y=this._wrapLat?L.Util.wrapNum(a.y,this._wrapLat):a.y}}),function(a){function b(a){this.values=a||[]}a.Layers.FeatureManager=a.Layers.FeatureGrid.extend({options:{where:"1=1",fields:["*"],from:!1,to:!1,timeField:!1,timeFilterMode:"server",simplifyFactor:0,precision:6},initialize:function(c){if(a.Layers.FeatureGrid.prototype.initialize.call(this,c),c.url=a.Util.cleanUrl(c.url),c=L.setOptions(this,c),this._service=new a.Services.FeatureLayerService(c),"*"!==this.options.fields[0]){for(var d=!1,e=0;e<this.options.fields.length;e++)this.options.fields[e].match(/^(OBJECTID|FID|OID|ID)$/i)&&(d=!0);d===!1&&a.Util.warn("no known esriFieldTypeOID field detected in fields Array. Please add an attribute field containing unique IDs to ensure the layer can be drawn correctly.")}this._service.on("authenticationrequired requeststart requestend requesterror requestsuccess",function(a){a=L.extend({target:this},a),this.fire(a.type,a)},this),this.options.timeField.start&&this.options.timeField.end?(this._startTimeIndex=new b,this._endTimeIndex=new b):this.options.timeField&&(this._timeIndex=new b),this._cache={},this._currentSnapshot=[],this._activeRequests=0,this._pendingRequests=[]},onAdd:function(b){return a.Layers.FeatureGrid.prototype.onAdd.call(this,b)},onRemove:function(b){return a.Layers.FeatureGrid.prototype.onRemove.call(this,b)},getAttribution:function(){return this.options.attribution},createCell:function(a,b){this._requestFeatures(a,b)},_requestFeatures:function(b,c,d){this._activeRequests++,1===this._activeRequests&&this.fire("loading",{bounds:b}),this._buildQuery(b).run(function(e,f,g){g&&g.exceededTransferLimit&&this.fire("drawlimitexceeded"),!e&&f&&f.features.length&&a.Util.requestAnimationFrame(L.Util.bind(function(){this._addFeatures(f.features,c),this._postProcessFeatures(b)},this)),e||!f||f.features.length||this._postProcessFeatures(b),d&&d.call(this,e,f)},this)},_postProcessFeatures:function(a){this._activeRequests--,this._activeRequests<=0&&this.fire("load",{bounds:a})},_cacheKey:function(a){return a.z+":"+a.x+":"+a.y},_addFeatures:function(a,b){var c=this._cacheKey(b);this._cache[c]=this._cache[c]||[];for(var d=a.length-1;d>=0;d--){var e=a[d].id;this._currentSnapshot.push(e),this._cache[c].push(e)}this.options.timeField&&this._buildTimeIndexes(a);var f=this._map.getZoom();f>this.options.maxZoom||f<this.options.minZoom||this.createLayers(a)},_buildQuery:function(a){var b=this._service.query().intersects(a).where(this.options.where).fields(this.options.fields).precision(this.options.precision);return this.options.simplifyFactor&&b.simplify(this._map,this.options.simplifyFactor),"server"===this.options.timeFilterMode&&this.options.from&&this.options.to&&b.between(this.options.from,this.options.to),b},setWhere:function(b,c,d){this.options.where=b&&b.length?b:"1=1";for(var e=[],f=[],g=0,h=null,i=L.Util.bind(function(b,i){if(g--,b&&(h=b),i)for(var j=i.features.length-1;j>=0;j--)f.push(i.features[j].id);0>=g&&(this._currentSnapshot=f,a.Util.requestAnimationFrame(L.Util.bind(function(){this.removeLayers(e),this.addLayers(f),c&&c.call(d,h)},this)))},this),j=this._currentSnapshot.length-1;j>=0;j--)e.push(this._currentSnapshot[j]);for(var k in this._activeCells){g++;var l=this._keyToCellCoords(k),m=this._cellCoordsToBounds(l);this._requestFeatures(m,k,i)}return this},getWhere:function(){return this.options.where},getTimeRange:function(){return[this.options.from,this.options.to]},setTimeRange:function(a,b,c,d){var e=this.options.from,f=this.options.to,g=0,h=null,i=L.Util.bind(function(i){i&&(h=i),this._filterExistingFeatures(e,f,a,b),g--,c&&0>=g&&c.call(d,h)},this);if(this.options.from=a,this.options.to=b,this._filterExistingFeatures(e,f,a,b),"server"===this.options.timeFilterMode)for(var j in this._activeCells){g++;var k=this._keyToCellCoords(j),l=this._cellCoordsToBounds(k);this._requestFeatures(l,j,i)}},refresh:function(){for(var a in this._activeCells){var b=this._keyToCellCoords(a),c=this._cellCoordsToBounds(b);this._requestFeatures(c,a)}this.redraw&&this.once("load",function(){this.eachFeature(function(a){this._redraw(a.feature.id)},this)},this)},_filterExistingFeatures:function(b,c,d,e){var f=b&&c?this._getFeaturesInTimeRange(b,c):this._currentSnapshot,g=this._getFeaturesInTimeRange(d,e);if(g.indexOf)for(var h=0;h<g.length;h++){var i=f.indexOf(g[h]);i>=0&&f.splice(i,1)}a.Util.requestAnimationFrame(L.Util.bind(function(){this.removeLayers(f),this.addLayers(g)},this))},_getFeaturesInTimeRange:function(a,b){var c,d=[];if(this.options.timeField.start&&this.options.timeField.end){var e=this._startTimeIndex.between(a,b),f=this._endTimeIndex.between(a,b);c=e.concat(f)}else c=this._timeIndex.between(a,b);for(var g=c.length-1;g>=0;g--)d.push(c[g].id);return d},_buildTimeIndexes:function(a){var b,c;if(this.options.timeField.start&&this.options.timeField.end){var d=[],e=[];for(b=a.length-1;b>=0;b--)c=a[b],d.push({id:c.id,value:new Date(c.properties[this.options.timeField.start])}),e.push({id:c.id,value:new Date(c.properties[this.options.timeField.end])});this._startTimeIndex.bulkAdd(d),this._endTimeIndex.bulkAdd(e)}else{var f=[];for(b=a.length-1;b>=0;b--)c=a[b],f.push({id:c.id,value:new Date(c.properties[this.options.timeField])});this._timeIndex.bulkAdd(f)}},_featureWithinTimeRange:function(a){if(!this.options.from||!this.options.to)return!0;var b=+this.options.from.valueOf(),c=+this.options.to.valueOf();if("string"==typeof this.options.timeField){var d=+a.properties[this.options.timeField];return d>=b&&c>=d}if(this.options.timeField.start&&this.options.timeField.end){var e=+a.properties[this.options.timeField.start],f=+a.properties[this.options.timeField.end];return e>=b&&c>=e||f>=b&&c>=f}},authenticate:function(a){return this._service.authenticate(a),this},metadata:function(a,b){return this._service.metadata(a,b),this},query:function(){return this._service.query()},_getMetadata:function(a){if(this._metadata){var b;a(b,this._metadata)}else this.metadata(L.Util.bind(function(b,c){this._metadata=c,a(b,this._metadata)},this))},addFeature:function(a,b,c){this._getMetadata(L.Util.bind(function(d,e){this._service.addFeature(a,L.Util.bind(function(d,f){d||(a.properties[e.objectIdField]=f.objectId,a.id=f.objectId,this.createLayers([a])),b&&b.call(c,d,f)},this))},this))},updateFeature:function(a,b,c){this._service.updateFeature(a,function(d,e){d||(this.removeLayers([a.id],!0),this.createLayers([a])),b&&b.call(c,d,e)},this)},deleteFeature:function(a,b,c){this._service.deleteFeature(a,function(a,d){!a&&d.objectId&&this.removeLayers([d.objectId],!0),b&&b.call(c,a,d)},this)},deleteFeatures:function(a,b,c){return this._service.deleteFeatures(a,function(a,d){if(!a&&d.length>0)for(var e=0;e<d.length;e++)this.removeLayers([d[e].objectId],!0);b&&b.call(c,a,d)},this)}}),b.prototype._query=function(a){for(var b,c,d,e=0,f=this.values.length-1;f>=e;)if(d=b=(e+f)/2|0,c=this.values[Math.round(b)],+c.value<+a)e=b+1;else{if(!(+c.value>+a))return b;f=b-1}return~f},b.prototype.sort=function(){this.values.sort(function(a,b){return+b.value-+a.value}).reverse(),this.dirty=!1},b.prototype.between=function(a,b){this.dirty&&this.sort();var c=this._query(a),d=this._query(b);return 0===c&&0===d?[]:(c=Math.abs(c),d=0>d?Math.abs(d):d+1,this.values.slice(c,d))},b.prototype.bulkAdd=function(a){this.dirty=!0,this.values=this.values.concat(a)}}(EsriLeaflet),EsriLeaflet.Layers.FeatureLayer=EsriLeaflet.Layers.FeatureManager.extend({statics:{EVENTS:"click dblclick mouseover mouseout mousemove contextmenu popupopen popupclose"},options:{cacheLayers:!0},initialize:function(a){EsriLeaflet.Layers.FeatureManager.prototype.initialize.call(this,a),a=L.setOptions(this,a),this._layers={},this._leafletIds={},this._key="c"+(1e9*Math.random()).toString(36).replace(".","_")},onAdd:function(a){return a.on("zoomstart zoomend",function(a){this._zooming="zoomstart"===a.type},this),EsriLeaflet.Layers.FeatureManager.prototype.onAdd.call(this,a)},onRemove:function(a){for(var b in this._layers)a.removeLayer(this._layers[b]);return EsriLeaflet.Layers.FeatureManager.prototype.onRemove.call(this,a)},createNewLayer:function(a){return L.GeoJSON.geometryToLayer(a,this.options.pointToLayer,L.GeoJSON.coordsToLatLng,this.options)},_updateLayer:function(a,b){var c=[],d=this.options.coordsToLatLng||L.GeoJSON.coordsToLatLng;switch(b.properties&&(a.feature.properties=b.properties),b.geometry.type){case"Point":c=L.GeoJSON.coordsToLatLng(b.geometry.coordinates),a.setLatLng(c);break;case"LineString":c=L.GeoJSON.coordsToLatLngs(b.geometry.coordinates,0,d),a.setLatLngs(c);break;case"MultiLineString":c=L.GeoJSON.coordsToLatLngs(b.geometry.coordinates,1,d),a.setLatLngs(c);break;case"Polygon":c=L.GeoJSON.coordsToLatLngs(b.geometry.coordinates,1,d),a.setLatLngs(c);break;case"MultiPolygon":c=L.GeoJSON.coordsToLatLngs(b.geometry.coordinates,2,d),a.setLatLngs(c)}},createLayers:function(a){for(var b=a.length-1;b>=0;b--){var c,d=a[b],e=this._layers[d.id];e&&!this._map.hasLayer(e)&&this._map.addLayer(e),e&&(e.setLatLngs||e.setLatLng)&&this._updateLayer(e,d),e||(c=this.createNewLayer(d),c.feature=d,this.options.style?c._originalStyle=this.options.style:c.setStyle&&(c._originalStyle=c.options),c._leaflet_id=this._key+"_"+d.id,this._leafletIds[c._leaflet_id]=d.id,c.on(EsriLeaflet.Layers.FeatureLayer.EVENTS,this._propagateEvent,this),this._popup&&c.bindPopup&&c.bindPopup(this._popup(c.feature,c),this._popupOptions),this.options.onEachFeature&&this.options.onEachFeature(c.feature,c),this._layers[c.feature.id]=c,this.resetStyle(c.feature.id),this.fire("createfeature",{feature:c.feature}),(!this.options.timeField||this.options.timeField&&this._featureWithinTimeRange(d))&&this._map.addLayer(c))}},addLayers:function(a){for(var b=a.length-1;b>=0;b--){var c=this._layers[a[b]];c&&(this.fire("addfeature",{feature:c.feature}),this._map.addLayer(c))}},removeLayers:function(a,b){for(var c=a.length-1;c>=0;c--){var d=a[c],e=this._layers[d];e&&(this.fire("removefeature",{feature:e.feature,permanent:b}),this._map.removeLayer(e)),e&&b&&delete this._layers[d]}},cellEnter:function(a,b){this._zooming||EsriLeaflet.Util.requestAnimationFrame(L.Util.bind(function(){var a=this._cacheKey(b),c=this._cellCoordsToKey(b),d=this._cache[a];this._activeCells[c]&&d&&this.addLayers(d)},this))},cellLeave:function(a,b){this._zooming||EsriLeaflet.Util.requestAnimationFrame(L.Util.bind(function(){var a=this._cacheKey(b),c=this._cellCoordsToKey(b),d=this._cache[a],e=this._map.getBounds();if(!this._activeCells[c]&&d){for(var f=!0,g=0;g<d.length;g++){var h=this._layers[d[g]];h&&h.getBounds&&e.intersects(h.getBounds())&&(f=!1)}f&&this.removeLayers(d,!this.options.cacheLayers),!this.options.cacheLayers&&f&&(delete this._cache[a],delete this._cells[c],delete this._activeCells[c])}},this))},resetStyle:function(a){var b=this._layers[a];return b&&this.setFeatureStyle(b.feature.id,b._originalStyle),this},setStyle:function(a){return this.options.style=a,this.eachFeature(function(b){this.setFeatureStyle(b.feature.id,a)},this),this},setFeatureStyle:function(a,b){var c=this._layers[a];return"function"==typeof b&&(b=b(c.feature)),b||c.defaultOptions||(b=L.Path.prototype.options,b.fill=!0),c&&c.setStyle&&c.setStyle(b),this},bindPopup:function(a,b){this._popup=a,this._popupOptions=b;for(var c in this._layers){var d=this._layers[c],e=this._popup(d.feature,d);d.bindPopup(e,b)}return this},unbindPopup:function(){this._popup=!1;for(var a in this._layers){var b=this._layers[a];if(b.unbindPopup)b.unbindPopup();else if(b.getLayers){var c=b.getLayers();for(var d in c){var e=c[d];e.unbindPopup()}}}return this},eachFeature:function(a,b){for(var c in this._layers)a.call(b,this._layers[c]);return this},getFeature:function(a){return this._layers[a]},bringToBack:function(){this.eachFeature(function(a){a.bringToBack&&a.bringToBack()})},bringToFront:function(){this.eachFeature(function(a){a.bringToFront&&a.bringToFront()})},redraw:function(a){return a&&this._redraw(a),this},_redraw:function(a){var b=this._layers[a],c=b.feature;if(b&&b.setIcon&&this.options.pointToLayer&&this.options.pointToLayer){var d=this.options.pointToLayer(c,L.latLng(c.geometry.coordinates[1],c.geometry.coordinates[0])),e=d.options.icon;b.setIcon(e)}if(b&&b.setStyle&&this.options.pointToLayer){var f=this.options.pointToLayer(c,L.latLng(c.geometry.coordinates[1],c.geometry.coordinates[0])),g=f.options;this.setFeatureStyle(c.id,g)}b&&b.setStyle&&this.options.style&&this.resetStyle(c.id)},_propagateEvent:function(a){a.layer=this._layers[this._leafletIds[a.target._leaflet_id]],a.target=this,this.fire(a.type,a)}}),EsriLeaflet.FeatureLayer=EsriLeaflet.Layers.FeatureLayer,EsriLeaflet.Layers.featureLayer=function(a){return new EsriLeaflet.Layers.FeatureLayer(a)},EsriLeaflet.featureLayer=function(a){return new EsriLeaflet.Layers.FeatureLayer(a)},EsriLeaflet.Controls.Logo=L.Control.extend({options:{position:"bottomright",marginTop:0,marginLeft:0,marginBottom:0,marginRight:0},onAdd:function(){var a=L.DomUtil.create("div","esri-leaflet-logo");return a.style.marginTop=this.options.marginTop,a.style.marginLeft=this.options.marginLeft,a.style.marginBottom=this.options.marginBottom,a.style.marginRight=this.options.marginRight,a.innerHTML=this._adjustLogo(this._map._size),this._map.on("resize",function(b){a.innerHTML=this._adjustLogo(b.newSize)},this),a},_adjustLogo:function(a){return a.x<=600||a.y<=600?'<a href="https://developers.arcgis.com" style="border: none;"><img src="https://js.arcgis.com/3.13/esri/images/map/logo-sm.png" alt="Powered by Esri" style="border: none;"></a>':'<a href="https://developers.arcgis.com" style="border: none;"><img src="https://js.arcgis.com/3.13/esri/images/map/logo-med.png" alt="Powered by Esri" style="border: none;"></a>'}}),EsriLeaflet.Controls.logo=function(a){return new L.esri.Controls.Logo(a)};
//# sourceMappingURL=esri-leaflet.js.map
return EsriLeaflet;
}));
* Apache-2.0 */
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e(t.L.esri={})}(this,function(t){"use strict";function e(t,e){for(var i=0;i<t.length;i++)if(t[i]!==e[i])return!1;return!0}function i(t){return e(t[0],t[t.length-1])||t.push(t[0]),t}function s(t){var e,i=0,s=0,r=t.length,o=t[s];for(s;r-1>s;s++)e=t[s+1],i+=(e[0]-o[0])*(e[1]+o[1]),o=e;return i>=0}function r(t,e,i,s){var r=(s[0]-i[0])*(t[1]-i[1])-(s[1]-i[1])*(t[0]-i[0]),o=(e[0]-t[0])*(t[1]-i[1])-(e[1]-t[1])*(t[0]-i[0]),n=(s[1]-i[1])*(e[0]-t[0])-(s[0]-i[0])*(e[1]-t[1]);if(0!==n){var a=r/n,l=o/n;if(a>=0&&1>=a&&l>=0&&1>=l)return!0}return!1}function o(t,e){for(var i=0;i<t.length-1;i++)for(var s=0;s<e.length-1;s++)if(r(t[i],t[i+1],e[s],e[s+1]))return!0;return!1}function n(t,e){for(var i=!1,s=-1,r=t.length,o=r-1;++s<r;o=s)(t[s][1]<=e[1]&&e[1]<t[o][1]||t[o][1]<=e[1]&&e[1]<t[s][1])&&e[0]<(t[o][0]-t[s][0])*(e[1]-t[s][1])/(t[o][1]-t[s][1])+t[s][0]&&(i=!i);return i}function a(t,e){var i=o(t,e),s=n(t,e[0]);return!i&&s?!0:!1}function l(t){for(var e,r,n,l=[],u=[],h=0;h<t.length;h++){var c=i(t[h].slice(0));if(!(c.length<4))if(s(c)){var p=[c];l.push(p)}else u.push(c)}for(var d=[];u.length;){n=u.pop();var m=!1;for(e=l.length-1;e>=0;e--)if(r=l[e][0],a(r,n)){l[e].push(n),m=!0;break}m||d.push(n)}for(;d.length;){n=d.pop();var f=!1;for(e=l.length-1;e>=0;e--)if(r=l[e][0],o(r,n)){l[e].push(n),f=!0;break}f||l.push([n.reverse()])}return 1===l.length?{type:"Polygon",coordinates:l[0]}:{type:"MultiPolygon",coordinates:l}}function u(t){var e=[],r=t.slice(0),o=i(r.shift().slice(0));if(o.length>=4){s(o)||o.reverse(),e.push(o);for(var n=0;n<r.length;n++){var a=i(r[n].slice(0));a.length>=4&&(s(a)&&a.reverse(),e.push(a))}}return e}function h(t){for(var e=[],i=0;i<t.length;i++)for(var s=u(t[i]),r=s.length-1;r>=0;r--){var o=s[r].slice(0);e.push(o)}return e}function c(t){var e={};for(var i in t)t.hasOwnProperty(i)&&(e[i]=t[i]);return e}function p(t){var e=L.latLng(t.ymin,t.xmin),i=L.latLng(t.ymax,t.xmax);return new L.LatLngBounds(e,i)}function d(t){return t=L.latLngBounds(t),{xmin:t.getSouthWest().lng,ymin:t.getSouthWest().lat,xmax:t.getNorthEast().lng,ymax:t.getNorthEast().lat,spatialReference:{wkid:4326}}}function m(t,e){var i={};return"number"==typeof t.x&&"number"==typeof t.y&&(i.type="Point",i.coordinates=[t.x,t.y]),t.points&&(i.type="MultiPoint",i.coordinates=t.points.slice(0)),t.paths&&(1===t.paths.length?(i.type="LineString",i.coordinates=t.paths[0].slice(0)):(i.type="MultiLineString",i.coordinates=t.paths.slice(0))),t.rings&&(i=l(t.rings.slice(0))),(t.geometry||t.attributes)&&(i.type="Feature",i.geometry=t.geometry?m(t.geometry):null,i.properties=t.attributes?c(t.attributes):null,t.attributes&&(i.id=t.attributes[e]||t.attributes.OBJECTID||t.attributes.FID)),i}function f(t,e){e=e||"OBJECTID";var i,s={wkid:4326},r={};switch(t.type){case"Point":r.x=t.coordinates[0],r.y=t.coordinates[1],r.spatialReference=s;break;case"MultiPoint":r.points=t.coordinates.slice(0),r.spatialReference=s;break;case"LineString":r.paths=[t.coordinates.slice(0)],r.spatialReference=s;break;case"MultiLineString":r.paths=t.coordinates.slice(0),r.spatialReference=s;break;case"Polygon":r.rings=u(t.coordinates.slice(0)),r.spatialReference=s;break;case"MultiPolygon":r.rings=h(t.coordinates.slice(0)),r.spatialReference=s;break;case"Feature":t.geometry&&(r.geometry=f(t.geometry,e)),r.attributes=t.properties?c(t.properties):{},t.id&&(r.attributes[e]=t.id);break;case"FeatureCollection":for(r=[],i=0;i<t.features.length;i++)r.push(f(t.features[i],e));break;case"GeometryCollection":for(r=[],i=0;i<t.geometries.length;i++)r.push(f(t.geometries[i],e))}return r}function y(t,e){var i;if(e)i=e;else if(t.objectIdFieldName)i=t.objectIdFieldName;else if(t.fields){for(var s=0;s<=t.fields.length-1;s++)if("esriFieldTypeOID"===t.fields[s].type){i=t.fields[s].name;break}}else i="OBJECTID";var r={type:"FeatureCollection",features:[]},o=t.features||t.results;if(o.length)for(var n=o.length-1;n>=0;n--)r.features.push(m(o[n],i));return r}function g(t){return t=L.Util.trim(t),"/"!==t[t.length-1]&&(t+="/"),t}function _(t){return/\.arcgis\.com.*?FeatureServer/g.test(t)}function v(t){var e;switch(t){case"Point":e="esriGeometryPoint";break;case"MultiPoint":e="esriGeometryMultipoint";break;case"LineString":e="esriGeometryPolyline";break;case"MultiLineString":e="esriGeometryPolyline";break;case"Polygon":e="esriGeometryPolygon";break;case"MultiPolygon":e="esriGeometryPolygon"}return e}function b(){console&&console.warn&&console.warn.apply(console,arguments)}function x(t){var e="";t.f=t.f||"json";for(var i in t)if(t.hasOwnProperty(i)){var s,r=t[i],o=Object.prototype.toString.call(r);e.length&&(e+="&"),s="[object Array]"===o?"[object Object]"===Object.prototype.toString.call(r[0])?JSON.stringify(r):r.join(","):"[object Object]"===o?JSON.stringify(r):"[object Date]"===o?r.valueOf():r,e+=encodeURIComponent(i)+"="+encodeURIComponent(s)}return e}function S(t,e){var i=new window.XMLHttpRequest;return i.onerror=function(s){i.onreadystatechange=L.Util.falseFn,t.call(e,{error:{code:500,message:"XMLHttpRequest error"}},null)},i.onreadystatechange=function(){var s,r;if(4===i.readyState){try{s=JSON.parse(i.responseText)}catch(o){s=null,r={code:500,message:"Could not parse response as JSON. This could also be caused by a CORS or XMLHttpRequest error."}}!r&&s.error&&(r=s.error,s=null),i.onerror=L.Util.falseFn,t.call(e,r,s)}},i}function T(t,e,i,s){var r=S(i,s);return r.open("POST",t),r.setRequestHeader("Content-Type","application/x-www-form-urlencoded"),r.send(x(e)),r}function I(t,e,i,s){var r=S(i,s);return r.open("GET",t+"?"+x(e),!0),r.send(null),r}function w(t,e,i,s){var r=x(e),o=S(i,s),n=(t+"?"+r).length;if(2e3>=n&&Q.cors)o.open("GET",t+"?"+r),o.send(null);else{if(!(n>2e3&&Q.cors))return 2e3>=n&&!Q.cors?R(t,e,i,s):void b("a request to "+t+" was longer then 2000 characters and this browser cannot make a cross-domain post request. Please use a proxy http://esri.github.io/esri-leaflet/api-reference/request.html");o.open("POST",t),o.setRequestHeader("Content-Type","application/x-www-form-urlencoded"),o.send(r)}return o}function R(t,e,i,s){var r="c"+H;e.callback="window._EsriLeafletCallbacks."+r;var o=L.DomUtil.create("script",null,document.body);return o.type="text/javascript",o.src=t+"?"+x(e),o.id=r,window._EsriLeafletCallbacks[r]=function(t){if(window._EsriLeafletCallbacks[r]!==!0){var e,o=Object.prototype.toString.call(t);"[object Object]"!==o&&"[object Array]"!==o&&(e={error:{code:500,message:"Expected array or object as JSONP response"}},t=null),!e&&t.error&&(e=t,t=null),i.call(s,e,t),window._EsriLeafletCallbacks[r]=!0}},H++,{id:r,url:o.src,abort:function(){window._EsriLeafletCallbacks._callback[r]({code:0,message:"Request aborted."})}}}function P(t){return new $(t)}function F(t){return new Y(t)}function C(t){return new et(t)}function O(t){return new it(t)}function k(t){return new st(t)}function M(t){return new rt(t)}function q(t){return new ot(t)}function G(t){return new nt(t)}function E(t){return new at(t)}function A(t){return new lt(t)}function D(t){return new ut(t)}function j(t,e){return new ct(t,e)}function B(t,e){return new pt(t,e)}function U(t,e){return new mt(t,e)}function z(t,e){return new ft(t,e)}function Z(t){this.values=t||[]}function N(t){return new _t(t)}var W=window.XMLHttpRequest&&"withCredentials"in new window.XMLHttpRequest,J=""===document.documentElement.style.pointerEvents,Q={cors:W,pointerEvents:J};t.Support=Q;var V={shallowClone:c,warn:b,cleanUrl:g,isArcgisOnline:_,geojsonTypeToArcGIS:v,responseToFeatureCollection:y,geojsonToArcGIS:f,arcgisToGeojson:m,boundsToExtent:d,extentToBounds:p};t.Util=V;var H=0;window._EsriLeafletCallbacks={};var K=Q.cors?I:R;K.CORS=I,K.JSONP=R;var X={request:w,get:K,post:T};t.get=K,t.post=T,t.request=w;var $=L.Class.extend({options:{proxy:!1,useCors:W},generateSetter:function(t,e){return L.Util.bind(function(e){return this.params[t]=e,this},e)},initialize:function(t){if(t.request&&t.options?(this._service=t,L.Util.setOptions(this,t.options)):(L.Util.setOptions(this,t),this.options.url=g(t.url)),this.params=L.Util.extend({},this.params||{}),this.setters)for(var e in this.setters){var i=this.setters[e];this[e]=this.generateSetter(i,this)}},token:function(t){return this._service?this._service.authenticate(t):this.params.token=t,this},request:function(t,e){return this._service?this._service.request(this.path,this.params,t,e):this._request("request",this.path,this.params,t,e)},_request:function(t,e,i,s,r){var o=this.options.proxy?this.options.proxy+"?"+this.options.url+e:this.options.url+e;return"get"!==t&&"request"!==t||this.options.useCors?X[t](o,i,s,r):X.get.JSONP(o,i,s,r)}}),Y=$.extend({setters:{offset:"offset",limit:"limit",fields:"outFields",precision:"geometryPrecision",featureIds:"objectIds",returnGeometry:"returnGeometry",token:"token"},path:"query",params:{returnGeometry:!0,where:"1=1",outSr:4326,outFields:"*"},within:function(t){return this._setGeometry(t),this.params.spatialRel="esriSpatialRelContains",this},intersects:function(t){return this._setGeometry(t),this.params.spatialRel="esriSpatialRelIntersects",this},contains:function(t){return this._setGeometry(t),this.params.spatialRel="esriSpatialRelWithin",this},crosses:function(t){return this._setGeometry(t),this.params.spatialRel="esriSpatialRelCrosses",this},touches:function(t){return this._setGeometry(t),this.params.spatialRel="esriSpatialRelTouches",this},overlaps:function(t){return this._setGeometry(t),this.params.spatialRel="esriSpatialRelOverlaps",this},nearby:function(t,e){return t=L.latLng(t),this.params.geometry=[t.lng,t.lat],this.params.geometryType="esriGeometryPoint",this.params.spatialRel="esriSpatialRelIntersects",this.params.units="esriSRUnit_Meter",this.params.distance=e,this.params.inSr=4326,this},where:function(t){return this.params.where=t,this},between:function(t,e){return this.params.time=[t.valueOf(),e.valueOf()],this},simplify:function(t,e){var i=Math.abs(t.getBounds().getWest()-t.getBounds().getEast());return this.params.maxAllowableOffset=i/t.getSize().y*e,this},orderBy:function(t,e){return e=e||"ASC",this.params.orderByFields=this.params.orderByFields?this.params.orderByFields+",":"",this.params.orderByFields+=[t,e].join(" "),this},run:function(t,e){return this._cleanParams(),V.isArcgisOnline(this.options.url)?(this.params.f="geojson",this.request(function(i,s){this._trapSQLerrors(i),t.call(e,i,s,s)},this)):this.request(function(i,s){this._trapSQLerrors(i),t.call(e,i,s&&V.responseToFeatureCollection(s),s)},this)},count:function(t,e){return this._cleanParams(),this.params.returnCountOnly=!0,this.request(function(e,i){t.call(this,e,i&&i.count,i)},e)},ids:function(t,e){return this._cleanParams(),this.params.returnIdsOnly=!0,this.request(function(e,i){t.call(this,e,i&&i.objectIds,i)},e)},bounds:function(t,e){return this._cleanParams(),this.params.returnExtentOnly=!0,this.request(function(i,s){t.call(e,i,s&&s.extent&&V.extentToBounds(s.extent),s)},e)},pixelSize:function(t){return t=L.point(t),this.params.pixelSize=[t.x,t.y],this},layer:function(t){return this.path=t+"/query",this},_trapSQLerrors:function(t){t&&"400"===t.code&&V.warn("one common syntax error in query requests is encasing string values in double quotes instead of single quotes")},_cleanParams:function(){delete this.params.returnIdsOnly,delete this.params.returnExtentOnly,delete this.params.returnCountOnly},_setGeometry:function(t){return this.params.inSr=4326,t instanceof L.LatLngBounds?(this.params.geometry=V.boundsToExtent(t),void(this.params.geometryType="esriGeometryEnvelope")):(t.getLatLng&&(t=t.getLatLng()),t instanceof L.LatLng&&(t={type:"Point",coordinates:[t.lng,t.lat]}),t instanceof L.GeoJSON&&(t=t.getLayers()[0].feature.geometry,this.params.geometry=V.geojsonToArcGIS(t),this.params.geometryType=V.geojsonTypeToArcGIS(t.type)),t.toGeoJSON&&(t=t.toGeoJSON()),"Feature"===t.type&&(t=t.geometry),"Point"===t.type||"LineString"===t.type||"Polygon"===t.type?(this.params.geometry=V.geojsonToArcGIS(t),void(this.params.geometryType=V.geojsonTypeToArcGIS(t.type))):void V.warn("invalid geometry passed to spatial query. Should be an L.LatLng, L.LatLngBounds or L.Marker or a GeoJSON Point Line or Polygon object"))}}),tt=F,et=$.extend({setters:{contains:"contains",text:"searchText",fields:"searchFields",spatialReference:"sr",sr:"sr",layers:"layers",returnGeometry:"returnGeometry",maxAllowableOffset:"maxAllowableOffset",precision:"geometryPrecision",dynamicLayers:"dynamicLayers",returnZ:"returnZ",returnM:"returnM",gdbVersion:"gdbVersion",token:"token"},path:"find",params:{sr:4326,contains:!0,returnGeometry:!0,returnZ:!0,returnM:!1},layerDefs:function(t,e){return this.params.layerDefs=this.params.layerDefs?this.params.layerDefs+";":"",this.params.layerDefs+=[t,e].join(":"),this},simplify:function(t,e){var i=Math.abs(t.getBounds().getWest()-t.getBounds().getEast());return this.params.maxAllowableOffset=i/t.getSize().y*e,this},run:function(t,e){return this.request(function(i,s){t.call(e,i,s&&V.responseToFeatureCollection(s),s)},e)}}),it=$.extend({path:"identify",between:function(t,e){return this.params.time=[t.valueOf(),e.valueOf()],this}}),st=it.extend({setters:{layers:"layers",precision:"geometryPrecision",tolerance:"tolerance",returnGeometry:"returnGeometry"},params:{sr:4326,layers:"all",tolerance:3,returnGeometry:!0},on:function(t){var e=V.boundsToExtent(t.getBounds()),i=t.getSize();return this.params.imageDisplay=[i.x,i.y,96],this.params.mapExtent=[e.xmin,e.ymin,e.xmax,e.ymax],this},at:function(t){return t=L.latLng(t),this.params.geometry=[t.lng,t.lat],this.params.geometryType="esriGeometryPoint",this},layerDef:function(t,e){return this.params.layerDefs=this.params.layerDefs?this.params.layerDefs+";":"",this.params.layerDefs+=[t,e].join(":"),this},simplify:function(t,e){var i=Math.abs(t.getBounds().getWest()-t.getBounds().getEast());return this.params.maxAllowableOffset=i/t.getSize().y*(1-e),this},run:function(t,e){return this.request(function(i,s){if(i)return void t.call(e,i,void 0,s);var r=V.responseToFeatureCollection(s);s.results=s.results.reverse();for(var o=0;o<r.features.length;o++){var n=r.features[o];n.layerId=s.results[o].layerId}t.call(e,void 0,r,s)})}}),rt=it.extend({setters:{setMosaicRule:"mosaicRule",setRenderingRule:"renderingRule",setPixelSize:"pixelSize",returnCatalogItems:"returnCatalogItems",returnGeometry:"returnGeometry"},params:{returnGeometry:!1},at:function(t){return t=L.latLng(t),this.params.geometry=JSON.stringify({x:t.lng,y:t.lat,spatialReference:{wkid:4326}}),this.params.geometryType="esriGeometryPoint",this},getMosaicRule:function(){return this.params.mosaicRule},getRenderingRule:function(){return this.params.renderingRule},getPixelSize:function(){return this.params.pixelSize},run:function(t,e){return this.request(function(i,s){t.call(e,i,s&&this._responseToGeoJSON(s),s)},this)},_responseToGeoJSON:function(t){var e=t.location,i=t.catalogItems,s=t.catalogItemVisibilities,r={pixel:{type:"Feature",geometry:{type:"Point",coordinates:[e.x,e.y]},crs:{type:"EPSG",properties:{code:e.spatialReference.wkid}},properties:{OBJECTID:t.objectId,name:t.name,value:t.value},id:t.objectId}};if(t.properties&&t.properties.Values&&(r.pixel.properties.values=t.properties.Values),i&&i.features&&(r.catalogItems=V.responseToFeatureCollection(i),s&&s.length===r.catalogItems.features.length))for(var o=s.length-1;o>=0;o--)r.catalogItems.features[o].properties.catalogItemVisibility=s[o];return r}}),ot=L.Evented.extend({options:{proxy:!1,useCors:W},initialize:function(t){t=t||{},this._requestQueue=[],this._authenticating=!1,L.Util.setOptions(this,t),this.options.url=g(this.options.url)},get:function(t,e,i,s){return this._request("get",t,e,i,s)},post:function(t,e,i,s){return this._request("post",t,e,i,s)},request:function(t,e,i,s){return this._request("request",t,e,i,s)},metadata:function(t,e){return this._request("get","",{},t,e)},authenticate:function(t){return this._authenticating=!1,this.options.token=t,this._runQueue(),this},_request:function(t,e,i,s,r){this.fire("requeststart",{url:this.options.url+e,params:i,method:t},!0);var o=this._createServiceCallback(t,e,i,s,r);if(this.options.token&&(i.token=this.options.token),this._authenticating)return void this._requestQueue.push([t,e,i,s,r]);var n=this.options.proxy?this.options.proxy+"?"+this.options.url+e:this.options.url+e;return"get"!==t&&"request"!==t||this.options.useCors?X[t](n,i,o):X.get.JSONP(n,i,o)},_createServiceCallback:function(t,e,i,s,r){return L.Util.bind(function(o,n){!o||499!==o.code&&498!==o.code||(this._authenticating=!0,this._requestQueue.push([t,e,i,s,r]),this.fire("authenticationrequired",{authenticate:L.Util.bind(this.authenticate,this)},!0),o.authenticate=L.Util.bind(this.authenticate,this)),s.call(r,o,n),o?this.fire("requesterror",{url:this.options.url+e,params:i,message:o.message,code:o.code,method:t},!0):this.fire("requestsuccess",{url:this.options.url+e,params:i,response:n,method:t},!0),this.fire("requestend",{url:this.options.url+e,params:i,method:t},!0)},this)},_runQueue:function(){for(var t=this._requestQueue.length-1;t>=0;t--){var e=this._requestQueue[t],i=e.shift();this[i].apply(this,e)}this._requestQueue=[]}}),nt=ot.extend({identify:function(){return k(this)},find:function(){return C(this)},query:function(){return tt(this)}}),at=ot.extend({query:function(){return tt(this)},identify:function(){return M(this)}}),lt=ot.extend({options:{idAttribute:"OBJECTID"},query:function(){return tt(this)},addFeature:function(t,e,i){return delete t.id,t=f(t),this.post("addFeatures",{features:[t]},function(t,s){var r=s&&s.addResults?s.addResults[0]:void 0;e&&e.call(i,t||s.addResults[0].error,r)},i)},updateFeature:function(t,e,i){return t=f(t,this.options.idAttribute),this.post("updateFeatures",{features:[t]},function(t,s){var r=s&&s.updateResults?s.updateResults[0]:void 0;e&&e.call(i,t||s.updateResults[0].error,r)},i)},deleteFeature:function(t,e,i){return this.post("deleteFeatures",{objectIds:t},function(t,s){var r=s&&s.deleteResults?s.deleteResults[0]:void 0;e&&e.call(i,t||s.deleteResults[0].error,r)},i)},deleteFeatures:function(t,e,i){return this.post("deleteFeatures",{objectIds:t},function(t,s){var r=s&&s.deleteResults?s.deleteResults:void 0;e&&e.call(i,t||s.deleteResults[0].error,r)},i)}}),ut=L.Control.extend({options:{position:"bottomright",marginTop:0,marginLeft:0,marginBottom:0,marginRight:0},onAdd:function(){var t=L.DomUtil.create("div","esri-leaflet-logo");return t.style.marginTop=this.options.marginTop,t.style.marginLeft=this.options.marginLeft,t.style.marginBottom=this.options.marginBottom,t.style.marginRight=this.options.marginRight,t.innerHTML=this._adjustLogo(this._map._size),this._map.on("resize",function(e){t.innerHTML=this._adjustLogo(e.newSize)},this),t},_adjustLogo:function(t){return t.x<=600||t.y<=600?'<a href="https://developers.arcgis.com" style="border: none;"><img src="https://js.arcgis.com/3.13/esri/images/map/logo-sm.png" alt="Powered by Esri" style="border: none;"></a>':'<a href="https://developers.arcgis.com" style="border: none;"><img src="https://js.arcgis.com/3.13/esri/images/map/logo-med.png" alt="Powered by Esri" style="border: none;"></a>'}}),ht="https:"!==window.location.protocol?"http:":"https:",ct=L.TileLayer.extend({statics:{TILES:{Streets:{urlTemplate:ht+"//{s}.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}",attributionUrl:"https://static.arcgis.com/attribution/World_Street_Map",options:{hideLogo:!1,logoPosition:"bottomright",minZoom:1,maxZoom:19,subdomains:["server","services"],attribution:"Esri"}},Topographic:{urlTemplate:ht+"//{s}.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}",attributionUrl:"https://static.arcgis.com/attribution/World_Topo_Map",options:{hideLogo:!1,logoPosition:"bottomright",minZoom:1,maxZoom:19,subdomains:["server","services"],attribution:"Esri"}},Oceans:{urlTemplate:ht+"//{s}.arcgisonline.com/arcgis/rest/services/Ocean/World_Ocean_Base/MapServer/tile/{z}/{y}/{x}",attributionUrl:"https://static.arcgis.com/attribution/Ocean_Basemap",options:{hideLogo:!1,logoPosition:"bottomright",minZoom:1,maxZoom:16,subdomains:["server","services"],attribution:"Esri"}},OceansLabels:{urlTemplate:ht+"//{s}.arcgisonline.com/arcgis/rest/services/Ocean/World_Ocean_Reference/MapServer/tile/{z}/{y}/{x}",options:{hideLogo:!0,logoPosition:"bottomright",minZoom:1,maxZoom:16,subdomains:["server","services"],pane:J?"esri-labels":"tilePane"}},NationalGeographic:{urlTemplate:ht+"//{s}.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer/tile/{z}/{y}/{x}",options:{hideLogo:!1,logoPosition:"bottomright",minZoom:1,maxZoom:16,subdomains:["server","services"],attribution:"Esri"}},DarkGray:{urlTemplate:ht+"//{s}.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Dark_Gray_Base/MapServer/tile/{z}/{y}/{x}",options:{hideLogo:!1,logoPosition:"bottomright",minZoom:1,maxZoom:16,subdomains:["server","services"],attribution:"Esri, DeLorme, HERE"}},DarkGrayLabels:{urlTemplate:ht+"//{s}.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Dark_Gray_Reference/MapServer/tile/{z}/{y}/{x}",options:{hideLogo:!0,logoPosition:"bottomright",minZoom:1,maxZoom:16,subdomains:["server","services"],pane:J?"esri-labels":"tilePane"}},Gray:{urlTemplate:ht+"//{s}.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer/tile/{z}/{y}/{x}",options:{hideLogo:!1,logoPosition:"bottomright",minZoom:1,maxZoom:16,subdomains:["server","services"],attribution:"Esri, NAVTEQ, DeLorme"}},GrayLabels:{urlTemplate:ht+"//{s}.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Reference/MapServer/tile/{z}/{y}/{x}",options:{hideLogo:!0,logoPosition:"bottomright",minZoom:1,maxZoom:16,subdomains:["server","services"],pane:J?"esri-labels":"tilePane"}},Imagery:{urlTemplate:ht+"//{s}.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}",options:{hideLogo:!1,logoPosition:"bottomright",minZoom:1,maxZoom:19,subdomains:["server","services"],attribution:"Esri, DigitalGlobe, GeoEye, i-cubed, USDA, USGS, AEX, Getmapping, Aerogrid, IGN, IGP, swisstopo, and the GIS User Community"}},ImageryLabels:{urlTemplate:ht+"//{s}.arcgisonline.com/ArcGIS/rest/services/Reference/World_Boundaries_and_Places/MapServer/tile/{z}/{y}/{x}",options:{hideLogo:!0,logoPosition:"bottomright",minZoom:1,maxZoom:19,subdomains:["server","services"],pane:J?"esri-labels":"tilePane"}},ImageryTransportation:{urlTemplate:ht+"//{s}.arcgisonline.com/ArcGIS/rest/services/Reference/World_Transportation/MapServer/tile/{z}/{y}/{x}",options:{hideLogo:!0,logoPosition:"bottomright",minZoom:1,maxZoom:19,subdomains:["server","services"],pane:J?"esri-labels":"tilePane"}},ShadedRelief:{urlTemplate:ht+"//{s}.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer/tile/{z}/{y}/{x}",options:{hideLogo:!1,logoPosition:"bottomright",minZoom:1,maxZoom:13,subdomains:["server","services"],attribution:"Esri, NAVTEQ, DeLorme"}},ShadedReliefLabels:{urlTemplate:ht+"//{s}.arcgisonline.com/ArcGIS/rest/services/Reference/World_Boundaries_and_Places_Alternate/MapServer/tile/{z}/{y}/{x}",options:{hideLogo:!0,logoPosition:"bottomright",minZoom:1,maxZoom:12,subdomains:["server","services"],pane:J?"esri-labels":"tilePane"}},Terrain:{urlTemplate:ht+"//{s}.arcgisonline.com/ArcGIS/rest/services/World_Terrain_Base/MapServer/tile/{z}/{y}/{x}",options:{hideLogo:!1,logoPosition:"bottomright",minZoom:1,maxZoom:13,subdomains:["server","services"],attribution:"Esri, USGS, NOAA"}},TerrainLabels:{urlTemplate:ht+"//{s}.arcgisonline.com/ArcGIS/rest/services/Reference/World_Reference_Overlay/MapServer/tile/{z}/{y}/{x}",options:{hideLogo:!0,logoPosition:"bottomright",minZoom:1,maxZoom:13,subdomains:["server","services"],pane:J?"esri-labels":"tilePane"}}}},initialize:function(t,e){var i;if("object"==typeof t&&t.urlTemplate&&t.options)i=t;else{if("string"!=typeof t||!ct.TILES[t])throw new Error('L.esri.BasemapLayer: Invalid parameter. Use one of "Streets", "Topographic", "Oceans", "OceansLabels", "NationalGeographic", "Gray", "GrayLabels", "DarkGray", "DarkGrayLabels", "Imagery", "ImageryLabels", "ImageryTransportation", "ShadedRelief", "ShadedReliefLabels", "Terrain" or "TerrainLabels"');i=ct.TILES[t]}var s=L.Util.extend(i.options,e);L.TileLayer.prototype.initialize.call(this,i.urlTemplate,L.Util.setOptions(this,s)),i.attributionUrl&&this._getAttributionData(i.attributionUrl),this._logo=D({position:this.options.logoPosition})},onAdd:function(t){this.options.hideLogo||t._hasEsriLogo||(this._logo.addTo(t),t._hasEsriLogo=!0),"esri-labels"===this.options.pane&&this._initPane(),L.TileLayer.prototype.onAdd.call(this,t),t.on("moveend",this._updateMapAttribution,this)},onRemove:function(t){this._logo&&this._logo._container&&(t.removeControl(this._logo),t._hasEsriLogo=!1),L.TileLayer.prototype.onRemove.call(this,t),t.off("moveend",this._updateMapAttribution,this)},getAttribution:function(){var t='<span class="esri-attributions" style="line-height:14px; vertical-align: -3px; text-overflow:ellipsis; white-space:nowrap; overflow:hidden; display:inline-block;">'+this.options.attribution+"</span>";return t},_initPane:function(){if(!this._map.getPane(this.options.pane)){var t=this._map.createPane(this.options.pane);t.style.pointerEvents="none",t.style.zIndex=500}},_getAttributionData:function(t){R(t,{},L.Util.bind(function(t,e){if(!t){this._attributions=[];for(var i=0;i<e.contributors.length;i++)for(var s=e.contributors[i],r=0;r<s.coverageAreas.length;r++){var o=s.coverageAreas[r],n=new L.LatLng(o.bbox[0],o.bbox[1]),a=new L.LatLng(o.bbox[2],o.bbox[3]);this._attributions.push({attribution:s.attribution,score:o.score,bounds:new L.LatLngBounds(n,a),minZoom:o.zoomMin,maxZoom:o.zoomMax})}this._attributions.sort(function(t,e){return e.score-t.score}),this._updateMapAttribution()}},this))},_updateMapAttribution:function(){if(this._map&&this._map.attributionControl&&this._attributions){for(var t="",e=this._map.getBounds(),i=this._map.getZoom(),s=0;s<this._attributions.length;s++){var r=this._attributions[s],o=r.attribution;!t.match(o)&&e.intersects(r.bounds)&&i>=r.minZoom&&i<=r.maxZoom&&(t+=", "+o)}t=t.substr(2);var n=this._map.attributionControl._container.querySelector(".esri-attributions");n.innerHTML=t,n.style.maxWidth=.65*this._map.getSize().x+"px",this.fire("attributionupdated",{attribution:t})}}});t.BasemapLayer=ct,t.basemapLayer=j;var pt=L.TileLayer.extend({options:{zoomOffsetAllowance:.1,correctZoomLevels:!0},statics:{MercatorZoomLevels:{0:156543.033928,1:78271.5169639999,2:39135.7584820001,3:19567.8792409999,4:9783.93962049996,5:4891.96981024998,6:2445.98490512499,7:1222.99245256249,8:611.49622628138,9:305.748113140558,10:152.874056570411,11:76.4370282850732,12:38.2185141425366,13:19.1092570712683,14:9.55462853563415,15:4.77731426794937,16:2.38865713397468,17:1.19432856685505,18:.597164283559817,19:.298582141647617,20:.14929107082381,21:.07464553541191,22:.0373227677059525,23:.0186613838529763}},initialize:function(t){t.url=g(t.url),t=L.Util.setOptions(this,t),this.tileUrl=t.url+"tile/{z}/{y}/{x}",this.service=G(t),this.service.addEventParent(this),this.tileUrl.match("://tiles.arcgisonline.com")&&(this.tileUrl=this.tileUrl.replace("://tiles.arcgisonline.com","://tiles{s}.arcgisonline.com"),t.subdomains=["1","2","3","4"]),this.options.token&&(this.tileUrl+="?token="+this.options.token),L.TileLayer.prototype.initialize.call(this,this.tileUrl,t)},getTileUrl:function(t){return L.Util.template(this.tileUrl,L.extend({s:this._getSubdomain(t),z:this._lodMap[t.z]||t.z,x:t.x,y:t.y},this.options))},onAdd:function(t){!this._lodMap&&this.options.correctZoomLevels?(this._lodMap={},this.metadata(function(e,i){if(!e){var s=i.spatialReference.latestWkid||i.spatialReference.wkid;if(102100===s||3857===s)for(var r=i.tileInfo.lods,o=pt.MercatorZoomLevels,n=0;n<r.length;n++){var a=r[n];for(var l in o){var u=o[l];if(this._withinPercentage(a.resolution,u,this.options.zoomOffsetAllowance)){this._lodMap[l]=a.level;break}}}else b("L.esri.TiledMapLayer is using a non-mercator spatial reference. Support may be available through Proj4Leaflet http://esri.github.io/esri-leaflet/examples/non-mercator-projection.html")}L.TileLayer.prototype.onAdd.call(this,t)},this)):L.TileLayer.prototype.onAdd.call(this,t)},metadata:function(t,e){return this.service.metadata(t,e),this},identify:function(){return this.service.identify()},find:function(){return this.service.find()},query:function(){return this.service.query()},authenticate:function(t){var e="?token="+t;return this.tileUrl=this.options.token?this.tileUrl.replace(/\?token=(.+)/g,e):this.tileUrl+e,this.options.token=t,this.service.authenticate(t),this},_withinPercentage:function(t,e,i){var s=Math.abs(t/e-1);return i>s}});t.TiledMapLayer=pt,t.tiledMapLayer=B;var dt=L.Layer.extend({options:{opacity:1,position:"front",f:"image",useCors:W,attribution:null,interactive:!1,alt:""},onAdd:function(t){if(this._update=L.Util.throttle(this._update,this.options.updateInterval,this),t.options.crs&&t.options.crs.code){var e=t.options.crs.code.split(":")[1];this.options.bboxSR=e,this.options.imageSR=e}t.on("moveend",this._update,this),this._currentImage&&this._currentImage._bounds.equals(this._map.getBounds())?t.addLayer(this._currentImage):this._currentImage&&(this._map.removeLayer(this._currentImage),this._currentImage=null),this._update(),this._popup&&(this._map.on("click",this._getPopupData,this),this._map.on("dblclick",this._resetPopupState,this))},onRemove:function(t){this._currentImage&&this._map.removeLayer(this._currentImage),this._popup&&(this._map.off("click",this._getPopupData,this),this._map.off("dblclick",this._resetPopupState,this)),this._map.off("moveend",this._update,this)},getEvents:function(){return{moveend:this._update}},bindPopup:function(t,e){return this._shouldRenderPopup=!1,this._lastClick=!1,this._popup=L.popup(e),this._popupFunction=t,this._map&&(this._map.on("click",this._getPopupData,this),this._map.on("dblclick",this._resetPopupState,this)),this},unbindPopup:function(){return this._map&&(this._map.closePopup(this._popup),this._map.off("click",this._getPopupData,this),this._map.off("dblclick",this._resetPopupState,this)),this._popup=!1,this},bringToFront:function(){return this.options.position="front",this._currentImage&&this._currentImage.bringToFront(),this},bringToBack:function(){return this.options.position="back",this._currentImage&&this._currentImage.bringToBack(),this},getAttribution:function(){return this.options.attribution},getOpacity:function(){return this.options.opacity},setOpacity:function(t){return this.options.opacity=t,this._currentImage.setOpacity(t),this},getTimeRange:function(){return[this.options.from,this.options.to]},setTimeRange:function(t,e){return this.options.from=t,this.options.to=e,this._update(),this},metadata:function(t,e){return this.service.metadata(t,e),this},authenticate:function(t){return this.service.authenticate(t),this},_renderImage:function(t,e){if(this._map){var i=new L.ImageOverlay(t,e,{opacity:0,crossOrigin:this.options.useCors,alt:this.options.alt,pane:this.options.pane||this.getPane(),interactive:this.options.interactive}).addTo(this._map);i.once("load",function(t){if(this._map){var i=t.target,s=this._currentImage;i._bounds.equals(e)&&i._bounds.equals(this._map.getBounds())?(this._currentImage=i,"front"===this.options.position?this.bringToFront():this.bringToBack(),this._map&&this._currentImage._map?this._currentImage.setOpacity(this.options.opacity):this._currentImage._map.removeLayer(this._currentImage),s&&this._map&&this._map.removeLayer(s),s&&s._map&&s._map.removeLayer(s)):this._map.removeLayer(i)}this.fire("load",{bounds:e})},this),this.fire("loading",{bounds:e})}},_update:function(){if(this._map){var t=this._map.getZoom(),e=this._map.getBounds();if(!this._animatingZoom&&!(this._map._panTransition&&this._map._panTransition._inProgress||t>this.options.maxZoom||t<this.options.minZoom)){var i=this._buildExportParams();this._requestExport(i,e);
}}},_renderPopup:function(t,e,i,s){if(t=L.latLng(t),this._shouldRenderPopup&&this._lastClick.equals(t)){var r=this._popupFunction(e,i,s);r&&this._popup.setLatLng(t).setContent(r).openOn(this._map)}},_resetPopupState:function(t){this._shouldRenderPopup=!1,this._lastClick=t.latlng}});t.RasterLayer=dt;var mt=dt.extend({options:{updateInterval:150,format:"jpgpng",transparent:!0,f:"json"},query:function(){return this.service.query()},identify:function(){return this.service.identify()},initialize:function(t){t.url=g(t.url),this.service=E(t),this.service.addEventParent(this),L.Util.setOptions(this,t)},setPixelType:function(t){return this.options.pixelType=t,this._update(),this},getPixelType:function(){return this.options.pixelType},setBandIds:function(t){return L.Util.isArray(t)?this.options.bandIds=t.join(","):this.options.bandIds=t.toString(),this._update(),this},getBandIds:function(){return this.options.bandIds},setNoData:function(t,e){return L.Util.isArray(t)?this.options.noData=t.join(","):this.options.noData=t.toString(),e&&(this.options.noDataInterpretation=e),this._update(),this},getNoData:function(){return this.options.noData},getNoDataInterpretation:function(){return this.options.noDataInterpretation},setRenderingRule:function(t){this.options.renderingRule=t,this._update()},getRenderingRule:function(){return this.options.renderingRule},setMosaicRule:function(t){this.options.mosaicRule=t,this._update()},getMosaicRule:function(){return this.options.mosaicRule},_getPopupData:function(t){var e=L.Util.bind(function(e,i,s){e||setTimeout(L.Util.bind(function(){this._renderPopup(t.latlng,e,i,s)},this),300)},this),i=this.identify().at(t.latlng);this.options.mosaicRule&&i.setMosaicRule(this.options.mosaicRule),i.run(e),this._shouldRenderPopup=!0,this._lastClick=t.latlng},_buildExportParams:function(){var t=this._map.getBounds(),e=this._map.getSize(),i=this._map.options.crs.project(t._northEast),s=this._map.options.crs.project(t._southWest),r={bbox:[s.x,s.y,i.x,i.y].join(","),size:e.x+","+e.y,format:this.options.format,transparent:this.options.transparent,bboxSR:this.options.bboxSR,imageSR:this.options.imageSR};return this.options.from&&this.options.to&&(r.time=this.options.from.valueOf()+","+this.options.to.valueOf()),this.options.pixelType&&(r.pixelType=this.options.pixelType),this.options.interpolation&&(r.interpolation=this.options.interpolation),this.options.compressionQuality&&(r.compressionQuality=this.options.compressionQuality),this.options.bandIds&&(r.bandIds=this.options.bandIds),this.options.noData&&(r.noData=this.options.noData),this.options.noDataInterpretation&&(r.noDataInterpretation=this.options.noDataInterpretation),this.service.options.token&&(r.token=this.service.options.token),this.options.renderingRule&&(r.renderingRule=JSON.stringify(this.options.renderingRule)),this.options.mosaicRule&&(r.mosaicRule=JSON.stringify(this.options.mosaicRule)),r},_requestExport:function(t,e){"json"===this.options.f?this.service.get("exportImage",t,function(t,i){t||this._renderImage(i.href,e)},this):(t.f="image",this._renderImage(this.options.url+"exportImage"+L.Util.getParamString(t),e))}});t.ImageMapLayer=mt,t.imageMapLayer=U;var ft=dt.extend({options:{updateInterval:150,layers:!1,layerDefs:!1,timeOptions:!1,format:"png24",transparent:!0,f:"json"},initialize:function(t){t.url=g(t.url),this.service=G(t),this.service.addEventParent(this),(t.proxy||t.token)&&"json"!==t.f&&(t.f="json"),L.Util.setOptions(this,t)},getDynamicLayers:function(){return this.options.dynamicLayers},setDynamicLayers:function(t){return this.options.dynamicLayers=t,this._update(),this},getLayers:function(){return this.options.layers},setLayers:function(t){return this.options.layers=t,this._update(),this},getLayerDefs:function(){return this.options.layerDefs},setLayerDefs:function(t){return this.options.layerDefs=t,this._update(),this},getTimeOptions:function(){return this.options.timeOptions},setTimeOptions:function(t){return this.options.timeOptions=t,this._update(),this},query:function(){return this.service.query()},identify:function(){return this.service.identify()},find:function(){return this.service.find()},_getPopupData:function(t){var e=L.Util.bind(function(e,i,s){e||setTimeout(L.Util.bind(function(){this._renderPopup(t.latlng,e,i,s)},this),300)},this),i=this.identify().on(this._map).at(t.latlng);this.options.layers?i.layers("visible:"+this.options.layers.join(",")):i.layers("visible"),i.run(e),this._shouldRenderPopup=!0,this._lastClick=t.latlng},_buildExportParams:function(){var t=this._map.getBounds(),e=this._map.getSize(),i=this._map.options.crs.project(t._northEast),s=this._map.options.crs.project(t._southWest),r=this._map.latLngToLayerPoint(t._northEast),o=this._map.latLngToLayerPoint(t._southWest);(r.y>0||o.y<e.y)&&(e.y=o.y-r.y);var n={bbox:[s.x,s.y,i.x,i.y].join(","),size:e.x+","+e.y,dpi:96,format:this.options.format,transparent:this.options.transparent,bboxSR:this.options.bboxSR,imageSR:this.options.imageSR};return this.options.dynamicLayers&&(n.dynamicLayers=this.options.dynamicLayers),this.options.layers&&(n.layers="show:"+this.options.layers.join(",")),this.options.layerDefs&&(n.layerDefs=JSON.stringify(this.options.layerDefs)),this.options.timeOptions&&(n.timeOptions=JSON.stringify(this.options.timeOptions)),this.options.from&&this.options.to&&(n.time=this.options.from.valueOf()+","+this.options.to.valueOf()),this.service.options.token&&(n.token=this.service.options.token),n},_requestExport:function(t,e){"json"===this.options.f?this.service.get("export",t,function(t,i){t||this._renderImage(i.href,e)},this):(t.f="image",this._renderImage(this.options.url+"export"+L.Util.getParamString(t),e))}});t.DynamicMapLayer=ft,t.dynamicMapLayer=z;var yt=L.Layer.extend({options:{cellSize:512,updateInterval:150},initialize:function(t){t=L.setOptions(this,t)},onAdd:function(t){this._map=t,this._update=L.Util.throttle(this._update,this.options.updateInterval,this),this._reset(),this._update()},onRemove:function(){this._map.removeEventListener(this.getEvents(),this),this._removeCells()},getEvents:function(){var t={moveend:this._update,zoomend:this._reset};return t},addTo:function(t){return t.addLayer(this),this},removeFrom:function(t){return t.removeLayer(this),this},_reset:function(){this._removeCells(),this._cells={},this._activeCells={},this._cellsToLoad=0,this._cellsTotal=0,this._cellNumBounds=this._getCellNumBounds(),this._resetWrap()},_resetWrap:function(){var t=this._map,e=t.options.crs;if(!e.infinite){var i=this._getCellSize();e.wrapLng&&(this._wrapLng=[Math.floor(t.project([0,e.wrapLng[0]]).x/i),Math.ceil(t.project([0,e.wrapLng[1]]).x/i)]),e.wrapLat&&(this._wrapLat=[Math.floor(t.project([e.wrapLat[0],0]).y/i),Math.ceil(t.project([e.wrapLat[1],0]).y/i)])}},_getCellSize:function(){return this.options.cellSize},_update:function(){if(this._map){var t=this._map.getPixelBounds(),e=this._map.getZoom(),i=this._getCellSize();if(!(e>this.options.maxZoom||e<this.options.minZoom)){var s=L.bounds(t.min.divideBy(i).floor(),t.max.divideBy(i).floor());this._removeOtherCells(s),this._addCells(s)}}},_addCells:function(t){var e,i,s,r=[],o=t.getCenter(),n=this._map.getZoom();for(e=t.min.y;e<=t.max.y;e++)for(i=t.min.x;i<=t.max.x;i++)s=new L.Point(i,e),s.z=n,this._isValidCell(s)&&r.push(s);var a=r.length;if(0!==a)for(this._cellsToLoad+=a,this._cellsTotal+=a,r.sort(function(t,e){return t.distanceTo(o)-e.distanceTo(o)}),i=0;a>i;i++)this._addCell(r[i])},_isValidCell:function(t){var e=this._map.options.crs;if(!e.infinite){var i=this._cellNumBounds;if(!e.wrapLng&&(t.x<i.min.x||t.x>i.max.x)||!e.wrapLat&&(t.y<i.min.y||t.y>i.max.y))return!1}if(!this.options.bounds)return!0;var s=this._cellCoordsToBounds(t);return L.latLngBounds(this.options.bounds).intersects(s)},_cellCoordsToBounds:function(t){var e=this._map,i=this.options.cellSize,s=t.multiplyBy(i),r=s.add([i,i]),o=e.wrapLatLng(e.unproject(s,t.z)),n=e.wrapLatLng(e.unproject(r,t.z));return new L.LatLngBounds(o,n)},_cellCoordsToKey:function(t){return t.x+":"+t.y},_keyToCellCoords:function(t){var e=t.split(":"),i=parseInt(e[0],10),s=parseInt(e[1],10);return new L.Point(i,s)},_removeOtherCells:function(t){for(var e in this._cells)t.contains(this._keyToCellCoords(e))||this._removeCell(e)},_removeCell:function(t){var e=this._activeCells[t];e&&(delete this._activeCells[t],this.cellLeave&&this.cellLeave(e.bounds,e.coords),this.fire("cellleave",{bounds:e.bounds,coords:e.coords}))},_removeCells:function(){for(var t in this._cells){var e=this._cells[t].bounds,i=this._cells[t].coords;this.cellLeave&&this.cellLeave(e,i),this.fire("cellleave",{bounds:e,coords:i})}},_addCell:function(t){this._wrapCoords(t);var e=this._cellCoordsToKey(t),i=this._cells[e];i&&!this._activeCells[e]&&(this.cellEnter&&this.cellEnter(i.bounds,t),this.fire("cellenter",{bounds:i.bounds,coords:t}),this._activeCells[e]=i),i||(i={coords:t,bounds:this._cellCoordsToBounds(t)},this._cells[e]=i,this._activeCells[e]=i,this.createCell&&this.createCell(i.bounds,t),this.fire("cellcreate",{bounds:i.bounds,coords:t}))},_wrapCoords:function(t){t.x=this._wrapLng?L.Util.wrapNum(t.x,this._wrapLng):t.x,t.y=this._wrapLat?L.Util.wrapNum(t.y,this._wrapLat):t.y},_getCellNumBounds:function(){var t=this._map.getPixelWorldBounds(),e=this._getCellSize();return t?L.bounds(t.min.divideBy(e).floor(),t.max.divideBy(e).ceil().subtract([1,1])):null}});t.FeatureGrid=yt;var gt=yt.extend({options:{attribution:null,where:"1=1",fields:["*"],from:!1,to:!1,timeField:!1,timeFilterMode:"server",simplifyFactor:0,precision:6},initialize:function(t){if(yt.prototype.initialize.call(this,t),t.url=g(t.url),t=L.setOptions(this,t),this.service=A(t),this.service.addEventParent(this),"*"!==this.options.fields[0]){for(var e=!1,i=0;i<this.options.fields.length;i++)this.options.fields[i].match(/^(OBJECTID|FID|OID|ID)$/i)&&(e=!0);e===!1&&b("no known esriFieldTypeOID field detected in fields Array. Please add an attribute field containing unique IDs to ensure the layer can be drawn correctly.")}this.options.timeField.start&&this.options.timeField.end?(this._startTimeIndex=new Z,this._endTimeIndex=new Z):this.options.timeField&&(this._timeIndex=new Z),this._cache={},this._currentSnapshot=[],this._activeRequests=0},onAdd:function(t){return yt.prototype.onAdd.call(this,t)},onRemove:function(t){return yt.prototype.onRemove.call(this,t)},getAttribution:function(){return this.options.attribution},createCell:function(t,e){this._requestFeatures(t,e)},_requestFeatures:function(t,e,i){return this._activeRequests++,1===this._activeRequests&&this.fire("loading",{bounds:t},!0),this._buildQuery(t).run(function(s,r,o){o&&o.exceededTransferLimit&&this.fire("drawlimitexceeded"),!s&&r&&r.features.length&&L.Util.requestAnimFrame(L.Util.bind(function(){this._addFeatures(r.features,e),this._postProcessFeatures(t)},this)),s||!r||r.features.length||this._postProcessFeatures(t),i&&i.call(this,s,r)},this)},_postProcessFeatures:function(t){this._activeRequests--,this._activeRequests<=0&&this.fire("load",{bounds:t})},_cacheKey:function(t){return t.z+":"+t.x+":"+t.y},_addFeatures:function(t,e){var i=this._cacheKey(e);this._cache[i]=this._cache[i]||[];for(var s=t.length-1;s>=0;s--){var r=t[s].id;this._currentSnapshot.push(r),this._cache[i].push(r)}this.options.timeField&&this._buildTimeIndexes(t);var o=this._map.getZoom();o>this.options.maxZoom||o<this.options.minZoom||this.createLayers(t)},_buildQuery:function(t){var e=this.service.query().intersects(t).where(this.options.where).fields(this.options.fields).precision(this.options.precision);return this.options.simplifyFactor&&e.simplify(this._map,this.options.simplifyFactor),"server"===this.options.timeFilterMode&&this.options.from&&this.options.to&&e.between(this.options.from,this.options.to),e},setWhere:function(t,e,i){this.options.where=t&&t.length?t:"1=1";for(var s=[],r=[],o=0,n=null,a=L.Util.bind(function(t,a){if(t&&(n=t),a)for(var l=a.features.length-1;l>=0;l--)r.push(a.features[l].id);o--,0>=o&&(this._currentSnapshot=r,L.Util.requestAnimFrame(L.Util.bind(function(){this.removeLayers(s),this.addLayers(r),e&&e.call(i,n)},this)))},this),l=this._currentSnapshot.length-1;l>=0;l--)s.push(this._currentSnapshot[l]);for(var u in this._activeCells){o++;var h=this._keyToCellCoords(u),c=this._cellCoordsToBounds(h);this._requestFeatures(c,u,a)}return this},getWhere:function(){return this.options.where},getTimeRange:function(){return[this.options.from,this.options.to]},setTimeRange:function(t,e,i,s){var r=this.options.from,o=this.options.to,n=0,a=null,l=L.Util.bind(function(l){l&&(a=l),this._filterExistingFeatures(r,o,t,e),n--,i&&0>=n&&i.call(s,a)},this);if(this.options.from=t,this.options.to=e,this._filterExistingFeatures(r,o,t,e),"server"===this.options.timeFilterMode)for(var u in this._activeCells){n++;var h=this._keyToCellCoords(u),c=this._cellCoordsToBounds(h);this._requestFeatures(c,u,l)}return this},refresh:function(){for(var t in this._activeCells){var e=this._keyToCellCoords(t),i=this._cellCoordsToBounds(e);this._requestFeatures(i,t)}this.redraw&&this.once("load",function(){this.eachFeature(function(t){this._redraw(t.feature.id)},this)},this)},_filterExistingFeatures:function(t,e,i,s){var r=t&&e?this._getFeaturesInTimeRange(t,e):this._currentSnapshot,o=this._getFeaturesInTimeRange(i,s);if(o.indexOf)for(var n=0;n<o.length;n++){var a=r.indexOf(o[n]);a>=0&&r.splice(a,1)}L.Util.requestAnimFrame(L.Util.bind(function(){this.removeLayers(r),this.addLayers(o)},this))},_getFeaturesInTimeRange:function(t,e){var i,s=[];if(this.options.timeField.start&&this.options.timeField.end){var r=this._startTimeIndex.between(t,e),o=this._endTimeIndex.between(t,e);i=r.concat(o)}else i=this._timeIndex.between(t,e);for(var n=i.length-1;n>=0;n--)s.push(i[n].id);return s},_buildTimeIndexes:function(t){var e,i;if(this.options.timeField.start&&this.options.timeField.end){var s=[],r=[];for(e=t.length-1;e>=0;e--)i=t[e],s.push({id:i.id,value:new Date(i.properties[this.options.timeField.start])}),r.push({id:i.id,value:new Date(i.properties[this.options.timeField.end])});this._startTimeIndex.bulkAdd(s),this._endTimeIndex.bulkAdd(r)}else{var o=[];for(e=t.length-1;e>=0;e--)i=t[e],o.push({id:i.id,value:new Date(i.properties[this.options.timeField])});this._timeIndex.bulkAdd(o)}},_featureWithinTimeRange:function(t){if(!this.options.from||!this.options.to)return!0;var e=+this.options.from.valueOf(),i=+this.options.to.valueOf();if("string"==typeof this.options.timeField){var s=+t.properties[this.options.timeField];return s>=e&&i>=s}if(this.options.timeField.start&&this.options.timeField.end){var r=+t.properties[this.options.timeField.start],o=+t.properties[this.options.timeField.end];return r>=e&&i>=r||o>=e&&i>=o}},authenticate:function(t){return this.service.authenticate(t),this},metadata:function(t,e){return this.service.metadata(t,e),this},query:function(){return this.service.query()},_getMetadata:function(t){if(this._metadata){var e;t(e,this._metadata)}else this.metadata(L.Util.bind(function(e,i){this._metadata=i,t(e,this._metadata)},this))},addFeature:function(t,e,i){this._getMetadata(L.Util.bind(function(s,r){return s?void(e&&e.call(this,s,null)):void this.service.addFeature(t,L.Util.bind(function(s,o){s||(t.properties[r.objectIdField]=o.objectId,t.id=o.objectId,this.createLayers([t])),e&&e.call(i,s,o)},this))},this))},updateFeature:function(t,e,i){this.service.updateFeature(t,function(s,r){s||(this.removeLayers([t.id],!0),this.createLayers([t])),e&&e.call(i,s,r)},this)},deleteFeature:function(t,e,i){this.service.deleteFeature(t,function(t,s){!t&&s.objectId&&this.removeLayers([s.objectId],!0),e&&e.call(i,t,s)},this)},deleteFeatures:function(t,e,i){return this.service.deleteFeatures(t,function(t,s){if(!t&&s.length>0)for(var r=0;r<s.length;r++)this.removeLayers([s[r].objectId],!0);e&&e.call(i,t,s)},this)}});Z.prototype._query=function(t){for(var e,i,s=0,r=this.values.length-1;r>=s;)if(e=(s+r)/2|0,i=this.values[Math.round(e)],+i.value<+t)s=e+1;else{if(!(+i.value>+t))return e;r=e-1}return~r},Z.prototype.sort=function(){this.values.sort(function(t,e){return+e.value-+t.value}).reverse(),this.dirty=!1},Z.prototype.between=function(t,e){this.dirty&&this.sort();var i=this._query(t),s=this._query(e);return 0===i&&0===s?[]:(i=Math.abs(i),s=0>s?Math.abs(s):s+1,this.values.slice(i,s))},Z.prototype.bulkAdd=function(t){this.dirty=!0,this.values=this.values.concat(t)},t.FeatureManager=gt;var _t=gt.extend({options:{cacheLayers:!0},initialize:function(t){gt.prototype.initialize.call(this,t),this._originalStyle=this.options.style,this._layers={}},onAdd:function(t){return t.on("zoomstart zoomend",function(t){this._zooming="zoomstart"===t.type},this),gt.prototype.onAdd.call(this,t)},onRemove:function(t){for(var e in this._layers)t.removeLayer(this._layers[e]);return gt.prototype.onRemove.call(this,t)},createNewLayer:function(t){var e=L.GeoJSON.geometryToLayer(t,this.options);return e.defaultOptions=e.options,e},_updateLayer:function(t,e){var i=[],s=this.options.coordsToLatLng||L.GeoJSON.coordsToLatLng;switch(e.properties&&(t.feature.properties=e.properties),e.geometry.type){case"Point":i=L.GeoJSON.coordsToLatLng(e.geometry.coordinates),t.setLatLng(i);break;case"LineString":i=L.GeoJSON.coordsToLatLngs(e.geometry.coordinates,0,s),t.setLatLngs(i);break;case"MultiLineString":i=L.GeoJSON.coordsToLatLngs(e.geometry.coordinates,1,s),t.setLatLngs(i);break;case"Polygon":i=L.GeoJSON.coordsToLatLngs(e.geometry.coordinates,1,s),t.setLatLngs(i);break;case"MultiPolygon":i=L.GeoJSON.coordsToLatLngs(e.geometry.coordinates,2,s),t.setLatLngs(i)}},createLayers:function(t){for(var e=t.length-1;e>=0;e--){var i,s=t[e],r=this._layers[s.id];r&&!this._map.hasLayer(r)&&this._map.addLayer(r),r&&(r.setLatLngs||r.setLatLng)&&this._updateLayer(r,s),r||(i=this.createNewLayer(s),i.feature=s,i.addEventParent(this),this.options.onEachFeature&&this.options.onEachFeature(i.feature,i),this._layers[i.feature.id]=i,this.setFeatureStyle(i.feature.id,this.options.style),this.fire("createfeature",{feature:i.feature},!0),(!this.options.timeField||this.options.timeField&&this._featureWithinTimeRange(s))&&this._map.addLayer(i))}},addLayers:function(t){for(var e=t.length-1;e>=0;e--){var i=this._layers[t[e]];i&&(this.fire("addfeature",{feature:i.feature},!0),this._map.addLayer(i))}},removeLayers:function(t,e){for(var i=t.length-1;i>=0;i--){var s=t[i],r=this._layers[s];r&&(this.fire("removefeature",{feature:r.feature,permanent:e},!0),this._map.removeLayer(r)),r&&e&&delete this._layers[s]}},cellEnter:function(t,e){this._zooming||L.Util.requestAnimFrame(L.Util.bind(function(){var t=this._cacheKey(e),i=this._cellCoordsToKey(e),s=this._cache[t];this._activeCells[i]&&s&&this.addLayers(s)},this))},cellLeave:function(t,e){this._zooming||L.Util.requestAnimFrame(L.Util.bind(function(){var t=this._cacheKey(e),i=this._cellCoordsToKey(e),s=this._cache[t],r=this._map.getBounds();if(!this._activeCells[i]&&s){for(var o=!0,n=0;n<s.length;n++){var a=this._layers[s[n]];a&&a.getBounds&&r.intersects(a.getBounds())&&(o=!1)}o&&this.removeLayers(s,!this.options.cacheLayers),!this.options.cacheLayers&&o&&(delete this._cache[t],delete this._cells[i],delete this._activeCells[i])}},this))},resetStyle:function(){return this.options.style=this._originalStyle,this.eachFeature(function(t){this.resetFeatureStyle(t.feature.id)},this),this},setStyle:function(t){return this.options.style=t,this.eachFeature(function(e){this.setFeatureStyle(e.feature.id,t)},this),this},resetFeatureStyle:function(t){var e=this._layers[t],i=this._originalStyle||L.Path.prototype.options;return e&&(L.Util.extend(e.options,e.defaultOptions),this.setFeatureStyle(t,i)),this},setFeatureStyle:function(t,e){var i=this._layers[t];return"function"==typeof e&&(e=e(i.feature)),i.setStyle&&i.setStyle(e),this},eachFeature:function(t,e){for(var i in this._layers)t.call(e,this._layers[i]);return this},getFeature:function(t){return this._layers[t]},bringToBack:function(){this.eachFeature(function(t){t.bringToBack&&t.bringToBack()})},bringToFront:function(){this.eachFeature(function(t){t.bringToFront&&t.bringToFront()})},redraw:function(t){return t&&this._redraw(t),this},_redraw:function(t){var e=this._layers[t],i=e.feature;if(e&&e.setIcon&&this.options.pointToLayer&&this.options.pointToLayer){var s=this.options.pointToLayer(i,L.latLng(i.geometry.coordinates[1],i.geometry.coordinates[0])),r=s.options.icon;e.setIcon(r)}if(e&&e.setStyle&&this.options.pointToLayer){var o=this.options.pointToLayer(i,L.latLng(i.geometry.coordinates[1],i.geometry.coordinates[0])),n=o.options;this.setFeatureStyle(i.id,n)}e&&e.setStyle&&this.options.style&&this.resetStyle(i.id)}});t.FeatureLayer=_t,t.featureLayer=N;var vt="2.0.0-beta.1",Lt={Task:$,task:P,Query:Y,query:F,Find:et,find:C,Identify:it,identify:O,IdentifyFeatures:st,identifyFeatures:k,IdentifyImage:rt,identifyImage:M},bt={Service:ot,service:q,MapService:nt,mapService:G,ImageService:at,imageService:E,FeatureLayerService:lt,featureLayerService:A},xt={BasemapLayer:ct,basemapLayer:j,TiledMapLayer:pt,tiledMapLayer:B,RasterLayer:dt,ImageMapLayer:mt,imageMapLayer:U,DynamicMapLayer:ft,dynamicMapLayer:z,FeatureGrid:yt,FeatureManager:gt,FeatureLayer:_t,featureLayer:N},St="undefined"==typeof define?!1:define.amd&&"function"==typeof define,Tt="object"==typeof t&&"undefined"!=typeof module,It=window&&window.System;(St||Tt||It)&&window&&window.L&&(window.L.esri={VERSION:vt,Support:Q,Util:V,get:K,post:T,request:w,Tasks:Lt,Services:bt,Layers:xt,BasemapLayer:ct,basemapLayer:j,TiledMapLayer:pt,tiledMapLayer:B,RasterLayer:dt,ImageMapLayer:mt,imageMapLayer:U,DynamicMapLayer:ft,dynamicMapLayer:z,FeatureGrid:yt,FeatureManager:gt,FeatureLayer:_t,featureLayer:N}),t.VERSION=vt,t.Tasks=Lt,t.Services=bt,t.Layers=xt});
//# sourceMappingURL=./esri-leaflet.js.map

@@ -1,164 +0,8 @@

var fs = require('fs');
module.exports = function (grunt) {
module.exports = function(grunt) {
var browsers = grunt.option('browser') ? grunt.option('browser').split(',') : ['PhantomJS'];
var copyright = '/*! <%= pkg.name %> - v<%= pkg.version %> - <%= grunt.template.today(\'yyyy-mm-dd\') %>\n' +
'* Copyright (c) <%= grunt.template.today(\'yyyy\') %> Environmental Systems Research Institute, Inc.\n' +
'* Apache License' +
'*/\n';
var umdHeader = '(function (factory) {\n' +
' //define an AMD module that relies on \'leaflet\'\n' +
' if (typeof define === \'function\' && define.amd) {\n' +
' define([\'leaflet\'], function (L) {\n' +
' return factory(L);\n' +
' });\n' +
' //define a common js module that relies on \'leaflet\'\n' +
' } else if (typeof module === \'object\' && typeof module.exports === \'object\') {\n' +
' module.exports = factory(require(\'leaflet\'));\n' +
' }\n\n' +
' if(typeof window !== \'undefined\' && window.L){\n' +
' factory(window.L);\n' +
' }\n' +
'}(function (L) {\n';
var umdFooter = '\n\n return EsriLeaflet;\n' +
'}));';
var complete = [
'src/EsriLeaflet.js',
'src/Util.js',
'src/Request.js',
'src/Services/Service.js',
'src/Services/FeatureLayerService.js',
'src/Services/MapService.js',
'src/Services/ImageService.js',
'src/Tasks/Task.js',
'src/Tasks/Query.js',
'src/Tasks/Find.js',
'src/Tasks/Identify.js',
'src/Tasks/IdentifyImage.js',
'src/Tasks/IdentifyFeatures.js',
'src/Layers/BasemapLayer.js',
'src/Layers/RasterLayer.js',
'src/Layers/DynamicMapLayer.js',
'src/Layers/ImageMapLayer.js',
'src/Layers/TiledMapLayer.js',
'src/Layers/FeatureLayer/FeatureGrid.js',
'src/Layers/FeatureLayer/FeatureManager.js',
'src/Layers/FeatureLayer/FeatureLayer.js',
'src/Controls/Logo.js'
];
var core = [
'src/EsriLeaflet.js',
'src/Util.js',
'src/Request.js',
'src/Tasks/Task.js',
'src/Services/Service.js'
];
var basemaps = [
'src/EsriLeaflet.js',
'src/Request.js',
'src/Layers/BasemapLayer.js',
'src/Controls/Logo.js'
];
var mapservice = [
'src/EsriLeaflet.js',
'src/Util.js',
'src/Request.js',
'src/Services/Service.js',
'src/Services/MapService.js',
'src/Tasks/Task.js',
'src/Tasks/Identify.js',
'src/Tasks/IdentifyFeatures.js',
'src/Tasks/Query.js',
'src/Tasks/Find.js',
'src/Layers/RasterLayer.js',
'src/Layers/DynamicMapLayer.js',
'src/Layers/TiledMapLayer.js'
];
var imageservice = [
'src/EsriLeaflet.js',
'src/Util.js',
'src/Request.js',
'src/Services/Service.js',
'src/Services/ImageService.js',
'src/Tasks/Task.js',
'src/Tasks/Query.js',
'src/Tasks/Identify.js',
'src/Tasks/Identify/IdentifyImage.js',
'src/Layers/RasterLayer.js',
'src/Layers/ImageMapLayer.js'
];
var featureservice = [
'src/EsriLeaflet.js',
'src/Util.js',
'src/Request.js',
'src/Services/Service.js',
'src/Services/FeatureLayerService.js',
'src/Tasks/Task.js',
'src/Tasks/Query.js',
'src/Layers/FeatureLayer/FeatureGrid.js',
'src/Layers/FeatureLayer/FeatureManager.js',
'src/Layers/FeatureLayer/FeatureLayer.js'
];
var customLaunchers = {
sl_chrome: {
base: 'SauceLabs',
browserName: 'chrome',
platform: 'Windows 7',
version: '35'
},
sl_firefox: {
base: 'SauceLabs',
browserName: 'firefox',
version: '30'
},
sl_ios_safari: {
base: 'SauceLabs',
browserName: 'iphone',
platform: 'OS X 10.9',
version: '7.1'
},
sl_ie_11: {
base: 'SauceLabs',
browserName: 'internet explorer',
platform: 'Windows 8.1',
version: '11'
}
};
// Project configuration.
// Project configuration
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
jshint: {
options: {
jshintrc: '.jshintrc'
},
all: {
src: [
'src/**/*.js'
]
}
},
watch: {
scripts: {
files: [
'src/**/*.js',
'spec/**/*.js'
],
tasks: ['jshint'],
options: {
spawn: false
}
},
'docs-sass': {

@@ -173,3 +17,3 @@ files: ['site/source/scss/**/*.scss'],

files: ['site/source/**/*.js'],
tasks: ['concat', 'uglify', 'copy:assemble'],
tasks: ['copy:assemble'],
options: {

@@ -196,99 +40,2 @@ nospawn: true

concurrent: {
options: {
logConcurrentOutput: true
},
dev: ['watch:scripts', 'karma:watch', 'docs']
},
concat: {
options: {
sourceMap: true,
separator: '\n\n',
banner: copyright + umdHeader,
footer: umdFooter,
},
complete: {
src: complete,
dest: 'dist/esri-leaflet-src.js'
},
core: {
src: core,
dest: 'dist/builds/core/esri-leaflet-core-src.js'
},
basemaps: {
src: basemaps,
dest: 'dist/builds/basemaps/esri-leaflet-basemaps-src.js'
},
mapservice: {
src: mapservice,
dest: 'dist/builds/map-service/esri-leaflet-map-service-src.js'
},
imageservice: {
src: imageservice,
dest: 'dist/builds/image-service/esri-leaflet-image-service-src.js'
},
featureservice: {
src: featureservice,
dest: 'dist/builds/feature-layer/esri-leaflet-feature-layer-src.js'
}
},
uglify: {
options: {
sourceMap: true,
sourceMapIncludeSources: true,
wrap: false,
mangle: {
except: ['L']
},
preserveComments: 'some',
report: 'gzip',
banner: copyright + umdHeader,
footer: umdFooter,
},
dist: {
files: {
'dist/esri-leaflet.js': complete,
'dist/builds/core/esri-leaflet-core.js': core,
'dist/builds/basemaps/esri-leaflet-basemaps.js': basemaps,
'dist/builds/map-service/esri-leaflet-map-service.js': mapservice,
'dist/builds/image-service/esri-leaflet-image-service.js': imageservice,
'dist/builds/feature-layer/esri-leaflet-feature-layer.js': featureservice
}
}
},
karma: {
options: {
configFile: 'karma.conf.js'
},
run: {
reporters: ['progress'],
browsers: browsers,
logLevel: 'ERROR'
},
coverage: {
reporters: ['progress', 'coverage'],
browsers: browsers,
preprocessors: {
'src/**/*.js': 'coverage'
}
},
watch: {
singleRun: false,
autoWatch: true,
browsers: browsers
},
sauce: {
sauceLabs: {
testName: 'Esri Leaflet Unit Tests'
},
customLaunchers: customLaunchers,
browsers: Object.keys(customLaunchers),
reporters: ['progress', 'saucelabs'],
singleRun: true
}
},
connect: {

@@ -332,2 +79,3 @@ server: {

options: {
data: ['package.json'],
assets: 'esri-leaflet/'

@@ -377,13 +125,2 @@ },

src: ['**']
},
releaseable: {
release: {
options: {
remote: 'upstream',
dryRun: grunt.option('dryRun') ? grunt.option('dryRun') : false,
silent: false
},
src: [ 'dist/**/*.js','dist/**/*.map' ]
}
}

@@ -393,14 +130,9 @@ });

// Development Tasks
grunt.registerTask('default', ['concurrent:dev']);
grunt.registerTask('build', ['jshint', 'karma:coverage', 'concat', 'uglify']);
grunt.registerTask('test', ['jshint', 'karma:run']);
grunt.registerTask('prepublish', ['concat', 'uglify']);
grunt.registerTask('release', ['releaseable']);
grunt.registerTask('test:sauce', ['karma:sauce']);
grunt.registerTask('default', ['docs']);
// Documentation Site Tasks
grunt.registerTask('docs', ['assemble:dev', 'concat', 'uglify', 'sass', 'copy', 'connect:docs', 'watch']);
grunt.registerTask('docs', ['assemble:dev', 'sass', 'copy', 'connect:docs', 'watch']);
// Documentation Site Tasks
grunt.registerTask('docs:build', ['assemble:build', 'copy', 'imagemin','sass', 'gh-pages']);
grunt.registerTask('docs:build', ['assemble:build', 'copy', 'imagemin', 'sass', 'gh-pages']);

@@ -407,0 +139,0 @@ // Require all grunt modules

// Karma configuration
// Generated on Fri May 30 2014 15:44:45 GMT-0400 (EDT)
module.exports = function(config) {
module.exports = function (config) {
config.set({

@@ -18,34 +18,4 @@

'node_modules/leaflet/dist/leaflet-src.js',
'src/EsriLeaflet.js',
'src/Util.js',
'src/Layers/BasemapLayer.js',
'src/Layers/RasterLayer.js',
'src/Layers/TiledMapLayer.js',
'src/Layers/DynamicMapLayer.js',
'src/Layers/ImageMapLayer.js',
'src/Layers/FeatureLayer/FeatureGrid.js',
'src/Layers/FeatureLayer/FeatureManager.js',
'src/Layers/FeatureLayer/FeatureLayer.js',
'src/Request.js',
'src/Services/Service.js',
'src/Services/FeatureLayerService.js',
'src/Services/MapService.js',
'src/Services/ImageService.js',
'src/Tasks/Task.js',
'src/Tasks/Query.js',
'src/Tasks/Identify.js',
'src/Tasks/IdentifyFeatures.js',
'src/Tasks/IdentifyImage.js',
'src/Tasks/Find.js',
'src/Controls/Logo.js',
'dist/esri-leaflet-src.js',
'spec/**/*Spec.js'
// 'spec/UtilSpec.js',
// 'spec/RequestSpec.js',
// 'spec/Tasks/*Spec.js',
// 'spec/Services/*Spec.js',
// 'spec/Layers/**/*Spec.js',
// 'spec/Layers/ImageMapLayerSpec.js',
// 'spec/**/QuerySpec.js',
// 'spec/**/FeatureManagerSpec.js'
],

@@ -58,4 +28,7 @@

// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {},
// preprocessors: {
// 'dist/**/*.js': ['sourcemap', 'coverage']
// },
// test results reporter to use

@@ -65,2 +38,3 @@ // possible values: 'dots', 'progress'

reporters: ['progress'],
// reporters: ['mocha', 'coverage'],

@@ -83,7 +57,7 @@ // web server port

browsers: [
'Chrome',
// 'Chrome',
// 'ChromeCanary',
// 'Firefox',
// 'Safari',
// 'PhantomJS'
'PhantomJS'
],

@@ -96,9 +70,19 @@

// Configure the coverage reporters
coverageReporter: {
reporters:[
{type: 'html', dir:'coverage/'},
{type: 'text'}
]
}
// coverageReporter: {
// instrumenters: {
// isparta: require('isparta')
// },
// instrumenter: {
// 'src/**/*.js': 'isparta'
// },
// reporters: [
// {
// type: 'html',
// dir: 'coverage/'
// }, {
// type: 'text'
// }
// ]
// }
});
};
{
"name": "esri-leaflet",
"version": "1.0.0",
"description": "Leaflet plugins for consuming ArcGIS Online and ArcGIS Server services",
"main": "dist/esri-leaflet.js",
"repository": {
"type": "git",
"url": "git@github.com:Esri/esri-leaflet.git"
"description": "Leaflet plugins for consuming ArcGIS Online and ArcGIS Server services.",
"version": "2.0.0-beta.1",
"author": "Patrick Arlt <parlt@esri.com> (http://patrickarlt.com)",
"browserify": {
"transform": [
"babelify"
]
},
"bugs": {
"url": "https://github.com/esri/esri-leaflet/issues"
},
"contributors": [
"Patrick Arlt <parlt@esri.com> (http://patrickarlt.com)",
"John Gravois <jgravois@esri.com> (http://johngravois.com)"
],
"dependencies": {
"leaflet": "1.0.0-beta.1"
},
"devDependencies": {
"assemble": "^0.4.37",
"babelify": "^6.1.3",
"chai": "2.3.0",
"esperanto": "^0.7.3",
"gh-release": "^2.0.0",
"grunt": "^0.4.2",
"grunt-concurrent": "^0.5.0",
"grunt-contrib-concat": "^0.5.0",
"grunt-contrib-connect": "^0.4.1",
"grunt-contrib-copy": "^0.5.0",
"grunt-contrib-imagemin": "^0.7.1",
"grunt-contrib-jshint": "^0.10.0",
"grunt-contrib-uglify": "^0.6.0",
"grunt-contrib-watch": "^0.6.1",
"grunt-gh-pages": "^0.8.1",
"grunt-karma": "^0.8.3",
"grunt-newer": "^0.7.0",
"grunt-releaseable": "0.0.16",
"grunt-sass": "^1.0.0",
"highlight.js": "^8.0.0",
"isparta": "^3.0.3",
"istanbul": "gotwarlost/istanbul.git#source-map",
"karma": "^0.12.16",
"karma-chai-sinon": "^0.1.3",
"karma-chrome-launcher": "^0.1.3",
"karma-coverage": "^0.1",
"karma-firefox-launcher": "^0.1.3",
"karma-coverage": "douglasduteil/karma-coverage#next",
"karma-mocha": "^0.1.0",
"karma-mocha-reporter": "^0.2.5",
"karma-phantomjs-launcher": "^0.1.4",
"karma-safari-launcher": "^0.1.1",
"karma-sauce-launcher": "^0.2.10",
"karma-phantomjs-launcher": "^0.2.0",
"karma-sourcemap-loader": "^0.3.5",
"load-grunt-tasks": "^0.4.0",
"sinon": "^1.11.1"
"phantomjs": "^1.9.17",
"rollup": "^0.10.0",
"semistandard": "^6.1.2",
"sinon": "^1.11.1",
"sinon-chai": "2.7.0",
"uglify-js": "^2.4.23"
},
"scripts": {
"prepublish": "grunt prepublish",
"start": "grunt dev",
"test": "grunt test"
"homepage": "http://esri.github.io/esri-leaflet",
"jsnext:main": "./index.js",
"jspm": {
"main": "./index.js",
"directories": {
"lib": "./lib"
},
"registry": "npm",
"format": "es6"
},
"author": "Patrick Arlt <parlt@esri.com> (http://patrickarlt.com)",
"contributors": [
"Patrick Arlt <parlt@esri.com> (http://patrickarlt.com)",
"John Gravois <jgravois@esri.com> (http://johngravois.com)"
"keywords": [
"arcgis",
"esri",
"esri leaflet",
"gis",
"leaflet plugin",
"mapping"
],
"license": "Apache-2.0",
"main": "dist/esri-leaflet.js",
"readmeFilename": "README.md",
"dependencies": {
"leaflet": "^0.7.3"
"repository": {
"type": "git",
"url": "git@github.com:Esri/esri-leaflet.git"
},
"scripts": {
"archive": "zip -r ./dist/esri-leaflet-v$(node --eval \"console.log(require('./package.json').version);\") ./dist/esri-leaflet.js ./dist/esri-leaflet.js.map",
"prerelease": "npm run build",
"release": "gh-release --assets ./dist/esri-leaflet-v$(node --eval \"console.log(require('./package.json').version);\") && npm publish",
"build": "./scripts/build.js",
"postbuild": "npm run archive",
"prepublish": "npm run build",
"start": "grunt",
"lint": "semistandard src/**/*.js",
"pretest": "npm run lint && esperanto -i src/EsriLeaflet.js -o ./dist/esri-leaflet-src.js --skip=leaflet --t umd --strict --name L.esri --bundle",
"test": "karma start"
}
}
# Esri Leaflet
[![Build Status](https://travis-ci.org/Esri/esri-leaflet.svg)](https://travis-ci.org/Esri/esri-leaflet)
[![Build Status](https://travis-ci.org/Esri/esri-leaflet.svg?branch=master)](https://travis-ci.org/Esri/esri-leaflet)
Leaflet plugins for [ArcGIS Services](http://developers.arcgis.com). Currently Esri Leaflet supports loading Esri [basemaps](http://esri.github.io/esri-leaflet/examples/switching-basemaps.html) and [feature services](http://esri.github.io/esri-leaflet/examples/simple-feature-layer.html), as well as [tiled](http://esri.github.io/esri-leaflet/examples/tile-layer-2.html) map, [dynamic](http://esri.github.io/esri-leaflet/examples/simple-dynamic-map-layer.html) map and [image](http://esri.github.io/esri-leaflet/examples/simple-image-map-layer.html) services.
[Leaflet](http://leafletjs.com/) plugins for [ArcGIS Services](http://developers.arcgis.com). Currently Esri Leaflet supports loading Esri [basemaps](http://esri.github.io/esri-leaflet/examples/switching-basemaps.html) and [feature services](http://esri.github.io/esri-leaflet/examples/simple-feature-layer.html), as well as [tiled](http://esri.github.io/esri-leaflet/examples/tile-layer-2.html) map, [dynamic](http://esri.github.io/esri-leaflet/examples/simple-dynamic-map-layer.html) map and [image](http://esri.github.io/esri-leaflet/examples/simple-image-map-layer.html) services.
The goal of Esri Leaflet is **not** to replace the [ArcGIS API for JavaScript](https://developers.arcgis.com/en/javascript/), but rather to provide small components to allow developers to build mapping applications with Leaflet.
The goal of Esri Leaflet is **not** to replace the [ArcGIS API for JavaScript](https://developers.arcgis.com/en/javascript/), but rather to provide small components to allow developers to build mapping applications with [Leaflet](http://leafletjs.com/).
**Currently Esri Leaflet is in development and should be thought of as a beta or preview.**
### Demos

@@ -27,3 +25,3 @@ We've written [loads of demos](http://esri.github.io/esri-leaflet/examples/) showing many of the features of Esri Leaflet.

<!-- we encourage you to replace 'latest' with a hardcode version number (like '1.0.0-rc.7') in production applications -->
<!-- we encourage you to replace 'latest' with a hardcode version number (like '1.0.0') in production applications -->
<script src="//cdn.jsdelivr.net/leaflet.esri/latest/esri-leaflet.js"></script>

@@ -45,3 +43,4 @@

var parks = new L.esri.FeatureLayer("http://services.arcgis.com/rOo16HdIMeOBI4Mb/arcgis/rest/services/Portland_Parks/FeatureServer/0", {
var parks = L.esri.featureLayer({
url: "http://services.arcgis.com/rOo16HdIMeOBI4Mb/arcgis/rest/services/Portland_Parks/FeatureServer/0",
style: function () {

@@ -84,3 +83,2 @@ return { color: "#70ca49", weight: 2 };

* [What are the goals of Esri Leaflet?](https://github.com//Esri/esri-leaflet/wiki/FAQ#what-are-the-goals-of-esri-leaflet)
* [When will Esri Leaflet leave beta?](https://github.com//Esri/esri-leaflet/wiki/FAQ#when-will-esri-leaflet-leave-beta)
* [How do you decide what features get included in Esri Leaflet?](https://github.com//Esri/esri-leaflet/wiki/FAQ#how-do-you-decide-what-features-get-included-in-esri-leaflet)

@@ -120,3 +118,3 @@ * [I have an idea! What should I do?](https://github.com//Esri/esri-leaflet/wiki/FAQ#i-have-an-idea-what-should-i-do)

* [Leaflet](http://leafletjs.com) version 0.7 or higher is required but the latest version is recommended.
* [Leaflet](http://leafletjs.com) version 0.7.3 is required.

@@ -123,0 +121,0 @@ ### Versioning

@@ -9,2 +9,2 @@ module.exports.register = function (Handlebars, options) {

});
};
};

@@ -5,2 +5,2 @@ module.exports.register = function (Handlebars, options) {

});
};
};

@@ -23,4 +23,4 @@ ---

<tr>
<td><code class="nobr">new L.esri.Layers.ClusteredFeatureLayer({{{param 'String' 'url'}}}, {{{param 'Object' 'options'}}})</code><br><br><code class="nobr">L.esri.Layers.clusteredFeatureLayer({{{param 'String' 'url'}}}, {{{param 'Object' 'options'}}})</code><br><br><code class="nobr">new L.esri.ClusteredFeatureLayer({{{param 'String' 'url'}}}, {{{param 'Object' 'options'}}})</code><br><br><code class="nobr">L.esri.clusteredFeatureLayer({{{param 'String' 'url'}}}, {{{param 'Object' 'options'}}})</code></td>
<td><code>url</code> should be the URL to the Feature Layer.</td>
<td><code class="nobr">L.esri.clusteredFeatureLayer({{{param 'Object' 'options'}}})</code></td>
<td>You must pass a <code>url</code> to a [Feature Layer](http://resources.arcgis.com/en/help/arcgis-rest-api/#/Layer/02r3000000w6000000/) in your <code>options</code></td>
</tr>

@@ -42,2 +42,7 @@ </tbody>

<tr>
<td><code>url</code></td>
<td><code>String</code></td>
<td><strong>Required</strong> The URL to the [Feature Layer](http://resources.arcgis.com/en/help/arcgis-rest-api/#/Layer/02r3000000w6000000/).</td>
</tr>
<tr>
<td><code>pointToLayer({{{param 'GeoJSON Feature' 'feature' 'http://geojson.org/geojson-spec.html#feature-objects'}}}, {{{param 'LatLng' 'latlng' 'http://leafletjs.com/reference.html#latlng'}}})</code></td>

@@ -44,0 +49,0 @@ <td><code>Function</code></td>

@@ -146,2 +146,12 @@ ---

</tr>
<tr>
<td><code>renderer</code></td>
<td><code>L.svg</code> or <code>L.canvas</code></td>
<td>The vector renderer to use to draw the service. Usually `L.svg` but setting to `L.canvas` contains performance benefits for large polygon layers..</td>
</tr>
<tr>
<td><code>pane</code></td>
<td><code>String</code></td>
<td>The map pane to render on. Usually `overlayPane` for vectors and `markerPane` for markers.</td>
</tr>
</tbody>

@@ -335,3 +345,3 @@ </table>

var busStops = L.esri.featureLayer('http://services.arcgis.com/rOo16HdIMeOBI4Mb/arcgis/rest/services/stops/FeatureServer/0/').addTo(map);
var busStops = L.esri.featureLayer({url: 'http://services.arcgis.com/rOo16HdIMeOBI4Mb/arcgis/rest/services/stops/FeatureServer/0/'}).addTo(map);
```

@@ -23,4 +23,4 @@ ---

<tr>
<td><code class="nobr">new L.esri.Layers.HeatmapFeatureLayer({{{param 'String' 'url'}}}, {{{param 'Object' 'options'}}})</code><br><br><code class="nobr">L.esri.Layers.heatmapFeatureLayer({{{param 'String' 'url'}}}, {{{param 'Object' 'options'}}})</code><br><br><code class="nobr">new L.esri.HeatmapFeatureLayer({{{param 'String' 'url'}}}, {{{param 'Object' 'options'}}})</code><br><br><code class="nobr">L.esri.heatmapFeatureLayer({{{param 'String' 'url'}}}, {{{param 'Object' 'options'}}})</code></td>
<td><code>url</code> should be the URL to the Feature Layer.</td>
<td><code class="nobr">L.esri.heatmapFeatureLayer({{{param 'Object' 'options'}}})</code></td>
<td>You must pass a <code>url</code> to a [Feature Layer](http://resources.arcgis.com/en/help/arcgis-rest-api/#/Layer/02r3000000w6000000/) in your <code>options</code></td>
</tr>

@@ -41,2 +41,7 @@ </tbody>

<tr>
<td><code>url</code></td>
<td><code>String</code></td>
<td><strong>Required</strong> The URL to the [Feature Layer](http://resources.arcgis.com/en/help/arcgis-rest-api/#/Layer/02r3000000w6000000/).</td>
</tr>
<tr>
<td><code>where</code></td>

@@ -43,0 +48,0 @@ <td><code>String</code></td>

@@ -50,2 +50,3 @@ ---

`mosaicRule` | `Object` | `undefined` | A JSON representation of a [mosaic rule](http://resources.arcgis.com/en/help/arcgis-rest-api/#/Mosaic_rule_objects/02r3000000s4000000/)
`pane` | `String` | `overlayPane` | The map pane to render on.

@@ -233,5 +234,5 @@ ### Methods

L.esri.imageMapLayer('http://imagery.oregonexplorer.info/arcgis/rest/services/NAIP_2011/NAIP_2011_Dynamic/ImageServer')
L.esri.imageMapLayer({url: 'http://imagery.oregonexplorer.info/arcgis/rest/services/NAIP_2011/NAIP_2011_Dynamic/ImageServer'})
.setBandIds('3,0,1')
.addTo(map);
```

@@ -39,3 +39,3 @@ ---

| --- | --- | --- | --- |
`url` | `String` | | *Required* URL of the [Map Service](http://resources.arcgis.com/en/help/arcgis-rest-api/#/Map_Service/02r3000000w2000000) with a tile cache.
|`url` | `String` | | *Required* URL of the [Map Service](http://resources.arcgis.com/en/help/arcgis-rest-api/#/Map_Service/02r3000000w2000000) with a tile cache.
| `correctZoomLevels` | `Boolean` | `true` | If your tiles were generated in web mercator but at non-standard zoom levels this will remap then to the standard zoom levels.

@@ -99,5 +99,6 @@ | `zoomOffsetAllowance` | `Number` | `0.1` | If `correctZoomLevels` is enabled this controls the amount of tolerance if the difference at each scale level for remapping tile levels.

L.esri.tiledMapLayer("http://services.arcgisonline.com/ArcGIS/rest/services/USA_Topo_Maps/MapServer", {
L.esri.tiledMapLayer({
url: 'http://services.arcgisonline.com/ArcGIS/rest/services/USA_Topo_Maps/MapServer',
maxZoom: 15
}).addTo(map);
```
---
title: L.esri.Services.FeatureLayer
title: L.esri.Services.FeatureLayerService
layout: documentation.hbs

@@ -10,3 +10,3 @@ ---

`L.esri.Services.FeatureLayer` is an abstraction for interacting with Feature Layers running on ArcGIS Online and ArcGIS Server that allows you to make requests to the API, as well as query, add, update and remove features from the service.
`L.esri.Services.FeatureLayerService` is an abstraction for interacting with Feature Layers running on ArcGIS Online and ArcGIS Server that allows you to make requests to the API, as well as query, add, update and remove features from the service.

@@ -24,3 +24,3 @@ ### Constructor

<tr>
<td><code class="nobr">L.esri.Services.featureLayer({{{param 'Object' 'options'}}})</code></td>
<td><code class="nobr">L.esri.Services.featureLayerService({{{param 'Object' 'options'}}})</code></td>
<td><code>options</code> for configuring the ArcGIS Server or ArcGIS Online feature layer you would like to consume. <code>Options</code> include a `url` parameter which refers to the ArcGIS Server or ArcGIS Online service you would like to consume.</td>

@@ -33,7 +33,7 @@ </tr>

`L.esri.Services.FeatureLayer` accepts all [`L.esri.Services.Service`]({{assets}}api-reference/services/service.html) options.
`L.esri.Services.FeatureLayerService` accepts all [`L.esri.Services.Service`]({{assets}}api-reference/services/service.html) options.
### Events
`L.esri.Services.FeatureLayer` fires all [`L.esri.Services.service`]({{assets}}api-reference/services/service.html) events.
`L.esri.Services.FeatureLayerService` fires all [`L.esri.Services.service`]({{assets}}api-reference/services/service.html) events.

@@ -117,3 +117,3 @@ ### Methods

```js
var service = L.esri.Services.featureLayer({
var service = L.esri.Services.featureLayerService({
url: 'http://services.arcgis.com/rOo16HdIMeOBI4Mb/arcgis/rest/services/Pubic_Feature_Service/FeatureServer/0'

@@ -145,3 +145,3 @@ });

```js
var service = L.esri.Services.featureLayer({
var service = L.esri.Services.featureLayerService({
url:'http://services.arcgis.com/rOo16HdIMeOBI4Mb/arcgis/rest/services/Pubic_Feature_Service/FeatureServer/0'

@@ -174,3 +174,3 @@ });

```js
var service = L.esri.Services.featureLayer({
var service = L.esri.Services.featureLayerService({
url: 'http://services.arcgis.com/rOo16HdIMeOBI4Mb/arcgis/rest/services/Pubic_Feature_Service/FeatureServer/0'

@@ -191,3 +191,3 @@ });

```js
var service = L.esri.Services.featureLayer({
var service = L.esri.Services.featureLayerService({
url: 'http://services.arcgis.com/rOo16HdIMeOBI4Mb/arcgis/rest/services/Pubic_Feature_Service/FeatureServer/0'

@@ -194,0 +194,0 @@ });

@@ -11,4 +11,4 @@ ---

* [`L.esri.Services.ImageService`]({{assets}}api-reference/services/image-service.html)
* [`L.esri.Services.FeatureLayer`]({{assets}}api-reference/services/feature-layer-service.html)
* [`L.esri.Services.FeatureLayerService`]({{assets}}api-reference/services/feature-layer-service.html)
* [`L.esri.Services.MapService`]({{assets}}api-reference/services/map-service.html)
* [`L.esri.Services.Service`]({{assets}}api-reference/services/service.html)

@@ -56,3 +56,3 @@ ---

<td><code>this</code></td>
<td>Queries features from the service within (fully contained by) the passed geometry object. `geometry` can be an instance of `L.Marker`, `L.Polygon`, `L.Polyline`, `L.LatLng`, `L.LatLngBounds` and `L.GeoJSON`. It can also accept valid GeoJSON Point, Polyline, Polygon objects and GeoJSON Feature objects containing Point, Polyline, Polygon.</td>
<td>Queries features from the service within (fully contained by) the passed geometry object. `geometry` can be an instance of [`L.Marker`](http://leafletjs.com/reference.html#marker), [`L.Polygon`](http://leafletjs.com/reference.html#polygon), [`L.Polyline`](http://leafletjs.com/reference.html#polyline), [`L.LatLng`](http://leafletjs.com/reference.html#latlng), [`L.LatLngBounds`](http://leafletjs.com/reference.html#latlngbounds) and [`L.GeoJSON`](http://leafletjs.com/reference.html#geojson). It can also accept valid GeoJSON [Point](http://geojson.org/geojson-spec.html#point), [Polyline](http://geojson.org/geojson-spec.html#polyline), [Polygon](http://geojson.org/geojson-spec.html#polygon) objects and GeoJSON [Feature objects](http://geojson.org/geojson-spec.html#feature-objects) containing Point, Polyline, Polygon.</td>
</tr>

@@ -62,3 +62,3 @@ <tr>

<td><code>this</code></td>
<td>Queries features from the service that fully contain the passed geometry object. `geometry` can be an instance of `L.Marker`, `L.Polygon`, `L.Polyline`, `L.LatLng`, `L.LatLngBounds` and `L.GeoJSON`. It can also accept valid GeoJSON Point, Polyline, Polygon objects and GeoJSON Feature objects containing Point, Polyline, Polygon.</td>
<td>Queries features from the service that fully contain the passed geometry object. `geometry` can be an instance of [`L.Marker`](http://leafletjs.com/reference.html#marker), [`L.Polygon`](http://leafletjs.com/reference.html#polygon), [`L.Polyline`](http://leafletjs.com/reference.html#polyline), [`L.LatLng`](http://leafletjs.com/reference.html#latlng), [`L.LatLngBounds`](http://leafletjs.com/reference.html#latlngbounds) and [`L.GeoJSON`](http://leafletjs.com/reference.html#geojson). It can also accept valid GeoJSON [Point](http://geojson.org/geojson-spec.html#point), [Polyline](http://geojson.org/geojson-spec.html#polyline), [Polygon](http://geojson.org/geojson-spec.html#polygon) objects and GeoJSON [Feature objects](http://geojson.org/geojson-spec.html#feature-objects) containing Point, Polyline, Polygon.</td>
</tr>

@@ -68,3 +68,3 @@ <tr>

<td><code>this</code></td>
<td>Queries features from the service that intersect (touch anywhere) the passed geometry object. `geometry` can be an instance of `L.Marker`, `L.Polygon`, `L.Polyline`, `L.LatLng`, `L.LatLngBounds` and `L.GeoJSON`. It can also accept valid GeoJSON Point, Polyline, Polygon objects and GeoJSON Feature objects containing Point, Polyline, Polygon.</td>
<td>Queries features from the service that intersect (touch anywhere) the passed geometry object. `geometry` can be an instance of [`L.Marker`](http://leafletjs.com/reference.html#marker), [`L.Polygon`](http://leafletjs.com/reference.html#polygon), [`L.Polyline`](http://leafletjs.com/reference.html#polyline), [`L.LatLng`](http://leafletjs.com/reference.html#latlng), [`L.LatLngBounds`](http://leafletjs.com/reference.html#latlngbounds) and [`L.GeoJSON`](http://leafletjs.com/reference.html#geojson). It can also accept valid GeoJSON [Point](http://geojson.org/geojson-spec.html#point), [Polyline](http://geojson.org/geojson-spec.html#polyline), [Polygon](http://geojson.org/geojson-spec.html#polygon) objects and GeoJSON [Feature objects](http://geojson.org/geojson-spec.html#feature-objects) containing Point, Polyline, Polygon.</td>
</tr>

@@ -74,3 +74,3 @@ <tr>

<td><code>this</code></td>
<td>Queries features from the service that overlap (touch but are not fully contained by) the passed geometry object. `geometry` can be an instance of `L.Marker`, `L.Polygon`, `L.Polyline`, `L.LatLng`, `L.LatLngBounds` and `L.GeoJSON`. It can also accept valid GeoJSON Point, Polyline, Polygon objects and GeoJSON Feature objects containing Point, Polyline, Polygon.</td>
<td>Queries features from the service that overlap (touch but are not fully contained by) the passed geometry object. `geometry` can be an instance of [`L.Marker`](http://leafletjs.com/reference.html#marker), [`L.Polygon`](http://leafletjs.com/reference.html#polygon), [`L.Polyline`](http://leafletjs.com/reference.html#polyline), [`L.LatLng`](http://leafletjs.com/reference.html#latlng), [`L.LatLngBounds`](http://leafletjs.com/reference.html#latlngbounds) and [`L.GeoJSON`](http://leafletjs.com/reference.html#geojson). It can also accept valid GeoJSON [Point](http://geojson.org/geojson-spec.html#point), [Polyline](http://geojson.org/geojson-spec.html#polyline), [Polygon](http://geojson.org/geojson-spec.html#polygon) objects and GeoJSON [Feature objects](http://geojson.org/geojson-spec.html#feature-objects) objects containing Point, Polyline, Polygon.</td>
</tr>

@@ -77,0 +77,0 @@ <tr>

@@ -11,3 +11,3 @@ ---

<a href="https://github.com/Esri/esri-leaflet/archive/v1.0.0-rc.8.zip" class="btn">Current Release</a>
<a href="https://github.com/Esri/esri-leaflet/releases/tag/v{{package.version}}" class="btn">Current Release</a>
<a href="https://github.com/Esri/esri-leaflet/releases/" class="btn">Past Releases</a>

@@ -33,37 +33,17 @@

Esri Leaflet is hosted on [jsDelivr](http://www.jsdelivr.com/).
#### Esri Leaflet
#### Standard Build
```xml
<script src="http://cdn.jsdelivr.net/leaflet.esri/1.0.0-rc.8/esri-leaflet.js"></script>
<script src="http://cdn.jsdelivr.net/leaflet.esri/{{package.version}}/esri-leaflet.js"></script>
```
#### Other Builds
#### Other Plugins
Esri Leaflet is also built into several smaller components and plugins for specific use cases. These more specialized builds are available on the CDN as well.
```xml
<!-- Core Build -->
<script src="http://cdn.jsdelivr.net/leaflet.esri/1.0.0-rc.8/builds/core/esri-leaflet-core.js"></script>
<!-- Basemaps Only Build -->
<script src="http://cdn.jsdelivr.net/leaflet.esri/1.0.0-rc.8/builds/basemaps/esri-leaflet-basemaps.js"></script>
<!-- Feature Layer Only Build -->
<script src="http://cdn.jsdelivr.net/leaflet.esri/1.0.0-rc.8/builds/feature-layer/esri-leaflet-feature-layer.js"></script>
<!-- Map Service Only Build -->
<script src="http://cdn.jsdelivr.net/leaflet.esri/1.0.0-rc.8/builds/map-service/esri-leaflet-map-service.js"></script>
<!-- Heatmap Feature Layer -->
<script src="http://cdn-geoweb.s3.amazonaws.com/esri-leaflet-heatmap-feature-layer/1.0.0-rc.3/esri-leaflet-heatmap-feature-layer.js"></script>
<!-- Clustered Feature Layer -->
<script src="http://cdn-geoweb.s3.amazonaws.com/esri-leaflet-clustered-feature-layer/1.0.0-rc.4/esri-leaflet-clustered-feature-layer.js"></script>
<script src="//cdn.jsdelivr.net/leaflet.esri.clustered-feature-layer/1.0.2/esri-leaflet-clustered-feature-layer.js"></script>
<!-- Geocoding Control -->
<script src="http://cdn-geoweb.s3.amazonaws.com/esri-leaflet-geocoder/1.0.0-rc.4/esri-leaflet-geocoder.js"></script>
<link rel="stylesheet" type="text/css" href="http://cdn-geoweb.s3.amazonaws.com/esri-leaflet-geocoder/1.0.0-rc.4/esri-leaflet-geocoder.css">
<link rel="stylesheet" href="//cdn.jsdelivr.net/leaflet.esri.geocoder/1.0.1/esri-leaflet-geocoder.css">
<script src="//cdn.jsdelivr.net/leaflet.esri.geocoder/1.0.1/esri-leaflet-geocoder.js"></script>

@@ -74,28 +54,3 @@ <!-- Renderers Plugin -->

<!-- Geoprocessing Plugin -->
<script src="http://cdn-geoweb.s3.amazonaws.com/esri-leaflet-gp/0.0.1-alpha.3/esri-leaflet-gp.js"></script>
<script src="//cdn.jsdelivr.net/leaflet.esri.gp/1.0.2/esri-leaflet-gp.js"></script>
```
# Builds
A summary of what features exist in which builds.
| Feature | Standard | Core | MapService | ImageService | FeatureLayer | Basemaps |
| -------------------------------------- | -------- | -------- | ---------- | ------------ | ------------ | -------- |
| Size | 52kb | 11.6kb | 24.3kb | 21.6kb | 29.6kb | 11kb |
| Gzipped | 12.9kb | 3.8kb | 6.8kb | 6.3kb | 8.7kb | 3.3kb |
| `L.esri.Request` | &#10003; | &#10003; | &#10003; | &#10003; | &#10003; | &#10003; |
| `L.esri.Util` | &#10003; | &#10003; | &#10003; | &#10003; | &#10003; | |
| `L.esri.Services.Service` | &#10003; | &#10003; | &#10003; | &#10003; | &#10003; | |
| `L.esri.Services.MapService` | &#10003; | | &#10003; | | | |
| `L.esri.Services.FeatureLayer` | &#10003; | | | | &#10003; | |
| `L.esri.Tasks.Task ` | &#10003; | &#10003; | &#10003; | &#10003; | &#10003; | |
| `L.esri.Tasks.Query` | &#10003; | | &#10003; | &#10003; | &#10003; | |
| `L.esri.Tasks.Find` | &#10003; | | &#10003; | | | |
| `L.esri.Tasks.IdentifyFeatures` | &#10003; | | &#10003; | | | |
| `L.esri.Tasks.IdentifyImage` | &#10003; | | | &#10003; | | |
| `L.esri.Layers.FeatureLayer` | &#10003; | | | | &#10003; | |
| `L.esri.Layers.ImageMapLayer` | &#10003; | | | &#10003; | | |
| `L.esri.Layers.DynamicMapLayer` | &#10003; | | &#10003; | | | |
| `L.esri.Layers.TiledMapLayer` | &#10003; | | &#10003; | | | |
| `L.esri.Layers.BasemapLayer` | &#10003; | | | | | &#10003; |

@@ -15,2 +15,10 @@ describe('L.esri.Layers.DynamicMapLayer', function () {

var Image1 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAH0AAAB9CAMAAAC4XpwXAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMDY3IDc5LjE1Nzc0NywgMjAxNS8wMy8zMC0yMzo0MDo0MiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6RjNGODI5NzkyMjYwMTFFNUJEOEJCNkRDM0Q3NUQxQ0UiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6RjNGODI5N0EyMjYwMTFFNUJEOEJCNkRDM0Q3NUQxQ0UiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpGM0Y4Mjk3NzIyNjAxMUU1QkQ4QkI2REMzRDc1RDFDRSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpGM0Y4Mjk3ODIyNjAxMUU1QkQ4QkI2REMzRDc1RDFDRSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PrtQ3ewAAAAwUExURbS0tN3d3dLS0qurq4yMjNbW1pOTk76+vqKios7OzpqamsbGxuXl5YSEhM/Pz8zMzOLy6/8AAAGBSURBVHja7Nu7cgMhDAVQIfESCuL//zYidpLOSUNIcXEBw6znrHgImiX2e4Vp3SzkF3GHDh06dOjQoUOHDh06dOjQoUOHDh06dOjQoUOH/u90LfzTI1zKId2N2uuHVUma6hGdbcrryNT7HMf0LD+Nq/d6Uuf981J0zzGX+HOJSld08V4Zvfo5PTVqvVknVY4GNeaYajJ26cZL+WjsbzJ7rr1OSlbziKrNWnNLkmtV3/rJ2Ckvm1R2a1q0gmXJpvECmcrh2EOPqpW6W6qZUq8fb5SpxY44H7uGzqFLXiv0MVLLZnWMTnw+dn/qn7E/9Bh5M/272L/nnfa8U8pydt5njzWve9XNntbXmh/VUuyEbDHyIx/S3aSVJmpiLM1jv1Mk/uiR2oo+9zvRIX2fccYlKl87sT3SHsmbTfNHrtudf3m+F5kyIs/cuV2oSx2N1x09jhcvvG7p+06BWyV06NChQ4cOHTp06NChQ4cOHTp06NChQ4cO/df6ulno6nfQ7wIMAAxMgKYG08xRAAAAAElFTkSuQmCC';
var Image2 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAH0AAAB9CAMAAAC4XpwXAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMDY3IDc5LjE1Nzc0NywgMjAxNS8wMy8zMC0yMzo0MDo0MiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MDI5MjEwNkEyMjYxMTFFNUJEOEJCNkRDM0Q3NUQxQ0UiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MDI5MjEwNkIyMjYxMTFFNUJEOEJCNkRDM0Q3NUQxQ0UiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDowMjkyMTA2ODIyNjExMUU1QkQ4QkI2REMzRDc1RDFDRSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDowMjkyMTA2OTIyNjExMUU1QkQ4QkI2REMzRDc1RDFDRSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PpxjvssAAAAwUExURd3d3bOzs9LS0qurq4uLi9bW1ry8vMnJyZubm5KSkoODg6SkpOPj48TExM/Pz8zMzIOgIpEAAAGeSURBVHja7NvLbsQgDAVQbGPzGuz//9tCuumqUdXSVOplpEEaoTkYjMkmif25ximebMkfxB06dOjQoUOHDh06dOjQoUOHDh06dOjQoUOHDh3639OVy80IVuUzuheym8FcRCYf0Xl20c9HRMu5fYH/kp5vdKU+Iw89pvP+uKrvPWb1Enp1vjdcpYe2cS72STZmGeTBNowmM4lRYZexvky83C3QN/QX9draaJ1SabmuznJreaaxuvCV8tTtmJ4oR+mkeax5lNltsSy5eLaUSZdfm/s5va21NW17Hh6ZUq0r/DIb2U43tTW1OBi7z2x86RFt63rptVZbeVdz8O/oH2NfK1/mFXqK39Dtfd8lM+USe99FdTTmU3ofL+k+r6z7kPO1vef8XDPK9dCJ8yKmJlFkuhhf5918/UJtqkud+7yTDDtSba47jldgq7Tt2+4qe0z0mn3yVet2xdP7i/Dn7vdVXKWuOvPM04W7tGocz+jh6srxlB7xjT/AUyV06NChQ4cOHTp06NChQ4cOHTp06NChQ4f+//R4sqVH34N+E2AAO/CAbzhay1gAAAAASUVORK5CYII=';
var WithLayers = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAH0AAAB9CAMAAAC4XpwXAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMDY3IDc5LjE1Nzc0NywgMjAxNS8wMy8zMC0yMzo0MDo0MiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MkU1NjVEN0MyMjZBMTFFNUI1NTc5NjAwMkVENUQwM0IiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MkU1NjVEN0QyMjZBMTFFNUI1NTc5NjAwMkVENUQwM0IiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDoyRTU2NUQ3QTIyNkExMUU1QjU1Nzk2MDAyRUQ1RDAzQiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDoyRTU2NUQ3QjIyNkExMUU1QjU1Nzk2MDAyRUQ1RDAzQiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Plrqc7EAAABgUExURaioqL29vba2tsbGxrm5uaGhobi4uLOzs5ycnMTExKampr+/v7KysrCwsMDAwMLCwq2traSkpMvLy5+fn6+vr8PDw6KiosjIyKOjo6Wlpa6urqurq8rKyp6enpmZmczMzKKB4ZgAAAEfSURBVHja7NXZboMwEIVhLzhQCMRAWEOY93/L2k26qb1Erir9vkAGIX0+gz0o+cuh0NHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0T/HJUuqF91sVSWVEekmEe3jw/aSSG/trt0kdgi5VXLdn/q8D+pVpN6t6Nk1Tz0vZ5FVm1CVdbEi51HLNt4O1Y3yanlkfst+O5un7oawqqxWL7KVJmyHax5eWY7NXhXZff2ie/OuF13QbdmKDEV5CroOW0Plh+p2H3rzq+5s0GUOpbZLo+NHCLebO/bEFZ1qfuixHLWLuo9HcByHR3Z796m6TRcv4/Qx/TZJ0usmlbLX8ZdBR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR/8H+qsAAwABe1cCMD1LDwAAAABJRU5ErkJggg==';
var WithTime = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAH0AAAB9CAMAAAC4XpwXAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMDY3IDc5LjE1Nzc0NywgMjAxNS8wMy8zMC0yMzo0MDo0MiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6RjNGODI5N0QyMjYwMTFFNUJEOEJCNkRDM0Q3NUQxQ0UiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6RjNGODI5N0UyMjYwMTFFNUJEOEJCNkRDM0Q3NUQxQ0UiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpGM0Y4Mjk3QjIyNjAxMUU1QkQ4QkI2REMzRDc1RDFDRSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpGM0Y4Mjk3QzIyNjAxMUU1QkQ4QkI2REMzRDc1RDFDRSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pk/Tz9QAAAAwUExURbS0tMrKypKSkqOjo6urq87OztnZ2dTU1JmZmb29vZ2dncLCwtHR0bi4uM/Pz8zMzLWz9KMAAAGMSURBVHja7NtB0pggDAVgQgiEEML9b9to2wt0ht8uHjKoq4+HElcWj++al/NlK/EhHtChQ4cOHTp06NChQ4cOHTp06NChQ4cOHTp06ND/d11+WBdJUv6qLnQk8vgZnRKORx+R7uE53hlRjJzHbV2Il7BMprJ8+KlljKlWCxWS+7onVFfRqNMbhe7utCv7rGtEhDyPwuPWyg9uCTXu5KvOodvDh85OJHmQUxx/Tpf01nYtXAavXdswy/RHS18sZGattr6qkV/SNzdr+bLVeXKxdbOlvvuskmuhXLTbzqW5o/syLpzhdLqmTsXe7FNl6eC9zI2NXa7oIqqk5qJTdOUEyp/sjy5cZuptTrmkD9WuKdYpdXl99ZrZa6waVqYO25PHpVo38qFy68dmZHZbJaXMnsGXvdnHqjpv6c9+zop3iE5uqxzea3lun57DuLfjDkU8PSv87y7vNYlnJTohknBcqzb4vkOHDh06dOjQoUOHDh06dOjQoUOHDh06dOjQoUP/N/182cqn/0H/EmAAhleDsZtu/OkAAAAASUVORK5CYII=';
var WithTimeTimeOptions = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAH0AAAB9CAMAAAC4XpwXAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMDY3IDc5LjE1Nzc0NywgMjAxNS8wMy8zMC0yMzo0MDo0MiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MkU1NjVENzgyMjZBMTFFNUI1NTc5NjAwMkVENUQwM0IiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MkU1NjVENzkyMjZBMTFFNUI1NTc5NjAwMkVENUQwM0IiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDoyOUVEREI3NTIyNkExMUU1QjU1Nzk2MDAyRUQ1RDAzQiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDoyOUVEREI3NjIyNkExMUU1QjU1Nzk2MDAyRUQ1RDAzQiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pno8yQ0AAABgUExURb29va6urqysrKioqLKyssvLy7Gxsbm5ucjIyLe3t7W1tcLCwr6+vsbGxrOzs8XFxbS0tMHBwaqqqsDAwLu7u7i4uLq6usfHx8nJyaurq8PDw8rKyqenp6Ojo7CwsMzMzDDnGUgAAAEDSURBVHja7NTbUoMwFIXhBhJCoJwLbT2t939L02A7elEdO2ov/JkMJGTtfMAAG91z26Cjo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6PfTS//Xp/DnOYbyUou231I74+DpndXtTfT2mm+8UA/CbbPrbSVcicT5apMozDH3RKJQqpL1SEc5MKjdpOR+kGHY4r5hxiNx8rdqBd5n+761Oyqn7qFlRt90n0n39pB9VhrqV/iube4nF2rnLlV7324omvcXvS+HdTknbosLvVUnSvMslZl5c+/8+7K2H6Z/M0vzvG3QUdHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dH//f6qwADAEAoWKnzLlffAAAAAElFTkSuQmCC';
var WithDefs = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAH0AAAB9CAMAAAC4XpwXAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMDY3IDc5LjE1Nzc0NywgMjAxNS8wMy8zMC0yMzo0MDo0MiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MjlFRERCNkYyMjZBMTFFNUI1NTc5NjAwMkVENUQwM0IiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MjlFRERCNzAyMjZBMTFFNUI1NTc5NjAwMkVENUQwM0IiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDoyOUVEREI2RDIyNkExMUU1QjU1Nzk2MDAyRUQ1RDAzQiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDoyOUVEREI2RTIyNkExMUU1QjU1Nzk2MDAyRUQ1RDAzQiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pg3iWmcAAABgUExURa6urr+/v8HBwcfHx7u7u56enrW1taWlpby8vLe3t7i4uMPDw8LCwqioqKamppmZmcjIyKurq7Kysq2trZaWlsrKypqampycnKOjo5eXl8vLy52dnZubm6KiorCwsMzMzADumocAAAFCSURBVHja7NXLbsMgEEBRMAH8KHEc41cch///yxLXSVrJm0p2uuhlhzTSYWYYEOEvl0BHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR//FurxHb1q1Yk/jHvo1vXhV+CYk+UP3s37wpT09w4pB7qFbo3ya6hCMjbsse+ltoW/PMHndpe9CpIMxbtnV4psezKvasttFz47nqarPUTvG+pZlEXWh5aynQwxIJhdPY30sTTJ2G+uJrkRv0xDy/pl7crzNuvSx8TZzZsm9EmpjvRl62Wn1Q1d1/aUPccy6qq8W/VAmW0/c2F7G+5Va0fM7eTXy49H3vD1trDsd7LSqH3RMOkzmLBZdqbbYWL+5IKo13bfuNJdbF4tuBvf2l7Z5vbENfxw6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6+r/XPwUYAAXsVASA6AUmAAAAAElFTkSuQmCC';
var WithToken = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAH0AAAB9CAMAAAC4XpwXAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMDY3IDc5LjE1Nzc0NywgMjAxNS8wMy8zMC0yMzo0MDo0MiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MjlFRERCNzMyMjZBMTFFNUI1NTc5NjAwMkVENUQwM0IiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MjlFRERCNzQyMjZBMTFFNUI1NTc5NjAwMkVENUQwM0IiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDoyOUVEREI3MTIyNkExMUU1QjU1Nzk2MDAyRUQ1RDAzQiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDoyOUVEREI3MjIyNkExMUU1QjU1Nzk2MDAyRUQ1RDAzQiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PhEp84oAAABgUExURcjIyJycnLa2tsTExL+/v7i4uJ+fn5mZmbS0tK6urqmpqbGxsaamppqamsDAwLKysrOzs6WlpcrKyqurq6Kioq2trby8vMvLy8PDw6SkpKqqqqysrKOjo8HBwbq6uszMzKcQTFcAAAEoSURBVHja7NTbboMwDIDhhHOABginAm39/m/ZsFGpmqpdQVdpfy4Qsi2+WDhR8pdLoaOjo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojf5iu7I9AGB6oF2MUqcpXb+W2WZ+BMcNWUNUH6km4GDuJ9IXIOXrow2W279DzoSljI+JGkbh/6NIG8g69zrqu8FSWiUxaiU2aetNdrqNVN/596Hxe9FLuqw/z1OXX7xa/er/Yy6Zfm1vuE23i/MZU4qOpS8dd9VD3uXZPenPuNj2eIz8QlV7WrvPSfy+Vk9v3xKVBnchL3ZY3H6iKk1qH04xH6J0dyte6axK7JqrWj4Vu5Qj9t/X0k90/uGnR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dE/X78LMAB6zVaMpfGcowAAAABJRU5ErkJggg==';
var url = 'http://services.arcgis.com/mock/arcgis/rest/services/MockMapService/MapServer';

@@ -49,3 +57,3 @@ var layer;

server.respondWith('GET',new RegExp(/http:\/\/services.arcgis.com\/mock\/arcgis\/rest\/services\/MockMapService\/MapServer\/export\?bbox=-?\d+\.\d+%2C-?\d+\.\d+%2C-?\d+\.\d+%2C-?\d+\.\d+&size=500%2C500&dpi=96&format=png24&transparent=true&bboxSR=3857&imageSR=3857&f=json/), JSON.stringify({
href: 'http://placehold.it/500&text=Image1'
href: Image1
}));

@@ -102,3 +110,3 @@ layer = L.esri.dynamicMapLayer({

layer.once('load', function(){
expect(layer._currentImage._url).to.equal('http://placehold.it/500&text=Image2');
expect(layer._currentImage._url).to.equal(Image2);
done();

@@ -109,3 +117,3 @@ });

server.respondWith('GET',new RegExp(/http:\/\/services.arcgis.com\/mock\/arcgis\/rest\/services\/MockMapService\/MapServer\/export\?bbox=-?\d+\.\d+%2C-?\d+\.\d+%2C-?\d+\.\d+%2C-?\d+\.\d+&size=500%2C500&dpi=96&format=png24&transparent=true&bboxSR=3857&imageSR=3857&f=json/), JSON.stringify({
href: 'http://placehold.it/500&text=Image2'
href: Image2
}));

@@ -120,3 +128,3 @@ server.respond();

expect(layer._currentImage).to.be.an.instanceof(L.ImageOverlay);
expect(layer._currentImage._url).to.equal('http://placehold.it/500&text=Image1');
expect(layer._currentImage._url).to.equal(Image1);
expect(layer._currentImage._bounds).to.deep.equal(map.getBounds());

@@ -140,3 +148,3 @@ done();

it('should expose the authenticate method on the underlying service', function(){
var spy = sinon.spy(layer._service, 'authenticate');
var spy = sinon.spy(layer.service, 'authenticate');
layer.authenticate('foo');

@@ -147,9 +155,9 @@ expect(spy).to.have.been.calledWith('foo');

it('should expose the identify method on the underlying service', function(){
var spy = sinon.spy(layer._service, 'identify');
var spy = sinon.spy(layer.service, 'identify');
var identify = layer.identify();
expect(identify).to.be.an.instanceof(L.esri.Tasks.IdentifyFeatures);
expect(identify._service).to.equal(layer._service);
expect(identify._service).to.equal(layer.service);
});
it('should propagate events from the service', function(){
it('should propagate events from the service', function(done){
server.respondWith('GET', 'http://services.arcgis.com/mock/arcgis/rest/services/MockMapService/MapServer&f=json', JSON.stringify({

@@ -165,3 +173,5 @@ currentVersion: 10.2

layer.metadata(function(){});
layer.metadata(function(){
done();
});

@@ -214,7 +224,7 @@ server.respond();

server.respondWith('GET', new RegExp(/http:\/\/services.arcgis.com\/mock\/arcgis\/rest\/services\/MockMapService\/MapServer\/export\?bbox=-?\d+\.\d+%2C-?\d+\.\d+%2C-?\d+\.\d+%2C-?\d+\.\d+&size=500%2C500&dpi=96&format=png24&transparent=true&bboxSR=3857&imageSR=3857&layers=show%3A0%2C1%2C2&f=json/), JSON.stringify({
href: 'http://placehold.it/500&text=WithLayers'
href: WithLayers
}));
layer.once('load', function(){
expect(layer._currentImage._url).to.equal('http://placehold.it/500&text=WithLayers');
expect(layer._currentImage._url).to.equal(WithLayers);
done();

@@ -231,7 +241,7 @@ });

server.respondWith('GET', new RegExp(/http:\/\/services.arcgis.com\/mock\/arcgis\/rest\/services\/MockMapService\/MapServer\/export\?bbox=-?\d+\.\d+%2C-?\d+\.\d+%2C-?\d+\.\d+%2C-?\d+\.\d+&size=500%2C500&dpi=96&format=png24&transparent=true&bboxSR=3857&imageSR=3857&time=1389254400000%2C1389513600000&f=json/), JSON.stringify({
href: 'http://placehold.it/500&text=WithTime'
href: WithTime
}));
layer.once('load', function(){
expect(layer._currentImage._url).to.equal('http://placehold.it/500&text=WithTime');
expect(layer._currentImage._url).to.equal(WithTime);
done();

@@ -247,8 +257,8 @@ });

it('should get and set extra time options', function(done){
server.respondWith('GET', new RegExp(/http:\/\/services.arcgis.com\/mock\/arcgis\/rest\/services\/MockMapService\/MapServer\/export\?bbox=-?\d+\.\d+%2C-?\d+\.\d+%2C-?\d+\.\d+%2C-?\d+\.\d+&size=500%2C500&dpi=96&format=png24&transparent=true&bboxSR=3857&imageSR=3857&timeOptions=%7B%22foo%22%3A%22bar%22%7D&time=1389254400000%2C1389513600000&f=json/), JSON.stringify({
href: 'http://placehold.it/500&text=WithTime&TimeOptions'
server.respondWith('GET', new RegExp(/http:\/\/services\.arcgis\.com\/mock\/arcgis\/rest\/services\/MockMapService\/MapServer\/export\?bbox=-?\d+\.\d+%2C-?\d+\.\d+%2C-?\d+\.\d+%2C-?\d+\.\d+&size=500%2C500&dpi=96&format=png24&transparent=true&bboxSR=3857&imageSR=3857&timeOptions=%7B%22foo%22%3A%22bar%22%7D&time=1389254400000%2C1389513600000&f=json/), JSON.stringify({
href: WithTimeTimeOptions
}));
layer.once('load', function(){
expect(layer._currentImage._url).to.equal('http://placehold.it/500&text=WithTime&TimeOptions');
expect(layer._currentImage._url).to.equal(WithTimeTimeOptions);
done();

@@ -267,7 +277,7 @@ });

server.respondWith('GET', new RegExp(/http:\/\/services.arcgis.com\/mock\/arcgis\/rest\/services\/MockMapService\/MapServer\/export\?bbox=-?\d+\.\d+%2C-?\d+\.\d+%2C-?\d+\.\d+%2C-?\d+\.\d+&size=500%2C500&dpi=96&format=png24&transparent=true&bboxSR=3857&imageSR=3857&layerDefs=%7B%221%22%3A%22Foo%3DBar%22%7D&f=json/), JSON.stringify({
href: 'http://placehold.it/500&text=WithDefs'
href: WithDefs
}));
layer.once('load', function(){
expect(layer._currentImage._url).to.equal('http://placehold.it/500&text=WithDefs');
expect(layer._currentImage._url).to.equal(WithDefs);
done();

@@ -285,7 +295,7 @@ });

server.respondWith('GET', new RegExp(/http:\/\/services.arcgis.com\/mock\/arcgis\/rest\/services\/MockMapService\/MapServer\/export\?bbox=-?\d+\.\d+%2C-?\d+\.\d+%2C-?\d+\.\d+%2C-?\d+\.\d+&size=500%2C500&dpi=96&format=png24&transparent=true&bboxSR=3857&imageSR=3857&token=foo&f=json/), JSON.stringify({
href: 'http://placehold.it/500&text=WithToken'
href: WithToken
}));
layer.once('load', function(){
expect(layer._currentImage._url).to.equal('http://placehold.it/500&text=WithToken');
expect(layer._currentImage._url).to.equal(WithToken);
done();

@@ -292,0 +302,0 @@ });

@@ -26,3 +26,5 @@ describe('L.esri.Layers.FeatureGrid', function () {

});
grid = new MockGrid();
grid = new MockGrid({
cellSize: 512
});
map = createMap();

@@ -38,3 +40,3 @@ clock = sinon.useFakeTimers();

it('should create cells based on the view of the map', function(){
map.setView([0,0,], 1);
map.setView([0,0], 1);
grid.addTo(map);

@@ -49,11 +51,9 @@ expect(grid.createCell.getCall(0).args[1].equals(L.point([0,0]))).to.equal(true);

clock.tick(1000);
expect(grid.cellLeave.getCall(0).args[1].equals(L.point([0,0,1]))).to.equal(true);
expect(grid.cellLeave.getCall(1).args[1].equals(L.point([1,0,1]))).to.equal(true);
expect(grid.cellLeave.getCall(2).args[1].equals(L.point([0,1,1]))).to.equal(true);
expect(grid.cellLeave.getCall(3).args[1].equals(L.point([1,1,1]))).to.equal(true);
expect(grid.createCell.getCall(4).args[1].equals(L.point([0,0,2]))).to.equal(true);
expect(grid.createCell.getCall(5).args[1].equals(L.point([1,0,2]))).to.equal(true);
expect(grid.createCell.getCall(6).args[1].equals(L.point([0,1,2]))).to.equal(true);
expect(grid.createCell.getCall(7).args[1].equals(L.point([1,1,2]))).to.equal(true);
expect(grid.createCell.getCall(1).args[1].equals(L.point([0,0,2]))).to.equal(true);
expect(grid.createCell.getCall(2).args[1].equals(L.point([1,0,2]))).to.equal(true);
expect(grid.createCell.getCall(3).args[1].equals(L.point([0,1,2]))).to.equal(true);
expect(grid.createCell.getCall(4).args[1].equals(L.point([1,1,2]))).to.equal(true);
});

@@ -66,3 +66,3 @@

map.panBy([256,256], {
map.panBy([512,512], {
animate: false,

@@ -78,2 +78,2 @@ duration: 0

});
});

@@ -196,52 +196,18 @@ describe('L.esri.Layers.FeatureLayer', function () {

it('should bind popups to existing features', function(){
layer.bindPopup(function(feature){
return 'ID: ' + feature.id;
});
expect(layer.getFeature(1)._popup.getContent()).to.equal('ID: 1');
expect(layer.getFeature(2)._popup.getContent()).to.equal('ID: 2');
it('should iterate over each feature', function(){
var spy = sinon.spy();
layer.eachFeature(spy);
expect(spy.callCount).to.equal(2);
});
it('should bind popups to new features', function(){
layer.bindPopup(function(feature){
return 'ID: ' + feature.id;
});
layer.createLayers([{
type: 'Feature',
id: 3,
geometry: {
type: 'Point',
coordinates: [-123, 46]
},
properties: {
time: new Date('Febuary 24 2014').valueOf()
}
}]);
expect(layer.getFeature(3)._popup.getContent()).to.equal('ID: 3');
it('should run a function against every feature', function(){
var spy = sinon.spy();
layer = L.esri.featureLayer({
url: 'http://gis.example.com/mock/arcgis/rest/services/MockService/MockFeatureServer/0',
onEachFeature: spy
}).addTo(map);
layer.createLayers(features);
expect(spy.callCount).to.equal(2);
});
it('should preserve popup options when binding popup to new or existing features', function(){
layer.bindPopup(function(feature){
return 'ID: ' + feature.id;
}, {minWidth: 500});
layer.createLayers([{
type: 'Feature',
id: 3,
geometry: {
type: 'Point',
coordinates: [-123, 46]
},
properties: {
time: new Date('Febuary 24 2014').valueOf()
}
}]);
expect(layer.getFeature(1)._popup.options.minWidth).to.equal(500);
expect(layer.getFeature(2)._popup.options.minWidth).to.equal(500);
expect(layer.getFeature(3)._popup.options.minWidth).to.equal(500);
});
it('should style L.circleMarker features appropriately', function(){

@@ -266,5 +232,7 @@ layer = L.esri.featureLayer({

});
layer.unbindPopup();
expect(layer.getFeature(1)._popup).to.equal(null);
expect(layer.getFeature(2)._popup).to.equal(null);
expect(layer._popup).to.equal(null);
expect(layer._popup).to.equal(null);
});

@@ -283,5 +251,6 @@

});
layer.unbindPopup();
expect(layer.getFeature(1).getLayers()[0]._popup).to.equal(null);
expect(layer.getFeature(1).getLayers()[1]._popup).to.equal(null);
expect(layer._popup).to.equal(null);
});

@@ -299,3 +268,3 @@

expect(layer.getFeature(1).getLayers()[0].options.color).to.equal('black');
expect(layer.getFeature(1).options.color).to.equal('black');

@@ -306,7 +275,7 @@ layer.setFeatureStyle(1, {

expect(layer.getFeature(1).getLayers()[0].options.color).to.equal('red');
expect(layer.getFeature(1).options.color).to.equal('red');
layer.resetStyle(1);
expect(layer.getFeature(1).getLayers()[0].options.color).to.equal('black');
expect(layer.getFeature(1).options.color).to.equal('black');
});

@@ -318,5 +287,8 @@

pointToLayer: function(feature, latlng){
return L.circleMarker(latlng, {
return L.circleMarker(latlng);
},
style: function () {
return {
color: 'green'
});
};
}

@@ -333,3 +305,3 @@ }).addTo(map);

layer.resetStyle(1);
layer.resetFeatureStyle(1);
expect(layer.getFeature(1).options.color).to.equal('green');

@@ -349,7 +321,7 @@ });

expect(layer.getFeature(1).getLayers()[0].options.color).to.equal('red');
expect(layer.getFeature(1).options.color).to.equal('red');
layer.resetStyle(1);
expect(layer.getFeature(1).getLayers()[0].options.color).to.equal('#0033ff');
expect(layer.getFeature(1).options.color).to.equal('#3388ff');
});

@@ -364,7 +336,7 @@

expect(layer.getFeature(1).getLayers()[0].options.fill).to.equal(true);
expect(layer.getFeature(1).options.fill).to.equal(true);
layer.resetStyle(1);
expect(layer.getFeature(1).getLayers()[0].options.color).to.equal('#0033ff');
expect(layer.getFeature(1).options.color).to.equal('#3388ff');
});

@@ -401,3 +373,3 @@

type: 'LineString',
coordinates: [[-122, 45], [-121, 40]]
coordinates: [[-122, 45], [-121, 63]]
},

@@ -427,3 +399,3 @@ properties: {

type: 'LineString',
coordinates: [[-122, 45], [-121, 40]]
coordinates: [[-122, 45], [-121, 63]]
},

@@ -444,3 +416,3 @@ properties: {

foo: 'bar'
});
}, true);

@@ -450,2 +422,26 @@ expect(spy.getCall(0).args[0].foo).to.equal('bar');

});
it('should pass renderer through to individual features', function(){
var renderer = L.canvas();
layer = L.esri.featureLayer({
url: 'http://gis.example.com/mock/arcgis/rest/services/MockService/MockFeatureServer/0',
renderer: renderer
}).addTo(map);
layer.createLayers(features);
expect(layer.getFeature(1).options.renderer).to.equal(renderer);
});
it('should pass pane through to individual features', function(){
map.createPane('custom');
layer = L.esri.featureLayer({
url: 'http://gis.example.com/mock/arcgis/rest/services/MockService/MockFeatureServer/0',
pane: 'custom'
}).addTo(map);
layer.createLayers(features);
expect(layer.getFeature(1).options.pane).to.equal('custom');
});
});

@@ -43,3 +43,3 @@ describe('L.esri.Layers.FeatureManager', function () {

sandbox = sinon.sandbox.create();
oldRaf = L.esri.Util.requestAnimationFrame;
oldRaf = L.Util.requestAnimFrame;

@@ -60,3 +60,3 @@ MockLayer = L.esri.Layers.FeatureManager.extend({

L.esri.Util.requestAnimationFrame = function(cd){
L.Util.requestAnimFrame = function(cd){
cd();

@@ -69,3 +69,3 @@ };

sandbox.restore();
L.esri.Util.requestAnimationFrame = oldRaf;
L.Util.requestAnimFrame = oldRaf;
});

@@ -636,3 +636,3 @@

it('should expose the authenticate method on the underlying service', function(){
var spy = sinon.spy(layer._service, 'authenticate');
var spy = sinon.spy(layer.service, 'authenticate');
layer.authenticate('foo');

@@ -643,3 +643,3 @@ expect(spy).to.have.been.calledWith('foo');

it('should expose the metadata method on the underlying service', function(){
var spy = sinon.spy(layer._service, 'metadata');
var spy = sinon.spy(layer.service, 'metadata');
var callback = sinon.spy();

@@ -651,6 +651,6 @@ layer.metadata(callback);

it('should expose the query method on the underlying service', function(){
var spy = sinon.spy(layer._service, 'query');
var spy = sinon.spy(layer.service, 'query');
var query = layer.query();
expect(query).to.be.an.instanceof(L.esri.Tasks.Query);
expect(query._service).to.equal(layer._service);
expect(query._service).to.equal(layer.service);
});

@@ -764,3 +764,3 @@

it('should support generalizing geometries', function(){
server.respondWith('GET', 'http://gis.example.com/mock/arcgis/rest/services/MockService/MockFeatureServer/0/query?returnGeometry=true&where=1%3D1&outSr=4326&outFields=*&inSr=4326&geometry=%7B%22xmin%22%3A-122.6953125%2C%22ymin%22%3A45.521743896993634%2C%22xmax%22%3A-122.6513671875%2C%22ymax%22%3A45.55252525134013%2C%22spatialReference%22%3A%7B%22wkid%22%3A4326%7D%7D&geometryType=esriGeometryEnvelope&spatialRel=esriSpatialRelIntersects&geometryPrecision=6&maxAllowableOffset=0.00004291534423829546&f=json', JSON.stringify({
server.respondWith('GET', 'http://gis.example.com/mock/arcgis/rest/services/MockService/MockFeatureServer/0/query?returnGeometry=true&where=1%3D1&outSr=4326&outFields=*&inSr=4326&geometry=%7B%22xmin%22%3A-122.6953125%2C%22ymin%22%3A45.521743896993634%2C%22xmax%22%3A-122.6513671875%2C%22ymax%22%3A45.55252525134013%2C%22spatialReference%22%3A%7B%22wkid%22%3A4326%7D%7D&geometryType=esriGeometryEnvelope&spatialRel=esriSpatialRelIntersects&geometryPrecision=6&maxAllowableOffset=0.00004291534423826704&f=json', JSON.stringify({
fields: fields,

@@ -777,5 +777,3 @@ features: [feature6],

layer.addTo(map);
server.respond();
expect(layer.createLayers).to.have.been.calledWith([{

@@ -807,3 +805,3 @@ 'type': 'Feature',

it('should propagate events from the service', function(){
server.respondWith('GET', 'http://gis.example.com/mock/arcgis/rest/services/MockService/MockFeatureServer/0/query?returnGeometry=true&where=1%3D1&outSr=4326&outFields=*&inSr=4326&geometry=%7B%22xmin%22%3A-122.6953125%2C%22ymin%22%3A45.521743896993634%2C%22xmax%22%3A-122.6513671875%2C%22ymax%22%3A45.55252525134013%2C%22spatialReference%22%3A%7B%22wkid%22%3A4326%7D%7D&geometryType=esriGeometryEnvelope&spatialRel=esriSpatialRelIntersects&geometryPrecision=6&f=json', JSON.stringify({
server.respondWith('GET', new RegExp(/.*/), JSON.stringify({
fields: fields,

@@ -810,0 +808,0 @@ features: [],

@@ -15,2 +15,13 @@ describe('L.esri.Layers.ImageMapLayer', function () {

var Image1 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAH0AAAB9CAMAAAC4XpwXAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMDY3IDc5LjE1Nzc0NywgMjAxNS8wMy8zMC0yMzo0MDo0MiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6RjNGODI5NzkyMjYwMTFFNUJEOEJCNkRDM0Q3NUQxQ0UiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6RjNGODI5N0EyMjYwMTFFNUJEOEJCNkRDM0Q3NUQxQ0UiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpGM0Y4Mjk3NzIyNjAxMUU1QkQ4QkI2REMzRDc1RDFDRSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpGM0Y4Mjk3ODIyNjAxMUU1QkQ4QkI2REMzRDc1RDFDRSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PrtQ3ewAAAAwUExURbS0tN3d3dLS0qurq4yMjNbW1pOTk76+vqKios7OzpqamsbGxuXl5YSEhM/Pz8zMzOLy6/8AAAGBSURBVHja7Nu7cgMhDAVQIfESCuL//zYidpLOSUNIcXEBw6znrHgImiX2e4Vp3SzkF3GHDh06dOjQoUOHDh06dOjQoUOHDh06dOjQoUOH/u90LfzTI1zKId2N2uuHVUma6hGdbcrryNT7HMf0LD+Nq/d6Uuf981J0zzGX+HOJSld08V4Zvfo5PTVqvVknVY4GNeaYajJ26cZL+WjsbzJ7rr1OSlbziKrNWnNLkmtV3/rJ2Ckvm1R2a1q0gmXJpvECmcrh2EOPqpW6W6qZUq8fb5SpxY44H7uGzqFLXiv0MVLLZnWMTnw+dn/qn7E/9Bh5M/272L/nnfa8U8pydt5njzWve9XNntbXmh/VUuyEbDHyIx/S3aSVJmpiLM1jv1Mk/uiR2oo+9zvRIX2fccYlKl87sT3SHsmbTfNHrtudf3m+F5kyIs/cuV2oSx2N1x09jhcvvG7p+06BWyV06NChQ4cOHTp06NChQ4cOHTp06NChQ4cO/df6ulno6nfQ7wIMAAxMgKYG08xRAAAAAElFTkSuQmCC';
var Image2 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAH0AAAB9CAMAAAC4XpwXAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMDY3IDc5LjE1Nzc0NywgMjAxNS8wMy8zMC0yMzo0MDo0MiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MDI5MjEwNkEyMjYxMTFFNUJEOEJCNkRDM0Q3NUQxQ0UiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MDI5MjEwNkIyMjYxMTFFNUJEOEJCNkRDM0Q3NUQxQ0UiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDowMjkyMTA2ODIyNjExMUU1QkQ4QkI2REMzRDc1RDFDRSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDowMjkyMTA2OTIyNjExMUU1QkQ4QkI2REMzRDc1RDFDRSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PpxjvssAAAAwUExURd3d3bOzs9LS0qurq4uLi9bW1ry8vMnJyZubm5KSkoODg6SkpOPj48TExM/Pz8zMzIOgIpEAAAGeSURBVHja7NvLbsQgDAVQbGPzGuz//9tCuumqUdXSVOplpEEaoTkYjMkmif25ximebMkfxB06dOjQoUOHDh06dOjQoUOHDh06dOjQoUOHDh3639OVy80IVuUzuheym8FcRCYf0Xl20c9HRMu5fYH/kp5vdKU+Iw89pvP+uKrvPWb1Enp1vjdcpYe2cS72STZmGeTBNowmM4lRYZexvky83C3QN/QX9draaJ1SabmuznJreaaxuvCV8tTtmJ4oR+mkeax5lNltsSy5eLaUSZdfm/s5va21NW17Hh6ZUq0r/DIb2U43tTW1OBi7z2x86RFt63rptVZbeVdz8O/oH2NfK1/mFXqK39Dtfd8lM+USe99FdTTmU3ofL+k+r6z7kPO1vef8XDPK9dCJ8yKmJlFkuhhf5918/UJtqkud+7yTDDtSba47jldgq7Tt2+4qe0z0mn3yVet2xdP7i/Dn7vdVXKWuOvPM04W7tGocz+jh6srxlB7xjT/AUyV06NChQ4cOHTp06NChQ4cOHTp06NChQ4f+//R4sqVH34N+E2AAO/CAbzhay1gAAAAASUVORK5CYII=';
var WithBandIds = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAH0AAAB9CAMAAAC4XpwXAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMDY3IDc5LjE1Nzc0NywgMjAxNS8wMy8zMC0yMzo0MDo0MiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MDI5MjEwNjYyMjYxMTFFNUJEOEJCNkRDM0Q3NUQxQ0UiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MDI5MjEwNjcyMjYxMTFFNUJEOEJCNkRDM0Q3NUQxQ0UiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDowMjkyMTA2NDIyNjExMUU1QkQ4QkI2REMzRDc1RDFDRSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDowMjkyMTA2NTIyNjExMUU1QkQ4QkI2REMzRDc1RDFDRSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PmMIuvMAAAAwUExURaOjo7q6upubm8rKysXFxa2traioqM3NzdTU1NHR0bW1tcDAwLGxsdra2s/Pz8zMzKnue9YAAAFqSURBVHja7NvLcoUgDAbgQMiNcPD937axPe102wVjFz86A4HRT0BwJcV+LgVdTybaD+IbOnTo0KFDhw4dOnTo0KFDhw4dOnTo0KFDhw4dOvR/qXMEX5f9qth3BVvYOT3q7rG9rsqxOdx/WmzkLXOyHdJtTK6jNQun5dF6i+82b+QrfdCIUzpTgZozJkt7uXYa7n6PAb9SvbdX3DXGR0beRbosS+5zFiUiPHRG6vTs4pRMZKl/6P6f9ElKbZD1XES7HuVV/f8cA+3qNKRr1Gln9NZXz6GhYzXhJZqSYtLmXHn3vSJuch3Ts4+kml1ZykKVE4UuTSXynhWx9+VHdGMZi8eKNVqbV+uzXnWJ2WolVFnqwSoi3kf0ezMJs+CwvfdVC++K2naqbHdetRHvjejIXmf3nNr7+Jxfe0dfoX2V8JWBDh06dOjQoUOHDh06dOjQoUOHDh06dOjQoUOHDv2tX08mevQ/6A8BBgCthIUYpHW5BgAAAABJRU5ErkJggg==';
var WithMosaicRule = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAH0AAAB9CAMAAAC4XpwXAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMDY3IDc5LjE1Nzc0NywgMjAxNS8wMy8zMC0yMzo0MDo0MiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MDE1NkNBMTMyMjYxMTFFNUJEOEJCNkRDM0Q3NUQxQ0UiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MDE1NkNBMTQyMjYxMTFFNUJEOEJCNkRDM0Q3NUQxQ0UiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDowMTU2Q0ExMTIyNjExMUU1QkQ4QkI2REMzRDc1RDFDRSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDowMTU2Q0ExMjIyNjExMUU1QkQ4QkI2REMzRDc1RDFDRSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PnU+MbkAAAAwUExURZaWlqKios7OzrW1tcXFxdHR0b29vbGxscHBwcrKytbW1rm5uampqa2trc/Pz8zMzJFOko0AAAFKSURBVHja7NtJjoQwDAXQeEyc8f63LYNUva8FohffgijgSA/FmB3F9nth5bwZZb+Ib+jQoUOHDh06dOjQoUOHDh06dOjQoUOHDh06dOjQoX/XbuZcHWwRmzfHN8F5c9t1zfaUHhF5Hu46mK8p/2WSDc+HYB2Hn9F3rSLSInz1Pr2O3pn7sc5De5ci3boSd4sn9C40q6tTI++0aFiNkOM1PIYOqtq0LZZmT+jmREurzzZJF5F6caEzqcmgGEV9iouXafyQPnm1JPKg0mSKXdVwqauP4m1dKfqh9L/UXVPi2qSJjCHTtfjO+pNKm82XaG5NDsOe6Xfm+82/g7PzdKtaKMcOzbeeNSemwY/onHEPd2w+lv2djZ47ve+c7ZwaB7600KFDhw4dOnTo0KFDhw4dOnTo0KFDhw4dOnTo0KH/C/28GeXV/6A/AgwASyKGXME0LNgAAAAASUVORK5CYII=';
var WithNoData = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAH0AAAB9CAMAAAC4XpwXAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMDY3IDc5LjE1Nzc0NywgMjAxNS8wMy8zMC0yMzo0MDo0MiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MDE1NkNBMEYyMjYxMTFFNUJEOEJCNkRDM0Q3NUQxQ0UiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MDE1NkNBMTAyMjYxMTFFNUJEOEJCNkRDM0Q3NUQxQ0UiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDowMTU2Q0EwRDIyNjExMUU1QkQ4QkI2REMzRDc1RDFDRSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDowMTU2Q0EwRTIyNjExMUU1QkQ4QkI2REMzRDc1RDFDRSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pmn1mFQAAAAwUExURdHR0crKyrS0tJWVlc3NzaqqqtXV1aWlpcXFxdvb25+fn76+vrm5ua6urs/Pz8zMzE0rlwYAAAF3SURBVHja7NuxshsxCAVQkEBgpEX//7cPbdKmSKF4JnPl4goXe8Qwlqslyu8tov3NRflFPKFDhw4dOnTo0KFDhw4dOnTo0KFDhw4dOnTo0KFD/9MS+de60CZJ2i8sv2riU9AQvqwLezqzU6FjKVUt7ucUe658j8GUfElPDrbVdCr5aDGIu6sOEeLolnKWc81ErvROtqI9jWcdY9nR26ODcnjUtjZE8QbfmPtQjUenr9mnR0zqZs+ndZdI1Y/2Jl1HRcoNfXVVk2b79K5Gan1x1FdHr00MW15BV/TZWwnLyPZ6poq2PqexeZBW7TZsnrjSO3mfFp9mGXvpqpbrOBzNOM4srL29V1zpXST4eT5L8/S+VGLX3LWvEV0p7Qx9jYor+u9rhnnXh0+IMG2nXZdAbb1+8Ewn7ty0Wf2z5JtvZJVUM6luOev+qfrvHoj/OOjQoUOHDh06dOjQoUOHDh06dOjQoUOHDh06dOj/ub6/ueir70H/CDAAWbCDHyCP7VgAAAAASUVORK5CYII=';
var WithNoDataArray = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAH0AAAB9CAMAAAC4XpwXAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMDY3IDc5LjE1Nzc0NywgMjAxNS8wMy8zMC0yMzo0MDo0MiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MDE1NkNBMEIyMjYxMTFFNUJEOEJCNkRDM0Q3NUQxQ0UiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MDE1NkNBMEMyMjYxMTFFNUJEOEJCNkRDM0Q3NUQxQ0UiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpGRkExMUM3RTIyNjAxMUU1QkQ4QkI2REMzRDc1RDFDRSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDowMTU2Q0EwQTIyNjExMUU1QkQ4QkI2REMzRDc1RDFDRSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PhRmDVYAAAAwUExURcXFxbq6uqSkpL29vc3NzcHBwba2tq6urtHR0bKyssrKypqamqmpqdXV1c/Pz8zMzGwSp8YAAAFOSURBVHja7NvJasUwDAVQyZJlWZ7+/2+r9JVCl4WXBspViONhcWwTeRNCvp8Lp/Nk0H4Q39ChQ4cOHTp06NChQ4cOHTp06NChQ4cOHTp06NChQ/8RsXd8VfXv9NDrm6mrE+n2nfL1iOzXq/B7dWeuwqSr82IW8nVmC187wt2ruX/OTdW/9+aN+rIyGxN3mYtHI6Johbd4Y5Vlw6lGDaEIumPttZRGYq0OoVGiTWEzGbUxD6ol5mtMCvv79R2lzOgiMiUnItY7t9wIEeMmNti0ExeJITfoenqzY8J11lxlrj1mOblsrlbYmnFYpWGrkN6RcZpXvCIbQU7hQRpZjePZGaG0pfkt+a6q1637Kk6mfb7dmWnZcNXX4PFMSH/urIvt8W9PWujQoUOHDh06dOjQoUOHDh06dOjQoUOHDh06dOjQf6ufJ4Me/Q/6Q4ABALYthstxpakQAAAAAElFTkSuQmCC';
var WithNoDataInterpretation = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAH0AAAB9CAMAAAC4XpwXAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMDY3IDc5LjE1Nzc0NywgMjAxNS8wMy8zMC0yMzo0MDo0MiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6RkZBMTFDN0MyMjYwMTFFNUJEOEJCNkRDM0Q3NUQxQ0UiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6RkZBMTFDN0QyMjYwMTFFNUJEOEJCNkRDM0Q3NUQxQ0UiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpGRkExMUM3QTIyNjAxMUU1QkQ4QkI2REMzRDc1RDFDRSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpGRkExMUM3QjIyNjAxMUU1QkQ4QkI2REMzRDc1RDFDRSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PreJ8vsAAAAwUExURbKystHR0cDAwLW1tb29vcrKysjIyLq6uq6urri4uKGhocTExMbGxqqqqs/Pz8zMzCbSCGIAAAEZSURBVHja7NtNb4MwDIBhx4nz0RTn///bOaOVduyhHZP2WoAhBx4TDBeEJL8ukqwrQ/xC3NHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0f+A7n5uIpm7nWO/pZu5WbLqYadaz++oFuXsevyxuCdb/npRr1/76M20tXU0T+2wNXWtNn1q1FNtVXOdMTjNlr1dT/3WquSuNymifUgeMnT03HIupY8yYk9ynk2iNn+3rjedpQTd4vyiR5uyqbKTHqOOfC9H0zmk9Lt/oOdtx4r7H7c/JtvqHok1aUuRVkz/PvzAzD8a/OyxZ5d9D/5M/nwseNugo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo/93fV0Zcul/0F8CDAAxmYsEaQKefgAAAABJRU5ErkJggg==';
var WithPixelType = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAH0AAAB9CAMAAAC4XpwXAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMDY3IDc5LjE1Nzc0NywgMjAxNS8wMy8zMC0yMzo0MDo0MiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6RkZBMTFDNzgyMjYwMTFFNUJEOEJCNkRDM0Q3NUQxQ0UiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6RkZBMTFDNzkyMjYwMTFFNUJEOEJCNkRDM0Q3NUQxQ0UiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpGRkExMUM3NjIyNjAxMUU1QkQ4QkI2REMzRDc1RDFDRSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpGRkExMUM3NzIyNjAxMUU1QkQ4QkI2REMzRDc1RDFDRSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pj6n55wAAAAwUExURcnJydHR0aWlpbW1tcXFxcHBwdXV1by8vNra2pqamqysrM3NzbGxsbm5uc/Pz8zMzJTUK3UAAAFXSURBVHja7NtJasAwDAVQjVY83/+2VUq3bcnCTRdfxBAT8EO27CxCiNd7wbTfDFov4gs6dOjQoUOHDh06dOjQoUOHDh06dOjQoUOHDh069H+p9x+7h/T7syX3tFa2wrt/satz9k7rRkTZuGhwj2CiT541XJ3P6p3byHCz3uIyqR5WuK9Smo7qhZnL2o8m4UnuRUVamNU5hWjIoHA3GmXEHtvNrRk/moRHeojIHrPFrI2r9Oaj0qihYY1aU63Tq3A/orPXVjNRNR1qwkW21kuapy7XqFszZNIZfZGoXC2Gq6SedTBVQoXGTP1+lLmL8qn9bmRsd9nncvvu5pSX3nvBymg5DfvcumfVLybuWeecWzyXgu+bsvMM4KVelPhczf8yUg7V/+Sk/eb07fs1HW9Y6NChQ4cOHTp06NChQ4cOHTp06NChQ4cOHTp06N/p+82gV/+D/hBgAPzNhkZ0jwchAAAAAElFTkSuQmCC';
var WithRenderingRule = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAH0AAAB9CAMAAAC4XpwXAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMDY3IDc5LjE1Nzc0NywgMjAxNS8wMy8zMC0yMzo0MDo0MiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6RkZBMTFDNzQyMjYwMTFFNUJEOEJCNkRDM0Q3NUQxQ0UiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6RkZBMTFDNzUyMjYwMTFFNUJEOEJCNkRDM0Q3NUQxQ0UiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpGM0Y4Mjk3RjIyNjAxMUU1QkQ4QkI2REMzRDc1RDFDRSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpGM0Y4Mjk4MDIyNjAxMUU1QkQ4QkI2REMzRDc1RDFDRSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PlNwcmIAAAAwUExURb29va2trcrKyrm5uc7OzqKiopubm9DQ0LW1tbKystPT08TExMDAwMLCws/Pz8zMzJixIfsAAAFASURBVHja7NvBjoQwCAZgCrS0gPX933ZxNpPsnvYyxj38JDZI1a821YuRbD8XRueTQftBfEOHDh06dOjQoUOHDh06dOjQoUOHDh06dOjQoUOHDv1XaJ2g71z5Z09trHqLzmqmtvVkVrdvtdJXx2uvqtUw36JbSiSxxfRo5H66WSx3dc5qt3MTd1/5HtpHdafelsSSFsdYZyqlt6WpSclyBkVvfOik4P15XbmNmTSltWMEjWiNekqnlkSDKh81gMzZl9+gWxuSQnNNGWXQmtVIF4mZnajGIjmSVhe7Yc1rEEdFHjXLh3Amr5rzCD5YWOrOM1YdIXmHzuZbr0/2tn2bX49AFXxXUd1p1Zq/CvuWVffXhVwZb1ro0KFDhw4dOnTo0KFDhw4dOnTo0KFDhw4dOnTo0P+Vfj4Z9Oh/0F8CDADZmofLM3dxUgAAAABJRU5ErkJggg==';
var WithTime = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAH0AAAB9CAMAAAC4XpwXAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMDY3IDc5LjE1Nzc0NywgMjAxNS8wMy8zMC0yMzo0MDo0MiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6RjNGODI5N0QyMjYwMTFFNUJEOEJCNkRDM0Q3NUQxQ0UiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6RjNGODI5N0UyMjYwMTFFNUJEOEJCNkRDM0Q3NUQxQ0UiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpGM0Y4Mjk3QjIyNjAxMUU1QkQ4QkI2REMzRDc1RDFDRSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpGM0Y4Mjk3QzIyNjAxMUU1QkQ4QkI2REMzRDc1RDFDRSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pk/Tz9QAAAAwUExURbS0tMrKypKSkqOjo6urq87OztnZ2dTU1JmZmb29vZ2dncLCwtHR0bi4uM/Pz8zMzLWz9KMAAAGMSURBVHja7NtB0pggDAVgQgiEEML9b9to2wt0ht8uHjKoq4+HElcWj++al/NlK/EhHtChQ4cOHTp06NChQ4cOHTp06NChQ4cOHTp06ND/d11+WBdJUv6qLnQk8vgZnRKORx+R7uE53hlRjJzHbV2Il7BMprJ8+KlljKlWCxWS+7onVFfRqNMbhe7utCv7rGtEhDyPwuPWyg9uCTXu5KvOodvDh85OJHmQUxx/Tpf01nYtXAavXdswy/RHS18sZGattr6qkV/SNzdr+bLVeXKxdbOlvvuskmuhXLTbzqW5o/syLpzhdLqmTsXe7FNl6eC9zI2NXa7oIqqk5qJTdOUEyp/sjy5cZuptTrmkD9WuKdYpdXl99ZrZa6waVqYO25PHpVo38qFy68dmZHZbJaXMnsGXvdnHqjpv6c9+zop3iE5uqxzea3lun57DuLfjDkU8PSv87y7vNYlnJTohknBcqzb4vkOHDh06dOjQoUOHDh06dOjQoUOHDh06dOjQoUP/N/182cqn/0H/EmAAhleDsZtu/OkAAAAASUVORK5CYII=';
var url = 'http://services.arcgis.com/mock/arcgis/rest/services/MockImageService/ImageServer';

@@ -42,9 +53,11 @@ var layer;

server.respondWith('GET',new RegExp(/http:\/\/services.arcgis.com\/mock\/arcgis\/rest\/services\/MockImageService\/ImageServer\/exportImage\?bbox=-?\d+\.\d+%2C-?\d+\.\d+%2C-?\d+\.\d+%2C-?\d+\.\d+&size=500%2C500&format=jpgpng&transparent=true&bboxSR=3857&imageSR=3857&f=json/), JSON.stringify({
href: 'http://placehold.it/500&text=Image1'
href: Image1
}));
map = createMap();
map.createPane('custom');
layer = L.esri.imageMapLayer({
pane: 'custom',
url: url,
f: 'json'
});
map = createMap();
});

@@ -96,3 +109,3 @@

layer.once('load', function(){
expect(layer._currentImage._url).to.equal('http://placehold.it/500&text=Image2');
expect(layer._currentImage._url).to.equal(Image2);
done();

@@ -103,3 +116,3 @@ });

server.respondWith('GET',new RegExp(/http:\/\/services.arcgis.com\/mock\/arcgis\/rest\/services\/MockImageService\/ImageServer\/exportImage\?bbox=-?\d+\.\d+%2C-?\d+\.\d+%2C-?\d+\.\d+%2C-?\d+\.\d+&size=500%2C500&format=jpgpng&transparent=true&bboxSR=3857&imageSR=3857&f=json/), JSON.stringify({
href: 'http://placehold.it/500&text=Image2'
href: Image2
}));

@@ -114,3 +127,3 @@ server.respond();

expect(layer._currentImage).to.be.an.instanceof(L.ImageOverlay);
expect(layer._currentImage._url).to.equal('http://placehold.it/500&text=Image1');
expect(layer._currentImage._url).to.equal(Image1);
expect(layer._currentImage._bounds).to.deep.equal(map.getBounds());

@@ -133,7 +146,16 @@ done();

it('should pass the pane option through to the image', function(done) {
layer.on('load', function(){
expect(layer._currentImage.options.pane).to.equal('custom');
done();
});
layer.addTo(map);
server.respond();
});
it('should expose the identify method on the underlying service', function(){
var spy = sinon.spy(layer._service, 'identify');
var spy = sinon.spy(layer.service, 'identify');
var identify = layer.identify();
expect(identify).to.be.an.instanceof(L.esri.Tasks.IdentifyImage);
expect(identify._service).to.equal(layer._service);
expect(identify._service).to.equal(layer.service);
});

@@ -233,3 +255,3 @@

it('should propagate events from the service', function(){
it('should propagate events from the service', function(done){
server.respondWith('GET', 'http://services.arcgis.com/mock/arcgis/rest/services/MockImageService/ImageServer&f=json', JSON.stringify({

@@ -245,3 +267,5 @@ currentVersion: 10.2

layer.metadata(function(){});
layer.metadata(function(){
done();
});

@@ -293,7 +317,7 @@ server.respond();

server.respondWith('GET', new RegExp(/http:\/\/services.arcgis.com\/mock\/arcgis\/rest\/services\/MockImageService\/ImageServer\/exportImage\?bbox=-?\d+\.\d+%2C-?\d+\.\d+%2C-?\d+\.\d+%2C-?\d+\.\d+&size=500%2C500&format=jpgpng&transparent=true&bboxSR=3857&imageSR=3857&renderingRule=%7B%22rasterFunction%22%3A%22RFTAspectColor%22%7D&f=json/), JSON.stringify({
href: 'http://placehold.it/500&text=WithRenderingRule'
href: WithRenderingRule
}));
layer.once('load', function(){
expect(layer._currentImage._url).to.equal('http://placehold.it/500&text=WithRenderingRule');
expect(layer._currentImage._url).to.equal(WithRenderingRule);
done();

@@ -310,7 +334,7 @@ });

server.respondWith('GET', new RegExp(/http:\/\/services.arcgis.com\/mock\/arcgis\/rest\/services\/MockImageService\/ImageServer\/exportImage\?bbox=-?\d+\.\d+%2C-?\d+\.\d+%2C-?\d+\.\d+%2C-?\d+\.\d+&size=500%2C500&format=jpgpng&transparent=true&bboxSR=3857&imageSR=3857&mosaicRule=%7B%22mosaicMethod%22%3A%22esriMosaicLockRaster%22%2C%22lockRasterIds%22%3A%5B8%5D%7D&f=json/), JSON.stringify({
href: 'http://placehold.it/500&text=WithMosaicRule'
href: WithMosaicRule
}));
layer.once('load', function(){
expect(layer._currentImage._url).to.equal('http://placehold.it/500&text=WithMosaicRule');
expect(layer._currentImage._url).to.equal(WithMosaicRule);
done();

@@ -327,7 +351,7 @@ });

server.respondWith('GET', new RegExp(/http:\/\/services.arcgis.com\/mock\/arcgis\/rest\/services\/MockImageService\/ImageServer\/exportImage\?bbox=-?\d+\.\d+%2C-?\d+\.\d+%2C-?\d+\.\d+%2C-?\d+\.\d+&size=500%2C500&format=jpgpng&transparent=true&bboxSR=3857&imageSR=3857&time=1389254400000%2C1389513600000&f=json/), JSON.stringify({
href: 'http://placehold.it/500&text=WithTime'
href: WithTime
}));
layer.once('load', function(){
expect(layer._currentImage._url).to.equal('http://placehold.it/500&text=WithTime');
expect(layer._currentImage._url).to.equal(WithTime);
done();

@@ -344,7 +368,7 @@ });

server.respondWith('GET', new RegExp(/http:\/\/services.arcgis.com\/mock\/arcgis\/rest\/services\/MockImageService\/ImageServer\/exportImage\?bbox=-?\d+\.\d+%2C-?\d+\.\d+%2C-?\d+\.\d+%2C-?\d+\.\d+&size=500%2C500&format=jpgpng&transparent=true&bboxSR=3857&imageSR=3857&bandIds=3%2C0%2C1&f=json/), JSON.stringify({
href: 'http://placehold.it/500&text=WithBandIds'
href: WithBandIds
}));
layer.once('load', function(){
expect(layer._currentImage._url).to.equal('http://placehold.it/500&text=WithBandIds');
expect(layer._currentImage._url).to.equal(WithBandIds);
done();

@@ -361,7 +385,7 @@ });

server.respondWith('GET', new RegExp(/http:\/\/services.arcgis.com\/mock\/arcgis\/rest\/services\/MockImageService\/ImageServer\/exportImage\?bbox=-?\d+\.\d+%2C-?\d+\.\d+%2C-?\d+\.\d+%2C-?\d+\.\d+&size=500%2C500&format=jpgpng&transparent=true&bboxSR=3857&imageSR=3857&bandIds=3%2C0%2C1&f=json/), JSON.stringify({
href: 'http://placehold.it/500&text=WithBandIds'
href: WithBandIds
}));
layer.once('load', function(){
expect(layer._currentImage._url).to.equal('http://placehold.it/500&text=WithBandIds');
expect(layer._currentImage._url).to.equal(WithBandIds);
done();

@@ -378,7 +402,7 @@ });

server.respondWith('GET', new RegExp(/http:\/\/services.arcgis.com\/mock\/arcgis\/rest\/services\/MockImageService\/ImageServer\/exportImage\?bbox=-?\d+\.\d+%2C-?\d+\.\d+%2C-?\d+\.\d+%2C-?\d+\.\d+&size=500%2C500&format=jpgpng&transparent=true&bboxSR=3857&imageSR=3857&noData=0&f=json/), JSON.stringify({
href: 'http://placehold.it/500&text=WithNoData'
href: WithNoData
}));
layer.once('load', function(){
expect(layer._currentImage._url).to.equal('http://placehold.it/500&text=WithNoData');
expect(layer._currentImage._url).to.equal(WithNoData);
done();

@@ -395,7 +419,7 @@ });

server.respondWith('GET', new RegExp(/http:\/\/services.arcgis.com\/mock\/arcgis\/rest\/services\/MockImageService\/ImageServer\/exportImage\?bbox=-?\d+\.\d+%2C-?\d+\.\d+%2C-?\d+\.\d+%2C-?\d+\.\d+&size=500%2C500&format=jpgpng&transparent=true&bboxSR=3857&imageSR=3857&noData=58%2C128%2C187&f=json/), JSON.stringify({
href: 'http://placehold.it/500&text=WithNoDataArray'
href: WithNoDataArray
}));
layer.once('load', function(){
expect(layer._currentImage._url).to.equal('http://placehold.it/500&text=WithNoDataArray');
expect(layer._currentImage._url).to.equal(WithNoDataArray);
done();

@@ -412,7 +436,7 @@ });

server.respondWith('GET', new RegExp(/http:\/\/services.arcgis.com\/mock\/arcgis\/rest\/services\/MockImageService\/ImageServer\/exportImage\?bbox=-?\d+\.\d+%2C-?\d+\.\d+%2C-?\d+\.\d+%2C-?\d+\.\d+&size=500%2C500&format=jpgpng&transparent=true&bboxSR=3857&imageSR=3857&noData=0&noDataInterpretation=esriNoDataMatchAll&f=json/), JSON.stringify({
href: 'http://placehold.it/500&text=WithNoDataInterpretation'
href: WithNoDataInterpretation
}));
layer.once('load', function(){
expect(layer._currentImage._url).to.equal('http://placehold.it/500&text=WithNoDataInterpretation');
expect(layer._currentImage._url).to.equal(WithNoDataInterpretation);
done();

@@ -429,7 +453,7 @@ });

server.respondWith('GET', new RegExp(/http:\/\/services.arcgis.com\/mock\/arcgis\/rest\/services\/MockImageService\/ImageServer\/exportImage\?bbox=-?\d+\.\d+%2C-?\d+\.\d+%2C-?\d+\.\d+%2C-?\d+\.\d+&size=500%2C500&format=jpgpng&transparent=true&bboxSR=3857&imageSR=3857&pixelType=U8&f=json/), JSON.stringify({
href: 'http://placehold.it/500&text=WithPixelType'
href: WithNoDataInterpretation
}));
layer.once('load', function(){
expect(layer._currentImage._url).to.equal('http://placehold.it/500&text=WithPixelType');
expect(layer._currentImage._url).to.equal(WithNoDataInterpretation);
done();

@@ -436,0 +460,0 @@ });

@@ -30,3 +30,3 @@ describe('L.esri.Layers.TiledMapLayer', function () {

it('should expose the authenticate method on the underlying service', function(){
var spy = sinon.spy(layer._service, 'authenticate');
var spy = sinon.spy(layer.service, 'authenticate');
layer.authenticate('foo');

@@ -37,6 +37,6 @@ expect(spy).to.have.been.calledWith('foo');

it('should expose the query method on the underlying service', function(){
var spy = sinon.spy(layer._service, 'identify');
var spy = sinon.spy(layer.service, 'identify');
var identify = layer.identify();
expect(identify).to.be.an.instanceof(L.esri.Tasks.IdentifyFeatures);
expect(identify._service).to.equal(layer._service);
expect(identify._service).to.equal(layer.service);
});

@@ -43,0 +43,0 @@

@@ -1,2 +0,2 @@

describe('L.esri.Request', function () {
describe('L.esri request helpers', function () {
var xhr;

@@ -36,3 +36,3 @@ var requests = [];

it('should be able to make a GET request with CORS', function(done){
L.esri.Request.get.CORS('http://services.arcgisonline.com/ArcGIS/rest/info', {}, function(error, response){
L.esri.get.CORS('http://services.arcgisonline.com/ArcGIS/rest/info', {}, function(error, response){
expect(this.foo).to.equal('bar');

@@ -51,3 +51,3 @@ expect(response).to.deep.equal(sampleResponse);

it('should be able to make a GET request with JSONP', function(done){
var request = L.esri.Request.get.JSONP('http://example.com/foo', {}, function(error, response){
var request = L.esri.get.JSONP('http://example.com/foo', {}, function(error, response){
expect(this.foo).to.equal('bar');

@@ -64,3 +64,3 @@ expect(response).to.deep.equal(sampleResponse);

it('should callback with an error on non-JSON reponses', function(done){
var request = L.esri.Request.get.JSONP('http://example.com/foo', {}, function(error){
var request = L.esri.get.JSONP('http://example.com/foo', {}, function(error){
expect(error).to.deep.equal({

@@ -79,3 +79,3 @@ error: {

it('should callback with an error when an error is recived from the server', function(done){
var request = L.esri.Request.get.JSONP('http://example.com/foo', {}, function(error){
var request = L.esri.get.JSONP('http://example.com/foo', {}, function(error){
expect(error).to.deep.equal(sampleError);

@@ -89,3 +89,3 @@ done();

it('should be able to make a POST request with CORS', function(done){
L.esri.Request.post.XMLHTTP('http://services.arcgisonline.com/ArcGIS/rest/info', {}, function(error, response){
L.esri.post('http://services.arcgisonline.com/ArcGIS/rest/info', {}, function(error, response){
expect(response).to.deep.equal(sampleResponse);

@@ -100,3 +100,3 @@ done();

it('should serialize arrays of objects as JSON', function(done){
L.esri.Request.get.CORS('http://services.arcgisonline.com/ArcGIS/rest/info', {
L.esri.get.CORS('http://services.arcgisonline.com/ArcGIS/rest/info', {
object: [{foo:'bar'}]

@@ -114,3 +114,3 @@ }, function(error, response){

it('should serialize arrays of non objects as comma seperated strings', function(done){
L.esri.Request.get.CORS('http://services.arcgisonline.com/ArcGIS/rest/info', {
L.esri.get.CORS('http://services.arcgisonline.com/ArcGIS/rest/info', {
array: ['foo', 'bar']

@@ -128,3 +128,3 @@ }, function(error, response){

it('should serialize Objects as JSON', function(done){
L.esri.Request.get.CORS('http://services.arcgisonline.com/ArcGIS/rest/info', {
L.esri.get.CORS('http://services.arcgisonline.com/ArcGIS/rest/info', {
object: {

@@ -147,3 +147,3 @@ foo:'bar'

L.esri.Request.get.CORS('http://services.arcgisonline.com/ArcGIS/rest/info', {
L.esri.get.CORS('http://services.arcgisonline.com/ArcGIS/rest/info', {
time: now

@@ -161,3 +161,3 @@ }, function(error, response){

it('should throw errors when response is not a JSON object', function(done){
L.esri.Request.get.CORS('http://services.arcgisonline.com/ArcGIS/rest/info', {}, function(error){
L.esri.get.CORS('http://services.arcgisonline.com/ArcGIS/rest/info', {}, function(error){
expect(error).to.deep.equal({

@@ -176,3 +176,3 @@ message: 'Could not parse response as JSON. This could also be caused by a CORS or XMLHttpRequest error.',

it('should callback with an error when an XMLHttpRequest error is encountered', function(done){
var request = L.esri.Request.post.XMLHTTP('http://services.arcgisonline.com/ArcGIS/rest/info', {}, function(error, response){
var request = L.esri.post('http://services.arcgisonline.com/ArcGIS/rest/info', {}, function(error, response){
expect(error).to.deep.equal({

@@ -197,2 +197,2 @@ error: {

});
});
});

@@ -109,3 +109,2 @@ describe('L.esri.Tasks.IdentifyFeatures', function () {

// server.respondWith('GET', url + 'identify?sr=4326&layers=all&tolerance=3&returnGeometry=true&imageDisplay=500%2C500%2C96&mapExtent=-122.66535758972167%2C45.50624163368495%2C-122.65462875366211%2C45.51376023843158&geometry=-122.66%2C45.51&geometryType=esriGeometryPoint&layerDefs=0%3ANAME%3DOregon%3B1%3ANAME%3DMultnomah&f=json', JSON.stringify(sampleResponse));

@@ -124,3 +123,2 @@ var request = task.layerDef(0, 'NAME=Oregon').layerDef(1, 'NAME=Multnomah').run(function(error, featureCollection, raw){

it('should identify features in a given time range', function(done){
// server.respondWith('GET', url + 'identify?sr=4326&layers=all&tolerance=3&returnGeometry=true&imageDisplay=500%2C500%2C96&mapExtent=-122.66535758972167%2C45.50624163368495%2C-122.65462875366211%2C45.51376023843158&geometry=-122.66%2C45.51&geometryType=esriGeometryPoint&time=1357027200000%2C1388563200000&f=json', JSON.stringify(sampleResponse));

@@ -142,3 +140,2 @@ var start = new Date('January 1 2013 GMT-0800');

it('should restrict identification to specific layers', function(done){
// server.respondWith('GET', url + 'identify?sr=4326&layers=top&tolerance=3&returnGeometry=true&imageDisplay=500%2C500%2C96&mapExtent=-122.66535758972167%2C45.50624163368495%2C-122.65462875366211%2C45.51376023843158&geometry=-122.66%2C45.51&geometryType=esriGeometryPoint&f=json', JSON.stringify(sampleResponse));

@@ -155,3 +152,2 @@ var request = task.layers('top').run(function(error, featureCollection, raw){

it('should identify features and limit geometries to a given precision', function(done){
// server.respondWith('GET', url + 'identify?sr=4326&layers=all&tolerance=3&returnGeometry=true&imageDisplay=500%2C500%2C96&mapExtent=-122.66535758972167%2C45.50624163368495%2C-122.65462875366211%2C45.51376023843158&geometry=-122.66%2C45.51&geometryType=esriGeometryPoint&geometryPrecision=4&f=json', JSON.stringify(sampleResponse));

@@ -170,3 +166,2 @@ var request = task.precision(4).run(function(error, featureCollection, raw){

it('should identify features and simplify geometries', function(done){
// server.respondWith('GET', url + 'identify?sr=4326&layers=all&tolerance=3&returnGeometry=true&imageDisplay=500%2C500%2C96&mapExtent=-122.66535758972167%2C45.50624163368495%2C-122.65462875366211%2C45.51376023843158&geometry=-122.66%2C45.51&geometryType=esriGeometryPoint&maxAllowableOffset=0.000010728836059556101&f=json', JSON.stringify(sampleResponse));

@@ -179,3 +174,3 @@ var request = task.simplify(map, 0.5).run(function(error, featureCollection, raw){

expect(request.url).to.contain('maxAllowableOffset=0.000010728836059556101');
expect(request.url).to.contain('maxAllowableOffset=0.000010728836059570313');

@@ -186,3 +181,2 @@ request.respond(200, { 'Content-Type': 'text/plain; charset=utf-8' }, JSON.stringify(sampleResponse));

it('should identify features with a token', function(done){
// server.respondWith('GET', url + 'identify?sr=4326&layers=all&tolerance=3&returnGeometry=true&imageDisplay=500%2C500%2C96&mapExtent=-122.66535758972167%2C45.50624163368495%2C-122.65462875366211%2C45.51376023843158&geometry=-122.66%2C45.51&geometryType=esriGeometryPoint&token=foo&f=json', JSON.stringify(sampleResponse));

@@ -201,3 +195,2 @@ var request = task.token('foo').run(function(error, featureCollection, raw){

it('should identify features within a certain pixel tolerance', function(done){
// server.respondWith('GET', url + 'identify?sr=4326&layers=all&tolerance=4&returnGeometry=true&imageDisplay=500%2C500%2C96&mapExtent=-122.66535758972167%2C45.50624163368495%2C-122.65462875366211%2C45.51376023843158&geometry=-122.66%2C45.51&geometryType=esriGeometryPoint&f=json', JSON.stringify(sampleResponse));

@@ -218,3 +211,2 @@ var request = task.tolerance(4).run(function(error, featureCollection, raw){

// server.respondWith('GET', url + 'identify?sr=4326&layers=all&tolerance=3&returnGeometry=true&imageDisplay=500%2C500%2C96&mapExtent=-122.66535758972167%2C45.50624163368495%2C-122.65462875366211%2C45.51376023843158&geometry=-122.66%2C45.51&geometryType=esriGeometryPoint&f=json', JSON.stringify(sampleResponse));

@@ -243,3 +235,2 @@ var request = service.identify().on(map).at(latlng).run(function(error, featureCollection, raw){

// server.respondWith('GET', url + 'identify?sr=4326&layers=all&tolerance=3&returnGeometry=true&imageDisplay=500%2C500%2C96&mapExtent=-122.66535758972167%2C45.50624163368495%2C-122.65462875366211%2C45.51376023843158&geometry=-122.66%2C45.51&geometryType=esriGeometryPoint&f=json', JSON.stringify(sampleResponse));

@@ -246,0 +237,0 @@ var request = service.identify().on(map).at(rawLatlng).run(function(error, featureCollection, raw){

@@ -520,3 +520,3 @@ describe('L.esri.Tasks.Query', function () {

it('should identify features and simplify geometries', function(done){
server.respondWith('GET', featureLayerUrl + 'query?returnGeometry=true&where=1%3D1&outSr=4326&outFields=*&maxAllowableOffset=0.000010728836059556101&f=json', JSON.stringify(sampleQueryResponse));
server.respondWith('GET', featureLayerUrl + 'query?returnGeometry=true&where=1%3D1&outSr=4326&outFields=*&maxAllowableOffset=0.000010728836059570313&f=json', JSON.stringify(sampleQueryResponse));

@@ -523,0 +523,0 @@ task.simplify(map, 0.5).run(function(error, featureCollection, raw){

@@ -1,2 +0,4 @@

EsriLeaflet.Controls.Logo = L.Control.extend({
import L from 'leaflet';
export var Logo = L.Control.extend({
options: {

@@ -18,3 +20,3 @@ position: 'bottomright',

this._map.on('resize', function(e){
this._map.on('resize', function (e) {
div.innerHTML = this._adjustLogo(e.newSize);

@@ -27,14 +29,12 @@ }, this);

_adjustLogo: function (mapSize) {
if (mapSize.x <= 600 || mapSize.y <= 600){
if (mapSize.x <= 600 || mapSize.y <= 600) {
return '<a href="https://developers.arcgis.com" style="border: none;"><img src="https://js.arcgis.com/3.13/esri/images/map/logo-sm.png" alt="Powered by Esri" style="border: none;"></a>';
}
else {
} else {
return '<a href="https://developers.arcgis.com" style="border: none;"><img src="https://js.arcgis.com/3.13/esri/images/map/logo-med.png" alt="Powered by Esri" style="border: none;"></a>';
}
}
});
EsriLeaflet.Controls.logo = function(options){
return new L.esri.Controls.Logo(options);
};
export default function logo (options) {
return new Logo(options);
}

@@ -1,16 +0,125 @@

var EsriLeaflet = { //jshint ignore:line
VERSION: '1.0.0',
Layers: {},
Services: {},
Controls: {},
Tasks: {},
Util: {},
Support: {
CORS: !!(window.XMLHttpRequest && 'withCredentials' in new XMLHttpRequest()),
pointerEvents: document.documentElement.style.pointerEvents === ''
}
// import leaflet to ensure a gloabl
import L from 'leaflet';
// import base
import { Support } from './Support.js';
import { Util } from './Util.js';
import { get, post, request } from './Request.js';
// import tasks
import { Task, task } from './Tasks/Task.js';
import { Query, query } from './Tasks/Query.js';
import { Find, find } from './Tasks/Find.js';
import { Identify, identify } from './Tasks/Identify.js';
import { IdentifyFeatures, identifyFeatures } from './Tasks/IdentifyFeatures.js';
import { IdentifyImage, identifyImage } from './Tasks/IdentifyImage.js';
// export services
import { Service, service } from './Services/Service.js';
import { MapService, mapService } from './Services/MapService.js';
import { ImageService, imageService } from './Services/ImageService.js';
import { FeatureLayerService, featureLayerService } from './Services/FeatureLayerService.js';
// export layers
import { BasemapLayer, basemapLayer } from './Layers/BasemapLayer.js';
import { TiledMapLayer, tiledMapLayer } from './Layers/TiledMapLayer.js';
import { RasterLayer } from './Layers/RasterLayer.js';
import { ImageMapLayer, imageMapLayer } from './Layers/ImageMapLayer.js';
import { DynamicMapLayer, dynamicMapLayer } from './Layers/DynamicMapLayer.js';
import { FeatureGrid } from './Layers/FeatureLayer/FeatureGrid.js';
import { FeatureManager } from './Layers/FeatureLayer/FeatureManager.js';
import { FeatureLayer, featureLayer } from './Layers/FeatureLayer/FeatureLayer.js';
export var VERSION = '2.0.0-beta.1';
export { Support };
export { Util };
export { get };
export { post };
export { request };
export var Tasks = {
Task: Task,
task: task,
Query: Query,
query: query,
Find: Find,
find: find,
Identify: Identify,
identify: identify,
IdentifyFeatures: IdentifyFeatures,
identifyFeatures: identifyFeatures,
IdentifyImage: IdentifyImage,
identifyImage: identifyImage
};
if(typeof window !== 'undefined' && window.L){
window.L.esri = EsriLeaflet;
export var Services = {
Service: Service,
service: service,
MapService: MapService,
mapService: mapService,
ImageService: ImageService,
imageService: imageService,
FeatureLayerService: FeatureLayerService,
featureLayerService: featureLayerService
};
export var Layers = {
BasemapLayer: BasemapLayer,
basemapLayer: basemapLayer,
TiledMapLayer: TiledMapLayer,
tiledMapLayer: tiledMapLayer,
RasterLayer: RasterLayer,
ImageMapLayer: ImageMapLayer,
imageMapLayer: imageMapLayer,
DynamicMapLayer: DynamicMapLayer,
dynamicMapLayer: dynamicMapLayer,
FeatureGrid: FeatureGrid,
FeatureManager: FeatureManager,
FeatureLayer: FeatureLayer,
featureLayer: featureLayer
};
export { BasemapLayer };
export { basemapLayer };
export { TiledMapLayer };
export { tiledMapLayer };
export { RasterLayer };
export { ImageMapLayer };
export { imageMapLayer };
export { DynamicMapLayer };
export { dynamicMapLayer };
export { FeatureGrid };
export { FeatureManager };
export { FeatureLayer };
export { featureLayer };
var _isAmd = (typeof define === 'undefined') ? false : define.amd && typeof define === 'function';
var _isCjs = (typeof exports === 'object') && (typeof module !== 'undefined');
var _isSystem = window && window.System;
if ((_isAmd || _isCjs || _isSystem) && window && window.L) {
window.L.esri = {
VERSION: VERSION,
Support: Support,
Util: Util,
get: get,
post: post,
request: request,
Tasks: Tasks,
Services: Services,
Layers: Layers,
BasemapLayer: BasemapLayer,
basemapLayer: basemapLayer,
TiledMapLayer: TiledMapLayer,
tiledMapLayer: tiledMapLayer,
RasterLayer: RasterLayer,
ImageMapLayer: ImageMapLayer,
imageMapLayer: imageMapLayer,
DynamicMapLayer: DynamicMapLayer,
dynamicMapLayer: dynamicMapLayer,
FeatureGrid: FeatureGrid,
FeatureManager: FeatureManager,
FeatureLayer: FeatureLayer,
featureLayer: featureLayer
};
}

@@ -1,312 +0,313 @@

(function(EsriLeaflet){
import L from 'leaflet';
import logo from '../Controls/Logo.js';
import { jsonp } from '../Request.js';
import { pointerEvents } from '../Support.js';
var tileProtocol = (window.location.protocol !== 'https:') ? 'http:' : 'https:';
var tileProtocol = (window.location.protocol !== 'https:') ? 'http:' : 'https:';
EsriLeaflet.Layers.BasemapLayer = L.TileLayer.extend({
statics: {
TILES: {
Streets: {
urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}',
attributionUrl: 'https://static.arcgis.com/attribution/World_Street_Map',
options: {
hideLogo: false,
logoPosition: 'bottomright',
minZoom: 1,
maxZoom: 19,
subdomains: ['server', 'services'],
attribution: 'Esri'
}
},
Topographic: {
urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}',
attributionUrl: 'https://static.arcgis.com/attribution/World_Topo_Map',
options: {
hideLogo: false,
logoPosition: 'bottomright',
minZoom: 1,
maxZoom: 19,
subdomains: ['server', 'services'],
attribution: 'Esri'
}
},
Oceans: {
urlTemplate: tileProtocol + '//{s}.arcgisonline.com/arcgis/rest/services/Ocean/World_Ocean_Base/MapServer/tile/{z}/{y}/{x}',
attributionUrl: 'https://static.arcgis.com/attribution/Ocean_Basemap',
options: {
hideLogo: false,
logoPosition: 'bottomright',
minZoom: 1,
maxZoom: 16,
subdomains: ['server', 'services'],
attribution: 'Esri'
}
},
OceansLabels: {
urlTemplate: tileProtocol + '//{s}.arcgisonline.com/arcgis/rest/services/Ocean/World_Ocean_Reference/MapServer/tile/{z}/{y}/{x}',
options: {
hideLogo: true,
logoPosition: 'bottomright',
//pane: 'esri-label',
minZoom: 1,
maxZoom: 16,
subdomains: ['server', 'services']
}
},
NationalGeographic: {
urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer/tile/{z}/{y}/{x}',
options: {
hideLogo: false,
logoPosition: 'bottomright',
minZoom: 1,
maxZoom: 16,
subdomains: ['server', 'services'],
attribution: 'Esri'
}
},
DarkGray: {
urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Dark_Gray_Base/MapServer/tile/{z}/{y}/{x}',
options: {
hideLogo: false,
logoPosition: 'bottomright',
minZoom: 1,
maxZoom: 16,
subdomains: ['server', 'services'],
attribution: 'Esri, DeLorme, HERE'
}
},
DarkGrayLabels: {
urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Dark_Gray_Reference/MapServer/tile/{z}/{y}/{x}',
options: {
hideLogo: true,
logoPosition: 'bottomright',
//pane: 'esri-label',
minZoom: 1,
maxZoom: 16,
subdomains: ['server', 'services']
}
},
Gray: {
urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer/tile/{z}/{y}/{x}',
options: {
hideLogo: false,
logoPosition: 'bottomright',
minZoom: 1,
maxZoom: 16,
subdomains: ['server', 'services'],
attribution: 'Esri, NAVTEQ, DeLorme'
}
},
GrayLabels: {
urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Reference/MapServer/tile/{z}/{y}/{x}',
options: {
hideLogo: true,
logoPosition: 'bottomright',
//pane: 'esri-label',
minZoom: 1,
maxZoom: 16,
subdomains: ['server', 'services']
}
},
Imagery: {
urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',
options: {
hideLogo: false,
logoPosition: 'bottomright',
minZoom: 1,
maxZoom: 19,
subdomains: ['server', 'services'],
attribution: 'Esri, DigitalGlobe, GeoEye, i-cubed, USDA, USGS, AEX, Getmapping, Aerogrid, IGN, IGP, swisstopo, and the GIS User Community'
}
},
ImageryLabels: {
urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/Reference/World_Boundaries_and_Places/MapServer/tile/{z}/{y}/{x}',
options: {
hideLogo: true,
logoPosition: 'bottomright',
//pane: 'esri-label',
minZoom: 1,
maxZoom: 19,
subdomains: ['server', 'services']
}
},
ImageryTransportation: {
urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/Reference/World_Transportation/MapServer/tile/{z}/{y}/{x}',
//pane: 'esri-label',
options: {
hideLogo: true,
logoPosition: 'bottomright',
minZoom: 1,
maxZoom: 19,
subdomains: ['server', 'services']
}
},
ShadedRelief: {
urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer/tile/{z}/{y}/{x}',
options: {
hideLogo: false,
logoPosition: 'bottomright',
minZoom: 1,
maxZoom: 13,
subdomains: ['server', 'services'],
attribution: 'Esri, NAVTEQ, DeLorme'
}
},
ShadedReliefLabels: {
urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/Reference/World_Boundaries_and_Places_Alternate/MapServer/tile/{z}/{y}/{x}',
options: {
hideLogo: true,
logoPosition: 'bottomright',
//pane: 'esri-label',
minZoom: 1,
maxZoom: 12,
subdomains: ['server', 'services']
}
},
Terrain: {
urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/World_Terrain_Base/MapServer/tile/{z}/{y}/{x}',
options: {
hideLogo: false,
logoPosition: 'bottomright',
minZoom: 1,
maxZoom: 13,
subdomains: ['server', 'services'],
attribution: 'Esri, USGS, NOAA'
}
},
TerrainLabels: {
urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/Reference/World_Reference_Overlay/MapServer/tile/{z}/{y}/{x}',
options: {
hideLogo: true,
logoPosition: 'bottomright',
//pane: 'esri-label',
minZoom: 1,
maxZoom: 13,
subdomains: ['server', 'services']
}
export var BasemapLayer = L.TileLayer.extend({
statics: {
TILES: {
Streets: {
urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}',
attributionUrl: 'https://static.arcgis.com/attribution/World_Street_Map',
options: {
hideLogo: false,
logoPosition: 'bottomright',
minZoom: 1,
maxZoom: 19,
subdomains: ['server', 'services'],
attribution: 'Esri'
}
},
Topographic: {
urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}',
attributionUrl: 'https://static.arcgis.com/attribution/World_Topo_Map',
options: {
hideLogo: false,
logoPosition: 'bottomright',
minZoom: 1,
maxZoom: 19,
subdomains: ['server', 'services'],
attribution: 'Esri'
}
},
Oceans: {
urlTemplate: tileProtocol + '//{s}.arcgisonline.com/arcgis/rest/services/Ocean/World_Ocean_Base/MapServer/tile/{z}/{y}/{x}',
attributionUrl: 'https://static.arcgis.com/attribution/Ocean_Basemap',
options: {
hideLogo: false,
logoPosition: 'bottomright',
minZoom: 1,
maxZoom: 16,
subdomains: ['server', 'services'],
attribution: 'Esri'
}
},
OceansLabels: {
urlTemplate: tileProtocol + '//{s}.arcgisonline.com/arcgis/rest/services/Ocean/World_Ocean_Reference/MapServer/tile/{z}/{y}/{x}',
options: {
hideLogo: true,
logoPosition: 'bottomright',
minZoom: 1,
maxZoom: 16,
subdomains: ['server', 'services'],
pane: (pointerEvents) ? 'esri-labels' : 'tilePane'
}
},
NationalGeographic: {
urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer/tile/{z}/{y}/{x}',
options: {
hideLogo: false,
logoPosition: 'bottomright',
minZoom: 1,
maxZoom: 16,
subdomains: ['server', 'services'],
attribution: 'Esri'
}
},
DarkGray: {
urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Dark_Gray_Base/MapServer/tile/{z}/{y}/{x}',
options: {
hideLogo: false,
logoPosition: 'bottomright',
minZoom: 1,
maxZoom: 16,
subdomains: ['server', 'services'],
attribution: 'Esri, DeLorme, HERE'
}
},
DarkGrayLabels: {
urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Dark_Gray_Reference/MapServer/tile/{z}/{y}/{x}',
options: {
hideLogo: true,
logoPosition: 'bottomright',
minZoom: 1,
maxZoom: 16,
subdomains: ['server', 'services'],
pane: (pointerEvents) ? 'esri-labels' : 'tilePane'
}
},
Gray: {
urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer/tile/{z}/{y}/{x}',
options: {
hideLogo: false,
logoPosition: 'bottomright',
minZoom: 1,
maxZoom: 16,
subdomains: ['server', 'services'],
attribution: 'Esri, NAVTEQ, DeLorme'
}
},
GrayLabels: {
urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Reference/MapServer/tile/{z}/{y}/{x}',
options: {
hideLogo: true,
logoPosition: 'bottomright',
minZoom: 1,
maxZoom: 16,
subdomains: ['server', 'services'],
pane: (pointerEvents) ? 'esri-labels' : 'tilePane'
}
},
Imagery: {
urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',
options: {
hideLogo: false,
logoPosition: 'bottomright',
minZoom: 1,
maxZoom: 19,
subdomains: ['server', 'services'],
attribution: 'Esri, DigitalGlobe, GeoEye, i-cubed, USDA, USGS, AEX, Getmapping, Aerogrid, IGN, IGP, swisstopo, and the GIS User Community'
}
},
ImageryLabels: {
urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/Reference/World_Boundaries_and_Places/MapServer/tile/{z}/{y}/{x}',
options: {
hideLogo: true,
logoPosition: 'bottomright',
minZoom: 1,
maxZoom: 19,
subdomains: ['server', 'services'],
pane: (pointerEvents) ? 'esri-labels' : 'tilePane'
}
},
ImageryTransportation: {
urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/Reference/World_Transportation/MapServer/tile/{z}/{y}/{x}',
options: {
hideLogo: true,
logoPosition: 'bottomright',
minZoom: 1,
maxZoom: 19,
subdomains: ['server', 'services'],
pane: (pointerEvents) ? 'esri-labels' : 'tilePane'
}
},
ShadedRelief: {
urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer/tile/{z}/{y}/{x}',
options: {
hideLogo: false,
logoPosition: 'bottomright',
minZoom: 1,
maxZoom: 13,
subdomains: ['server', 'services'],
attribution: 'Esri, NAVTEQ, DeLorme'
}
},
ShadedReliefLabels: {
urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/Reference/World_Boundaries_and_Places_Alternate/MapServer/tile/{z}/{y}/{x}',
options: {
hideLogo: true,
logoPosition: 'bottomright',
minZoom: 1,
maxZoom: 12,
subdomains: ['server', 'services'],
pane: (pointerEvents) ? 'esri-labels' : 'tilePane'
}
},
Terrain: {
urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/World_Terrain_Base/MapServer/tile/{z}/{y}/{x}',
options: {
hideLogo: false,
logoPosition: 'bottomright',
minZoom: 1,
maxZoom: 13,
subdomains: ['server', 'services'],
attribution: 'Esri, USGS, NOAA'
}
},
TerrainLabels: {
urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/Reference/World_Reference_Overlay/MapServer/tile/{z}/{y}/{x}',
options: {
hideLogo: true,
logoPosition: 'bottomright',
minZoom: 1,
maxZoom: 13,
subdomains: ['server', 'services'],
pane: (pointerEvents) ? 'esri-labels' : 'tilePane'
}
}
},
initialize: function(key, options){
var config;
}
},
initialize: function (key, options) {
var config;
// set the config variable with the appropriate config object
if (typeof key === 'object' && key.urlTemplate && key.options){
config = key;
} else if(typeof key === 'string' && EsriLeaflet.BasemapLayer.TILES[key]){
config = EsriLeaflet.BasemapLayer.TILES[key];
} else {
throw new Error('L.esri.BasemapLayer: Invalid parameter. Use one of "Streets", "Topographic", "Oceans", "OceansLabels", "NationalGeographic", "Gray", "GrayLabels", "DarkGray", "DarkGrayLabels", "Imagery", "ImageryLabels", "ImageryTransportation", "ShadedRelief", "ShadedReliefLabels", "Terrain" or "TerrainLabels"');
}
// set the config variable with the appropriate config object
if (typeof key === 'object' && key.urlTemplate && key.options) {
config = key;
} else if (typeof key === 'string' && BasemapLayer.TILES[key]) {
config = BasemapLayer.TILES[key];
} else {
throw new Error('L.esri.BasemapLayer: Invalid parameter. Use one of "Streets", "Topographic", "Oceans", "OceansLabels", "NationalGeographic", "Gray", "GrayLabels", "DarkGray", "DarkGrayLabels", "Imagery", "ImageryLabels", "ImageryTransportation", "ShadedRelief", "ShadedReliefLabels", "Terrain" or "TerrainLabels"');
}
// merge passed options into the config options
var tileOptions = L.Util.extend(config.options, options);
// merge passed options into the config options
var tileOptions = L.Util.extend(config.options, options);
// call the initialize method on L.TileLayer to set everything up
L.TileLayer.prototype.initialize.call(this, config.urlTemplate, L.Util.setOptions(this, tileOptions));
// call the initialize method on L.TileLayer to set everything up
L.TileLayer.prototype.initialize.call(this, config.urlTemplate, L.Util.setOptions(this, tileOptions));
// if this basemap requires dynamic attribution set it up
if(config.attributionUrl){
this._getAttributionData(config.attributionUrl);
}
this._logo = new EsriLeaflet.Controls.Logo({
position: this.options.logoPosition
});
},
onAdd: function(map){
if(!this.options.hideLogo && !map._hasEsriLogo){
this._logo.addTo(map);
map._hasEsriLogo = true;
}
// if this basemap requires dynamic attribution set it up
if (config.attributionUrl) {
this._getAttributionData(config.attributionUrl);
}
// if(this.options.pane && EsriLeaflet.Support.pointerEvents){
// this._initPane();
// }
this._logo = logo({
position: this.options.logoPosition
});
},
onAdd: function (map) {
if (!this.options.hideLogo && !map._hasEsriLogo) {
this._logo.addTo(map);
map._hasEsriLogo = true;
}
L.TileLayer.prototype.onAdd.call(this, map);
if (this.options.pane === 'esri-labels') {
this._initPane();
}
map.on('moveend', this._updateMapAttribution, this);
},
onRemove: function(map){
// check to make sure the logo hasn't already been removed
if(this._logo && this._logo._container){
map.removeControl(this._logo);
map._hasEsriLogo = false;
}
L.TileLayer.prototype.onAdd.call(this, map);
L.TileLayer.prototype.onRemove.call(this, map);
map.on('moveend', this._updateMapAttribution, this);
},
onRemove: function (map) {
// check to make sure the logo hasn't already been removed
if (this._logo && this._logo._container) {
map.removeControl(this._logo);
map._hasEsriLogo = false;
}
map.off('moveend', this._updateMapAttribution, this);
},
getAttribution:function(){
var attribution = '<span class="esri-attributions" style="line-height:14px; vertical-align: -3px; text-overflow:ellipsis; white-space:nowrap; overflow:hidden; display:inline-block;">' + this.options.attribution + '</span>'/* + logo*/;
return attribution;
},
// _initPane: function(){
// if(!this._map.getPane(this.options.pane)){
// var pane = this._map.createPane(this.options.pane);
// pane.style.pointerEvents = 'none';
// pane.style.zIndex = 5;
// }
// },
_getAttributionData: function(url){
L.esri.Request.get.JSONP(url, {}, L.Util.bind(function(error, attributions){
this._attributions = [];
L.TileLayer.prototype.onRemove.call(this, map);
for (var c = 0; c < attributions.contributors.length; c++) {
var contributor = attributions.contributors[c];
for (var i = 0; i < contributor.coverageAreas.length; i++) {
var coverageArea = contributor.coverageAreas[i];
var southWest = new L.LatLng(coverageArea.bbox[0], coverageArea.bbox[1]);
var northEast = new L.LatLng(coverageArea.bbox[2], coverageArea.bbox[3]);
this._attributions.push({
attribution: contributor.attribution,
score: coverageArea.score,
bounds: new L.LatLngBounds(southWest, northEast),
minZoom: coverageArea.zoomMin,
maxZoom: coverageArea.zoomMax
});
}
map.off('moveend', this._updateMapAttribution, this);
},
getAttribution: function () {
var attribution = '<span class="esri-attributions" style="line-height:14px; vertical-align: -3px; text-overflow:ellipsis; white-space:nowrap; overflow:hidden; display:inline-block;">' + this.options.attribution + '</span>';
return attribution;
},
_initPane: function () {
if (!this._map.getPane(this.options.pane)) {
var pane = this._map.createPane(this.options.pane);
pane.style.pointerEvents = 'none';
pane.style.zIndex = 500;
}
},
_getAttributionData: function (url) {
jsonp(url, {}, L.Util.bind(function (error, attributions) {
if (error) { return; }
this._attributions = [];
for (var c = 0; c < attributions.contributors.length; c++) {
var contributor = attributions.contributors[c];
for (var i = 0; i < contributor.coverageAreas.length; i++) {
var coverageArea = contributor.coverageAreas[i];
var southWest = new L.LatLng(coverageArea.bbox[0], coverageArea.bbox[1]);
var northEast = new L.LatLng(coverageArea.bbox[2], coverageArea.bbox[3]);
this._attributions.push({
attribution: contributor.attribution,
score: coverageArea.score,
bounds: new L.LatLngBounds(southWest, northEast),
minZoom: coverageArea.zoomMin,
maxZoom: coverageArea.zoomMax
});
}
}
this._attributions.sort(function(a, b){
return b.score - a.score;
});
this._attributions.sort(function (a, b) {
return b.score - a.score;
});
this._updateMapAttribution();
}, this));
},
_updateMapAttribution: function(){
if(this._map && this._map.attributionControl && this._attributions){
var newAttributions = '';
var bounds = this._map.getBounds();
var zoom = this._map.getZoom();
this._updateMapAttribution();
}, this));
},
_updateMapAttribution: function () {
if (this._map && this._map.attributionControl && this._attributions) {
var newAttributions = '';
var bounds = this._map.getBounds();
var zoom = this._map.getZoom();
for (var i = 0; i < this._attributions.length; i++) {
var attribution = this._attributions[i];
var text = attribution.attribution;
if(!newAttributions.match(text) && bounds.intersects(attribution.bounds) && zoom >= attribution.minZoom && zoom <= attribution.maxZoom) {
newAttributions += (', ' + text);
}
for (var i = 0; i < this._attributions.length; i++) {
var attribution = this._attributions[i];
var text = attribution.attribution;
if (!newAttributions.match(text) && bounds.intersects(attribution.bounds) && zoom >= attribution.minZoom && zoom <= attribution.maxZoom) {
newAttributions += (', ' + text);
}
newAttributions = newAttributions.substr(2);
var attributionElement = this._map.attributionControl._container.querySelector('.esri-attributions');
attributionElement.innerHTML = newAttributions;
attributionElement.style.maxWidth = (this._map.getSize().x * 0.65) + 'px';
this.fire('attributionupdated', {
attribution: newAttributions
});
}
}
});
newAttributions = newAttributions.substr(2);
var attributionElement = this._map.attributionControl._container.querySelector('.esri-attributions');
EsriLeaflet.BasemapLayer = EsriLeaflet.Layers.BasemapLayer;
attributionElement.innerHTML = newAttributions;
attributionElement.style.maxWidth = (this._map.getSize().x * 0.65) + 'px';
EsriLeaflet.Layers.basemapLayer = function(key, options){
return new EsriLeaflet.Layers.BasemapLayer(key, options);
};
this.fire('attributionupdated', {
attribution: newAttributions
});
}
}
});
EsriLeaflet.basemapLayer = function(key, options){
return new EsriLeaflet.Layers.BasemapLayer(key, options);
};
export function basemapLayer (key, options) {
return new BasemapLayer(key, options);
}
})(EsriLeaflet);
export default basemapLayer;

@@ -1,3 +0,8 @@

EsriLeaflet.Layers.DynamicMapLayer = EsriLeaflet.Layers.RasterLayer.extend({
import L from 'leaflet';
import { RasterLayer } from './RasterLayer.js';
import { cleanUrl } from '../Util.js';
import mapService from '../Services/MapService.js';
export var DynamicMapLayer = RasterLayer.extend({
options: {

@@ -14,6 +19,7 @@ updateInterval: 150,

initialize: function (options) {
options.url = EsriLeaflet.Util.cleanUrl(options.url);
this._service = new EsriLeaflet.Services.MapService(options);
this._service.on('authenticationrequired requeststart requestend requesterror requestsuccess', this._propagateEvent, this);
if ((options.proxy || options.token) && options.f !== 'json'){
options.url = cleanUrl(options.url);
this.service = mapService(options);
this.service.addEventParent(this);
if ((options.proxy || options.token) && options.f !== 'json') {
options.f = 'json';

@@ -24,7 +30,7 @@ }

getDynamicLayers: function(){
getDynamicLayers: function () {
return this.options.dynamicLayers;
},
setDynamicLayers: function(dynamicLayers){
setDynamicLayers: function (dynamicLayers) {
this.options.dynamicLayers = dynamicLayers;

@@ -35,7 +41,7 @@ this._update();

getLayers: function(){
getLayers: function () {
return this.options.layers;
},
setLayers: function(layers){
setLayers: function (layers) {
this.options.layers = layers;

@@ -46,7 +52,7 @@ this._update();

getLayerDefs: function(){
getLayerDefs: function () {
return this.options.layerDefs;
},
setLayerDefs: function(layerDefs){
setLayerDefs: function (layerDefs) {
this.options.layerDefs = layerDefs;

@@ -57,7 +63,7 @@ this._update();

getTimeOptions: function(){
getTimeOptions: function () {
return this.options.timeOptions;
},
setTimeOptions: function(timeOptions){
setTimeOptions: function (timeOptions) {
this.options.timeOptions = timeOptions;

@@ -68,18 +74,18 @@ this._update();

query: function(){
return this._service.query();
query: function () {
return this.service.query();
},
identify: function(){
return this._service.identify();
identify: function () {
return this.service.identify();
},
find: function(){
return this._service.find();
find: function () {
return this.service.find();
},
_getPopupData: function(e){
var callback = L.Util.bind(function(error, featureCollection, response) {
if(error) { return; } // we really can't do anything here but authenticate or requesterror will fire
setTimeout(L.Util.bind(function(){
_getPopupData: function (e) {
var callback = L.Util.bind(function (error, featureCollection, response) {
if (error) { return; } // we really can't do anything here but authenticate or requesterror will fire
setTimeout(L.Util.bind(function () {
this._renderPopup(e.latlng, error, featureCollection, response);

@@ -91,3 +97,3 @@ }, this), 300);

if(this.options.layers){
if (this.options.layers) {
identifyRequest.layers('visible:' + this.options.layers.join(','));

@@ -111,7 +117,7 @@ } else {

//ensure that we don't ask ArcGIS Server for a taller image than we have actual map displaying
// ensure that we don't ask ArcGIS Server for a taller image than we have actual map displaying
var top = this._map.latLngToLayerPoint(bounds._northEast);
var bottom = this._map.latLngToLayerPoint(bounds._southWest);
if (top.y > 0 || bottom.y < size.y){
if (top.y > 0 || bottom.y < size.y) {
size.y = bottom.y - top.y;

@@ -130,24 +136,24 @@ }

if(this.options.dynamicLayers){
if (this.options.dynamicLayers) {
params.dynamicLayers = this.options.dynamicLayers;
}
if(this.options.layers){
if (this.options.layers) {
params.layers = 'show:' + this.options.layers.join(',');
}
if(this.options.layerDefs){
if (this.options.layerDefs) {
params.layerDefs = JSON.stringify(this.options.layerDefs);
}
if(this.options.timeOptions){
if (this.options.timeOptions) {
params.timeOptions = JSON.stringify(this.options.timeOptions);
}
if(this.options.from && this.options.to){
if (this.options.from && this.options.to) {
params.time = this.options.from.valueOf() + ',' + this.options.to.valueOf();
}
if(this._service.options.token) {
params.token = this._service.options.token;
if (this.service.options.token) {
params.token = this.service.options.token;
}

@@ -159,5 +165,5 @@

_requestExport: function (params, bounds) {
if(this.options.f === 'json'){
this._service.request('export', params, function(error, response){
if(error) { return; } // we really can't do anything here but authenticate or requesterror will fire
if (this.options.f === 'json') {
this.service.get('export', params, function (error, response) {
if (error) { return; } // we really can't do anything here but authenticate or requesterror will fire
this._renderImage(response.href, bounds);

@@ -172,10 +178,6 @@ }, this);

EsriLeaflet.DynamicMapLayer = EsriLeaflet.Layers.DynamicMapLayer;
export function dynamicMapLayer (url, options) {
return new DynamicMapLayer(url, options);
}
EsriLeaflet.Layers.dynamicMapLayer = function(options){
return new EsriLeaflet.Layers.DynamicMapLayer(options);
};
EsriLeaflet.dynamicMapLayer = function(options){
return new EsriLeaflet.Layers.DynamicMapLayer(options);
};
export default dynamicMapLayer;

@@ -1,4 +0,4 @@

EsriLeaflet.Layers.FeatureGrid = L.Class.extend({
import L from 'leaflet';
includes: L.Mixin.Events,
export var FeatureGrid = L.Layer.extend({

@@ -16,7 +16,3 @@ options: {

this._map = map;
this._update = L.Util.limitExecByInterval(this._update, this.options.updateInterval, this);
// @TODO remove for leaflet 0.8
this._map.addEventListener(this.getEvents(), this);
this._update = L.Util.throttle(this._update, this.options.updateInterval, this);
this._reset();

@@ -26,3 +22,3 @@ this._update();

onRemove: function(){
onRemove: function () {
this._map.removeEventListener(this.getEvents(), this);

@@ -34,5 +30,4 @@ this._removeCells();

var events = {
viewreset: this._reset,
moveend: this._update,
zoomend : this._onZoom
zoomend: this._reset
};

@@ -43,3 +38,3 @@

addTo: function(map){
addTo: function (map) {
map.addLayer(this);

@@ -49,3 +44,3 @@ return this;

removeFrom: function(map){
removeFrom: function (map) {
map.removeLayer(this);

@@ -55,16 +50,2 @@ return this;

_onZoom : function () {
var zoom = this._map.getZoom();
if (zoom > this.options.maxZoom ||
zoom < this.options.minZoom) {
this.removeFrom(this._map);
this._map.addEventListener('zoomend', this.getEvents().zoomend, this);
} else if (!this._map.hasLayer(this)) {
this._map.removeEventListener('zoomend', this.getEvents().zoomend, this);
this.addTo(this._map);
}
},
_reset: function () {

@@ -77,6 +58,4 @@ this._removeCells();

this._cellsTotal = 0;
this._cellNumBounds = this._getCellNumBounds();
// @TODO enable at Leaflet 0.8
// this._cellNumBounds = this._getCellNumBounds();
this._resetWrap();

@@ -86,4 +65,4 @@ },

_resetWrap: function () {
var map = this._map,
crs = map.options.crs;
var map = this._map;
var crs = map.options.crs;

@@ -116,7 +95,5 @@ if (crs.infinite) { return; }

var bounds = this._map.getPixelBounds(),
zoom = this._map.getZoom(),
cellSize = this._getCellSize(),
cellPadding = [cellSize/2,cellSize/2];
// cellPadding = [0,0]
var bounds = this._map.getPixelBounds();
var zoom = this._map.getZoom();
var cellSize = this._getCellSize();

@@ -127,9 +104,6 @@ if (zoom > this.options.maxZoom ||

// cell coordinates range for the current view
var topLeft = bounds.min.subtract(cellPadding).divideBy(cellSize).floor();
topLeft.x = Math.max(topLeft.x, 0);
topLeft.y = Math.max(topLeft.y, 0);
var cellBounds = L.bounds(
bounds.min.divideBy(cellSize).floor(),
bounds.max.divideBy(cellSize).floor());
var cellBounds = L.bounds(topLeft, bounds.max.add(cellPadding).divideBy(cellSize).floor());
// remove any present cells that are off the specified bounds
this._removeOtherCells(cellBounds);

@@ -140,5 +114,5 @@ this._addCells(cellBounds);

_addCells: function (bounds) {
var queue = [],
center = bounds.getCenter(),
zoom = this._map.getZoom();
var queue = [];
var center = bounds.getCenter();
var zoom = this._map.getZoom();

@@ -152,10 +126,8 @@ var j, i, coords;

// @TODO enable at Leaflet 0.8
// if (this._isValidCell(coords)) {
// queue.push(coords);
// }
queue.push(coords);
if (this._isValidCell(coords)) {
queue.push(coords);
}
}
}
var cellsToLoad = queue.length;

@@ -178,41 +150,34 @@

// @TODO enable at Leaflet 0.8
// _isValidCell: function (coords) {
// var crs = this._map.options.crs;
_isValidCell: function (coords) {
var crs = this._map.options.crs;
// if (!crs.infinite) {
// // don't load cell if it's out of bounds and not wrapped
// var bounds = this._cellNumBounds;
// if (
// (!crs.wrapLng && (coords.x < bounds.min.x || coords.x > bounds.max.x)) ||
// (!crs.wrapLat && (coords.y < bounds.min.y || coords.y > bounds.max.y))
// ) {
// return false;
// }
// }
if (!crs.infinite) {
// don't load cell if it's out of bounds and not wrapped
var bounds = this._cellNumBounds;
if (
(!crs.wrapLng && (coords.x < bounds.min.x || coords.x > bounds.max.x)) ||
(!crs.wrapLat && (coords.y < bounds.min.y || coords.y > bounds.max.y))
) {
return false;
}
}
// if (!this.options.bounds) {
// return true;
// }
if (!this.options.bounds) {
return true;
}
// // don't load cell if it doesn't intersect the bounds in options
// var cellBounds = this._cellCoordsToBounds(coords);
// return L.latLngBounds(this.options.bounds).intersects(cellBounds);
// },
// don't load cell if it doesn't intersect the bounds in options
var cellBounds = this._cellCoordsToBounds(coords);
return L.latLngBounds(this.options.bounds).intersects(cellBounds);
},
// converts cell coordinates to its geographical bounds
_cellCoordsToBounds: function (coords) {
var map = this._map,
cellSize = this.options.cellSize,
var map = this._map;
var cellSize = this.options.cellSize;
var nwPoint = coords.multiplyBy(cellSize);
var sePoint = nwPoint.add([cellSize, cellSize]);
var nw = map.wrapLatLng(map.unproject(nwPoint, coords.z));
var se = map.wrapLatLng(map.unproject(sePoint, coords.z));
nwPoint = coords.multiplyBy(cellSize),
sePoint = nwPoint.add([cellSize, cellSize]),
// @TODO for Leaflet 0.8
// nw = map.wrapLatLng(map.unproject(nwPoint, coords.z)),
// se = map.wrapLatLng(map.unproject(sePoint, coords.z));
nw = map.unproject(nwPoint, coords.z).wrap(),
se = map.unproject(sePoint, coords.z).wrap();
return new L.LatLngBounds(nw, se);

@@ -228,5 +193,5 @@ },

_keyToCellCoords: function (key) {
var kArr = key.split(':'),
x = parseInt(kArr[0], 10),
y = parseInt(kArr[1], 10);
var kArr = key.split(':');
var x = parseInt(kArr[0], 10);
var y = parseInt(kArr[1], 10);

@@ -247,3 +212,4 @@ return new L.Point(x, y);

var cell = this._activeCells[key];
if(cell){
if (cell) {
delete this._activeCells[key];

@@ -262,3 +228,3 @@

_removeCells: function(){
_removeCells: function () {
for (var key in this._cells) {

@@ -280,3 +246,2 @@ var bounds = this._cells[key].bounds;

_addCell: function (coords) {
// wrap cell coords if necessary (depending on CRS)

@@ -315,3 +280,3 @@ this._wrapCoords(coords);

if(this.createCell){
if (this.createCell) {
this.createCell(cell.bounds, coords);

@@ -330,16 +295,13 @@ }

coords.y = this._wrapLat ? L.Util.wrapNum(coords.y, this._wrapLat) : coords.y;
}
},
// get the global cell coordinates range for the current zoom
// @TODO enable at Leaflet 0.8
// _getCellNumBounds: function () {
// // @TODO for Leaflet 0.8
// // var bounds = this._map.getPixelWorldBounds(),
// // size = this._getCellSize();
// //
// // return bounds ? L.bounds(
// // bounds.min.divideBy(size).floor(),
// // bounds.max.divideBy(size).ceil().subtract([1, 1])) : null;
// }
_getCellNumBounds: function () {
var bounds = this._map.getPixelWorldBounds();
var size = this._getCellSize();
});
return bounds ? L.bounds(
bounds.min.divideBy(size).floor(),
bounds.max.divideBy(size).ceil().subtract([1, 1])) : null;
}
});

@@ -1,6 +0,5 @@

EsriLeaflet.Layers.FeatureLayer = EsriLeaflet.Layers.FeatureManager.extend({
import L from 'leaflet';
import { FeatureManager } from './FeatureManager.js';
statics: {
EVENTS: 'click dblclick mouseover mouseout mousemove contextmenu popupopen popupclose'
},
export var FeatureLayer = FeatureManager.extend({

@@ -14,11 +13,6 @@ options: {

*/
initialize: function (options) {
EsriLeaflet.Layers.FeatureManager.prototype.initialize.call(this, options);
options = L.setOptions(this, options);
FeatureManager.prototype.initialize.call(this, options);
this._originalStyle = this.options.style;
this._layers = {};
this._leafletIds = {};
this._key = 'c'+(Math.random() * 1e9).toString(36).replace('.', '_');
},

@@ -30,10 +24,10 @@

onAdd: function(map){
map.on('zoomstart zoomend', function(e){
onAdd: function (map) {
map.on('zoomstart zoomend', function (e) {
this._zooming = (e.type === 'zoomstart');
}, this);
return EsriLeaflet.Layers.FeatureManager.prototype.onAdd.call(this, map);
return FeatureManager.prototype.onAdd.call(this, map);
},
onRemove: function(map){
onRemove: function (map) {
for (var i in this._layers) {

@@ -43,12 +37,12 @@ map.removeLayer(this._layers[i]);

return EsriLeaflet.Layers.FeatureManager.prototype.onRemove.call(this, map);
return FeatureManager.prototype.onRemove.call(this, map);
},
createNewLayer: function(geojson){
// @TODO Leaflet 0.8
//newLayer = L.GeoJSON.geometryToLayer(geojson, this.options);
return L.GeoJSON.geometryToLayer(geojson, this.options.pointToLayer, L.GeoJSON.coordsToLatLng, this.options);
createNewLayer: function (geojson) {
var layer = L.GeoJSON.geometryToLayer(geojson, this.options);
layer.defaultOptions = layer.options;
return layer;
},
_updateLayer: function(layer, geojson){
_updateLayer: function (layer, geojson) {
// convert the geojson coordinates into a Leaflet LatLng array/nested arrays

@@ -64,3 +58,3 @@ // pass it to setLatLngs to update layer geometries

switch(geojson.geometry.type){
switch (geojson.geometry.type) {
case 'Point':

@@ -93,5 +87,4 @@ latlngs = L.GeoJSON.coordsToLatLng(geojson.geometry.coordinates);

createLayers: function(features){
createLayers: function (features) {
for (var i = features.length - 1; i >= 0; i--) {
var geojson = features[i];

@@ -102,3 +95,3 @@

if(layer && !this._map.hasLayer(layer)){
if (layer && !this._map.hasLayer(layer)) {
this._map.addLayer(layer);

@@ -112,32 +105,10 @@ }

if(!layer){
newLayer = this.createNewLayer(geojson);
if (!layer) {
newLayer = this.createNewLayer(geojson);
newLayer.feature = geojson;
if (this.options.style) {
newLayer._originalStyle = this.options.style;
}
// bubble events from individual layers to the feature layer
newLayer.addEventParent(this);
// circleMarker check
else if (newLayer.setStyle) {
newLayer._originalStyle = newLayer.options;
}
newLayer._leaflet_id = this._key + '_' + geojson.id;
this._leafletIds[newLayer._leaflet_id] = geojson.id;
// bubble events from layers to this
// @TODO Leaflet 0.8
// newLayer.addEventParent(this);
newLayer.on(EsriLeaflet.Layers.FeatureLayer.EVENTS, this._propagateEvent, this);
// bind a popup if we have one
if(this._popup && newLayer.bindPopup){
newLayer.bindPopup(this._popup(newLayer.feature, newLayer), this._popupOptions);
}
if(this.options.onEachFeature){
if (this.options.onEachFeature) {
this.options.onEachFeature(newLayer.feature, newLayer);

@@ -150,10 +121,10 @@ }

// style the layer
this.resetStyle(newLayer.feature.id);
this.setFeatureStyle(newLayer.feature.id, this.options.style);
this.fire('createfeature', {
feature: newLayer.feature
});
}, true);
// add the layer if it is within the time bounds or our layer is not time enabled
if(!this.options.timeField || (this.options.timeField && this._featureWithinTimeRange(geojson)) ){
if (!this.options.timeField || (this.options.timeField && this._featureWithinTimeRange(geojson))) {
this._map.addLayer(newLayer);

@@ -165,9 +136,9 @@ }

addLayers: function(ids){
addLayers: function (ids) {
for (var i = ids.length - 1; i >= 0; i--) {
var layer = this._layers[ids[i]];
if(layer){
if (layer) {
this.fire('addfeature', {
feature: layer.feature
});
}, true);
this._map.addLayer(layer);

@@ -178,14 +149,14 @@ }

removeLayers: function(ids, permanent){
removeLayers: function (ids, permanent) {
for (var i = ids.length - 1; i >= 0; i--) {
var id = ids[i];
var layer = this._layers[id];
if(layer){
if (layer) {
this.fire('removefeature', {
feature: layer.feature,
permanent: permanent
});
}, true);
this._map.removeLayer(layer);
}
if(layer && permanent){
if (layer && permanent) {
delete this._layers[id];

@@ -196,9 +167,9 @@ }

cellEnter: function(bounds, coords){
if(!this._zooming){
EsriLeaflet.Util.requestAnimationFrame(L.Util.bind(function(){
cellEnter: function (bounds, coords) {
if (!this._zooming) {
L.Util.requestAnimFrame(L.Util.bind(function () {
var cacheKey = this._cacheKey(coords);
var cellKey = this._cellCoordsToKey(coords);
var layers = this._cache[cacheKey];
if(this._activeCells[cellKey] && layers){
if (this._activeCells[cellKey] && layers) {
this.addLayers(layers);

@@ -210,5 +181,5 @@ }

cellLeave: function(bounds, coords){
if(!this._zooming){
EsriLeaflet.Util.requestAnimationFrame(L.Util.bind(function(){
cellLeave: function (bounds, coords) {
if (!this._zooming) {
L.Util.requestAnimFrame(L.Util.bind(function () {
var cacheKey = this._cacheKey(coords);

@@ -218,3 +189,3 @@ var cellKey = this._cellCoordsToKey(coords);

var mapBounds = this._map.getBounds();
if(!this._activeCells[cellKey] && layers){
if (!this._activeCells[cellKey] && layers) {
var removable = true;

@@ -224,3 +195,3 @@

var layer = this._layers[layers[i]];
if(layer && layer.getBounds && mapBounds.intersects(layer.getBounds())){
if (layer && layer.getBounds && mapBounds.intersects(layer.getBounds())) {
removable = false;

@@ -230,7 +201,7 @@ }

if(removable){
if (removable) {
this.removeLayers(layers, !this.options.cacheLayers);
}
if(!this.options.cacheLayers && removable){
if (!this.options.cacheLayers && removable) {
delete this._cache[cacheKey];

@@ -249,9 +220,7 @@ delete this._cells[cellKey];

resetStyle: function (id) {
var layer = this._layers[id];
if(layer){
this.setFeatureStyle(layer.feature.id, layer._originalStyle);
}
resetStyle: function () {
this.options.style = this._originalStyle;
this.eachFeature(function (layer) {
this.resetFeatureStyle(layer.feature.id);
}, this);
return this;

@@ -268,18 +237,20 @@ },

resetFeatureStyle: function (id) {
var layer = this._layers[id];
var style = this._originalStyle || L.Path.prototype.options;
if (layer) {
L.Util.extend(layer.options, layer.defaultOptions);
this.setFeatureStyle(id, style);
}
return this;
},
setFeatureStyle: function (id, style) {
var layer = this._layers[id];
if (typeof style === 'function') {
style = style(layer.feature);
}
if (!style && !layer.defaultOptions) {
style = L.Path.prototype.options;
style.fill = true; //not set by default
}
if (layer && layer.setStyle) {
if (layer.setStyle) {
layer.setStyle(style);
}
return this;

@@ -289,34 +260,2 @@ },

/**
* Popup Methods
*/
bindPopup: function (fn, options) {
this._popup = fn;
this._popupOptions = options;
for (var i in this._layers) {
var layer = this._layers[i];
var popupContent = this._popup(layer.feature, layer);
layer.bindPopup(popupContent, options);
}
return this;
},
unbindPopup: function () {
this._popup = false;
for (var i in this._layers) {
var layer = this._layers[i];
if (layer.unbindPopup) {
layer.unbindPopup();
} else if (layer.getLayers) {
var groupLayers = layer.getLayers();
for (var j in groupLayers) {
var gLayer = groupLayers[j];
gLayer.unbindPopup();
}
}
}
return this;
},
/**
* Utility Methods

@@ -338,3 +277,3 @@ */

this.eachFeature(function (layer) {
if(layer.bringToBack) {
if (layer.bringToBack) {
layer.bringToBack();

@@ -347,3 +286,3 @@ }

this.eachFeature(function (layer) {
if(layer.bringToFront) {
if (layer.bringToFront) {
layer.bringToFront();

@@ -361,3 +300,3 @@ }

_redraw: function(id) {
_redraw: function (id) {
var layer = this._layers[id];

@@ -369,3 +308,3 @@ var geojson = layer.feature;

// update custom symbology, if necessary
if (this.options.pointToLayer){
if (this.options.pointToLayer) {
var getIcon = this.options.pointToLayer(geojson, L.latLng(geojson.geometry.coordinates[1], geojson.geometry.coordinates[0]));

@@ -385,24 +324,12 @@ var updatedIcon = getIcon.options.icon;

// looks like a path (polygon/polyline)
if(layer && layer.setStyle && this.options.style) {
if (layer && layer.setStyle && this.options.style) {
this.resetStyle(geojson.id);
}
},
// from https://github.com/Leaflet/Leaflet/blob/v0.7.2/src/layer/FeatureGroup.js
// @TODO remove at Leaflet 0.8
_propagateEvent: function (e) {
e.layer = this._layers[this._leafletIds[e.target._leaflet_id]];
e.target = this;
this.fire(e.type, e);
}
});
EsriLeaflet.FeatureLayer = EsriLeaflet.Layers.FeatureLayer;
export function featureLayer (options) {
return new FeatureLayer(options);
}
EsriLeaflet.Layers.featureLayer = function(options){
return new EsriLeaflet.Layers.FeatureLayer(options);
};
EsriLeaflet.featureLayer = function(options){
return new EsriLeaflet.Layers.FeatureLayer(options);
};
export default featureLayer;

@@ -1,543 +0,531 @@

(function(EsriLeaflet){
import L from 'leaflet';
import { FeatureGrid } from './FeatureGrid.js';
import featureLayerService from '../../Services/FeatureLayerService.js';
import { cleanUrl, warn } from '../../Util.js';
EsriLeaflet.Layers.FeatureManager = EsriLeaflet.Layers.FeatureGrid.extend({
export var FeatureManager = FeatureGrid.extend({
/**
* Options
*/
/**
* Options
*/
options: {
attribution: null,
where: '1=1',
fields: ['*'],
from: false,
to: false,
timeField: false,
timeFilterMode: 'server',
simplifyFactor: 0,
precision: 6
},
options: {
where: '1=1',
fields: ['*'],
from: false,
to: false,
timeField: false,
timeFilterMode: 'server',
simplifyFactor: 0,
precision: 6
},
/**
* Constructor
*/
/**
* Constructor
*/
initialize: function (options) {
FeatureGrid.prototype.initialize.call(this, options);
initialize: function (options) {
EsriLeaflet.Layers.FeatureGrid.prototype.initialize.call(this, options);
options.url = cleanUrl(options.url);
options = L.setOptions(this, options);
options.url = EsriLeaflet.Util.cleanUrl(options.url);
options = L.setOptions(this, options);
this.service = featureLayerService(options);
this.service.addEventParent(this);
this._service = new EsriLeaflet.Services.FeatureLayerService(options);
//use case insensitive regex to look for common fieldnames used for indexing
/*global console */
if (this.options.fields[0] !== '*'){
var oidCheck = false;
for (var i = 0; i < this.options.fields.length; i++){
if (this.options.fields[i].match(/^(OBJECTID|FID|OID|ID)$/i)){
oidCheck = true;
}
// use case insensitive regex to look for common fieldnames used for indexing
if (this.options.fields[0] !== '*') {
var oidCheck = false;
for (var i = 0; i < this.options.fields.length; i++) {
if (this.options.fields[i].match(/^(OBJECTID|FID|OID|ID)$/i)) {
oidCheck = true;
}
if (oidCheck === false) {
EsriLeaflet.Util.warn('no known esriFieldTypeOID field detected in fields Array. Please add an attribute field containing unique IDs to ensure the layer can be drawn correctly.');
}
}
if (oidCheck === false) {
warn('no known esriFieldTypeOID field detected in fields Array. Please add an attribute field containing unique IDs to ensure the layer can be drawn correctly.');
}
}
// Leaflet 0.8 change to new propagation
this._service.on('authenticationrequired requeststart requestend requesterror requestsuccess', function (e) {
e = L.extend({
target: this
}, e);
this.fire(e.type, e);
}, this);
if (this.options.timeField.start && this.options.timeField.end) {
this._startTimeIndex = new BinarySearchIndex();
this._endTimeIndex = new BinarySearchIndex();
} else if (this.options.timeField) {
this._timeIndex = new BinarySearchIndex();
}
if(this.options.timeField.start && this.options.timeField.end){
this._startTimeIndex = new BinarySearchIndex();
this._endTimeIndex = new BinarySearchIndex();
} else if(this.options.timeField){
this._timeIndex = new BinarySearchIndex();
}
this._cache = {};
this._currentSnapshot = []; // cache of what layers should be active
this._activeRequests = 0;
},
this._cache = {};
this._currentSnapshot = []; // cache of what layers should be active
this._activeRequests = 0;
this._pendingRequests = [];
},
/**
* Layer Interface
*/
/**
* Layer Interface
*/
onAdd: function (map) {
return FeatureGrid.prototype.onAdd.call(this, map);
},
onAdd: function(map){
return EsriLeaflet.Layers.FeatureGrid.prototype.onAdd.call(this, map);
},
onRemove: function (map) {
return FeatureGrid.prototype.onRemove.call(this, map);
},
onRemove: function(map){
return EsriLeaflet.Layers.FeatureGrid.prototype.onRemove.call(this, map);
},
getAttribution: function () {
return this.options.attribution;
},
getAttribution: function () {
return this.options.attribution;
},
/**
* Feature Managment
*/
/**
* Feature Managment
*/
createCell: function (bounds, coords) {
this._requestFeatures(bounds, coords);
},
createCell: function(bounds, coords){
this._requestFeatures(bounds, coords);
},
_requestFeatures: function (bounds, coords, callback) {
this._activeRequests++;
_requestFeatures: function(bounds, coords, callback){
this._activeRequests++;
// our first active request fires loading
if (this._activeRequests === 1) {
this.fire('loading', {
bounds: bounds
}, true);
}
// our first active request fires loading
if(this._activeRequests === 1){
this.fire('loading', {
bounds: bounds
});
return this._buildQuery(bounds).run(function (error, featureCollection, response) {
if (response && response.exceededTransferLimit) {
this.fire('drawlimitexceeded');
}
this._buildQuery(bounds).run(function(error, featureCollection, response){
if(response && response.exceededTransferLimit){
this.fire('drawlimitexceeded');
}
// no error, features
if(!error && featureCollection && featureCollection.features.length){
// schedule adding features until the next animation frame
EsriLeaflet.Util.requestAnimationFrame(L.Util.bind(function(){
this._addFeatures(featureCollection.features, coords);
this._postProcessFeatures(bounds);
}, this));
}
// no error, no features
if (!error && featureCollection && !featureCollection.features.length) {
// no error, features
if (!error && featureCollection && featureCollection.features.length) {
// schedule adding features until the next animation frame
L.Util.requestAnimFrame(L.Util.bind(function () {
this._addFeatures(featureCollection.features, coords);
this._postProcessFeatures(bounds);
}
}, this));
}
if(callback){
callback.call(this, error, featureCollection);
}
}, this);
},
// no error, no features
if (!error && featureCollection && !featureCollection.features.length) {
this._postProcessFeatures(bounds);
}
_postProcessFeatures: function (bounds) {
//deincriment the request counter now that we have processed features
this._activeRequests--;
// if there are no more active requests fire a load event for this view
if(this._activeRequests <= 0){
this.fire('load', {
bounds: bounds
});
if (callback) {
callback.call(this, error, featureCollection);
}
},
}, this);
},
_cacheKey: function (coords){
return coords.z + ':' + coords.x + ':' +coords.y;
},
_postProcessFeatures: function (bounds) {
// deincriment the request counter now that we have processed features
this._activeRequests--;
_addFeatures: function(features, coords){
var key = this._cacheKey(coords);
this._cache[key] = this._cache[key] || [];
// if there are no more active requests fire a load event for this view
if (this._activeRequests <= 0) {
this.fire('load', {
bounds: bounds
});
}
},
for (var i = features.length - 1; i >= 0; i--) {
var id = features[i].id;
this._currentSnapshot.push(id);
this._cache[key].push(id);
/*
should we refactor the code in FeatureManager.setWhere()
so that we can reuse it to make sure that we remove features
on the client that are removed from the service?
*/
_cacheKey: function (coords) {
return coords.z + ':' + coords.x + ':' + coords.y;
},
}
_addFeatures: function (features, coords) {
var key = this._cacheKey(coords);
this._cache[key] = this._cache[key] || [];
if(this.options.timeField){
this._buildTimeIndexes(features);
}
for (var i = features.length - 1; i >= 0; i--) {
var id = features[i].id;
this._currentSnapshot.push(id);
this._cache[key].push(id);
}
var zoom = this._map.getZoom();
if (this.options.timeField) {
this._buildTimeIndexes(features);
}
if (zoom > this.options.maxZoom ||
zoom < this.options.minZoom) { return; }
var zoom = this._map.getZoom();
this.createLayers(features);
},
if (zoom > this.options.maxZoom ||
zoom < this.options.minZoom) { return; }
_buildQuery: function(bounds){
var query = this._service.query()
.intersects(bounds)
.where(this.options.where)
.fields(this.options.fields)
.precision(this.options.precision);
this.createLayers(features);
},
if(this.options.simplifyFactor){
query.simplify(this._map, this.options.simplifyFactor);
}
_buildQuery: function (bounds) {
var query = this.service.query()
.intersects(bounds)
.where(this.options.where)
.fields(this.options.fields)
.precision(this.options.precision);
if(this.options.timeFilterMode === 'server' && this.options.from && this.options.to){
query.between(this.options.from, this.options.to);
}
if (this.options.simplifyFactor) {
query.simplify(this._map, this.options.simplifyFactor);
}
return query;
},
if (this.options.timeFilterMode === 'server' && this.options.from && this.options.to) {
query.between(this.options.from, this.options.to);
}
/**
* Where Methods
*/
return query;
},
setWhere: function(where, callback, context){
/**
* Where Methods
*/
this.options.where = (where && where.length) ? where : '1=1';
setWhere: function (where, callback, context) {
this.options.where = (where && where.length) ? where : '1=1';
var oldSnapshot = [];
var newSnapshot = [];
var pendingRequests = 0;
var mostRecentError = null;
var requestCallback = L.Util.bind(function(error, featureCollection){
pendingRequests--;
var oldSnapshot = [];
var newSnapshot = [];
var pendingRequests = 0;
var requestError = null;
var requestCallback = L.Util.bind(function (error, featureCollection) {
if (error) {
requestError = error;
}
if(error) {
mostRecentError = error;
if (featureCollection) {
for (var i = featureCollection.features.length - 1; i >= 0; i--) {
newSnapshot.push(featureCollection.features[i].id);
}
}
if(featureCollection){
for (var i = featureCollection.features.length - 1; i >= 0; i--) {
newSnapshot.push(featureCollection.features[i].id);
pendingRequests--;
if (pendingRequests <= 0) {
this._currentSnapshot = newSnapshot;
// schedule adding features until the next animation frame
L.Util.requestAnimFrame(L.Util.bind(function () {
this.removeLayers(oldSnapshot);
this.addLayers(newSnapshot);
if (callback) {
callback.call(context, requestError);
}
}
if(pendingRequests <= 0) {
this._currentSnapshot = newSnapshot;
// delay adding features until the next animation frame
EsriLeaflet.Util.requestAnimationFrame(L.Util.bind(function() {
this.removeLayers(oldSnapshot);
this.addLayers(newSnapshot);
if(callback) {
callback.call(context, mostRecentError);
}
}, this));
}
}, this);
for (var i = this._currentSnapshot.length - 1; i >= 0; i--) {
oldSnapshot.push(this._currentSnapshot[i]);
}, this));
}
}, this);
for(var key in this._activeCells){
pendingRequests++;
var coords = this._keyToCellCoords(key);
var bounds = this._cellCoordsToBounds(coords);
this._requestFeatures(bounds, key, requestCallback);
}
for (var i = this._currentSnapshot.length - 1; i >= 0; i--) {
oldSnapshot.push(this._currentSnapshot[i]);
}
return this;
},
for (var key in this._activeCells) {
pendingRequests++;
var coords = this._keyToCellCoords(key);
var bounds = this._cellCoordsToBounds(coords);
this._requestFeatures(bounds, key, requestCallback);
}
getWhere: function(){
return this.options.where;
},
return this;
},
/**
* Time Range Methods
*/
getWhere: function () {
return this.options.where;
},
getTimeRange: function(){
return [this.options.from, this.options.to];
},
/**
* Time Range Methods
*/
setTimeRange: function(from, to, callback, context){
var oldFrom = this.options.from;
var oldTo = this.options.to;
var pendingRequests = 0;
var mostRecentError = null;
var requestCallback = L.Util.bind(function(error){
if(error){
mostRecentError = error;
}
getTimeRange: function () {
return [this.options.from, this.options.to];
},
this._filterExistingFeatures(oldFrom, oldTo, from, to);
setTimeRange: function (from, to, callback, context) {
var oldFrom = this.options.from;
var oldTo = this.options.to;
var pendingRequests = 0;
var requestError = null;
var requestCallback = L.Util.bind(function (error) {
if (error) {
requestError = error;
}
this._filterExistingFeatures(oldFrom, oldTo, from, to);
pendingRequests--;
pendingRequests--;
if(callback && pendingRequests <= 0){
callback.call(context, mostRecentError);
}
}, this);
if (callback && pendingRequests <= 0) {
callback.call(context, requestError);
}
}, this);
this.options.from = from;
this.options.to = to;
this.options.from = from;
this.options.to = to;
this._filterExistingFeatures(oldFrom, oldTo, from, to);
this._filterExistingFeatures(oldFrom, oldTo, from, to);
if(this.options.timeFilterMode === 'server') {
for(var key in this._activeCells){
pendingRequests++;
var coords = this._keyToCellCoords(key);
var bounds = this._cellCoordsToBounds(coords);
this._requestFeatures(bounds, key, requestCallback);
}
}
},
refresh: function(){
for(var key in this._activeCells){
if (this.options.timeFilterMode === 'server') {
for (var key in this._activeCells) {
pendingRequests++;
var coords = this._keyToCellCoords(key);
var bounds = this._cellCoordsToBounds(coords);
this._requestFeatures(bounds, key);
this._requestFeatures(bounds, key, requestCallback);
}
}
if(this.redraw){
this.once('load', function(){
this.eachFeature(function(layer){
this._redraw(layer.feature.id);
}, this);
return this;
},
refresh: function () {
for (var key in this._activeCells) {
var coords = this._keyToCellCoords(key);
var bounds = this._cellCoordsToBounds(coords);
this._requestFeatures(bounds, key);
}
if (this.redraw) {
this.once('load', function () {
this.eachFeature(function (layer) {
this._redraw(layer.feature.id);
}, this);
}
},
}, this);
}
},
_filterExistingFeatures: function (oldFrom, oldTo, newFrom, newTo) {
var layersToRemove = (oldFrom && oldTo) ? this._getFeaturesInTimeRange(oldFrom, oldTo) : this._currentSnapshot;
var layersToAdd = this._getFeaturesInTimeRange(newFrom, newTo);
_filterExistingFeatures: function (oldFrom, oldTo, newFrom, newTo) {
var layersToRemove = (oldFrom && oldTo) ? this._getFeaturesInTimeRange(oldFrom, oldTo) : this._currentSnapshot;
var layersToAdd = this._getFeaturesInTimeRange(newFrom, newTo);
if(layersToAdd.indexOf){
for (var i = 0; i < layersToAdd.length; i++) {
var shouldRemoveLayer = layersToRemove.indexOf(layersToAdd[i]);
if(shouldRemoveLayer >= 0){
layersToRemove.splice(shouldRemoveLayer, 1);
}
if (layersToAdd.indexOf) {
for (var i = 0; i < layersToAdd.length; i++) {
var shouldRemoveLayer = layersToRemove.indexOf(layersToAdd[i]);
if (shouldRemoveLayer >= 0) {
layersToRemove.splice(shouldRemoveLayer, 1);
}
}
}
// schedule adding features until the next animation frame
EsriLeaflet.Util.requestAnimationFrame(L.Util.bind(function(){
this.removeLayers(layersToRemove);
this.addLayers(layersToAdd);
}, this));
},
// schedule adding features until the next animation frame
L.Util.requestAnimFrame(L.Util.bind(function () {
this.removeLayers(layersToRemove);
this.addLayers(layersToAdd);
}, this));
},
_getFeaturesInTimeRange: function(start, end){
var ids = [];
var search;
_getFeaturesInTimeRange: function (start, end) {
var ids = [];
var search;
if(this.options.timeField.start && this.options.timeField.end){
var startTimes = this._startTimeIndex.between(start, end);
var endTimes = this._endTimeIndex.between(start, end);
search = startTimes.concat(endTimes);
} else {
search = this._timeIndex.between(start, end);
}
if (this.options.timeField.start && this.options.timeField.end) {
var startTimes = this._startTimeIndex.between(start, end);
var endTimes = this._endTimeIndex.between(start, end);
search = startTimes.concat(endTimes);
} else {
search = this._timeIndex.between(start, end);
}
for (var i = search.length - 1; i >= 0; i--) {
ids.push(search[i].id);
}
for (var i = search.length - 1; i >= 0; i--) {
ids.push(search[i].id);
}
return ids;
},
return ids;
},
_buildTimeIndexes: function(geojson){
var i;
var feature;
if(this.options.timeField.start && this.options.timeField.end){
var startTimeEntries = [];
var endTimeEntries = [];
for (i = geojson.length - 1; i >= 0; i--) {
feature = geojson[i];
startTimeEntries.push( {
id: feature.id,
value: new Date(feature.properties[this.options.timeField.start])
});
endTimeEntries.push( {
id: feature.id,
value: new Date(feature.properties[this.options.timeField.end])
});
}
this._startTimeIndex.bulkAdd(startTimeEntries);
this._endTimeIndex.bulkAdd(endTimeEntries);
} else {
var timeEntries = [];
for (i = geojson.length - 1; i >= 0; i--) {
feature = geojson[i];
timeEntries.push( {
id: feature.id,
value: new Date(feature.properties[this.options.timeField])
});
}
this._timeIndex.bulkAdd(timeEntries);
_buildTimeIndexes: function (geojson) {
var i;
var feature;
if (this.options.timeField.start && this.options.timeField.end) {
var startTimeEntries = [];
var endTimeEntries = [];
for (i = geojson.length - 1; i >= 0; i--) {
feature = geojson[i];
startTimeEntries.push({
id: feature.id,
value: new Date(feature.properties[this.options.timeField.start])
});
endTimeEntries.push({
id: feature.id,
value: new Date(feature.properties[this.options.timeField.end])
});
}
},
_featureWithinTimeRange: function(feature){
if(!this.options.from || !this.options.to){
return true;
this._startTimeIndex.bulkAdd(startTimeEntries);
this._endTimeIndex.bulkAdd(endTimeEntries);
} else {
var timeEntries = [];
for (i = geojson.length - 1; i >= 0; i--) {
feature = geojson[i];
timeEntries.push({
id: feature.id,
value: new Date(feature.properties[this.options.timeField])
});
}
var from = +this.options.from.valueOf();
var to = +this.options.to.valueOf();
this._timeIndex.bulkAdd(timeEntries);
}
},
if(typeof this.options.timeField === 'string'){
var date = +feature.properties[this.options.timeField];
return (date >= from) && (date <= to);
}
_featureWithinTimeRange: function (feature) {
if (!this.options.from || !this.options.to) {
return true;
}
if(this.options.timeField.start && this.options.timeField.end){
var startDate = +feature.properties[this.options.timeField.start];
var endDate = +feature.properties[this.options.timeField.end];
return ((startDate >= from) && (startDate <= to)) || ((endDate >= from) && (endDate <= to));
}
},
var from = +this.options.from.valueOf();
var to = +this.options.to.valueOf();
/**
* Service Methods
*/
if (typeof this.options.timeField === 'string') {
var date = +feature.properties[this.options.timeField];
return (date >= from) && (date <= to);
}
authenticate: function(token){
this._service.authenticate(token);
return this;
},
if (this.options.timeField.start && this.options.timeField.end) {
var startDate = +feature.properties[this.options.timeField.start];
var endDate = +feature.properties[this.options.timeField.end];
return ((startDate >= from) && (startDate <= to)) || ((endDate >= from) && (endDate <= to));
}
},
metadata: function(callback, context){
this._service.metadata(callback, context);
return this;
},
/**
* Service Methods
*/
query: function(){
return this._service.query();
},
authenticate: function (token) {
this.service.authenticate(token);
return this;
},
_getMetadata: function(callback){
if(this._metadata){
var error;
metadata: function (callback, context) {
this.service.metadata(callback, context);
return this;
},
query: function () {
return this.service.query();
},
_getMetadata: function (callback) {
if (this._metadata) {
var error;
callback(error, this._metadata);
} else {
this.metadata(L.Util.bind(function (error, response) {
this._metadata = response;
callback(error, this._metadata);
} else {
this.metadata(L.Util.bind(function(error, response) {
this._metadata = response;
callback(error, this._metadata);
}, this));
}, this));
}
},
addFeature: function (feature, callback, context) {
this._getMetadata(L.Util.bind(function (error, metadata) {
if (error) {
if (callback) { callback.call(this, error, null); }
return;
}
},
addFeature: function(feature, callback, context){
this._getMetadata(L.Util.bind(function(error, metadata){
this._service.addFeature(feature, L.Util.bind(function(error, response){
if(!error){
// assign ID from result to appropriate objectid field from service metadata
feature.properties[metadata.objectIdField] = response.objectId;
this.service.addFeature(feature, L.Util.bind(function (error, response) {
if (!error) {
// assign ID from result to appropriate objectid field from service metadata
feature.properties[metadata.objectIdField] = response.objectId;
// we also need to update the geojson id for createLayers() to function
feature.id = response.objectId;
this.createLayers([feature]);
}
if(callback){
callback.call(context, error, response);
}
}, this));
}, this));
},
updateFeature: function(feature, callback, context){
this._service.updateFeature(feature, function(error, response){
if(!error){
this.removeLayers([feature.id], true);
// we also need to update the geojson id for createLayers() to function
feature.id = response.objectId;
this.createLayers([feature]);
}
if(callback){
if (callback) {
callback.call(context, error, response);
}
}, this);
},
}, this));
}, this));
},
deleteFeature: function(id, callback, context){
this._service.deleteFeature(id, function(error, response){
if(!error && response.objectId){
this.removeLayers([response.objectId], true);
}
updateFeature: function (feature, callback, context) {
this.service.updateFeature(feature, function (error, response) {
if (!error) {
this.removeLayers([feature.id], true);
this.createLayers([feature]);
}
if(callback){
callback.call(context, error, response);
}
}, this);
},
if (callback) {
callback.call(context, error, response);
}
}, this);
},
deleteFeatures: function(ids, callback, context){
return this._service.deleteFeatures(ids, function(error, response){
if(!error && response.length > 0){
for (var i=0; i<response.length; i++){
this.removeLayers([response[i].objectId], true);
}
}
deleteFeature: function (id, callback, context) {
this.service.deleteFeature(id, function (error, response) {
if (!error && response.objectId) {
this.removeLayers([response.objectId], true);
}
if (callback) {
callback.call(context, error, response);
}
}, this);
},
if(callback){
callback.call(context, error, response);
deleteFeatures: function (ids, callback, context) {
return this.service.deleteFeatures(ids, function (error, response) {
if (!error && response.length > 0) {
for (var i = 0; i < response.length; i++) {
this.removeLayers([response[i].objectId], true);
}
}, this);
}
});
}
if (callback) {
callback.call(context, error, response);
}
}, this);
}
});
/**
* Temporal Binary Search Index
*/
/**
* Temporal Binary Search Index
*/
function BinarySearchIndex(values) {
this.values = values || [];
}
function BinarySearchIndex (values) {
this.values = values || [];
}
BinarySearchIndex.prototype._query = function(query){
var minIndex = 0;
var maxIndex = this.values.length - 1;
var currentIndex;
var currentElement;
var resultIndex;
BinarySearchIndex.prototype._query = function (query) {
var minIndex = 0;
var maxIndex = this.values.length - 1;
var currentIndex;
var currentElement;
while (minIndex <= maxIndex) {
resultIndex = currentIndex = (minIndex + maxIndex) / 2 | 0;
currentElement = this.values[Math.round(currentIndex)];
if (+currentElement.value < +query) {
minIndex = currentIndex + 1;
} else if (+currentElement.value > +query) {
maxIndex = currentIndex - 1;
} else {
return currentIndex;
}
while (minIndex <= maxIndex) {
currentIndex = (minIndex + maxIndex) / 2 | 0;
currentElement = this.values[Math.round(currentIndex)];
if (+currentElement.value < +query) {
minIndex = currentIndex + 1;
} else if (+currentElement.value > +query) {
maxIndex = currentIndex - 1;
} else {
return currentIndex;
}
}
return ~maxIndex;
};
return ~maxIndex;
};
BinarySearchIndex.prototype.sort = function(){
this.values.sort(function(a, b) {
return +b.value - +a.value;
}).reverse();
this.dirty = false;
};
BinarySearchIndex.prototype.sort = function () {
this.values.sort(function (a, b) {
return +b.value - +a.value;
}).reverse();
this.dirty = false;
};
BinarySearchIndex.prototype.between = function(start, end){
if(this.dirty){
this.sort();
}
BinarySearchIndex.prototype.between = function (start, end) {
if (this.dirty) {
this.sort();
}
var startIndex = this._query(start);
var endIndex = this._query(end);
var startIndex = this._query(start);
var endIndex = this._query(end);
if(startIndex === 0 && endIndex === 0){
return [];
}
if (startIndex === 0 && endIndex === 0) {
return [];
}
startIndex = Math.abs(startIndex);
endIndex = (endIndex < 0) ? Math.abs(endIndex): endIndex + 1;
startIndex = Math.abs(startIndex);
endIndex = (endIndex < 0) ? Math.abs(endIndex) : endIndex + 1;
return this.values.slice(startIndex, endIndex);
};
return this.values.slice(startIndex, endIndex);
};
BinarySearchIndex.prototype.bulkAdd = function(items){
this.dirty = true;
this.values = this.values.concat(items);
};
})(EsriLeaflet);
BinarySearchIndex.prototype.bulkAdd = function (items) {
this.dirty = true;
this.values = this.values.concat(items);
};

@@ -1,3 +0,8 @@

EsriLeaflet.Layers.ImageMapLayer = EsriLeaflet.Layers.RasterLayer.extend({
import L from 'leaflet';
import { RasterLayer } from './RasterLayer.js';
import { cleanUrl } from '../Util.js';
import imageService from '../Services/ImageService.js';
export var ImageMapLayer = RasterLayer.extend({
options: {

@@ -10,14 +15,15 @@ updateInterval: 150,

query: function(){
return this._service.query();
query: function () {
return this.service.query();
},
identify: function(){
return this._service.identify();
identify: function () {
return this.service.identify();
},
initialize: function (options) {
options.url = EsriLeaflet.Util.cleanUrl(options.url);
this._service = new EsriLeaflet.Services.ImageService(options);
this._service.on('authenticationrequired requeststart requestend requesterror requestsuccess', this._propagateEvent, this);
options.url = cleanUrl(options.url);
this.service = imageService(options);
this.service.addEventParent(this);
L.Util.setOptions(this, options);

@@ -71,3 +77,3 @@ },

setRenderingRule: function(renderingRule) {
setRenderingRule: function (renderingRule) {
this.options.renderingRule = renderingRule;

@@ -77,7 +83,7 @@ this._update();

getRenderingRule: function() {
getRenderingRule: function () {
return this.options.renderingRule;
},
setMosaicRule: function(mosaicRule) {
setMosaicRule: function (mosaicRule) {
this.options.mosaicRule = mosaicRule;

@@ -87,10 +93,10 @@ this._update();

getMosaicRule: function() {
getMosaicRule: function () {
return this.options.mosaicRule;
},
_getPopupData: function(e){
var callback = L.Util.bind(function(error, results, response) {
if(error) { return; } // we really can't do anything here but authenticate or requesterror will fire
setTimeout(L.Util.bind(function(){
_getPopupData: function (e) {
var callback = L.Util.bind(function (error, results, response) {
if (error) { return; } // we really can't do anything here but authenticate or requesterror will fire
setTimeout(L.Util.bind(function () {
this._renderPopup(e.latlng, error, results, response);

@@ -164,11 +170,11 @@ }, this), 300);

if (this._service.options.token) {
params.token = this._service.options.token;
if (this.service.options.token) {
params.token = this.service.options.token;
}
if(this.options.renderingRule) {
if (this.options.renderingRule) {
params.renderingRule = JSON.stringify(this.options.renderingRule);
}
if(this.options.mosaicRule) {
if (this.options.mosaicRule) {
params.mosaicRule = JSON.stringify(this.options.mosaicRule);

@@ -182,4 +188,4 @@ }

if (this.options.f === 'json') {
this._service.request('exportImage', params, function(error, response){
if(error) { return; } // we really can't do anything here but authenticate or requesterror will fire
this.service.get('exportImage', params, function (error, response) {
if (error) { return; } // we really can't do anything here but authenticate or requesterror will fire
this._renderImage(response.href, bounds);

@@ -194,10 +200,6 @@ }, this);

EsriLeaflet.ImageMapLayer = EsriLeaflet.Layers.ImageMapLayer;
export function imageMapLayer (url, options) {
return new ImageMapLayer(url, options);
}
EsriLeaflet.Layers.imageMapLayer = function (options) {
return new EsriLeaflet.Layers.ImageMapLayer(options);
};
EsriLeaflet.imageMapLayer = function (options) {
return new EsriLeaflet.Layers.ImageMapLayer(options);
};
export default imageMapLayer;

@@ -1,15 +0,19 @@

EsriLeaflet.Layers.RasterLayer = L.Class.extend({
includes: L.Mixin.Events,
import L from 'leaflet';
import {cors} from '../Support.js';
export var RasterLayer = L.Layer.extend({
options: {
opacity: 1,
position: 'front',
f: 'image'
f: 'image',
useCors: cors,
attribution: null,
interactive: false,
alt: ''
},
onAdd: function (map) {
this._map = map;
this._update = L.Util.throttle(this._update, this.options.updateInterval, this);
this._update = L.Util.limitExecByInterval(this._update, this.options.updateInterval, this);
if (map.options.crs && map.options.crs.code) {

@@ -25,5 +29,5 @@ var sr = map.options.crs.code.split(':')[1];

// current bounds show the image otherwise remove it
if(this._currentImage && this._currentImage._bounds.equals(this._map.getBounds())){
if (this._currentImage && this._currentImage._bounds.equals(this._map.getBounds())) {
map.addLayer(this._currentImage);
} else if(this._currentImage) {
} else if (this._currentImage) {
this._map.removeLayer(this._currentImage);

@@ -35,3 +39,3 @@ this._currentImage = null;

if(this._popup){
if (this._popup) {
this._map.on('click', this._getPopupData, this);

@@ -42,3 +46,22 @@ this._map.on('dblclick', this._resetPopupState, this);

bindPopup: function(fn, popupOptions){
onRemove: function (map) {
if (this._currentImage) {
this._map.removeLayer(this._currentImage);
}
if (this._popup) {
this._map.off('click', this._getPopupData, this);
this._map.off('dblclick', this._resetPopupState, this);
}
this._map.off('moveend', this._update, this);
},
getEvents: function () {
return {
moveend: this._update
};
},
bindPopup: function (fn, popupOptions) {
this._shouldRenderPopup = false;

@@ -48,3 +71,3 @@ this._lastClick = false;

this._popupFunction = fn;
if(this._map){
if (this._map) {
this._map.on('click', this._getPopupData, this);

@@ -56,4 +79,4 @@ this._map.on('dblclick', this._resetPopupState, this);

unbindPopup: function(){
if(this._map){
unbindPopup: function () {
if (this._map) {
this._map.closePopup(this._popup);

@@ -67,29 +90,5 @@ this._map.off('click', this._getPopupData, this);

onRemove: function (map) {
bringToFront: function () {
this.options.position = 'front';
if (this._currentImage) {
this._map.removeLayer(this._currentImage);
}
if(this._popup){
this._map.off('click', this._getPopupData, this);
this._map.off('dblclick', this._resetPopupState, this);
}
this._map.off('moveend', this._update, this);
this._map = null;
},
addTo: function(map){
map.addLayer(this);
return this;
},
removeFrom: function(map){
map.removeLayer(this);
return this;
},
bringToFront: function(){
this.options.position = 'front';
if(this._currentImage){
this._currentImage.bringToFront();

@@ -100,5 +99,5 @@ }

bringToBack: function(){
bringToBack: function () {
this.options.position = 'back';
if(this._currentImage){
if (this._currentImage) {
this._currentImage.bringToBack();

@@ -113,7 +112,7 @@ }

getOpacity: function(){
getOpacity: function () {
return this.options.opacity;
},
setOpacity: function(opacity){
setOpacity: function (opacity) {
this.options.opacity = opacity;

@@ -124,7 +123,7 @@ this._currentImage.setOpacity(opacity);

getTimeRange: function(){
getTimeRange: function () {
return [this.options.from, this.options.to];
},
setTimeRange: function(from, to){
setTimeRange: function (from, to) {
this.options.from = from;

@@ -136,14 +135,14 @@ this.options.to = to;

metadata: function(callback, context){
this._service.metadata(callback, context);
metadata: function (callback, context) {
this.service.metadata(callback, context);
return this;
},
authenticate: function(token){
this._service.authenticate(token);
authenticate: function (token) {
this.service.authenticate(token);
return this;
},
_renderImage: function(url, bounds){
if(this._map){
_renderImage: function (url, bounds) {
if (this._map) {
// create a new image overlay and add it to the map

@@ -153,38 +152,44 @@ // to start loading the image

var image = new L.ImageOverlay(url, bounds, {
opacity: 0
opacity: 0,
crossOrigin: this.options.useCors,
alt: this.options.alt,
pane: this.options.pane || this.getPane(),
interactive: this.options.interactive
}).addTo(this._map);
// once the image loads
image.once('load', function(e){
var newImage = e.target;
var oldImage = this._currentImage;
image.once('load', function (e) {
if (this._map) {
var newImage = e.target;
var oldImage = this._currentImage;
// if the bounds of this image matches the bounds that
// _renderImage was called with and we have a map with the same bounds
// hide the old image if there is one and set the opacity
// of the new image otherwise remove the new image
if(newImage._bounds.equals(bounds) && newImage._bounds.equals(this._map.getBounds())){
this._currentImage = newImage;
// if the bounds of this image matches the bounds that
// _renderImage was called with and we have a map with the same bounds
// hide the old image if there is one and set the opacity
// of the new image otherwise remove the new image
if (newImage._bounds.equals(bounds) && newImage._bounds.equals(this._map.getBounds())) {
this._currentImage = newImage;
if(this.options.position === 'front'){
this.bringToFront();
} else {
this.bringToBack();
}
if (this.options.position === 'front') {
this.bringToFront();
} else {
this.bringToBack();
}
if(this._map && this._currentImage._map){
this._currentImage.setOpacity(this.options.opacity);
} else {
this._currentImage._map.removeLayer(this._currentImage);
}
if (this._map && this._currentImage._map) {
this._currentImage.setOpacity(this.options.opacity);
} else {
this._currentImage._map.removeLayer(this._currentImage);
}
if(oldImage && this._map) {
this._map.removeLayer(oldImage);
}
if (oldImage && this._map) {
this._map.removeLayer(oldImage);
}
if(oldImage && oldImage._map){
oldImage._map.removeLayer(oldImage);
if (oldImage && oldImage._map) {
oldImage._map.removeLayer(oldImage);
}
} else {
this._map.removeLayer(newImage);
}
} else {
this._map.removeLayer(newImage);
}

@@ -195,3 +200,2 @@

});
}, this);

@@ -206,3 +210,3 @@

_update: function () {
if(!this._map){
if (!this._map) {
return;

@@ -214,3 +218,3 @@ }

if(this._animatingZoom){
if (this._animatingZoom) {
return;

@@ -231,7 +235,6 @@ }

// TODO: refactor these into raster layer
_renderPopup: function(latlng, error, results, response){
_renderPopup: function (latlng, error, results, response) {
latlng = L.latLng(latlng);
if(this._shouldRenderPopup && this._lastClick.equals(latlng)){
//add the popup to the map where the mouse was clicked at
if (this._shouldRenderPopup && this._lastClick.equals(latlng)) {
// add the popup to the map where the mouse was clicked at
var content = this._popupFunction(error, results, response);

@@ -244,16 +247,6 @@ if (content) {

_resetPopupState: function(e){
_resetPopupState: function (e) {
this._shouldRenderPopup = false;
this._lastClick = e.latlng;
},
// from https://github.com/Leaflet/Leaflet/blob/v0.7.2/src/layer/FeatureGroup.js
// @TODO remove at Leaflet 0.8
_propagateEvent: function (e) {
e = L.extend({
layer: e.target,
target: this
}, e);
this.fire(e.type, e);
}
});

@@ -1,2 +0,6 @@

EsriLeaflet.Layers.TiledMapLayer = L.TileLayer.extend({
import L from 'leaflet';
import {warn, cleanUrl} from '../Util.js';
import mapService from '../Services/MapService.js';
export var TiledMapLayer = L.TileLayer.extend({
options: {

@@ -9,41 +13,40 @@ zoomOffsetAllowance: 0.1,

MercatorZoomLevels: {
'0':156543.03392799999,
'1':78271.516963999893,
'2':39135.758482000099,
'3':19567.879240999901,
'4':9783.9396204999593,
'5':4891.9698102499797,
'6':2445.9849051249898,
'7':1222.9924525624899,
'8':611.49622628138002,
'9':305.74811314055802,
'10':152.874056570411,
'11':76.437028285073197,
'12':38.218514142536598,
'13':19.109257071268299,
'14':9.5546285356341496,
'15':4.7773142679493699,
'16':2.38865713397468,
'17':1.1943285668550501,
'18':0.59716428355981699,
'19':0.29858214164761698,
'20':0.14929107082381,
'21':0.07464553541191,
'22':0.0373227677059525,
'23':0.0186613838529763
'0': 156543.03392799999,
'1': 78271.516963999893,
'2': 39135.758482000099,
'3': 19567.879240999901,
'4': 9783.9396204999593,
'5': 4891.9698102499797,
'6': 2445.9849051249898,
'7': 1222.9924525624899,
'8': 611.49622628138002,
'9': 305.74811314055802,
'10': 152.874056570411,
'11': 76.437028285073197,
'12': 38.218514142536598,
'13': 19.109257071268299,
'14': 9.5546285356341496,
'15': 4.7773142679493699,
'16': 2.38865713397468,
'17': 1.1943285668550501,
'18': 0.59716428355981699,
'19': 0.29858214164761698,
'20': 0.14929107082381,
'21': 0.07464553541191,
'22': 0.0373227677059525,
'23': 0.0186613838529763
}
},
initialize: function(options){
options.url = EsriLeaflet.Util.cleanUrl(options.url);
initialize: function (options) {
options.url = cleanUrl(options.url);
options = L.Util.setOptions(this, options);
// set the urls
//this.url = L.esri.Util.cleanUrl(url);
this.tileUrl = L.esri.Util.cleanUrl(options.url) + 'tile/{z}/{y}/{x}';
this._service = new L.esri.Services.MapService(options);
this._service.on('authenticationrequired requeststart requestend requesterror requestsuccess', this._propagateEvent, this);
this.tileUrl = options.url + 'tile/{z}/{y}/{x}';
this.service = mapService(options);
this.service.addEventParent(this);
//if this is looking at the AGO tiles subdomain insert the subdomain placeholder
if(this.tileUrl.match('://tiles.arcgisonline.com')){
// if this is looking at the AGO tiles subdomain insert the subdomain placeholder
if (this.tileUrl.match('://tiles.arcgisonline.com')) {
this.tileUrl = this.tileUrl.replace('://tiles.arcgisonline.com', '://tiles{s}.arcgisonline.com');

@@ -53,3 +56,3 @@ options.subdomains = ['1', '2', '3', '4'];

if(this.options.token) {
if (this.options.token) {
this.tileUrl += ('?token=' + this.options.token);

@@ -71,20 +74,20 @@ }

onAdd: function(map){
onAdd: function (map) {
if (!this._lodMap && this.options.correctZoomLevels) {
this._lodMap = {}; // make sure we always have an lod map even if its empty
this.metadata(function(error, metadata) {
if(!error) {
this.metadata(function (error, metadata) {
if (!error) {
var sr = metadata.spatialReference.latestWkid || metadata.spatialReference.wkid;
if (sr === 102100 || sr === 3857) {
//create the zoom level data
// create the zoom level data
var arcgisLODs = metadata.tileInfo.lods;
var correctResolutions = EsriLeaflet.Layers.TiledMapLayer.MercatorZoomLevels;
var correctResolutions = TiledMapLayer.MercatorZoomLevels;
for(var i = 0; i < arcgisLODs.length; i++) {
for (var i = 0; i < arcgisLODs.length; i++) {
var arcgisLOD = arcgisLODs[i];
for(var ci in correctResolutions) {
for (var ci in correctResolutions) {
var correctRes = correctResolutions[ci];
if(this._withinPercentage(arcgisLOD.resolution, correctRes, this.options.zoomOffsetAllowance)) {
if (this._withinPercentage(arcgisLOD.resolution, correctRes, this.options.zoomOffsetAllowance)) {
this._lodMap[ci] = arcgisLOD.level;

@@ -96,3 +99,3 @@ break;

} else {
EsriLeaflet.Util.warn('L.esri.TiledMapLayer is using a non-mercator spatial reference. Support may be available through Proj4Leaflet http://esri.github.io/esri-leaflet/examples/non-mercator-projection.html');
warn('L.esri.TiledMapLayer is using a non-mercator spatial reference. Support may be available through Proj4Leaflet http://esri.github.io/esri-leaflet/examples/non-mercator-projection.html');
}

@@ -108,31 +111,29 @@ }

metadata: function(callback, context){
this._service.metadata(callback, context);
metadata: function (callback, context) {
this.service.metadata(callback, context);
return this;
},
identify: function(){
return this._service.identify();
identify: function () {
return this.service.identify();
},
authenticate: function(token){
find: function () {
return this.service.find();
},
query: function () {
return this.service.query();
},
authenticate: function (token) {
var tokenQs = '?token=' + token;
this.tileUrl = (this.options.token) ? this.tileUrl.replace(/\?token=(.+)/g, tokenQs) : this.tileUrl + tokenQs;
this.options.token = token;
this._service.authenticate(token);
this.service.authenticate(token);
return this;
},
// from https://github.com/Leaflet/Leaflet/blob/v0.7.2/src/layer/FeatureGroup.js
// @TODO remove at Leaflet 0.8
_propagateEvent: function (e) {
e = L.extend({
layer: e.target,
target: this
}, e);
this.fire(e.type, e);
},
_withinPercentage: function (a, b, percentage) {
var diff = Math.abs((a/b) - 1);
var diff = Math.abs((a / b) - 1);
return diff < percentage;

@@ -142,10 +143,6 @@ }

L.esri.TiledMapLayer = L.esri.Layers.tiledMapLayer;
export function tiledMapLayer (url, options) {
return new TiledMapLayer(url, options);
}
L.esri.Layers.tiledMapLayer = function(options){
return new L.esri.Layers.TiledMapLayer(options);
};
L.esri.tiledMapLayer = function(options){
return new L.esri.Layers.TiledMapLayer(options);
};
export default tiledMapLayer;

@@ -1,193 +0,198 @@

(function(EsriLeaflet){
import L from 'leaflet';
import Support from './Support.js';
import {warn} from './Util.js';
var callbacks = 0;
var callbacks = 0;
window._EsriLeafletCallbacks = {};
window._EsriLeafletCallbacks = {};
function serialize(params){
var data = '';
function serialize (params) {
var data = '';
params.f = params.f || 'json';
params.f = params.f || 'json';
for (var key in params){
if(params.hasOwnProperty(key)){
var param = params[key];
var type = Object.prototype.toString.call(param);
var value;
for (var key in params) {
if (params.hasOwnProperty(key)) {
var param = params[key];
var type = Object.prototype.toString.call(param);
var value;
if(data.length){
data += '&';
}
if (data.length) {
data += '&';
}
if (type === '[object Array]'){
value = (Object.prototype.toString.call(param[0]) === '[object Object]') ? JSON.stringify(param) : param.join(',');
} else if (type === '[object Object]') {
value = JSON.stringify(param);
} else if (type === '[object Date]'){
value = param.valueOf();
} else {
value = param;
}
if (type === '[object Array]') {
value = (Object.prototype.toString.call(param[0]) === '[object Object]') ? JSON.stringify(param) : param.join(',');
} else if (type === '[object Object]') {
value = JSON.stringify(param);
} else if (type === '[object Date]') {
value = param.valueOf();
} else {
value = param;
}
data += encodeURIComponent(key) + '=' + encodeURIComponent(value);
}
data += encodeURIComponent(key) + '=' + encodeURIComponent(value);
}
return data;
}
function createRequest(callback, context){
var httpRequest = new XMLHttpRequest();
return data;
}
httpRequest.onerror = function(e) {
httpRequest.onreadystatechange = L.Util.falseFn;
function createRequest (callback, context) {
var httpRequest = new window.XMLHttpRequest();
callback.call(context, {
error: {
code: 500,
message: 'XMLHttpRequest error'
}
}, null);
};
httpRequest.onerror = function (e) {
httpRequest.onreadystatechange = L.Util.falseFn;
httpRequest.onreadystatechange = function(){
var response;
var error;
callback.call(context, {
error: {
code: 500,
message: 'XMLHttpRequest error'
}
}, null);
};
if (httpRequest.readyState === 4) {
try {
response = JSON.parse(httpRequest.responseText);
} catch(e) {
response = null;
error = {
code: 500,
message: 'Could not parse response as JSON. This could also be caused by a CORS or XMLHttpRequest error.'
};
}
httpRequest.onreadystatechange = function () {
var response;
var error;
if (!error && response.error) {
error = response.error;
response = null;
}
if (httpRequest.readyState === 4) {
try {
response = JSON.parse(httpRequest.responseText);
} catch(e) {
response = null;
error = {
code: 500,
message: 'Could not parse response as JSON. This could also be caused by a CORS or XMLHttpRequest error.'
};
}
httpRequest.onerror = L.Util.falseFn;
callback.call(context, error, response);
if (!error && response.error) {
error = response.error;
response = null;
}
};
return httpRequest;
}
httpRequest.onerror = L.Util.falseFn;
// AJAX handlers for CORS (modern browsers) or JSONP (older browsers)
EsriLeaflet.Request = {
request: function(url, params, callback, context){
var paramString = serialize(params);
var httpRequest = createRequest(callback, context);
var requestLength = (url + '?' + paramString).length;
callback.call(context, error, response);
}
};
// request is less then 2000 characters and the browser supports CORS, make GET request with XMLHttpRequest
if(requestLength <= 2000 && L.esri.Support.CORS){
httpRequest.open('GET', url + '?' + paramString);
httpRequest.send(null);
return httpRequest;
}
// request is less more then 2000 characters and the browser supports CORS, make POST request with XMLHttpRequest
} else if (requestLength > 2000 && L.esri.Support.CORS){
httpRequest.open('POST', url);
httpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
httpRequest.send(paramString);
function xmlHttpPost (url, params, callback, context) {
var httpRequest = createRequest(callback, context);
httpRequest.open('POST', url);
httpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
httpRequest.send(serialize(params));
// request is less more then 2000 characters and the browser does not support CORS, make a JSONP request
} else if(requestLength <= 2000 && !L.esri.Support.CORS){
return L.esri.Request.get.JSONP(url, params, callback, context);
return httpRequest;
}
// request is longer then 2000 characters and the browser does not support CORS, log a warning
} else {
EsriLeaflet.Util.warn('a request to ' + url + ' was longer then 2000 characters and this browser cannot make a cross-domain post request. Please use a proxy http://esri.github.io/esri-leaflet/api-reference/request.html');
return;
}
function xmlHttpGet (url, params, callback, context) {
var httpRequest = createRequest(callback, context);
return httpRequest;
},
httpRequest.open('GET', url + '?' + serialize(params), true);
httpRequest.send(null);
post: {
XMLHTTP: function (url, params, callback, context) {
var httpRequest = createRequest(callback, context);
httpRequest.open('POST', url);
httpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
httpRequest.send(serialize(params));
return httpRequest;
}
return httpRequest;
}
},
// AJAX handlers for CORS (modern browsers) or JSONP (older browsers)
export function request (url, params, callback, context) {
var paramString = serialize(params);
var httpRequest = createRequest(callback, context);
var requestLength = (url + '?' + paramString).length;
get: {
CORS: function (url, params, callback, context) {
var httpRequest = createRequest(callback, context);
// request is less then 2000 characters and the browser supports CORS, make GET request with XMLHttpRequest
if (requestLength <= 2000 && Support.cors) {
httpRequest.open('GET', url + '?' + paramString);
httpRequest.send(null);
httpRequest.open('GET', url + '?' + serialize(params), true);
httpRequest.send(null);
// request is less more then 2000 characters and the browser supports CORS, make POST request with XMLHttpRequest
} else if (requestLength > 2000 && Support.cors) {
httpRequest.open('POST', url);
httpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
httpRequest.send(paramString);
return httpRequest;
},
JSONP: function(url, params, callback, context){
var callbackId = 'c' + callbacks;
// request is less more then 2000 characters and the browser does not support CORS, make a JSONP request
} else if (requestLength <= 2000 && !Support.cors) {
return jsonp(url, params, callback, context);
params.callback = 'window._EsriLeafletCallbacks.' + callbackId;
// request is longer then 2000 characters and the browser does not support CORS, log a warning
} else {
warn('a request to ' + url + ' was longer then 2000 characters and this browser cannot make a cross-domain post request. Please use a proxy http://esri.github.io/esri-leaflet/api-reference/request.html');
return;
}
var script = L.DomUtil.create('script', null, document.body);
script.type = 'text/javascript';
script.src = url + '?' + serialize(params);
script.id = callbackId;
return httpRequest;
}
window._EsriLeafletCallbacks[callbackId] = function(response){
if(window._EsriLeafletCallbacks[callbackId] !== true){
var error;
var responseType = Object.prototype.toString.call(response);
export function jsonp (url, params, callback, context) {
var callbackId = 'c' + callbacks;
if(!(responseType === '[object Object]' || responseType === '[object Array]')){
error = {
error: {
code: 500,
message: 'Expected array or object as JSONP response'
}
};
response = null;
}
params.callback = 'window._EsriLeafletCallbacks.' + callbackId;
if (!error && response.error) {
error = response;
response = null;
}
var script = L.DomUtil.create('script', null, document.body);
script.type = 'text/javascript';
script.src = url + '?' + serialize(params);
script.id = callbackId;
callback.call(context, error, response);
window._EsriLeafletCallbacks[callbackId] = true;
window._EsriLeafletCallbacks[callbackId] = function (response) {
if (window._EsriLeafletCallbacks[callbackId] !== true) {
var error;
var responseType = Object.prototype.toString.call(response);
if (!(responseType === '[object Object]' || responseType === '[object Array]')) {
error = {
error: {
code: 500,
message: 'Expected array or object as JSONP response'
}
};
response = null;
}
callbacks++;
if (!error && response.error) {
error = response;
response = null;
}
return {
id: callbackId,
url: script.src,
abort: function(){
window._EsriLeafletCallbacks._callback[callbackId]({
code: 0,
message: 'Request aborted.'
});
}
};
}
callback.call(context, error, response);
window._EsriLeafletCallbacks[callbackId] = true;
}
};
// choose the correct AJAX handler depending on CORS support
EsriLeaflet.get = (EsriLeaflet.Support.CORS) ? EsriLeaflet.Request.get.CORS : EsriLeaflet.Request.get.JSONP;
callbacks++;
// always use XMLHttpRequest for posts
EsriLeaflet.post = EsriLeaflet.Request.post.XMLHTTP;
return {
id: callbackId,
url: script.src,
abort: function () {
window._EsriLeafletCallbacks._callback[callbackId]({
code: 0,
message: 'Request aborted.'
});
}
};
}
// expose a common request method the uses GET\POST based on request length
EsriLeaflet.request = EsriLeaflet.Request.request;
var get = ((Support.cors) ? xmlHttpGet : jsonp);
get.CORS = xmlHttpGet;
get.JSONP = jsonp;
})(EsriLeaflet);
// choose the correct AJAX handler depending on CORS support
export { get };
// always use XMLHttpRequest for posts
export { xmlHttpPost as post };
// export the Request object to call the different handlers for debugging
export var Request = {
request: request,
get: get,
post: xmlHttpPost
};
export default Request;

@@ -1,3 +0,7 @@

EsriLeaflet.Services.FeatureLayerService = EsriLeaflet.Services.Service.extend({
import { Service } from './Service.js';
import query from '../Tasks/Query.js';
import { geojsonToArcGIS } from '../Util.js';
export var FeatureLayerService = Service.extend({
options: {

@@ -7,16 +11,16 @@ idAttribute: 'OBJECTID'

query: function(){
return new EsriLeaflet.Tasks.Query(this);
query: function () {
return query(this);
},
addFeature: function(feature, callback, context) {
addFeature: function (feature, callback, context) {
delete feature.id;
feature = EsriLeaflet.Util.geojsonToArcGIS(feature);
feature = geojsonToArcGIS(feature);
return this.post('addFeatures', {
features: [feature]
}, function(error, response){
}, function (error, response) {
var result = (response && response.addResults) ? response.addResults[0] : undefined;
if(callback){
if (callback) {
callback.call(context, error || response.addResults[0].error, result);

@@ -27,10 +31,10 @@ }

updateFeature: function(feature, callback, context) {
feature = EsriLeaflet.Util.geojsonToArcGIS(feature, this.options.idAttribute);
updateFeature: function (feature, callback, context) {
feature = geojsonToArcGIS(feature, this.options.idAttribute);
return this.post('updateFeatures', {
features: [feature]
}, function(error, response){
}, function (error, response) {
var result = (response && response.updateResults) ? response.updateResults[0] : undefined;
if(callback){
if (callback) {
callback.call(context, error || response.updateResults[0].error, result);

@@ -41,8 +45,8 @@ }

deleteFeature: function(id, callback, context) {
deleteFeature: function (id, callback, context) {
return this.post('deleteFeatures', {
objectIds: id
}, function(error, response){
}, function (error, response) {
var result = (response && response.deleteResults) ? response.deleteResults[0] : undefined;
if(callback){
if (callback) {
callback.call(context, error || response.deleteResults[0].error, result);

@@ -53,9 +57,9 @@ }

deleteFeatures: function(ids, callback, context) {
deleteFeatures: function (ids, callback, context) {
return this.post('deleteFeatures', {
objectIds: ids
}, function(error, response){
}, function (error, response) {
// pass back the entire array
var result = (response && response.deleteResults) ? response.deleteResults : undefined;
if(callback){
if (callback) {
callback.call(context, error || response.deleteResults[0].error, result);

@@ -67,4 +71,6 @@ }

EsriLeaflet.Services.featureLayerService = function(options) {
return new EsriLeaflet.Services.FeatureLayerService(options);
};
export function featureLayerService (options) {
return new FeatureLayerService(options);
}
export default featureLayerService;

@@ -1,14 +0,20 @@

EsriLeaflet.Services.ImageService = EsriLeaflet.Services.Service.extend({
import { Service } from './Service.js';
import identifyImage from '../Tasks/IdentifyImage.js';
import query from '../Tasks/Query.js';
export var ImageService = Service.extend({
query: function () {
return new EsriLeaflet.Tasks.Query(this);
return query(this);
},
identify: function() {
return new EsriLeaflet.Tasks.IdentifyImage(this);
identify: function () {
return identifyImage(this);
}
});
EsriLeaflet.Services.imageService = function(params){
return new EsriLeaflet.Services.ImageService(params);
};
export function imageService (options) {
return new ImageService(options);
}
export default imageService;

@@ -1,13 +0,18 @@

EsriLeaflet.Services.MapService = EsriLeaflet.Services.Service.extend({
import { Service } from './Service.js';
import identifyFeatures from '../Tasks/IdentifyFeatures.js';
import query from '../Tasks/Query.js';
import find from '../Tasks/Find.js';
export var MapService = Service.extend({
identify: function () {
return new EsriLeaflet.Tasks.identifyFeatures(this);
return identifyFeatures(this);
},
find: function () {
return new EsriLeaflet.Tasks.Find(this);
return find(this);
},
query: function () {
return new EsriLeaflet.Tasks.Query(this);
return query(this);
}

@@ -17,4 +22,6 @@

EsriLeaflet.Services.mapService = function(params){
return new EsriLeaflet.Services.MapService(params);
};
export function mapService (options) {
return new MapService(options);
}
export default mapService;

@@ -1,8 +0,11 @@

EsriLeaflet.Services.Service = L.Class.extend({
import L from 'leaflet';
import {cors} from '../Support.js';
import {cleanUrl} from '../Util.js';
import Request from '../Request.js';
includes: L.Mixin.Events,
export var Service = L.Evented.extend({
options: {
proxy: false,
useCors: EsriLeaflet.Support.CORS
useCors: cors
},

@@ -15,3 +18,3 @@

L.Util.setOptions(this, options);
this.options.url = EsriLeaflet.Util.cleanUrl(this.options.url);
this.options.url = cleanUrl(this.options.url);
},

@@ -35,3 +38,3 @@

authenticate: function(token){
authenticate: function (token) {
this._authenticating = false;

@@ -43,3 +46,3 @@ this.options.token = token;

_request: function(method, path, params, callback, context){
_request: function (method, path, params, callback, context) {
this.fire('requeststart', {

@@ -49,3 +52,3 @@ url: this.options.url + path,

method: method
});
}, true);

@@ -64,6 +67,6 @@ var wrappedCallback = this._createServiceCallback(method, path, params, callback, context);

if((method === 'get' || method === 'request') && !this.options.useCors){
return EsriLeaflet.Request.get.JSONP(url, params, wrappedCallback);
if ((method === 'get' || method === 'request') && !this.options.useCors) {
return Request.get.JSONP(url, params, wrappedCallback);
} else {
return EsriLeaflet[method](url, params, wrappedCallback);
return Request[method](url, params, wrappedCallback);
}

@@ -73,5 +76,4 @@ }

_createServiceCallback: function(method, path, params, callback, context){
return L.Util.bind(function(error, response){
_createServiceCallback: function (method, path, params, callback, context) {
return L.Util.bind(function (error, response) {
if (error && (error.code === 499 || error.code === 498)) {

@@ -85,3 +87,3 @@ this._authenticating = true;

authenticate: L.Util.bind(this.authenticate, this)
});
}, true);

@@ -94,3 +96,3 @@ // if the user has access to a callback they can handle the auth error

if(error) {
if (error) {
this.fire('requesterror', {

@@ -102,3 +104,3 @@ url: this.options.url + path,

method: method
});
}, true);
} else {

@@ -110,3 +112,3 @@ this.fire('requestsuccess', {

method: method
});
}, true);
}

@@ -118,7 +120,7 @@

method: method
});
}, true);
}, this);
},
_runQueue: function(){
_runQueue: function () {
for (var i = this._requestQueue.length - 1; i >= 0; i--) {

@@ -131,7 +133,8 @@ var request = this._requestQueue[i];

}
});
EsriLeaflet.Services.service = function(params){
return new EsriLeaflet.Services.Service(params);
};
export function service (options) {
return new Service(options);
}
export default service;

@@ -1,2 +0,5 @@

EsriLeaflet.Tasks.Find = EsriLeaflet.Tasks.Task.extend({
import { Task } from './Task.js';
import Util from '../Util.js';
export var Find = Task.extend({
setters: {

@@ -14,6 +17,6 @@ // method name > param name

'dynamicLayers': 'dynamicLayers',
'returnZ' : 'returnZ',
'returnM' : 'returnM',
'gdbVersion' : 'gdbVersion',
'token' : 'token'
'returnZ': 'returnZ',
'returnM': 'returnM',
'gdbVersion': 'gdbVersion',
'token': 'token'
},

@@ -37,3 +40,3 @@

simplify: function(map, factor){
simplify: function (map, factor) {
var mapWidth = Math.abs(map.getBounds().getWest() - map.getBounds().getEast());

@@ -45,4 +48,4 @@ this.params.maxAllowableOffset = (mapWidth / map.getSize().y) * factor;

run: function (callback, context) {
return this.request(function(error, response){
callback.call(context, error, (response && EsriLeaflet.Util.responseToFeatureCollection(response)), response);
return this.request(function (error, response) {
callback.call(context, error, (response && Util.responseToFeatureCollection(response)), response);
}, context);

@@ -52,4 +55,6 @@ }

EsriLeaflet.Tasks.find = function (params) {
return new EsriLeaflet.Tasks.Find(params);
};
export function find (options) {
return new Find(options);
}
export default find;

@@ -1,5 +0,7 @@

EsriLeaflet.Tasks.Identify = EsriLeaflet.Tasks.Task.extend({
import { Task } from './Task.js';
export var Identify = Task.extend({
path: 'identify',
between: function(start, end){
between: function (start, end) {
this.params.time = [start.valueOf(), end.valueOf()];

@@ -9,1 +11,7 @@ return this;

});
export function identify (options) {
return new Identify(options);
}
export default identify;

@@ -1,2 +0,6 @@

EsriLeaflet.Tasks.IdentifyFeatures = EsriLeaflet.Tasks.Identify.extend({
import L from 'leaflet';
import { Identify } from './Identify.js';
import Util from '../Util.js';
export var IdentifyFeatures = Identify.extend({
setters: {

@@ -16,4 +20,4 @@ 'layers': 'layers',

on: function(map){
var extent = EsriLeaflet.Util.boundsToExtent(map.getBounds());
on: function (map) {
var extent = Util.boundsToExtent(map.getBounds());
var size = map.getSize();

@@ -25,3 +29,3 @@ this.params.imageDisplay = [size.x, size.y, 96];

at: function(latlng){
at: function (latlng) {
latlng = L.latLng(latlng);

@@ -33,3 +37,3 @@ this.params.geometry = [latlng.lng, latlng.lat];

layerDef: function (id, where){
layerDef: function (id, where) {
this.params.layerDefs = (this.params.layerDefs) ? this.params.layerDefs + ';' : '';

@@ -40,3 +44,3 @@ this.params.layerDefs += ([id, where]).join(':');

simplify: function(map, factor){
simplify: function (map, factor) {
var mapWidth = Math.abs(map.getBounds().getWest() - map.getBounds().getEast());

@@ -47,6 +51,6 @@ this.params.maxAllowableOffset = (mapWidth / map.getSize().y) * (1 - factor);

run: function (callback, context){
return this.request(function(error, response){
run: function (callback, context) {
return this.request(function (error, response) {
// immediately invoke with an error
if(error) {
if (error) {
callback.call(context, error, undefined, response);

@@ -57,3 +61,3 @@ return;

} else {
var featureCollection = EsriLeaflet.Util.responseToFeatureCollection(response);
var featureCollection = Util.responseToFeatureCollection(response);
response.results = response.results.reverse();

@@ -70,4 +74,6 @@ for (var i = 0; i < featureCollection.features.length; i++) {

EsriLeaflet.Tasks.identifyFeatures = function(params){
return new EsriLeaflet.Tasks.IdentifyFeatures(params);
};
export function identifyFeatures (options) {
return new IdentifyFeatures(options);
}
export default identifyFeatures;

@@ -1,2 +0,6 @@

EsriLeaflet.Tasks.IdentifyImage = EsriLeaflet.Tasks.Identify.extend({
import L from 'leaflet';
import { Identify } from './Identify.js';
import Util from '../Util.js';
export var IdentifyImage = Identify.extend({
setters: {

@@ -14,3 +18,3 @@ 'setMosaicRule': 'mosaicRule',

at: function(latlng){
at: function (latlng) {
latlng = L.latLng(latlng);

@@ -20,3 +24,3 @@ this.params.geometry = JSON.stringify({

y: latlng.lat,
spatialReference:{
spatialReference: {
wkid: 4326

@@ -29,16 +33,16 @@ }

getMosaicRule: function() {
getMosaicRule: function () {
return this.params.mosaicRule;
},
getRenderingRule: function() {
getRenderingRule: function () {
return this.params.renderingRule;
},
getPixelSize: function() {
getPixelSize: function () {
return this.params.pixelSize;
},
run: function (callback, context){
return this.request(function(error, response){
run: function (callback, context) {
return this.request(function (error, response) {
callback.call(context, error, (response && this._responseToGeoJSON(response)), response);

@@ -51,7 +55,7 @@ }, this);

// merging in any catalogItemVisibilities as a propery of each feature
_responseToGeoJSON: function(response) {
_responseToGeoJSON: function (response) {
var location = response.location;
var catalogItems = response.catalogItems;
var catalogItemVisibilities = response.catalogItemVisibilities;
var geoJSON = {
var geoJSON = {
'pixel': {

@@ -77,7 +81,9 @@ 'type': 'Feature',

};
if (response.properties && response.properties.Values) {
geoJSON.pixel.properties.values = response.properties.Values;
}
if (catalogItems && catalogItems.features) {
geoJSON.catalogItems = EsriLeaflet.Util.responseToFeatureCollection(catalogItems);
geoJSON.catalogItems = Util.responseToFeatureCollection(catalogItems);
if (catalogItemVisibilities && catalogItemVisibilities.length === geoJSON.catalogItems.features.length) {

@@ -94,4 +100,6 @@ for (var i = catalogItemVisibilities.length - 1; i >= 0; i--) {

EsriLeaflet.Tasks.identifyImage = function(params){
return new EsriLeaflet.Tasks.IdentifyImage(params);
};
export function identifyImage (params) {
return new IdentifyImage(params);
}
export default identifyImage;

@@ -1,2 +0,6 @@

EsriLeaflet.Tasks.Query = EsriLeaflet.Tasks.Task.extend({
import L from 'leaflet';
import { Task } from './Task.js';
import Util from '../Util.js';
export var Query = Task.extend({
setters: {

@@ -21,3 +25,3 @@ 'offset': 'offset',

within: function(geometry){
within: function (geometry) {
this._setGeometry(geometry);

@@ -28,3 +32,3 @@ this.params.spatialRel = 'esriSpatialRelContains'; // will make code read layer within geometry, to the api this will reads geometry contains layer

intersects: function(geometry){
intersects: function (geometry) {
this._setGeometry(geometry);

@@ -35,3 +39,3 @@ this.params.spatialRel = 'esriSpatialRelIntersects';

contains: function(geometry){
contains: function (geometry) {
this._setGeometry(geometry);

@@ -42,15 +46,15 @@ this.params.spatialRel = 'esriSpatialRelWithin'; // will make code read layer contains geometry, to the api this will reads geometry within layer

// crosses: function(geometry){
// this._setGeometry(geometry);
// this.params.spatialRel = 'esriSpatialRelCrosses';
// return this;
// },
crosses: function (geometry) {
this._setGeometry(geometry);
this.params.spatialRel = 'esriSpatialRelCrosses';
return this;
},
// touches: function(geometry){
// this._setGeometry(geometry);
// this.params.spatialRel = 'esriSpatialRelTouches';
// return this;
// },
touches: function (geometry) {
this._setGeometry(geometry);
this.params.spatialRel = 'esriSpatialRelTouches';
return this;
},
overlaps: function(geometry){
overlaps: function (geometry) {
this._setGeometry(geometry);

@@ -62,3 +66,3 @@ this.params.spatialRel = 'esriSpatialRelOverlaps';

// only valid for Feature Services running on ArcGIS Server 10.3 or ArcGIS Online
nearby: function(latlng, radius){
nearby: function (latlng, radius) {
latlng = L.latLng(latlng);

@@ -74,3 +78,3 @@ this.params.geometry = [latlng.lng, latlng.lat];

where: function(string){
where: function (string) {
// instead of converting double-quotes to single quotes, pass as is, and provide a more informative message if a 400 is encountered

@@ -81,3 +85,3 @@ this.params.where = string;

between: function(start, end){
between: function (start, end) {
this.params.time = [start.valueOf(), end.valueOf()];

@@ -87,3 +91,3 @@ return this;

simplify: function(map, factor){
simplify: function (map, factor) {
var mapWidth = Math.abs(map.getBounds().getWest() - map.getBounds().getEast());

@@ -94,3 +98,3 @@ this.params.maxAllowableOffset = (mapWidth / map.getSize().y) * factor;

orderBy: function(fieldName, order){
orderBy: function (fieldName, order) {
order = order || 'ASC';

@@ -102,10 +106,10 @@ this.params.orderByFields = (this.params.orderByFields) ? this.params.orderByFields + ',' : '';

run: function(callback, context){
run: function (callback, context) {
this._cleanParams();
// if the service is hosted on arcgis online request geojson directly
if(EsriLeaflet.Util.isArcgisOnline(this.options.url)){
if (Util.isArcgisOnline(this.options.url)) {
this.params.f = 'geojson';
return this.request(function(error, response){
return this.request(function (error, response) {
this._trapSQLerrors(error);

@@ -117,5 +121,5 @@ callback.call(context, error, response, response);

} else {
return this.request(function(error, response){
return this.request(function (error, response) {
this._trapSQLerrors(error);
callback.call(context, error, (response && EsriLeaflet.Util.responseToFeatureCollection(response)), response);
callback.call(context, error, (response && Util.responseToFeatureCollection(response)), response);
}, this);

@@ -125,6 +129,6 @@ }

count: function(callback, context){
count: function (callback, context) {
this._cleanParams();
this.params.returnCountOnly = true;
return this.request(function(error, response){
return this.request(function (error, response) {
callback.call(this, error, (response && response.count), response);

@@ -134,6 +138,6 @@ }, context);

ids: function(callback, context){
ids: function (callback, context) {
this._cleanParams();
this.params.returnIdsOnly = true;
return this.request(function(error, response){
return this.request(function (error, response) {
callback.call(this, error, (response && response.objectIds), response);

@@ -144,7 +148,7 @@ }, context);

// only valid for Feature Services running on ArcGIS Server 10.3 or ArcGIS Online
bounds: function(callback, context){
bounds: function (callback, context) {
this._cleanParams();
this.params.returnExtentOnly = true;
return this.request(function(error, response){
callback.call(context, error, (response && response.extent && EsriLeaflet.Util.extentToBounds(response.extent)), response);
return this.request(function (error, response) {
callback.call(context, error, (response && response.extent && Util.extentToBounds(response.extent)), response);
}, context);

@@ -154,5 +158,5 @@ },

// only valid for image services
pixelSize: function(point){
pixelSize: function (point) {
point = L.point(point);
this.params.pixelSize = [point.x,point.y];
this.params.pixelSize = [point.x, point.y];
return this;

@@ -162,3 +166,3 @@ },

// only valid for map services
layer: function(layer){
layer: function (layer) {
this.path = layer + '/query';

@@ -168,6 +172,6 @@ return this;

_trapSQLerrors: function(error){
if (error){
if (error.code === '400'){
EsriLeaflet.Util.warn('one common syntax error in query requests is encasing string values in double quotes instead of single quotes');
_trapSQLerrors: function (error) {
if (error) {
if (error.code === '400') {
Util.warn('one common syntax error in query requests is encasing string values in double quotes instead of single quotes');
}

@@ -177,3 +181,3 @@ }

_cleanParams: function(){
_cleanParams: function () {
delete this.params.returnIdsOnly;

@@ -184,9 +188,9 @@ delete this.params.returnExtentOnly;

_setGeometry: function(geometry) {
_setGeometry: function (geometry) {
this.params.inSr = 4326;
// convert bounds to extent and finish
if ( geometry instanceof L.LatLngBounds ) {
if (geometry instanceof L.LatLngBounds) {
// set geometry + geometryType
this.params.geometry = EsriLeaflet.Util.boundsToExtent(geometry);
this.params.geometry = Util.boundsToExtent(geometry);
this.params.geometryType = 'esriGeometryEnvelope';

@@ -197,3 +201,3 @@ return;

// convert L.Marker > L.LatLng
if(geometry.getLatLng){
if (geometry.getLatLng) {
geometry = geometry.getLatLng();

@@ -211,7 +215,7 @@ }

// handle L.GeoJSON, pull out the first geometry
if ( geometry instanceof L.GeoJSON ) {
//reassign geometry to the GeoJSON value (we are assuming that only one feature is present)
if (geometry instanceof L.GeoJSON) {
// reassign geometry to the GeoJSON value (we are assuming that only one feature is present)
geometry = geometry.getLayers()[0].feature.geometry;
this.params.geometry = EsriLeaflet.Util.geojsonToArcGIS(geometry);
this.params.geometryType = EsriLeaflet.Util.geojsonTypeToArcGIS(geometry.type);
this.params.geometry = Util.geojsonToArcGIS(geometry);
this.params.geometryType = Util.geojsonTypeToArcGIS(geometry.type);
}

@@ -225,3 +229,3 @@

// handle GeoJSON feature by pulling out the geometry
if ( geometry.type === 'Feature' ) {
if (geometry.type === 'Feature') {
// get the geometry of the geojson feature

@@ -232,5 +236,5 @@ geometry = geometry.geometry;

// confirm that our GeoJSON is a point, line or polygon
if ( geometry.type === 'Point' || geometry.type === 'LineString' || geometry.type === 'Polygon') {
this.params.geometry = EsriLeaflet.Util.geojsonToArcGIS(geometry);
this.params.geometryType = EsriLeaflet.Util.geojsonTypeToArcGIS(geometry.type);
if (geometry.type === 'Point' || geometry.type === 'LineString' || geometry.type === 'Polygon') {
this.params.geometry = Util.geojsonToArcGIS(geometry);
this.params.geometryType = Util.geojsonTypeToArcGIS(geometry.type);
return;

@@ -241,3 +245,3 @@ }

/* global console */
EsriLeaflet.Util.warn('invalid geometry passed to spatial query. Should be an L.LatLng, L.LatLngBounds or L.Marker or a GeoJSON Point Line or Polygon object');
Util.warn('invalid geometry passed to spatial query. Should be an L.LatLng, L.LatLngBounds or L.Marker or a GeoJSON Point Line or Polygon object');

@@ -248,4 +252,6 @@ return;

EsriLeaflet.Tasks.query = function(params){
return new EsriLeaflet.Tasks.Query(params);
};
export function query (options) {
return new Query(options);
}
export default query;

@@ -1,11 +0,16 @@

EsriLeaflet.Tasks.Task = L.Class.extend({
import L from 'leaflet';
import {cors} from '../Support.js';
import {cleanUrl} from '../Util.js';
import Request from '../Request.js';
export var Task = L.Class.extend({
options: {
proxy: false,
useCors: EsriLeaflet.Support.CORS
useCors: cors
},
//Generate a method for each methodName:paramName in the setters for this task.
generateSetter: function(param, context){
return L.Util.bind(function(value){
// Generate a method for each methodName:paramName in the setters for this task.
generateSetter: function (param, context) {
return L.Util.bind(function (value) {
this.params[param] = value;

@@ -16,5 +21,5 @@ return this;

initialize: function(endpoint){
initialize: function (endpoint) {
// endpoint can be either a url (and options) for an ArcGIS Rest Service or an instance of EsriLeaflet.Service
if(endpoint.request && endpoint.options){
if (endpoint.request && endpoint.options) {
this._service = endpoint;

@@ -24,3 +29,3 @@ L.Util.setOptions(this, endpoint.options);

L.Util.setOptions(this, endpoint);
this.options.url = L.esri.Util.cleanUrl(endpoint.url);
this.options.url = cleanUrl(endpoint.url);
}

@@ -32,4 +37,4 @@

// generate setter methods based on the setters object implimented a child class
if(this.setters){
for (var setter in this.setters){
if (this.setters) {
for (var setter in this.setters) {
var param = this.setters[setter];

@@ -41,4 +46,4 @@ this[setter] = this.generateSetter(param, this);

token: function(token){
if(this._service){
token: function (token) {
if (this._service) {
this._service.authenticate(token);

@@ -51,18 +56,25 @@ } else {

request: function(callback, context){
if(this._service){
request: function (callback, context) {
if (this._service) {
return this._service.request(this.path, this.params, callback, context);
} else {
return this._request('request', this.path, this.params, callback, context);
}
return this._request('request', this.path, this.params, callback, context);
},
_request: function(method, path, params, callback, context){
_request: function (method, path, params, callback, context) {
var url = (this.options.proxy) ? this.options.proxy + '?' + this.options.url + path : this.options.url + path;
if((method === 'get' || method === 'request') && !this.options.useCors){
return EsriLeaflet.Request.get.JSONP(url, params, callback, context);
} else{
return EsriLeaflet[method](url, params, callback, context);
if ((method === 'get' || method === 'request') && !this.options.useCors) {
return Request.get.JSONP(url, params, callback, context);
}
return Request[method](url, params, callback, context);
}
});
});
export function task (options) {
return new Task(options);
}
export default task;

@@ -1,442 +0,449 @@

(function(EsriLeaflet){
import L from 'leaflet';
// normalize request animation frame
var raf = window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(cb) { return window.setTimeout(cb, 1000 / 60); };
// shallow object clone for feature properties and attributes
// from http://jsperf.com/cloning-an-object/2
function clone(obj) {
var target = {};
for (var i in obj) {
if (obj.hasOwnProperty(i)) {
target[i] = obj[i];
}
// checks if 2 x,y points are equal
function pointsEqual (a, b) {
for (var i = 0; i < a.length; i++) {
if (a[i] !== b[i]) {
return false;
}
return target;
}
return true;
}
// checks if 2 x,y points are equal
function pointsEqual(a, b) {
for (var i = 0; i < a.length; i++) {
if (a[i] !== b[i]) {
return false;
}
}
return true;
// checks if the first and last points of a ring are equal and closes the ring
function closeRing (coordinates) {
if (!pointsEqual(coordinates[0], coordinates[coordinates.length - 1])) {
coordinates.push(coordinates[0]);
}
return coordinates;
}
// checks if the first and last points of a ring are equal and closes the ring
function closeRing(coordinates) {
if (!pointsEqual(coordinates[0], coordinates[coordinates.length - 1])) {
coordinates.push(coordinates[0]);
}
return coordinates;
// determine if polygon ring coordinates are clockwise. clockwise signifies outer ring, counter-clockwise an inner ring
// or hole. this logic was found at http://stackoverflow.com/questions/1165647/how-to-determine-if-a-list-of-polygon-
// points-are-in-clockwise-order
function ringIsClockwise (ringToTest) {
var total = 0;
var i = 0;
var rLength = ringToTest.length;
var pt1 = ringToTest[i];
var pt2;
for (i; i < rLength - 1; i++) {
pt2 = ringToTest[i + 1];
total += (pt2[0] - pt1[0]) * (pt2[1] + pt1[1]);
pt1 = pt2;
}
return (total >= 0);
}
// determine if polygon ring coordinates are clockwise. clockwise signifies outer ring, counter-clockwise an inner ring
// or hole. this logic was found at http://stackoverflow.com/questions/1165647/how-to-determine-if-a-list-of-polygon-
// points-are-in-clockwise-order
function ringIsClockwise(ringToTest) {
var total = 0,i = 0;
var rLength = ringToTest.length;
var pt1 = ringToTest[i];
var pt2;
for (i; i < rLength - 1; i++) {
pt2 = ringToTest[i + 1];
total += (pt2[0] - pt1[0]) * (pt2[1] + pt1[1]);
pt1 = pt2;
// ported from terraformer.js https://github.com/Esri/Terraformer/blob/master/terraformer.js#L504-L519
function vertexIntersectsVertex (a1, a2, b1, b2) {
var uaT = (b2[0] - b1[0]) * (a1[1] - b1[1]) - (b2[1] - b1[1]) * (a1[0] - b1[0]);
var ubT = (a2[0] - a1[0]) * (a1[1] - b1[1]) - (a2[1] - a1[1]) * (a1[0] - b1[0]);
var uB = (b2[1] - b1[1]) * (a2[0] - a1[0]) - (b2[0] - b1[0]) * (a2[1] - a1[1]);
if (uB !== 0) {
var ua = uaT / uB;
var ub = ubT / uB;
if (ua >= 0 && ua <= 1 && ub >= 0 && ub <= 1) {
return true;
}
return (total >= 0);
}
// ported from terraformer.js https://github.com/Esri/Terraformer/blob/master/terraformer.js#L504-L519
function vertexIntersectsVertex(a1, a2, b1, b2) {
var uaT = (b2[0] - b1[0]) * (a1[1] - b1[1]) - (b2[1] - b1[1]) * (a1[0] - b1[0]);
var ubT = (a2[0] - a1[0]) * (a1[1] - b1[1]) - (a2[1] - a1[1]) * (a1[0] - b1[0]);
var uB = (b2[1] - b1[1]) * (a2[0] - a1[0]) - (b2[0] - b1[0]) * (a2[1] - a1[1]);
return false;
}
if ( uB !== 0 ) {
var ua = uaT / uB;
var ub = ubT / uB;
if ( 0 <= ua && ua <= 1 && 0 <= ub && ub <= 1 ) {
// ported from terraformer.js https://github.com/Esri/Terraformer/blob/master/terraformer.js#L521-L531
function arrayIntersectsArray (a, b) {
for (var i = 0; i < a.length - 1; i++) {
for (var j = 0; j < b.length - 1; j++) {
if (vertexIntersectsVertex(a[i], a[i + 1], b[j], b[j + 1])) {
return true;
}
}
return false;
}
// ported from terraformer.js https://github.com/Esri/Terraformer/blob/master/terraformer.js#L521-L531
function arrayIntersectsArray(a, b) {
for (var i = 0; i < a.length - 1; i++) {
for (var j = 0; j < b.length - 1; j++) {
if (vertexIntersectsVertex(a[i], a[i + 1], b[j], b[j + 1])) {
return true;
}
}
}
return false;
}
return false;
}
// ported from terraformer.js https://github.com/Esri/Terraformer/blob/master/terraformer.js#L470-L480
function coordinatesContainPoint(coordinates, point) {
var contains = false;
for(var i = -1, l = coordinates.length, j = l - 1; ++i < l; j = i) {
if (((coordinates[i][1] <= point[1] && point[1] < coordinates[j][1]) ||
(coordinates[j][1] <= point[1] && point[1] < coordinates[i][1])) &&
(point[0] < (coordinates[j][0] - coordinates[i][0]) * (point[1] - coordinates[i][1]) / (coordinates[j][1] - coordinates[i][1]) + coordinates[i][0])) {
contains = !contains;
}
// ported from terraformer.js https://github.com/Esri/Terraformer/blob/master/terraformer.js#L470-L480
function coordinatesContainPoint (coordinates, point) {
var contains = false;
for (var i = -1, l = coordinates.length, j = l - 1; ++i < l; j = i) {
if (((coordinates[i][1] <= point[1] && point[1] < coordinates[j][1]) ||
(coordinates[j][1] <= point[1] && point[1] < coordinates[i][1])) &&
(point[0] < (coordinates[j][0] - coordinates[i][0]) * (point[1] - coordinates[i][1]) / (coordinates[j][1] - coordinates[i][1]) + coordinates[i][0])) {
contains = !contains;
}
return contains;
}
return contains;
}
// ported from terraformer-arcgis-parser.js https://github.com/Esri/terraformer-arcgis-parser/blob/master/terraformer-arcgis-parser.js#L106-L113
function coordinatesContainCoordinates(outer, inner){
var intersects = arrayIntersectsArray(outer, inner);
var contains = coordinatesContainPoint(outer, inner[0]);
if(!intersects && contains){
return true;
}
return false;
// ported from terraformer-arcgis-parser.js https://github.com/Esri/terraformer-arcgis-parser/blob/master/terraformer-arcgis-parser.js#L106-L113
function coordinatesContainCoordinates (outer, inner) {
var intersects = arrayIntersectsArray(outer, inner);
var contains = coordinatesContainPoint(outer, inner[0]);
if (!intersects && contains) {
return true;
}
return false;
}
// do any polygons in this array contain any other polygons in this array?
// used for checking for holes in arcgis rings
// ported from terraformer-arcgis-parser.js https://github.com/Esri/terraformer-arcgis-parser/blob/master/terraformer-arcgis-parser.js#L117-L172
function convertRingsToGeoJSON(rings){
var outerRings = [];
var holes = [];
var x; // iterator
var outerRing; // current outer ring being evaluated
var hole; // current hole being evaluated
// do any polygons in this array contain any other polygons in this array?
// used for checking for holes in arcgis rings
// ported from terraformer-arcgis-parser.js https://github.com/Esri/terraformer-arcgis-parser/blob/master/terraformer-arcgis-parser.js#L117-L172
function convertRingsToGeoJSON (rings) {
var outerRings = [];
var holes = [];
var x; // iterator
var outerRing; // current outer ring being evaluated
var hole; // current hole being evaluated
// for each ring
for (var r = 0; r < rings.length; r++) {
var ring = closeRing(rings[r].slice(0));
if(ring.length < 4){
continue;
}
// is this ring an outer ring? is it clockwise?
if(ringIsClockwise(ring)){
var polygon = [ ring ];
outerRings.push(polygon); // push to outer rings
} else {
holes.push(ring); // counterclockwise push to holes
}
// for each ring
for (var r = 0; r < rings.length; r++) {
var ring = closeRing(rings[r].slice(0));
if (ring.length < 4) {
continue;
}
// is this ring an outer ring? is it clockwise?
if (ringIsClockwise(ring)) {
var polygon = [ ring ];
outerRings.push(polygon); // push to outer rings
} else {
holes.push(ring); // counterclockwise push to holes
}
}
var uncontainedHoles = [];
var uncontainedHoles = [];
// while there are holes left...
while(holes.length){
// pop a hole off out stack
hole = holes.pop();
// while there are holes left...
while (holes.length) {
// pop a hole off out stack
hole = holes.pop();
// loop over all outer rings and see if they contain our hole.
var contained = false;
for (x = outerRings.length - 1; x >= 0; x--) {
outerRing = outerRings[x][0];
if(coordinatesContainCoordinates(outerRing, hole)){
// the hole is contained push it into our polygon
outerRings[x].push(hole);
contained = true;
break;
}
// loop over all outer rings and see if they contain our hole.
var contained = false;
for (x = outerRings.length - 1; x >= 0; x--) {
outerRing = outerRings[x][0];
if (coordinatesContainCoordinates(outerRing, hole)) {
// the hole is contained push it into our polygon
outerRings[x].push(hole);
contained = true;
break;
}
}
// ring is not contained in any outer ring
// sometimes this happens https://github.com/Esri/esri-leaflet/issues/320
if(!contained){
uncontainedHoles.push(hole);
}
// ring is not contained in any outer ring
// sometimes this happens https://github.com/Esri/esri-leaflet/issues/320
if (!contained) {
uncontainedHoles.push(hole);
}
}
// if we couldn't match any holes using contains we can try intersects...
while(uncontainedHoles.length){
// pop a hole off out stack
hole = uncontainedHoles.pop();
// if we couldn't match any holes using contains we can try intersects...
while (uncontainedHoles.length) {
// pop a hole off out stack
hole = uncontainedHoles.pop();
// loop over all outer rings and see if any intersect our hole.
var intersects = false;
for (x = outerRings.length - 1; x >= 0; x--) {
outerRing = outerRings[x][0];
if(arrayIntersectsArray(outerRing, hole)){
// the hole is contained push it into our polygon
outerRings[x].push(hole);
intersects = true;
break;
}
}
// loop over all outer rings and see if any intersect our hole.
var intersects = false;
if(!intersects) {
outerRings.push([hole.reverse()]);
for (x = outerRings.length - 1; x >= 0; x--) {
outerRing = outerRings[x][0];
if (arrayIntersectsArray(outerRing, hole)) {
// the hole is contained push it into our polygon
outerRings[x].push(hole);
intersects = true;
break;
}
}
if(outerRings.length === 1){
return {
type: 'Polygon',
coordinates: outerRings[0]
};
} else {
return {
type: 'MultiPolygon',
coordinates: outerRings
};
if (!intersects) {
outerRings.push([hole.reverse()]);
}
}
// This function ensures that rings are oriented in the right directions
// outer rings are clockwise, holes are counterclockwise
// used for converting GeoJSON Polygons to ArcGIS Polygons
function orientRings(poly){
var output = [];
var polygon = poly.slice(0);
var outerRing = closeRing(polygon.shift().slice(0));
if(outerRing.length >= 4){
if(!ringIsClockwise(outerRing)){
outerRing.reverse();
}
if (outerRings.length === 1) {
return {
type: 'Polygon',
coordinates: outerRings[0]
};
} else {
return {
type: 'MultiPolygon',
coordinates: outerRings
};
}
}
output.push(outerRing);
// This function ensures that rings are oriented in the right directions
// outer rings are clockwise, holes are counterclockwise
// used for converting GeoJSON Polygons to ArcGIS Polygons
function orientRings (poly) {
var output = [];
var polygon = poly.slice(0);
var outerRing = closeRing(polygon.shift().slice(0));
if (outerRing.length >= 4) {
if (!ringIsClockwise(outerRing)) {
outerRing.reverse();
}
for (var i = 0; i < polygon.length; i++) {
var hole = closeRing(polygon[i].slice(0));
if(hole.length >= 4){
if(ringIsClockwise(hole)){
hole.reverse();
}
output.push(hole);
output.push(outerRing);
for (var i = 0; i < polygon.length; i++) {
var hole = closeRing(polygon[i].slice(0));
if (hole.length >= 4) {
if (ringIsClockwise(hole)) {
hole.reverse();
}
output.push(hole);
}
}
}
return output;
return output;
}
// This function flattens holes in multipolygons to one array of polygons
// used for converting GeoJSON Polygons to ArcGIS Polygons
function flattenMultiPolygonRings (rings) {
var output = [];
for (var i = 0; i < rings.length; i++) {
var polygon = orientRings(rings[i]);
for (var x = polygon.length - 1; x >= 0; x--) {
var ring = polygon[x].slice(0);
output.push(ring);
}
}
return output;
}
// This function flattens holes in multipolygons to one array of polygons
// used for converting GeoJSON Polygons to ArcGIS Polygons
function flattenMultiPolygonRings(rings){
var output = [];
for (var i = 0; i < rings.length; i++) {
var polygon = orientRings(rings[i]);
for (var x = polygon.length - 1; x >= 0; x--) {
var ring = polygon[x].slice(0);
output.push(ring);
}
// shallow object clone for feature properties and attributes
// from http://jsperf.com/cloning-an-object/2
function shallowClone (obj) {
var target = {};
for (var i in obj) {
if (obj.hasOwnProperty(i)) {
target[i] = obj[i];
}
return output;
}
return target;
}
// convert an extent (ArcGIS) to LatLngBounds (Leaflet)
EsriLeaflet.Util.extentToBounds = function(extent){
var sw = new L.LatLng(extent.ymin, extent.xmin);
var ne = new L.LatLng(extent.ymax, extent.xmax);
return new L.LatLngBounds(sw, ne);
};
// convert an extent (ArcGIS) to LatLngBounds (Leaflet)
export function extentToBounds (extent) {
var sw = L.latLng(extent.ymin, extent.xmin);
var ne = L.latLng(extent.ymax, extent.xmax);
return new L.LatLngBounds(sw, ne);
}
// convert an LatLngBounds (Leaflet) to extent (ArcGIS)
EsriLeaflet.Util.boundsToExtent = function(bounds) {
bounds = L.latLngBounds(bounds);
return {
'xmin': bounds.getSouthWest().lng,
'ymin': bounds.getSouthWest().lat,
'xmax': bounds.getNorthEast().lng,
'ymax': bounds.getNorthEast().lat,
'spatialReference': {
'wkid' : 4326
}
};
// convert an LatLngBounds (Leaflet) to extent (ArcGIS)
export function boundsToExtent (bounds) {
bounds = L.latLngBounds(bounds);
return {
'xmin': bounds.getSouthWest().lng,
'ymin': bounds.getSouthWest().lat,
'xmax': bounds.getNorthEast().lng,
'ymax': bounds.getNorthEast().lat,
'spatialReference': {
'wkid': 4326
}
};
}
EsriLeaflet.Util.arcgisToGeojson = function (arcgis, idAttribute){
var geojson = {};
export function arcgisToGeojson (arcgis, idAttribute) {
var geojson = {};
if(typeof arcgis.x === 'number' && typeof arcgis.y === 'number'){
geojson.type = 'Point';
geojson.coordinates = [arcgis.x, arcgis.y];
}
if (typeof arcgis.x === 'number' && typeof arcgis.y === 'number') {
geojson.type = 'Point';
geojson.coordinates = [arcgis.x, arcgis.y];
}
if(arcgis.points){
geojson.type = 'MultiPoint';
geojson.coordinates = arcgis.points.slice(0);
}
if (arcgis.points) {
geojson.type = 'MultiPoint';
geojson.coordinates = arcgis.points.slice(0);
}
if(arcgis.paths) {
if(arcgis.paths.length === 1){
geojson.type = 'LineString';
geojson.coordinates = arcgis.paths[0].slice(0);
} else {
geojson.type = 'MultiLineString';
geojson.coordinates = arcgis.paths.slice(0);
}
if (arcgis.paths) {
if (arcgis.paths.length === 1) {
geojson.type = 'LineString';
geojson.coordinates = arcgis.paths[0].slice(0);
} else {
geojson.type = 'MultiLineString';
geojson.coordinates = arcgis.paths.slice(0);
}
}
if(arcgis.rings) {
geojson = convertRingsToGeoJSON(arcgis.rings.slice(0));
}
if (arcgis.rings) {
geojson = convertRingsToGeoJSON(arcgis.rings.slice(0));
}
if(arcgis.geometry || arcgis.attributes) {
geojson.type = 'Feature';
geojson.geometry = (arcgis.geometry) ? EsriLeaflet.Util.arcgisToGeojson(arcgis.geometry) : null;
geojson.properties = (arcgis.attributes) ? clone(arcgis.attributes) : null;
if(arcgis.attributes) {
geojson.id = arcgis.attributes[idAttribute] || arcgis.attributes.OBJECTID || arcgis.attributes.FID;
}
if (arcgis.geometry || arcgis.attributes) {
geojson.type = 'Feature';
geojson.geometry = (arcgis.geometry) ? arcgisToGeojson(arcgis.geometry) : null;
geojson.properties = (arcgis.attributes) ? shallowClone(arcgis.attributes) : null;
if (arcgis.attributes) {
geojson.id = arcgis.attributes[idAttribute] || arcgis.attributes.OBJECTID || arcgis.attributes.FID;
}
}
return geojson;
};
return geojson;
}
// GeoJSON -> ArcGIS
EsriLeaflet.Util.geojsonToArcGIS = function(geojson, idAttribute){
idAttribute = idAttribute || 'OBJECTID';
var spatialReference = { wkid: 4326 };
var result = {};
var i;
// GeoJSON -> ArcGIS
export function geojsonToArcGIS (geojson, idAttribute) {
idAttribute = idAttribute || 'OBJECTID';
var spatialReference = { wkid: 4326 };
var result = {};
var i;
switch(geojson.type){
case 'Point':
result.x = geojson.coordinates[0];
result.y = geojson.coordinates[1];
result.spatialReference = spatialReference;
break;
case 'MultiPoint':
result.points = geojson.coordinates.slice(0);
result.spatialReference = spatialReference;
break;
case 'LineString':
result.paths = [geojson.coordinates.slice(0)];
result.spatialReference = spatialReference;
break;
case 'MultiLineString':
result.paths = geojson.coordinates.slice(0);
result.spatialReference = spatialReference;
break;
case 'Polygon':
result.rings = orientRings(geojson.coordinates.slice(0));
result.spatialReference = spatialReference;
break;
case 'MultiPolygon':
result.rings = flattenMultiPolygonRings(geojson.coordinates.slice(0));
result.spatialReference = spatialReference;
break;
case 'Feature':
if(geojson.geometry) {
result.geometry = EsriLeaflet.Util.geojsonToArcGIS(geojson.geometry, idAttribute);
}
result.attributes = (geojson.properties) ? clone(geojson.properties) : {};
if(geojson.id){
result.attributes[idAttribute] = geojson.id;
}
break;
case 'FeatureCollection':
result = [];
for (i = 0; i < geojson.features.length; i++){
result.push(EsriLeaflet.Util.geojsonToArcGIS(geojson.features[i], idAttribute));
}
break;
case 'GeometryCollection':
result = [];
for (i = 0; i < geojson.geometries.length; i++){
result.push(EsriLeaflet.Util.geojsonToArcGIS(geojson.geometries[i], idAttribute));
}
break;
switch (geojson.type) {
case 'Point':
result.x = geojson.coordinates[0];
result.y = geojson.coordinates[1];
result.spatialReference = spatialReference;
break;
case 'MultiPoint':
result.points = geojson.coordinates.slice(0);
result.spatialReference = spatialReference;
break;
case 'LineString':
result.paths = [geojson.coordinates.slice(0)];
result.spatialReference = spatialReference;
break;
case 'MultiLineString':
result.paths = geojson.coordinates.slice(0);
result.spatialReference = spatialReference;
break;
case 'Polygon':
result.rings = orientRings(geojson.coordinates.slice(0));
result.spatialReference = spatialReference;
break;
case 'MultiPolygon':
result.rings = flattenMultiPolygonRings(geojson.coordinates.slice(0));
result.spatialReference = spatialReference;
break;
case 'Feature':
if (geojson.geometry) {
result.geometry = geojsonToArcGIS(geojson.geometry, idAttribute);
}
result.attributes = (geojson.properties) ? shallowClone(geojson.properties) : {};
if (geojson.id) {
result.attributes[idAttribute] = geojson.id;
}
break;
case 'FeatureCollection':
result = [];
for (i = 0; i < geojson.features.length; i++) {
result.push(geojsonToArcGIS(geojson.features[i], idAttribute));
}
break;
case 'GeometryCollection':
result = [];
for (i = 0; i < geojson.geometries.length; i++) {
result.push(geojsonToArcGIS(geojson.geometries[i], idAttribute));
}
break;
}
return result;
};
return result;
}
EsriLeaflet.Util.responseToFeatureCollection = function(response, idAttribute){
var objectIdField;
export function responseToFeatureCollection (response, idAttribute) {
var objectIdField;
if(idAttribute){
objectIdField = idAttribute;
} else if(response.objectIdFieldName){
objectIdField = response.objectIdFieldName;
} else if(response.fields) {
for (var j = 0; j <= response.fields.length - 1; j++) {
if(response.fields[j].type === 'esriFieldTypeOID') {
objectIdField = response.fields[j].name;
break;
}
if (idAttribute) {
objectIdField = idAttribute;
} else if (response.objectIdFieldName) {
objectIdField = response.objectIdFieldName;
} else if (response.fields) {
for (var j = 0; j <= response.fields.length - 1; j++) {
if (response.fields[j].type === 'esriFieldTypeOID') {
objectIdField = response.fields[j].name;
break;
}
} else {
objectIdField = 'OBJECTID';
}
} else {
objectIdField = 'OBJECTID';
}
var featureCollection = {
type: 'FeatureCollection',
features: []
};
var features = response.features || response.results;
if(features.length){
for (var i = features.length - 1; i >= 0; i--) {
featureCollection.features.push(EsriLeaflet.Util.arcgisToGeojson(features[i], objectIdField));
}
var featureCollection = {
type: 'FeatureCollection',
features: []
};
var features = response.features || response.results;
if (features.length) {
for (var i = features.length - 1; i >= 0; i--) {
featureCollection.features.push(arcgisToGeojson(features[i], objectIdField));
}
}
return featureCollection;
};
return featureCollection;
}
// trim url whitespace and add a trailing slash if needed
EsriLeaflet.Util.cleanUrl = function(url){
//trim leading and trailing spaces, but not spaces inside the url
url = url.replace(/^\s+|\s+$|\A\s+|\s+\z/g, '');
// trim url whitespace and add a trailing slash if needed
export function cleanUrl (url) {
// trim leading and trailing spaces, but not spaces inside the url
url = L.Util.trim(url);
//add a trailing slash to the url if the user omitted it
if(url[url.length-1] !== '/'){
url += '/';
}
// add a trailing slash to the url if the user omitted it
if (url[url.length - 1] !== '/') {
url += '/';
}
return url;
};
return url;
}
EsriLeaflet.Util.isArcgisOnline = function(url){
/* hosted feature services can emit geojson natively.
our check for 'geojson' support will need to be revisted
once the functionality makes its way to ArcGIS Server*/
return (/\.arcgis\.com.*?FeatureServer/g).test(url);
};
export function isArcgisOnline (url) {
/* hosted feature services can emit geojson natively.
our check for 'geojson' support will need to be revisted
once the functionality makes its way to ArcGIS Server*/
return (/\.arcgis\.com.*?FeatureServer/g).test(url);
}
EsriLeaflet.Util.geojsonTypeToArcGIS = function (geoJsonType) {
var arcgisGeometryType;
switch (geoJsonType) {
case 'Point':
arcgisGeometryType = 'esriGeometryPoint';
break;
case 'MultiPoint':
arcgisGeometryType = 'esriGeometryMultipoint';
break;
case 'LineString':
arcgisGeometryType = 'esriGeometryPolyline';
break;
case 'MultiLineString':
arcgisGeometryType = 'esriGeometryPolyline';
break;
case 'Polygon':
arcgisGeometryType = 'esriGeometryPolygon';
break;
case 'MultiPolygon':
arcgisGeometryType = 'esriGeometryPolygon';
break;
}
return arcgisGeometryType;
};
export function geojsonTypeToArcGIS (geoJsonType) {
var arcgisGeometryType;
switch (geoJsonType) {
case 'Point':
arcgisGeometryType = 'esriGeometryPoint';
break;
case 'MultiPoint':
arcgisGeometryType = 'esriGeometryMultipoint';
break;
case 'LineString':
arcgisGeometryType = 'esriGeometryPolyline';
break;
case 'MultiLineString':
arcgisGeometryType = 'esriGeometryPolyline';
break;
case 'Polygon':
arcgisGeometryType = 'esriGeometryPolygon';
break;
case 'MultiPolygon':
arcgisGeometryType = 'esriGeometryPolygon';
break;
}
EsriLeaflet.Util.requestAnimationFrame = L.Util.bind(raf, window);
return arcgisGeometryType;
}
EsriLeaflet.Util.warn = function (message) {
if(console && console.warn) {
console.warn(message);
}
};
export function warn () {
if (console && console.warn) {
console.warn.apply(console, arguments);
}
}
})(EsriLeaflet);
export var Util = {
shallowClone: shallowClone,
warn: warn,
cleanUrl: cleanUrl,
isArcgisOnline: isArcgisOnline,
geojsonTypeToArcGIS: geojsonTypeToArcGIS,
responseToFeatureCollection: responseToFeatureCollection,
geojsonToArcGIS: geojsonToArcGIS,
arcgisToGeojson: arcgisToGeojson,
boundsToExtent: boundsToExtent,
extentToBounds: extentToBounds
};
export default Util;

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc