Skip to content

Commit

Permalink
88-enterprise-support (#97)
Browse files Browse the repository at this point in the history
* `VectorTileLayer`: added a `portalUrl` option

* Added `f=json` query param to style sources urls.
Some VectorTileServer endpoints default to `f=html` which will break when the underlying mapbox-gl-js communicates with them and expects JSON in return.

* updated README documentation

* updated CHANGELOG
  • Loading branch information
jwasilgeo authored Jul 26, 2021
1 parent fc77c4c commit 6f1d21a
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 15 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).

### Added

* `L.esri.Vector.vectorTileLayer` has been extended to support vector tiles layers hosted in ArcGIS Enterprise. A new `portalUrl` layer constructor option was added and is intended to be used with the "ITEM_ID" constructor flavor. [#97](https://github.com/Esri/esri-leaflet-vector/pull/97)

* New README documentation and a developer console warning for `L.esri.Vector.vectorTileLayer` explaining that only services with a Web Mercator `spatialReference` are fully supported. [#95](https://github.com/Esri/esri-leaflet-vector/pull/95)

## [3.0.1] - 2021-06-03
Expand Down
41 changes: 31 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ Take a look at the [live demo](https://esri.github.io/esri-leaflet/examples/vect
var map = L.map("map").setView([40.706, -73.926], 14);
L.esri.Vector.vectorBasemapLayer("ArcGIS:Streets", {
apikey: "< YOUR VALID API KEY HERE >",
apikey: "< YOUR VALID API KEY HERE >"
}).addTo(map);
</script>
</body>
Expand All @@ -67,17 +67,22 @@ Take a look at the [live demo](https://esri.github.io/esri-leaflet/examples/vect

For rendering basemap layers which use the Esri Basemap Styles API internally. Extends [L.Layer](https://leafletjs.com/reference#layer).


```javascript
// example using an Esri Basemap Styles API name
L.esri.Vector.vectorBasemapLayer("ArcGIS:Streets", {
// provide either apikey or token
// provide either `apikey` or `token`
apikey: "...",
token: "...",
token: "..."
}).addTo(map);
```

```javascript
// example using an ITEM_ID
L.esri.Vector.vectorBasemapLayer("ITEM_ID", {
// provide either apikey or token
// provide either `apikey` or `token`
apikey: "...",
token: "...",
token: "..."
}).addTo(map);
```

Expand All @@ -92,25 +97,41 @@ For custom vector tiles layers published from user data. Extends [L.Layer](https
:warning: This only supports services using the Web Mercator projection because it [relies directly upon `mapbox-gl-js v1`](#dependencies). Otherwise, the layer is not guaranteed to display properly. More information is available at <https://docs.mapbox.com/help/glossary/projection/> and <https://github.com/Esri/esri-leaflet-vector/issues/94>.

```javascript
// example using an ITEM_ID
L.esri.Vector.vectorTileLayer("ITEM_ID", {
// provide either apikey or token if not public
// optional: provide either `apikey` or `token` if not public
apikey: "...",
token: "...",
// optionally customize the style with a function that gets the default style from the service

// optional: if your layer is not hosted on ArcGIS Online,
// change `portalUrl` to the ArcGIS Enterprise base url
// (this is necessary when specifying an ITEM_ID)
portalUrl: "https://www.arcgis.com", // default value

// optional: customize the style with a function that gets the default style from the service
// and returns the new style to be used
style: (style) => {
return newStyle;
}
}).addTo(map);
```

```javascript
// example using a VectorTileServer SERVICE_URL
L.esri.Vector.vectorTileLayer("SERVICE_URL", {
// provide either apikey or token if not public
// optional: provide either `apikey` or `token` if not public
apikey: "...",
token: "...",
// optionally customize the style with a function that gets the default style from the service

// optional: if your layer is not hosted on ArcGIS Online,
// change `portalUrl` to the ArcGIS Enterprise base url
// (this may not be necessary when specifying a SERVICE_URL)
portalUrl: "https://www.arcgis.com", // default value

// optional: customize the style with a function that gets the default style from the service
// and returns the new style to be used
style: (style) => {
return newStyle
return newStyle;
}
}).addTo(map);
```
Expand Down
33 changes: 33 additions & 0 deletions spec/VectorTileLayerSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ var serviceUrl = 'https://tiles.arcgis.com/tiles/P3ePLMYs2RVChkJx/arcgis/rest/se
var token = '1234abcd';
var apikey = 'dcba4321';

// for layers hosted in ArcGIS Enterprise instead of ArcGIS Online
var onPremisePortalUrl = 'https://PATH/TO/ARCGIS/ENTERPRISE'; // defaults to https://www.arcgis.com
var onPremiseItemId = '1c365daf37a744fbad748b67aa69dac8';
var onPremiseServiceUrl = 'https://tiles.arcgis.com/tiles/P3ePLMYs2RVChkJx/arcgis/rest/services/Microsoft_Building_Footprints/VectorTileServer';

describe('VectorTileLayer', function () {
it('should have a L.esri.vectorTileLayer alias', function () {
console.log('L.esri.Vector.vectorTileLayer', L.esri.Vector.vectorTileLayer);
Expand Down Expand Up @@ -64,4 +69,32 @@ describe('VectorTileLayer', function () {

expect(layer.options.pane).to.equal(otherPane);
});

it('should default to ArcGIS Online as the base "portalUrl" for loading the style - itemId', function () {
const layer = L.esri.Vector.vectorTileLayer(itemId);

expect(layer.options.portalUrl).to.equal('https://www.arcgis.com');
});

it('should default to ArcGIS Online as the base "portalUrl" for loading the style - serviceUrl', function () {
const layer = L.esri.Vector.vectorTileLayer(serviceUrl);

expect(layer.options.portalUrl).to.equal('https://www.arcgis.com');
});

it('should let the base "portalUrl" be changed in the constructor for loading an on-premise style - itemId', function () {
const layer = L.esri.Vector.vectorTileLayer(onPremiseItemId, {
portalUrl: onPremisePortalUrl
});

expect(layer.options.portalUrl).to.equal(onPremisePortalUrl);
});

it('should let the base "portalUrl" be changed in the constructor for loading an on-premise style - serviceUrl', function () {
const layer = L.esri.Vector.vectorTileLayer(onPremiseServiceUrl, {
portalUrl: onPremisePortalUrl
});

expect(layer.options.portalUrl).to.equal(onPremisePortalUrl);
});
});
13 changes: 10 additions & 3 deletions src/Util.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,16 @@ export function loadService (serviceUrl, options, callback) {

function loadItem (itemId, options, callback) {
var params = options.token ? { token: options.token } : {};
var url = 'https://www.arcgis.com/sharing/rest/content/items/' + itemId;
var url = options.portalUrl +
'/sharing/rest/content/items/' +
itemId;
request(url, params, callback);
}

function loadStyleFromItem (itemId, options, callback) {
var itemStyleUrl =
'https://www.arcgis.com/sharing/rest/content/items/' +
options.portalUrl +
'/sharing/rest/content/items/' +
itemId +
'/resources/styles/root.json';

Expand Down Expand Up @@ -128,8 +131,12 @@ export function formatStyle (style, styleUrl, metadata, token) {
source.tiles = [source.url + metadata.tiles[0]];
}

// some VectorTileServer endpoints may default to returning f=html,
// specify f=json to account for that behavior
source.url += '?f=json';

// add the token to the source url and tiles properties as a query param
source.url += token ? '?token=' + token : '';
source.url += token ? '&token=' + token : '';
source.tiles[0] += token ? '?token=' + token : '';

// add minzoom and maxzoom to each source based on the service metadata
Expand Down
7 changes: 5 additions & 2 deletions src/VectorTileLayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@ import { mapboxGLJSLayer } from './MapBoxGLLayer';

export var VectorTileLayer = Layer.extend({
options: {
// if pane is not provided default to LeafletJS's overlayPane
// if pane is not provided, default to LeafletJS's overlayPane
// https://leafletjs.com/reference.html#map-pane
pane: 'overlayPane'
pane: 'overlayPane',

// if portalUrl is not provided, default to ArcGIS Online
portalUrl: 'https://www.arcgis.com'
},

/**
Expand Down

0 comments on commit 6f1d21a

Please sign in to comment.