esri-leaflet
Advanced tools
Comparing version 1.0.0 to 2.0.0-beta.1
{ | ||
"name": "esri-leaflet", | ||
"version": "v1.0.0", | ||
"version": "v2.0.0-beta.1", | ||
"main": "dist/esri-leaflet.js", | ||
@@ -5,0 +5,0 @@ "ignore": [ |
156
CHANGELOG.md
@@ -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 |
282
Gruntfile.js
@@ -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` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | ||
| `L.esri.Util` | ✓ | ✓ | ✓ | ✓ | ✓ | | | ||
| `L.esri.Services.Service` | ✓ | ✓ | ✓ | ✓ | ✓ | | | ||
| `L.esri.Services.MapService` | ✓ | | ✓ | | | | | ||
| `L.esri.Services.FeatureLayer` | ✓ | | | | ✓ | | | ||
| `L.esri.Tasks.Task ` | ✓ | ✓ | ✓ | ✓ | ✓ | | | ||
| `L.esri.Tasks.Query` | ✓ | | ✓ | ✓ | ✓ | | | ||
| `L.esri.Tasks.Find` | ✓ | | ✓ | | | | | ||
| `L.esri.Tasks.IdentifyFeatures` | ✓ | | ✓ | | | | | ||
| `L.esri.Tasks.IdentifyImage` | ✓ | | | ✓ | | | | ||
| `L.esri.Layers.FeatureLayer` | ✓ | | | | ✓ | | | ||
| `L.esri.Layers.ImageMapLayer` | ✓ | | | ✓ | | | | ||
| `L.esri.Layers.DynamicMapLayer` | ✓ | | ✓ | | | | | ||
| `L.esri.Layers.TiledMapLayer` | ✓ | | ✓ | | | | | ||
| `L.esri.Layers.BasemapLayer` | ✓ | | | | | ✓ | |
@@ -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; |
729
src/Util.js
@@ -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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
0
1
2480257
30
174
11889
161
+ Addedleaflet@1.0.0-beta.1(transitive)
- Removedleaflet@0.7.7(transitive)
Updatedleaflet@1.0.0-beta.1