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

slippy-tile

Package Overview
Dependencies
Maintainers
1
Versions
43
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

slippy-tile - npm Package Compare versions

Comparing version 1.13.1 to 2.0.0

6

CHANGELOG.md
# Changelog
## 2.0.0 - 2017-04-01
- Performance increase
- Drop providers in favor of `map-providers`
- **Breaking** Single function module `parse()` is now the only function for this library.
## 1.13.0 - 2017-03-27

@@ -5,0 +11,0 @@

1650

docs/slippy-tile.js

@@ -7,280 +7,1315 @@ (function (global, factory) {

var natgeo = {
name: 'ESRI National Geographic World Map',
categories: [
'esri',
'national',
'geographic',
'world'
],
minZoom: 0,
maxZoom: 12,
url: 'https://services.arcgisonline.com/arcgis/rest/services/NatGeo_World_Map/MapServer/WMTS/tile/1.0.0/World_Imagery/{Style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.jpg',
description: 'This map is designed to be used as a general reference map for informational and educational purposes as well as a basemap by GIS professionals and other users for creating web maps and web mapping applications.',
attribution: 'National Geographic, Esri, DeLorme, HERE, UNEP-WCMC, USGS, NASA, ESA, METI, NRCAN, GEBCO, NOAA, INCREMENT P',
format: 'jpg',
type: 'baselayer'
};
/**
* Callback for coordEach
*
* @private
* @callback coordEachCallback
* @param {[number, number]} currentCoords The current coordinates being processed.
* @param {number} currentIndex The index of the current element being processed in the
* array.Starts at index 0, if an initialValue is provided, and at index 1 otherwise.
*/
var ocean = {
name: 'ESRI Ocean Basemap',
categories: [
'esri',
'ocean',
'world'
],
minZoom: 0,
maxZoom: 10,
url: 'https://services.arcgisonline.com/arcgis/rest/services/Ocean_Basemap/MapServer/WMTS/tile/1.0.0/World_Imagery/{Style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.jpg',
description: 'The ocean basemap includes bathymetry, surface and subsurface feature names, and derived depths. This service is designed to be used as a basemap by marine GIS professionals and as a reference map by anyone interested in ocean data.',
attribution: 'Esri, GEBCO, NOAA, National Geographic, DeLorme, HERE, Geonames.org, and other contributors',
format: 'jpg',
type: 'baselayer'
};
/**
* Iterate over coordinates in any GeoJSON object, similar to Array.forEach()
*
* @name coordEach
* @param {Object} layer any GeoJSON object
* @param {Function} callback a method that takes (currentCoords, currentIndex)
* @param {boolean} [excludeWrapCoord=false] whether or not to include
* the final coordinate of LinearRings that wraps the ring in its iteration.
* @example
* var features = {
* "type": "FeatureCollection",
* "features": [
* {
* "type": "Feature",
* "properties": {},
* "geometry": {
* "type": "Point",
* "coordinates": [26, 37]
* }
* },
* {
* "type": "Feature",
* "properties": {},
* "geometry": {
* "type": "Point",
* "coordinates": [36, 53]
* }
* }
* ]
* };
* turf.coordEach(features, function (currentCoords, currentIndex) {
* //=currentCoords
* //=currentIndex
* });
*/
function coordEach(layer, callback, excludeWrapCoord) {
var i, j, k, g, l, geometry, stopG, coords,
geometryMaybeCollection,
wrapShrink = 0,
currentIndex = 0,
isGeometryCollection,
isFeatureCollection = layer.type === 'FeatureCollection',
isFeature = layer.type === 'Feature',
stop = isFeatureCollection ? layer.features.length : 1;
var usatopo = {
name: 'ESRI USA Topo Maps',
categories: [
'esri',
'topo',
'topographicusa'
],
minZoom: 0,
maxZoom: 15,
url: 'https://services.arcgisonline.com/arcgis/rest/services/USA_Topo_Maps/MapServer/WMTS/tile/1.0.0/World_Imagery/{Style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.jpg',
description: 'This map service presents detailed USGS topographic maps for the United States at multiple scales.',
attribution: '© 2011 National Geographic Society, i-cubed',
format: 'jpg',
type: 'baselayer'
// This logic may look a little weird. The reason why it is that way
// is because it's trying to be fast. GeoJSON supports multiple kinds
// of objects at its root: FeatureCollection, Features, Geometries.
// This function has the responsibility of handling all of them, and that
// means that some of the `for` loops you see below actually just don't apply
// to certain inputs. For instance, if you give this just a
// Point geometry, then both loops are short-circuited and all we do
// is gradually rename the input until it's called 'geometry'.
//
// This also aims to allocate as few resources as possible: just a
// few numbers and booleans, rather than any temporary arrays as would
// be required with the normalization approach.
for (i = 0; i < stop; i++) {
geometryMaybeCollection = (isFeatureCollection ? layer.features[i].geometry :
(isFeature ? layer.geometry : layer));
isGeometryCollection = geometryMaybeCollection.type === 'GeometryCollection';
stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1;
for (g = 0; g < stopG; g++) {
geometry = isGeometryCollection ?
geometryMaybeCollection.geometries[g] : geometryMaybeCollection;
coords = geometry.coordinates;
wrapShrink = (excludeWrapCoord &&
(geometry.type === 'Polygon' || geometry.type === 'MultiPolygon')) ?
1 : 0;
if (geometry.type === 'Point') {
callback(coords, currentIndex);
currentIndex++;
} else if (geometry.type === 'LineString' || geometry.type === 'MultiPoint') {
for (j = 0; j < coords.length; j++) {
callback(coords[j], currentIndex);
currentIndex++;
}
} else if (geometry.type === 'Polygon' || geometry.type === 'MultiLineString') {
for (j = 0; j < coords.length; j++)
for (k = 0; k < coords[j].length - wrapShrink; k++) {
callback(coords[j][k], currentIndex);
currentIndex++;
}
} else if (geometry.type === 'MultiPolygon') {
for (j = 0; j < coords.length; j++)
for (k = 0; k < coords[j].length; k++)
for (l = 0; l < coords[j][k].length - wrapShrink; l++) {
callback(coords[j][k][l], currentIndex);
currentIndex++;
}
} else if (geometry.type === 'GeometryCollection') {
for (j = 0; j < geometry.geometries.length; j++)
coordEach(geometry.geometries[j], callback, excludeWrapCoord);
} else {
throw new Error('Unknown Geometry Type');
}
}
}
}
var coordEach_1 = coordEach;
/**
* Callback for coordReduce
*
* The first time the callback function is called, the values provided as arguments depend
* on whether the reduce method has an initialValue argument.
*
* If an initialValue is provided to the reduce method:
* - The previousValue argument is initialValue.
* - The currentValue argument is the value of the first element present in the array.
*
* If an initialValue is not provided:
* - The previousValue argument is the value of the first element present in the array.
* - The currentValue argument is the value of the second element present in the array.
*
* @private
* @callback coordReduceCallback
* @param {*} previousValue The accumulated value previously returned in the last invocation
* of the callback, or initialValue, if supplied.
* @param {[number, number]} currentCoords The current coordinate being processed.
* @param {number} currentIndex The index of the current element being processed in the
* array.Starts at index 0, if an initialValue is provided, and at index 1 otherwise.
*/
/**
* Reduce coordinates in any GeoJSON object, similar to Array.reduce()
*
* @name coordReduce
* @param {Object} layer any GeoJSON object
* @param {Function} callback a method that takes (previousValue, currentCoords, currentIndex)
* @param {*} [initialValue] Value to use as the first argument to the first call of the callback.
* @param {boolean} [excludeWrapCoord=false] whether or not to include
* the final coordinate of LinearRings that wraps the ring in its iteration.
* @returns {*} The value that results from the reduction.
* @example
* var features = {
* "type": "FeatureCollection",
* "features": [
* {
* "type": "Feature",
* "properties": {},
* "geometry": {
* "type": "Point",
* "coordinates": [26, 37]
* }
* },
* {
* "type": "Feature",
* "properties": {},
* "geometry": {
* "type": "Point",
* "coordinates": [36, 53]
* }
* }
* ]
* };
* turf.coordReduce(features, function (previousValue, currentCoords, currentIndex) {
* //=previousValue
* //=currentCoords
* //=currentIndex
* return currentCoords;
* });
*/
function coordReduce(layer, callback, initialValue, excludeWrapCoord) {
var previousValue = initialValue;
coordEach(layer, function (currentCoords, currentIndex) {
if (currentIndex === 0 && initialValue === undefined) {
previousValue = currentCoords;
} else {
previousValue = callback(previousValue, currentCoords, currentIndex);
}
}, excludeWrapCoord);
return previousValue;
}
var coordReduce_1 = coordReduce;
/**
* Callback for propEach
*
* @private
* @callback propEachCallback
* @param {*} currentProperties The current properties being processed.
* @param {number} currentIndex The index of the current element being processed in the
* array.Starts at index 0, if an initialValue is provided, and at index 1 otherwise.
*/
/**
* Iterate over properties in any GeoJSON object, similar to Array.forEach()
*
* @name propEach
* @param {Object} layer any GeoJSON object
* @param {Function} callback a method that takes (currentProperties, currentIndex)
* @example
* var features = {
* "type": "FeatureCollection",
* "features": [
* {
* "type": "Feature",
* "properties": {"foo": "bar"},
* "geometry": {
* "type": "Point",
* "coordinates": [26, 37]
* }
* },
* {
* "type": "Feature",
* "properties": {"hello": "world"},
* "geometry": {
* "type": "Point",
* "coordinates": [36, 53]
* }
* }
* ]
* };
* turf.propEach(features, function (currentProperties, currentIndex) {
* //=currentProperties
* //=currentIndex
* });
*/
function propEach(layer, callback) {
var i;
switch (layer.type) {
case 'FeatureCollection':
for (i = 0; i < layer.features.length; i++) {
callback(layer.features[i].properties, i);
}
break;
case 'Feature':
callback(layer.properties, 0);
break;
}
}
var propEach_1 = propEach;
/**
* Callback for propReduce
*
* The first time the callback function is called, the values provided as arguments depend
* on whether the reduce method has an initialValue argument.
*
* If an initialValue is provided to the reduce method:
* - The previousValue argument is initialValue.
* - The currentValue argument is the value of the first element present in the array.
*
* If an initialValue is not provided:
* - The previousValue argument is the value of the first element present in the array.
* - The currentValue argument is the value of the second element present in the array.
*
* @private
* @callback propReduceCallback
* @param {*} previousValue The accumulated value previously returned in the last invocation
* of the callback, or initialValue, if supplied.
* @param {*} currentProperties The current properties being processed.
* @param {number} currentIndex The index of the current element being processed in the
* array.Starts at index 0, if an initialValue is provided, and at index 1 otherwise.
*/
/**
* Reduce properties in any GeoJSON object into a single value,
* similar to how Array.reduce works. However, in this case we lazily run
* the reduction, so an array of all properties is unnecessary.
*
* @name propReduce
* @param {Object} layer any GeoJSON object
* @param {Function} callback a method that takes (previousValue, currentProperties, currentIndex)
* @param {*} [initialValue] Value to use as the first argument to the first call of the callback.
* @returns {*} The value that results from the reduction.
* @example
* var features = {
* "type": "FeatureCollection",
* "features": [
* {
* "type": "Feature",
* "properties": {"foo": "bar"},
* "geometry": {
* "type": "Point",
* "coordinates": [26, 37]
* }
* },
* {
* "type": "Feature",
* "properties": {"hello": "world"},
* "geometry": {
* "type": "Point",
* "coordinates": [36, 53]
* }
* }
* ]
* };
* turf.propReduce(features, function (previousValue, currentProperties, currentIndex) {
* //=previousValue
* //=currentProperties
* //=currentIndex
* return currentProperties
* });
*/
function propReduce(layer, callback, initialValue) {
var previousValue = initialValue;
propEach(layer, function (currentProperties, currentIndex) {
if (currentIndex === 0 && initialValue === undefined) {
previousValue = currentProperties;
} else {
previousValue = callback(previousValue, currentProperties, currentIndex);
}
});
return previousValue;
}
var propReduce_1 = propReduce;
/**
* Callback for featureEach
*
* @private
* @callback featureEachCallback
* @param {Feature<any>} currentFeature The current feature being processed.
* @param {number} currentIndex The index of the current element being processed in the
* array.Starts at index 0, if an initialValue is provided, and at index 1 otherwise.
*/
/**
* Iterate over features in any GeoJSON object, similar to
* Array.forEach.
*
* @name featureEach
* @param {Object} layer any GeoJSON object
* @param {Function} callback a method that takes (currentFeature, currentIndex)
* @example
* var features = {
* "type": "FeatureCollection",
* "features": [
* {
* "type": "Feature",
* "properties": {},
* "geometry": {
* "type": "Point",
* "coordinates": [26, 37]
* }
* },
* {
* "type": "Feature",
* "properties": {},
* "geometry": {
* "type": "Point",
* "coordinates": [36, 53]
* }
* }
* ]
* };
* turf.featureEach(features, function (currentFeature, currentIndex) {
* //=currentFeature
* //=currentIndex
* });
*/
function featureEach(layer, callback) {
if (layer.type === 'Feature') {
callback(layer, 0);
} else if (layer.type === 'FeatureCollection') {
for (var i = 0; i < layer.features.length; i++) {
callback(layer.features[i], i);
}
}
}
var featureEach_1 = featureEach;
/**
* Callback for featureReduce
*
* The first time the callback function is called, the values provided as arguments depend
* on whether the reduce method has an initialValue argument.
*
* If an initialValue is provided to the reduce method:
* - The previousValue argument is initialValue.
* - The currentValue argument is the value of the first element present in the array.
*
* If an initialValue is not provided:
* - The previousValue argument is the value of the first element present in the array.
* - The currentValue argument is the value of the second element present in the array.
*
* @private
* @callback featureReduceCallback
* @param {*} previousValue The accumulated value previously returned in the last invocation
* of the callback, or initialValue, if supplied.
* @param {Feature<any>} currentFeature The current Feature being processed.
* @param {number} currentIndex The index of the current element being processed in the
* array.Starts at index 0, if an initialValue is provided, and at index 1 otherwise.
*/
/**
* Reduce features in any GeoJSON object, similar to Array.reduce().
*
* @name featureReduce
* @param {Object} layer any GeoJSON object
* @param {Function} callback a method that takes (previousValue, currentFeature, currentIndex)
* @param {*} [initialValue] Value to use as the first argument to the first call of the callback.
* @returns {*} The value that results from the reduction.
* @example
* var features = {
* "type": "FeatureCollection",
* "features": [
* {
* "type": "Feature",
* "properties": {"foo": "bar"},
* "geometry": {
* "type": "Point",
* "coordinates": [26, 37]
* }
* },
* {
* "type": "Feature",
* "properties": {"hello": "world"},
* "geometry": {
* "type": "Point",
* "coordinates": [36, 53]
* }
* }
* ]
* };
* turf.featureReduce(features, function (previousValue, currentFeature, currentIndex) {
* //=previousValue
* //=currentFeature
* //=currentIndex
* return currentFeature
* });
*/
function featureReduce(layer, callback, initialValue) {
var previousValue = initialValue;
featureEach(layer, function (currentFeature, currentIndex) {
if (currentIndex === 0 && initialValue === undefined) {
previousValue = currentFeature;
} else {
previousValue = callback(previousValue, currentFeature, currentIndex);
}
});
return previousValue;
}
var featureReduce_1 = featureReduce;
/**
* Get all coordinates from any GeoJSON object.
*
* @name coordAll
* @param {Object} layer any GeoJSON object
* @returns {Array<Array<number>>} coordinate position array
* @example
* var features = {
* "type": "FeatureCollection",
* "features": [
* {
* "type": "Feature",
* "properties": {},
* "geometry": {
* "type": "Point",
* "coordinates": [26, 37]
* }
* },
* {
* "type": "Feature",
* "properties": {},
* "geometry": {
* "type": "Point",
* "coordinates": [36, 53]
* }
* }
* ]
* };
* var coords = turf.coordAll(features);
* //=coords
*/
function coordAll(layer) {
var coords = [];
coordEach(layer, function (coord) {
coords.push(coord);
});
return coords;
}
var coordAll_1 = coordAll;
/**
* Iterate over each geometry in any GeoJSON object, similar to Array.forEach()
*
* @name geomEach
* @param {Object} layer any GeoJSON object
* @param {Function} callback a method that takes (currentGeometry, currentIndex)
* @example
* var features = {
* "type": "FeatureCollection",
* "features": [
* {
* "type": "Feature",
* "properties": {},
* "geometry": {
* "type": "Point",
* "coordinates": [26, 37]
* }
* },
* {
* "type": "Feature",
* "properties": {},
* "geometry": {
* "type": "Point",
* "coordinates": [36, 53]
* }
* }
* ]
* };
* turf.geomEach(features, function (currentGeometry, currentIndex) {
* //=currentGeometry
* //=currentIndex
* });
*/
function geomEach(layer, callback) {
var i, j, g, geometry, stopG,
geometryMaybeCollection,
isGeometryCollection,
currentIndex = 0,
isFeatureCollection = layer.type === 'FeatureCollection',
isFeature = layer.type === 'Feature',
stop = isFeatureCollection ? layer.features.length : 1;
// This logic may look a little weird. The reason why it is that way
// is because it's trying to be fast. GeoJSON supports multiple kinds
// of objects at its root: FeatureCollection, Features, Geometries.
// This function has the responsibility of handling all of them, and that
// means that some of the `for` loops you see below actually just don't apply
// to certain inputs. For instance, if you give this just a
// Point geometry, then both loops are short-circuited and all we do
// is gradually rename the input until it's called 'geometry'.
//
// This also aims to allocate as few resources as possible: just a
// few numbers and booleans, rather than any temporary arrays as would
// be required with the normalization approach.
for (i = 0; i < stop; i++) {
geometryMaybeCollection = (isFeatureCollection ? layer.features[i].geometry :
(isFeature ? layer.geometry : layer));
isGeometryCollection = geometryMaybeCollection.type === 'GeometryCollection';
stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1;
for (g = 0; g < stopG; g++) {
geometry = isGeometryCollection ?
geometryMaybeCollection.geometries[g] : geometryMaybeCollection;
if (geometry.type === 'Point' ||
geometry.type === 'LineString' ||
geometry.type === 'MultiPoint' ||
geometry.type === 'Polygon' ||
geometry.type === 'MultiLineString' ||
geometry.type === 'MultiPolygon') {
callback(geometry, currentIndex);
currentIndex++;
} else if (geometry.type === 'GeometryCollection') {
for (j = 0; j < geometry.geometries.length; j++) {
callback(geometry.geometries[j], currentIndex);
currentIndex++;
}
} else {
throw new Error('Unknown Geometry Type');
}
}
}
}
var geomEach_1 = geomEach;
/**
* Callback for geomReduce
*
* The first time the callback function is called, the values provided as arguments depend
* on whether the reduce method has an initialValue argument.
*
* If an initialValue is provided to the reduce method:
* - The previousValue argument is initialValue.
* - The currentValue argument is the value of the first element present in the array.
*
* If an initialValue is not provided:
* - The previousValue argument is the value of the first element present in the array.
* - The currentValue argument is the value of the second element present in the array.
*
* @private
* @callback geomReduceCallback
* @param {*} previousValue The accumulated value previously returned in the last invocation
* of the callback, or initialValue, if supplied.
* @param {*} currentGeometry The current Feature being processed.
* @param {number} currentIndex The index of the current element being processed in the
* array.Starts at index 0, if an initialValue is provided, and at index 1 otherwise.
*/
/**
* Reduce geometry in any GeoJSON object, similar to Array.reduce().
*
* @name geomReduce
* @param {Object} layer any GeoJSON object
* @param {Function} callback a method that takes (previousValue, currentGeometry, currentIndex)
* @param {*} [initialValue] Value to use as the first argument to the first call of the callback.
* @returns {*} The value that results from the reduction.
* @example
* var features = {
* "type": "FeatureCollection",
* "features": [
* {
* "type": "Feature",
* "properties": {"foo": "bar"},
* "geometry": {
* "type": "Point",
* "coordinates": [26, 37]
* }
* },
* {
* "type": "Feature",
* "properties": {"hello": "world"},
* "geometry": {
* "type": "Point",
* "coordinates": [36, 53]
* }
* }
* ]
* };
* turf.geomReduce(features, function (previousValue, currentGeometry, currentIndex) {
* //=previousValue
* //=currentGeometry
* //=currentIndex
* return currentGeometry
* });
*/
function geomReduce(layer, callback, initialValue) {
var previousValue = initialValue;
geomEach(layer, function (currentGeometry, currentIndex) {
if (currentIndex === 0 && initialValue === undefined) {
previousValue = currentGeometry;
} else {
previousValue = callback(previousValue, currentGeometry, currentIndex);
}
});
return previousValue;
}
var geomReduce_1 = geomReduce;
var index$8 = {
coordEach: coordEach_1,
coordReduce: coordReduce_1,
propEach: propEach_1,
propReduce: propReduce_1,
featureEach: featureEach_1,
featureReduce: featureReduce_1,
coordAll: coordAll_1,
geomEach: geomEach_1,
geomReduce: geomReduce_1
};
var imagery = {
name: 'ESRI World Imagery',
categories: [
'esri',
'imagery',
'world'
],
minZoom: 0,
maxZoom: 19,
url: 'https://services.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer/WMTS/tile/1.0.0/World_Imagery/{Style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.jpg',
description: 'This map service presents satellite imagery for the world and high-resolution imagery for the United States and other areas around the world.',
attribution: 'Esri, DigitalGlobe, Earthstar Geographics, CNES/Airbus DS, GeoEye, USDA FSA, USGS, Getmapping, Aerogrid, IGN, IGP, and the GIS User Community',
format: 'jpg',
type: 'baselayer'
var each = index$8.coordEach;
/**
* Takes a set of features, calculates the bbox of all input features, and returns a bounding box.
*
* @name bbox
* @param {(Feature|FeatureCollection)} geojson input features
* @returns {Array<number>} bbox extent in [minX, minY, maxX, maxY] order
* @addToMap features, bboxPolygon
* @example
* var pt1 = turf.point([114.175329, 22.2524])
* var pt2 = turf.point([114.170007, 22.267969])
* var pt3 = turf.point([114.200649, 22.274641])
* var pt4 = turf.point([114.200649, 22.274641])
* var pt5 = turf.point([114.186744, 22.265745])
* var features = turf.featureCollection([pt1, pt2, pt3, pt4, pt5])
*
* var bbox = turf.bbox(features);
*
* var bboxPolygon = turf.bboxPolygon(bbox);
*
* //=bbox
*
* //=bboxPolygon
*/
var index$6 = function (geojson) {
var bbox = [Infinity, Infinity, -Infinity, -Infinity];
each(geojson, function (coord) {
if (bbox[0] > coord[0]) bbox[0] = coord[0];
if (bbox[1] > coord[1]) bbox[1] = coord[1];
if (bbox[2] < coord[0]) bbox[2] = coord[0];
if (bbox[3] < coord[1]) bbox[3] = coord[1];
});
return bbox;
};
var street = {
name: 'ESRI World Street Map',
categories: [
'esri',
'street',
'world'
],
minZoom: 0,
maxZoom: 19,
url: 'https://services.arcgisonline.com/arcgis/rest/services/World_Street_Map/MapServer/WMTS/tile/1.0.0/World_Topo_Map/{Style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.jpg',
description: 'This map service presents highway-level data for the world and street-level data for North America, Europe, Africa, parts of the Middle East, Asia, and more.',
attribution: 'Esri, HERE, DeLorme, USGS, Intermap, INCREMENT P, NRCAN, Esri Japan, METI, Esri China (Hong Kong), Esri (Thailand), MapmyIndia, © OpenStreetMap contributors, and the GIS User Community',
format: 'jpg',
type: 'baselayer'
/**
* Wraps a GeoJSON {@link Geometry} in a GeoJSON {@link Feature}.
*
* @name feature
* @param {Geometry} geometry input geometry
* @param {Object} properties properties
* @returns {FeatureCollection} a FeatureCollection of input features
* @example
* var geometry = {
* "type": "Point",
* "coordinates": [
* 67.5,
* 32.84267363195431
* ]
* }
*
* var feature = turf.feature(geometry);
*
* //=feature
*/
function feature(geometry, properties) {
if (!geometry) throw new Error('No geometry passed');
return {
type: 'Feature',
properties: properties || {},
geometry: geometry
};
}
var feature_1 = feature;
/**
* Takes coordinates and properties (optional) and returns a new {@link Point} feature.
*
* @name point
* @param {Array<number>} coordinates longitude, latitude position (each in decimal degrees)
* @param {Object=} properties an Object that is used as the {@link Feature}'s
* properties
* @returns {Feature<Point>} a Point feature
* @example
* var pt1 = turf.point([-75.343, 39.984]);
*
* //=pt1
*/
var point$1 = function (coordinates, properties) {
if (!coordinates) throw new Error('No coordinates passed');
if (coordinates.length === undefined) throw new Error('Coordinates must be an array');
if (coordinates.length < 2) throw new Error('Coordinates must be at least 2 numbers long');
if (typeof coordinates[0] !== 'number' || typeof coordinates[1] !== 'number') throw new Error('Coordinates must numbers');
return feature({
type: 'Point',
coordinates: coordinates
}, properties);
};
var topo = {
name: 'ESRI World Topographic Map',
categories: [
'esri',
'topo',
'topographic',
'world'
],
minZoom: 0,
maxZoom: 19,
url: 'https://services.arcgisonline.com/arcgis/rest/services/World_Topo_Map/MapServer/WMTS/tile/1.0.0/World_Imagery/{Style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.jpg',
description: 'This world topographic map includes boundaries, cities, water features, physiographic features, parks, landmarks, transportation, and buildings.',
attribution: 'Esri, HERE, DeLorme, Intermap, INCREMENT P, GEBCO, USGS, FAO, NPS, NRCAN, GeoBase, IGN, Kadaster NL, Ordnance Survey, Esri Japan, METI, Esri China (Hong Kong), swisstopo, MapmyIndia, © OpenStreetMap contributors, GIS User Community',
format: 'jpg',
type: 'baselayer'
/**
* Takes an array of LinearRings and optionally an {@link Object} with properties and returns a {@link Polygon} feature.
*
* @name polygon
* @param {Array<Array<Array<number>>>} coordinates an array of LinearRings
* @param {Object=} properties a properties object
* @returns {Feature<Polygon>} a Polygon feature
* @throws {Error} throw an error if a LinearRing of the polygon has too few positions
* or if a LinearRing of the Polygon does not have matching Positions at the
* beginning & end.
* @example
* var polygon = turf.polygon([[
* [-2.275543, 53.464547],
* [-2.275543, 53.489271],
* [-2.215118, 53.489271],
* [-2.215118, 53.464547],
* [-2.275543, 53.464547]
* ]], { name: 'poly1', population: 400});
*
* //=polygon
*/
var polygon = function (coordinates, properties) {
if (!coordinates) throw new Error('No coordinates passed');
for (var i = 0; i < coordinates.length; i++) {
var ring = coordinates[i];
if (ring.length < 4) {
throw new Error('Each LinearRing of a Polygon must have 4 or more Positions.');
}
for (var j = 0; j < ring[ring.length - 1].length; j++) {
if (ring[ring.length - 1][j] !== ring[0][j]) {
throw new Error('First and last Position are not equivalent.');
}
}
}
return feature({
type: 'Polygon',
coordinates: coordinates
}, properties);
};
var esri = {
natgeo: natgeo,
ocean: ocean,
usatopo: usatopo,
imagery: imagery,
street: street,
topo: topo
/**
* Creates a {@link LineString} based on a
* coordinate array. Properties can be added optionally.
*
* @name lineString
* @param {Array<Array<number>>} coordinates an array of Positions
* @param {Object=} properties an Object of key-value pairs to add as properties
* @returns {Feature<LineString>} a LineString feature
* @throws {Error} if no coordinates are passed
* @example
* var linestring1 = turf.lineString([
* [-21.964416, 64.148203],
* [-21.956176, 64.141316],
* [-21.93901, 64.135924],
* [-21.927337, 64.136673]
* ]);
* var linestring2 = turf.lineString([
* [-21.929054, 64.127985],
* [-21.912918, 64.134726],
* [-21.916007, 64.141016],
* [-21.930084, 64.14446]
* ], {name: 'line 1', distance: 145});
*
* //=linestring1
*
* //=linestring2
*/
var lineString = function (coordinates, properties) {
if (!coordinates) throw new Error('No coordinates passed');
return feature({
type: 'LineString',
coordinates: coordinates
}, properties);
};
var imagery$1 = {
name: 'Bing Imagery',
categories: [
'bing',
'imagery',
'world'
],
minZoom: 1,
maxZoom: 20,
url: 'https://ecn.t{switch:0,1,2,3}.tiles.virtualearth.net/tiles/a{quadkey}.jpeg?g=5250',
description: 'Tiles from Bing',
attribution: 'Map data © Bing',
format: 'jpg',
type: 'baselayer'
/**
* Takes one or more {@link Feature|Features} and creates a {@link FeatureCollection}.
*
* @name featureCollection
* @param {Feature[]} features input features
* @returns {FeatureCollection} a FeatureCollection of input features
* @example
* var features = [
* turf.point([-75.343, 39.984], {name: 'Location A'}),
* turf.point([-75.833, 39.284], {name: 'Location B'}),
* turf.point([-75.534, 39.123], {name: 'Location C'})
* ];
*
* var fc = turf.featureCollection(features);
*
* //=fc
*/
var featureCollection = function (features) {
if (!features) throw new Error('No features passed');
return {
type: 'FeatureCollection',
features: features
};
};
var bing = {
imagery: imagery$1
/**
* Creates a {@link Feature<MultiLineString>} based on a
* coordinate array. Properties can be added optionally.
*
* @name multiLineString
* @param {Array<Array<Array<number>>>} coordinates an array of LineStrings
* @param {Object=} properties an Object of key-value pairs to add as properties
* @returns {Feature<MultiLineString>} a MultiLineString feature
* @throws {Error} if no coordinates are passed
* @example
* var multiLine = turf.multiLineString([[[0,0],[10,10]]]);
*
* //=multiLine
*
*/
var multiLineString = function (coordinates, properties) {
if (!coordinates) throw new Error('No coordinates passed');
return feature({
type: 'MultiLineString',
coordinates: coordinates
}, properties);
};
var standard = {
name: 'OpenStreetMap Standard',
categories: [
'openstreetmap',
'standard',
'world'
],
minZoom: 0,
maxZoom: 19,
url: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
description: 'Tiles from OpenStreetMap',
attribution: 'Map data © OpenStreetMap',
format: 'png',
type: 'baselayer'
/**
* Creates a {@link Feature<MultiPoint>} based on a
* coordinate array. Properties can be added optionally.
*
* @name multiPoint
* @param {Array<Array<number>>} coordinates an array of Positions
* @param {Object=} properties an Object of key-value pairs to add as properties
* @returns {Feature<MultiPoint>} a MultiPoint feature
* @throws {Error} if no coordinates are passed
* @example
* var multiPt = turf.multiPoint([[0,0],[10,10]]);
*
* //=multiPt
*
*/
var multiPoint = function (coordinates, properties) {
if (!coordinates) throw new Error('No coordinates passed');
return feature({
type: 'MultiPoint',
coordinates: coordinates
}, properties);
};
var cycle = {
name: 'OpenStreetMap Cycle Map',
categories: [
'openstreetmap',
'cycle',
'world'
],
minZoom: 0,
maxZoom: 19,
url: 'https://{s}.tile.thunderforest.com/cycle/{z}/{x}/{y}.png',
description: 'Tiles from OpenStreetMap',
attribution: 'Map data © OpenStreetMap',
format: 'png',
type: 'baselayer'
/**
* Creates a {@link Feature<MultiPolygon>} based on a
* coordinate array. Properties can be added optionally.
*
* @name multiPolygon
* @param {Array<Array<Array<Array<number>>>>} coordinates an array of Polygons
* @param {Object=} properties an Object of key-value pairs to add as properties
* @returns {Feature<MultiPolygon>} a multipolygon feature
* @throws {Error} if no coordinates are passed
* @example
* var multiPoly = turf.multiPolygon([[[[0,0],[0,10],[10,10],[10,0],[0,0]]]]);
*
* //=multiPoly
*
*/
var multiPolygon = function (coordinates, properties) {
if (!coordinates) throw new Error('No coordinates passed');
return feature({
type: 'MultiPolygon',
coordinates: coordinates
}, properties);
};
var hot = {
name: 'OpenStreetMap Humanitarian',
categories: [
'openstreetmap',
'hot',
'humanitarian',
'world'
],
minZoom: 0,
maxZoom: 19,
url: 'https://tile-{s}.openstreetmap.fr/hot/{z}/{x}/{y}.png',
description: 'Tiles from OpenStreetMap',
attribution: 'Map data © OpenStreetMap',
format: 'png',
type: 'baselayer'
/**
* Creates a {@link Feature<GeometryCollection>} based on a
* coordinate array. Properties can be added optionally.
*
* @name geometryCollection
* @param {Array<{Geometry}>} geometries an array of GeoJSON Geometries
* @param {Object=} properties an Object of key-value pairs to add as properties
* @returns {Feature<GeometryCollection>} a GeoJSON GeometryCollection Feature
* @example
* var pt = {
* "type": "Point",
* "coordinates": [100, 0]
* };
* var line = {
* "type": "LineString",
* "coordinates": [ [101, 0], [102, 1] ]
* };
* var collection = turf.geometryCollection([pt, line]);
*
* //=collection
*/
var geometryCollection = function (geometries, properties) {
if (!geometries) throw new Error('No geometries passed');
return feature({
type: 'GeometryCollection',
geometries: geometries
}, properties);
};
var transport = {
name: 'OpenStreetMap Transport Map',
categories: [
'openstreetmap',
'transport',
'world'
],
minZoom: 0,
maxZoom: 19,
url: 'https://{s}.tile.thunderforest.com/transport/{z}/{x}/{y}.png',
description: 'Tiles from OpenStreetMap',
attribution: 'Map data © OpenStreetMap',
format: 'png',
type: 'baselayer'
var factors = {
miles: 3960,
nauticalmiles: 3441.145,
degrees: 57.2957795,
radians: 1,
inches: 250905600,
yards: 6969600,
meters: 6373000,
metres: 6373000,
kilometers: 6373,
kilometres: 6373,
feet: 20908792.65
};
var wikimedia = {
name: 'OpenStreetMap Wikimedia',
categories: [
'openstreetmap',
'wikimedia',
'world'
],
minZoom: 0,
maxZoom: 19,
url: 'https://maps.wikimedia.org/osm-intl/{z}/{x}/{y}.png',
description: 'Tiles from OSM',
attribution: 'Map data © OSM',
format: 'png',
type: 'baselayer'
/*
* Convert a distance measurement from radians to a more friendly unit.
*
* @name radiansToDistance
* @param {number} distance in radians across the sphere
* @param {string} [units=kilometers] can be degrees, radians, miles, or kilometers
* inches, yards, metres, meters, kilometres, kilometers.
* @returns {number} distance
*/
var radiansToDistance = function (radians, units) {
var factor = factors[units || 'kilometers'];
if (factor === undefined) throw new Error('Invalid unit');
return radians * factor;
};
var lyrk = {
name: 'OpenStreetMap Lyrk',
categories: [
'openstreetmap',
'lyrk',
'world'
],
minZoom: 0,
maxZoom: 19,
url: 'https://tiles.lyrk.org/ls/{z}/{x}/{y}?apikey=6e8cfef737a140e2a58c8122aaa26077',
description: 'Tiles from OpenStreetMap',
attribution: 'Map data © OpenStreetMap',
format: 'png',
type: 'baselayer'
/*
* Convert a distance measurement from a real-world unit into radians
*
* @name distanceToRadians
* @param {number} distance in real units
* @param {string} [units=kilometers] can be degrees, radians, miles, or kilometers
* inches, yards, metres, meters, kilometres, kilometers.
* @returns {number} radians
*/
var distanceToRadians = function (distance, units) {
var factor = factors[units || 'kilometers'];
if (factor === undefined) throw new Error('Invalid unit');
return distance / factor;
};
var openstreetmap = {
standard: standard,
cycle: cycle,
hot: hot,
transport: transport,
wikimedia: wikimedia,
lyrk: lyrk
/*
* Convert a distance measurement from a real-world unit into degrees
*
* @name distanceToRadians
* @param {number} distance in real units
* @param {string} [units=kilometers] can be degrees, radians, miles, or kilometers
* inches, yards, metres, meters, kilometres, kilometers.
* @returns {number} degrees
*/
var distanceToDegrees = function (distance, units) {
var factor = factors[units || 'kilometers'];
if (factor === undefined) throw new Error('Invalid unit');
return (distance / factor) * 57.2958;
};
var en = {
name: 'Toporama',
categories: [
'toporama',
'canada',
'topographic',
'english'
],
minZoom: 1,
maxZoom: 19,
url: 'http://wms.ess-ws.nrcan.gc.ca/wms/toporama_en?&service=WMS&request=GetMap&layers=WMS-Toporama&format=image/jpeg&transparent=false&version=1.1.1&height={height}&width={width}&srs={srs}&bbox={bbox}',
description: 'Tiles from Toporama',
attribution: 'Map data Toporama',
format: 'jpeg',
type: 'baselayer'
var index$12 = {
feature: feature_1,
point: point$1,
polygon: polygon,
lineString: lineString,
featureCollection: featureCollection,
multiLineString: multiLineString,
multiPoint: multiPoint,
multiPolygon: multiPolygon,
geometryCollection: geometryCollection,
radiansToDistance: radiansToDistance,
distanceToRadians: distanceToRadians,
distanceToDegrees: distanceToDegrees
};
// module.exports.fr = {
// name: 'Toporama French',
// categories: [
// 'toporama',
// 'canada',
// 'topographic',
// 'francais'
// ],
// minZoom: 1,
// maxZoom: 19,
// url: 'http://wms.ess-ws.nrcan.gc.ca/wms/toporama_fr?&service=WMS&request=GetMap&layers=WMS-Toporama&format=image/jpeg&transparent=false&version=1.1.1&height={height}&width={width}&srs={srs}&bbox={bbox}',
// description: 'Tiles from Toporama',
// attribution: 'Map data Toporama',
// format: 'jpeg',
// type: 'baselayer'
// }
var bbox$1 = index$6;
var point = index$12.point;
var toporama = {
en: en
/**
* Takes a {@link Feature} or {@link FeatureCollection} and returns the absolute center point of all features.
*
* @name center
* @param {(Feature|FeatureCollection)} layer input features
* @return {Feature<Point>} a Point feature at the absolute center point of all input features
* @addToMap features, centerPt
* @example
* var features = {
* "type": "FeatureCollection",
* "features": [
* {
* "type": "Feature",
* "properties": {},
* "geometry": {
* "type": "Point",
* "coordinates": [-97.522259, 35.4691]
* }
* }, {
* "type": "Feature",
* "properties": {},
* "geometry": {
* "type": "Point",
* "coordinates": [-97.502754, 35.463455]
* }
* }, {
* "type": "Feature",
* "properties": {},
* "geometry": {
* "type": "Point",
* "coordinates": [-97.508269, 35.463245]
* }
* }, {
* "type": "Feature",
* "properties": {},
* "geometry": {
* "type": "Point",
* "coordinates": [-97.516809, 35.465779]
* }
* }, {
* "type": "Feature",
* "properties": {},
* "geometry": {
* "type": "Point",
* "coordinates": [-97.515372, 35.467072]
* }
* }, {
* "type": "Feature",
* "properties": {},
* "geometry": {
* "type": "Point",
* "coordinates": [-97.509363, 35.463053]
* }
* }, {
* "type": "Feature",
* "properties": {},
* "geometry": {
* "type": "Point",
* "coordinates": [-97.511123, 35.466601]
* }
* }, {
* "type": "Feature",
* "properties": {},
* "geometry": {
* "type": "Point",
* "coordinates": [-97.518547, 35.469327]
* }
* }, {
* "type": "Feature",
* "properties": {},
* "geometry": {
* "type": "Point",
* "coordinates": [-97.519706, 35.469659]
* }
* }, {
* "type": "Feature",
* "properties": {},
* "geometry": {
* "type": "Point",
* "coordinates": [-97.517839, 35.466998]
* }
* }, {
* "type": "Feature",
* "properties": {},
* "geometry": {
* "type": "Point",
* "coordinates": [-97.508678, 35.464942]
* }
* }, {
* "type": "Feature",
* "properties": {},
* "geometry": {
* "type": "Point",
* "coordinates": [-97.514914, 35.463453]
* }
* }
* ]
* };
*
* var centerPt = turf.center(features);
* centerPt.properties['marker-size'] = 'large';
* centerPt.properties['marker-color'] = '#000';
*
* var resultFeatures = features.features.concat(centerPt);
* var result = {
* "type": "FeatureCollection",
* "features": resultFeatures
* };
*
* //=result
*/
var index$10 = function (layer) {
var ext = bbox$1(layer);
var x = (ext[0] + ext[2]) / 2;
var y = (ext[1] + ext[3]) / 2;
return point([x, y]);
};
var index$2 = {
esri: esri,
bing: bing,
openstreetmap: openstreetmap,
toporama: toporama
var turfBBox = index$6;
var turfCenter = index$10;
/**
* Modifies a BBox to fit within the bounds of the International Date Line.
*
* @param {BBox|FeatureCollection|Feature<any>} bbox BBox [west, south, east, north] or GeoJSON Feature
* @returns {BBox} valid BBox extent
* @example
* dateline.bbox([190, 100, -200, -120])
* //= [-170, -80, 160, 60]
*/
function bbox (bbox) {
// input validation
if (!bbox) throw new Error('bbox is required')
if (!Array.isArray(bbox)) bbox = turfBBox(bbox);
if (bbox.length !== 4) throw new Error('bbox must have 4 numbers')
var west = bbox[0];
var south = bbox[1];
var east = bbox[2];
var north = bbox[3];
// Support bbox that overlaps the entire world
if (west < -180 && east > 180) {
west = -180;
east = 180;
}
if (east < -180 && west > 180) {
west = -180;
east = 180;
}
if (south < -90 && north > 90) {
south = -90;
north = 90;
}
if (north < -90 && south > 90) {
south = -90;
north = 90;
}
if (north > 90) north = 90;
if (south < -90) south = -90;
// Beyond 360 longitude degrees
if (Math.abs(bbox[0] - bbox[2]) > 360) {
west = -180;
east = 180;
}
// Beyond 180 latitude degrees
if (Math.abs(bbox[1] - bbox[3]) > 180) {
south = -90;
north = 90;
}
// Convert Lat & Lng within dateline
west = longitude$1(west);
south = latitude$1(south);
east = longitude$1(east);
north = latitude$1(north);
return [west, south, east, north]
}
/**
* Modifies a Center to fit within the bounds of the International Date Line.
*
* @param {[number, number]|BBox|FeatureCollection|Feature<any>} center Center [lng, lat], BBox [west, south, east, south] or GeoJSON Feature
* @returns {[number, number]} valid center coordinate
* @example
* dateline.center([190, 100])
* //= [-170, -80]
*/
function center (center) {
var coords;
if (!center) throw new Error('center is required')
// Support BBox [west, south, east, north]
if (Array.isArray(center)) {
if (center.length === 4) {
var bbox = center;
var west = bbox[0];
var south = bbox[1];
var east = bbox[2];
var north = bbox[3];
coords = [(west + east) / 2, (south + north) / 2];
// Support Center [lng, lat]
} else coords = [center[0], center[1]];
// Support any GeoJSON
} else coords = turfCenter(center).geometry.coordinates;
if (coords.length !== 2) throw new Error('center must have 2 numbers')
var lng = longitude$1(coords[0]);
var lat = latitude$1(coords[1]);
return [lng, lat]
}
/**
* Modifies a Latitude to fit within +/-90 degrees.
*
* @param {number} lat latitude to modify
* @returns {number} modified latitude
* @example
* dateline.latitude(100)
* //= -80
*/
function latitude$1 (lat) {
if (lat === undefined || lat === null) throw new Error('lat is required')
// Latitudes cannot extends beyond +/-90 degrees
if (lat > 90 || lat < -90) {
lat = lat % 180;
if (lat > 90) lat = -180 + lat;
if (lat < -90) lat = 180 + lat;
if (lat === -0) lat = 0;
}
return lat
}
/**
* Modifies a Longitude to fit within +/-180 degrees.
*
* @param {number} lng longitude to modify
* @returns {number} modified longitude
* @example
* dateline.longitude(190)
* //= -170
*/
function longitude$1 (lng) {
if (lng === undefined || lng === undefined) throw new Error('lng is required')
// lngitudes cannot extends beyond +/-90 degrees
if (lng > 180 || lng < -180) {
lng = lng % 360;
if (lng > 180) lng = -360 + lng;
if (lng < -180) lng = 360 + lng;
if (lng === -0) lng = 0;
}
return lng
}
var index$4 = {
bbox: bbox,
longitude: longitude$1,
latitude: latitude$1,
center: center
};
var latitude = index$4.latitude;
var longitude = index$4.longitude;
var originShift = 2 * Math.PI * 6378137 / 2.0;

@@ -817,3 +1852,3 @@ function initialResolution (tileSize) {

if (lat > 85) lat = 85;
if (lng < -85) lat = -85;
if (lat < -85) lat = -85;
return [lng, lat]

@@ -901,47 +1936,3 @@ }

/**
* Modifies a Latitude to fit within +/-90 degrees.
*
* @param {number} lat latitude to modify
* @returns {number} modified latitude
* @example
* dateline.latitude(100)
* //= -80
*/
function latitude (lat) {
if (lat === null || lat === undefined) throw new Error('lat is required')
// Latitudes cannot extends beyond +/-90 degrees
if (lat > 90 || lat < -90) {
lat = lat % 180;
if (lat > 90) lat = -180 + lat;
if (lat < -90) lat = 180 + lat;
if (lat === -0) lat = 0;
}
return lat
}
/**
* Modifies a Longitude to fit within +/-180 degrees.
*
* @param {number} lng longitude to modify
* @returns {number} modified longitude
* @example
* dateline.longitude(190)
* //= -170
*/
function longitude (lng) {
if (lng === null || lng === undefined) throw new Error('lng is required')
// lngitudes cannot extends beyond +/-90 degrees
if (lng > 180 || lng < -180) {
lng = lng % 360;
if (lng > 180) lng = -360 + lng;
if (lng < -180) lng = 360 + lng;
if (lng === -0) lng = 0;
}
return lng
}
var index$4 = {
var index$2 = {
hash: hash,

@@ -973,9 +1964,6 @@ bboxToCenter: bboxToCenter,

range: range,
maxBBox: maxBBox,
latitude: latitude,
longitude: longitude
maxBBox: maxBBox
};
var providers = index$2;
var mercator = index$4;
var mercator = index$2;
var googleToBBox = mercator.googleToBBox;

@@ -989,2 +1977,3 @@ var googleToTile = mercator.googleToTile;

*
* @name slippyTile
* @param {Tile} tile Tile [x, y, z]

@@ -994,6 +1983,6 @@ * @param {string} url URL Tile scheme or provider unique key

* @example
* slippyTile.parse([10, 15, 8], 'https://{s}.tile.openstreetmap.org/{zoom}/{x}/{y}.png')
* slippyTile([10, 15, 8], 'https://{s}.tile.openstreetmap.org/{zoom}/{x}/{y}.png')
* //='https://c.tile.openstreetmap.org/8/10/15.png'
*/
function parse (tile, url) {
var index = function (tile, url) {
var x = tile[0];

@@ -1005,10 +1994,10 @@ var y = tile[1];

url = parseSwitch(url);
url = url.replace(/{(zoom|z|level)}/, String(zoom));
url = url.replace(/{(x|col)}/, String(x));
url = url.replace(/{(y|row)}/, String(y));
if (url.match(/{-y}/)) { url = url.replace(/{-y}/, String(googleToTile(tile)[1])); }
if (url.match(/{(quadkey|q)}/)) { url = url.replace(/{(quadkey|q)}/, googleToQuadkey(tile)); }
if (url.match(/{.*}/)) { throw new Error('Could not completly parse URL' + url) }
url = url.replace(/{(zoom|z|level)}/gi, String(zoom));
url = url.replace(/{(x|col)}/gi, String(x));
url = url.replace(/{(y|row)}/gi, String(y));
if (url.match(/{-y}/)) url = url.replace(/{-y}/gi, String(googleToTile(tile)[1]));
if (url.match(/{(quadkey|q)}/)) url = url.replace(/{(quadkey|q)}/gi, googleToQuadkey(tile));
if (url.match(/{.*}/)) throw new Error('Could not completly parse URL' + url)
return url
}
};

@@ -1018,2 +2007,3 @@ /**

*
* @private
* @param {Tile} tile Tile [x, y, z]

@@ -1023,17 +2013,19 @@ * @param {string} url WMTS URL scheme

* @example
* slippyTile.wms([10, 15, 8], 'https://<Tile Server>/?layers=imagery&SRS={proj}&WIDTH={width}&HEIGHT={height}&BBOX={bbox}')
* wms([10, 15, 8], 'https://<Tile Server>/?layers=imagery&SRS={proj}&WIDTH={width}&HEIGHT={height}&BBOX={bbox}')
* //='https://<Tile Server>/?layers=imagery&SRS=EPSG:3857&WIDTH=256&HEIGHT=256&BBOX=-165.9375,82.676285,-164.53125,82.853382'
*/
function wms (tile, url) {
url = url.replace(/{height}/gi, '256');
url = url.replace(/{width}/gi, '256');
url = url.replace(/{(proj|srs|crs)}/gi, 'EPSG:3857');
var bbox;
if (url.match(/EPSG:(3857|900913)/i)) {
bbox = bboxToMeters(googleToBBox(tile));
} else {
bbox = googleToBBox(tile);
if (url.match(/{height|width|proj|srs|crs|bbox}/gi)) {
url = url.replace(/{height}/gi, '256');
url = url.replace(/{width}/gi, '256');
url = url.replace(/{(proj|srs|crs)}/gi, 'EPSG:3857');
var bbox;
if (url.match(/EPSG:(3857|900913)/i)) {
bbox = bboxToMeters(googleToBBox(tile));
} else {
bbox = googleToBBox(tile);
}
if (url.match(/{bbox}/i)) { url = url.replace(/{bbox}/gi, bbox.join(',')); }
}
if (url.match(/{bbox}/i)) { url = url.replace(/{bbox}/gi, bbox.join(',')); }
return url

@@ -1045,14 +2037,17 @@ }

*
* @private
* @param {string} url WMTS URL scheme
* @returns {string} parsed URL
* @example
* slippyTile.wmts('https://<Tile Server>/WMTS/tile/1.0.0/Imagery/{Style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.jpg')
* wmts('https://<Tile Server>/WMTS/tile/1.0.0/Imagery/{Style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.jpg')
* //='https://<Tile Server>/WMTS/tile/1.0.0/Imagery/default/GoogleMapsCompatible/{z}/{y}/{x}.jpg'
*/
function wmts (url) {
url = url.replace(/{TileCol}/gi, '{x}');
url = url.replace(/{TileRow}/gi, '{y}');
url = url.replace(/{TileMatrix}/gi, '{z}');
url = url.replace(/{TileMatrixSet}/gi, 'GoogleMapsCompatible');
url = url.replace(/{Style}/gi, 'default');
if (url.match(/{TileCol|TileRow|TileMatrix|TileMatrixSet|Style}/gi)) {
url = url.replace(/{TileCol}/gi, '{x}');
url = url.replace(/{TileRow}/gi, '{y}');
url = url.replace(/{TileMatrix}/gi, '{z}');
url = url.replace(/{TileMatrixSet}/gi, 'GoogleMapsCompatible');
url = url.replace(/{Style}/gi, 'default');
}
return url

@@ -1064,6 +2059,7 @@ }

*
* @private
* @param {string} url - URL Scheme
* @returns {string} Parsed URL with switch replaced
* @example
* slippyTile.parseSwitch('http://tile-{switch:a,b,c}.openstreetmap.fr/hot/{zoom}/{x}/{y}.png')
* parseSwitch('http://tile-{switch:a,b,c}.openstreetmap.fr/hot/{zoom}/{x}/{y}.png')
* //='http://tile-b.openstreetmap.fr/hot/{zoom}/{x}/{y}.png'

@@ -1073,7 +2069,7 @@ */

// Default simple switch
if (url.match(/{s}/)) {
if (url.match(/{s}/gi)) {
return url.replace(/{s}/gi, String(sample(['a', 'b', 'c'])))
}
// Custom switch
var pattern = /{switch:([a-z,\d]*)}/;
var pattern = /{switch:([a-z,\d]*)}/gi;
var found = url.match(pattern);

@@ -1089,2 +2085,3 @@ if (found) {

*
* @private
* @name sample

@@ -1094,3 +2091,3 @@ * @param {Array} array List of items

* @example
* slippyTile.sample(['a', 'b', 'c'])
* sample(['a', 'b', 'c'])
* //='b'

@@ -1103,13 +2100,4 @@ */

var index = {
parse: parse,
providers: providers,
wms: wms,
wmts: wmts,
parseSwitch: parseSwitch,
sample: sample
};
return index;
})));

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

!function(e,r){"object"==typeof exports&&"undefined"!=typeof module?module.exports=r():"function"==typeof define&&define.amd?define(r):e.slippyTile=r()}(this,function(){function e(e){return e=e||256,2*Math.PI*6378137/e}function r(e){var r=e[0],t=e[1],a=e[2];return(1<<a)*((1<<a)+r)+t}function t(e){var r=e[0],t=e[1],a=e[2],o=e[3],i=(r-a)/2+a,n=(t-o)/2+o;return i=Number(i.toFixed(6)),n=Number(n.toFixed(6)),[i,n]}function a(e,r){e=x(e,r);var t=e[0],a=e[1],o=t*ee/180,i=Math.log(Math.tan((90+a)*Math.PI/360))/(Math.PI/180);return i=i*ee/180,o=Number(o.toFixed(1)),i=Number(i.toFixed(1)),[o,i]}function o(e){var r=e[0],t=e[1],a=r/ee*180,o=t/ee*180;return o=180/Math.PI*(2*Math.atan(Math.exp(o*Math.PI/180))-Math.PI/2),a=Number(a.toFixed(6)),o=Number(o.toFixed(6)),[a,o]}function i(e,r,t){var a=e[0],o=e[1],i=E(r,t),n=(a+ee)/i,s=(o+ee)/i;return[n,s,r]}function n(e,r,t){e=x(e,t);var o=a(e),n=i(o,r);return m(n)}function s(e,r,t){if(e=x(e,t),0===r)return[0,0,0];var a=n(e,r);return h(a)}function p(e,r){if(0===r)return[0,0,0];var t=i(e,r);return m(t)}function l(e,r){var t=e[0],a=e[1],o=e[2],i=E(o,r),n=t*i-ee,s=a*i-ee;return n=Number(n.toFixed(1)),s=Number(s.toFixed(1)),[n,s]}function m(e,r,t){r=r||256;var a=e[0],o=e[1],i=e[2];if(0===i)return[0,0,0];w(i,t);var n=Math.ceil(a/r)-1,s=Math.ceil(o/r)-1;return 0>n&&(n=0),0>s&&(s=0),[n,s,i]}function c(e,r,t){v(e,t),r=r||256;var a=e[0],o=e[1],i=e[2],n=l([a*r,o*r,i]),s=l([(a+1)*r,(o+1)*r,i]);return[n[0],n[1],s[0],s[1]]}function u(e,r){v(e,r);var t=e[0],a=e[1],i=e[2];if(0===i)return[-180,-85.051129,180,85.051129];var n=c([t,a,i]),s=n[0],p=n[1],l=n[2],m=n[3],u=o([s,p,i]),d=o([l,m,i]);return[u[0],u[1],d[0],d[1]]}function d(e){var r=f(e);return c(r)}function g(e){var r=f(e);return u(r)}function h(e,r){v(e,r);var t=e[0],a=e[1],o=e[2];if(0===o)return[0,0,0];var i=t,n=Math.pow(2,o)-1-a;return[i,n,o]}function f(e){var r=e[0],t=e[1],a=e[2],o=r,i=Math.pow(2,a)-t-1;return[o,i,a]}function M(e){var r=f(e);return y(r)}function y(e,r){v(e,r);var t=e[0],a=e[1],o=e[2];if(0===o)return"";var i="";return a=Math.pow(2,o)-1-a,I(o,0,-1).map(function(e){var r=0,o=1<<e-1;0!==(t&o)&&(r+=1),0!==(a&o)&&(r+=2),i=i.concat(r)}),i}function T(e){var r=S(e);return f(r)}function S(e){var r=0,t=0,a=e.length;return I(a,0,-1).map(function(o){var i=1<<o-1;switch(parseInt(e[a-o],0)){case 0:break;case 1:r+=i;break;case 2:t+=i;break;case 3:r+=i,t+=i;break;default:throw new Error("Invalid Quadkey digit sequence")}}),[r,t,a]}function b(e){var r=a([e[0],e[1]]),t=a([e[2],e[3]]);return[r[0],r[1],t[0],t[1]]}function v(e,r){var t=e[0],a=e[1],o=e[2];if(r===!1)return e;if(w(o),void 0===t||null===t)throw new Error("<x> is required");if(void 0===a||null===a)throw new Error("<y> is required");if(0>t)throw new Error("<x> must not be less than 0");if(0>a)throw new Error("<y> must not be less than 0");var i=Math.pow(2,o);if(t>=i||a>=i)throw new Error("Illegal parameters for tile");return e}function w(e){if(e===!1)return e;if(void 0===e||null===e)throw new Error("<zoom> is required");if(0>e)throw new Error("<zoom> cannot be less than 0");if(e>30)throw new Error("<zoom> cannot be greater than 30");return e}function x(e,r){if(r===!1)return e;var t=O(e[0]),a=G(e[1]);return a>85&&(a=85),-85>t&&(a=-85),[t,a]}function E(r,t){return e(t)/Math.pow(2,r)}function I(e,r,t){null==r&&(r=e||0,e=0),t||(t=e>r?-1:1);for(var a=Math.max(Math.ceil((r-e)/t),0),o=Array(a),i=0;a>i;i++,e+=t)o[i]=e;return o}function N(e){if(e&&e[0]&&4===e.length&&void 0===e[0][0])return e;if(e&&e[0]&&void 0!==e[0][0]){var r=e[0][0],t=e[0][1],a=e[0][2],o=e[0][3];return e.map(function(e){e[0]<r&&(r=e[0]),e[1]<t&&(t=e[1]),e[2]>a&&(a=e[2]),e[3]>o&&(o=e[3])}),[r,t,a,o]}}function G(e){if(null===e||void 0===e)throw new Error("lat is required");return(e>90||-90>e)&&(e%=180,e>90&&(e=-180+e),-90>e&&(e=180+e),e===-0&&(e=0)),e}function O(e){if(null===e||void 0===e)throw new Error("lng is required");return(e>180||-180>e)&&(e%=360,e>180&&(e=-360+e),-180>e&&(e=360+e),e===-0&&(e=0)),e}function Z(e,r){var t=e[0],a=e[1],o=e[2];if(r=C(e,r),r=k(r),r=R(r),r=r.replace(/{(zoom|z|level)}/,String(o)),r=r.replace(/{(x|col)}/,String(t)),r=r.replace(/{(y|row)}/,String(a)),r.match(/{-y}/)&&(r=r.replace(/{-y}/,String(ie(e)[1]))),r.match(/{(quadkey|q)}/)&&(r=r.replace(/{(quadkey|q)}/,ne(e))),r.match(/{.*}/))throw new Error("Could not completly parse URL"+r);return r}function C(e,r){r=r.replace(/{height}/gi,"256"),r=r.replace(/{width}/gi,"256"),r=r.replace(/{(proj|srs|crs)}/gi,"EPSG:3857");var t;return t=r.match(/EPSG:(3857|900913)/i)?se(oe(e)):oe(e),r.match(/{bbox}/i)&&(r=r.replace(/{bbox}/gi,t.join(","))),r}function k(e){return e=e.replace(/{TileCol}/gi,"{x}"),e=e.replace(/{TileRow}/gi,"{y}"),e=e.replace(/{TileMatrix}/gi,"{z}"),e=e.replace(/{TileMatrixSet}/gi,"GoogleMapsCompatible"),e=e.replace(/{Style}/gi,"default")}function R(e){if(e.match(/{s}/))return e.replace(/{s}/gi,String(W(["a","b","c"])));var r=/{switch:([a-z,\d]*)}/,t=e.match(r);return t?e.replace(r,String(W(t[1].split(",")))):e}function W(e){return null===e||void 0===e||0===e.length?void 0:e[Math.floor(Math.random()*e.length)]}var A={name:"ESRI National Geographic World Map",categories:["esri","national","geographic","world"],minZoom:0,maxZoom:12,url:"https://services.arcgisonline.com/arcgis/rest/services/NatGeo_World_Map/MapServer/WMTS/tile/1.0.0/World_Imagery/{Style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.jpg",description:"This map is designed to be used as a general reference map for informational and educational purposes as well as a basemap by GIS professionals and other users for creating web maps and web mapping applications.",attribution:"National Geographic, Esri, DeLorme, HERE, UNEP-WCMC, USGS, NASA, ESA, METI, NRCAN, GEBCO, NOAA, INCREMENT P",format:"jpg",type:"baselayer"},B={name:"ESRI Ocean Basemap",categories:["esri","ocean","world"],minZoom:0,maxZoom:10,url:"https://services.arcgisonline.com/arcgis/rest/services/Ocean_Basemap/MapServer/WMTS/tile/1.0.0/World_Imagery/{Style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.jpg",description:"The ocean basemap includes bathymetry, surface and subsurface feature names, and derived depths. This service is designed to be used as a basemap by marine GIS professionals and as a reference map by anyone interested in ocean data.",attribution:"Esri, GEBCO, NOAA, National Geographic, DeLorme, HERE, Geonames.org, and other contributors",format:"jpg",type:"baselayer"},j={name:"ESRI USA Topo Maps",categories:["esri","topo","topographicusa"],minZoom:0,maxZoom:15,url:"https://services.arcgisonline.com/arcgis/rest/services/USA_Topo_Maps/MapServer/WMTS/tile/1.0.0/World_Imagery/{Style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.jpg",description:"This map service presents detailed USGS topographic maps for the United States at multiple scales.",attribution:"© 2011 National Geographic Society, i-cubed",format:"jpg",type:"baselayer"},_={name:"ESRI World Imagery",categories:["esri","imagery","world"],minZoom:0,maxZoom:19,url:"https://services.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer/WMTS/tile/1.0.0/World_Imagery/{Style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.jpg",description:"This map service presents satellite imagery for the world and high-resolution imagery for the United States and other areas around the world.",attribution:"Esri, DigitalGlobe, Earthstar Geographics, CNES/Airbus DS, GeoEye, USDA FSA, USGS, Getmapping, Aerogrid, IGN, IGP, and the GIS User Community",format:"jpg",type:"baselayer"},P={name:"ESRI World Street Map",categories:["esri","street","world"],minZoom:0,maxZoom:19,url:"https://services.arcgisonline.com/arcgis/rest/services/World_Street_Map/MapServer/WMTS/tile/1.0.0/World_Topo_Map/{Style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.jpg",description:"This map service presents highway-level data for the world and street-level data for North America, Europe, Africa, parts of the Middle East, Asia, and more.",attribution:"Esri, HERE, DeLorme, USGS, Intermap, INCREMENT P, NRCAN, Esri Japan, METI, Esri China (Hong Kong), Esri (Thailand), MapmyIndia, © OpenStreetMap contributors, and the GIS User Community",format:"jpg",type:"baselayer"},U={name:"ESRI World Topographic Map",categories:["esri","topo","topographic","world"],minZoom:0,maxZoom:19,url:"https://services.arcgisonline.com/arcgis/rest/services/World_Topo_Map/MapServer/WMTS/tile/1.0.0/World_Imagery/{Style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.jpg",description:"This world topographic map includes boundaries, cities, water features, physiographic features, parks, landmarks, transportation, and buildings.",attribution:"Esri, HERE, DeLorme, Intermap, INCREMENT P, GEBCO, USGS, FAO, NPS, NRCAN, GeoBase, IGN, Kadaster NL, Ordnance Survey, Esri Japan, METI, Esri China (Hong Kong), swisstopo, MapmyIndia, © OpenStreetMap contributors, GIS User Community",format:"jpg",type:"baselayer"},q={natgeo:A,ocean:B,usatopo:j,imagery:_,street:P,topo:U},L={name:"Bing Imagery",categories:["bing","imagery","world"],minZoom:1,maxZoom:20,url:"https://ecn.t{switch:0,1,2,3}.tiles.virtualearth.net/tiles/a{quadkey}.jpeg?g=5250",description:"Tiles from Bing",attribution:"Map data © Bing",format:"jpg",type:"baselayer"},z={imagery:L},F={name:"OpenStreetMap Standard",categories:["openstreetmap","standard","world"],minZoom:0,maxZoom:19,url:"https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",description:"Tiles from OpenStreetMap",attribution:"Map data © OpenStreetMap",format:"png",type:"baselayer"},D={name:"OpenStreetMap Cycle Map",categories:["openstreetmap","cycle","world"],minZoom:0,maxZoom:19,url:"https://{s}.tile.thunderforest.com/cycle/{z}/{x}/{y}.png",description:"Tiles from OpenStreetMap",attribution:"Map data © OpenStreetMap",format:"png",type:"baselayer"},H={name:"OpenStreetMap Humanitarian",categories:["openstreetmap","hot","humanitarian","world"],minZoom:0,maxZoom:19,url:"https://tile-{s}.openstreetmap.fr/hot/{z}/{x}/{y}.png",description:"Tiles from OpenStreetMap",attribution:"Map data © OpenStreetMap",format:"png",type:"baselayer"},Q={name:"OpenStreetMap Transport Map",categories:["openstreetmap","transport","world"],minZoom:0,maxZoom:19,url:"https://{s}.tile.thunderforest.com/transport/{z}/{x}/{y}.png",description:"Tiles from OpenStreetMap",attribution:"Map data © OpenStreetMap",format:"png",type:"baselayer"},K={name:"OpenStreetMap Wikimedia",categories:["openstreetmap","wikimedia","world"],minZoom:0,maxZoom:19,url:"https://maps.wikimedia.org/osm-intl/{z}/{x}/{y}.png",description:"Tiles from OSM",attribution:"Map data © OSM",format:"png",type:"baselayer"},J={name:"OpenStreetMap Lyrk",categories:["openstreetmap","lyrk","world"],minZoom:0,maxZoom:19,url:"https://tiles.lyrk.org/ls/{z}/{x}/{y}?apikey=6e8cfef737a140e2a58c8122aaa26077",description:"Tiles from OpenStreetMap",attribution:"Map data © OpenStreetMap",format:"png",type:"baselayer"},V={standard:F,cycle:D,hot:H,transport:Q,wikimedia:K,lyrk:J},X={name:"Toporama",categories:["toporama","canada","topographic","english"],minZoom:1,maxZoom:19,url:"http://wms.ess-ws.nrcan.gc.ca/wms/toporama_en?&service=WMS&request=GetMap&layers=WMS-Toporama&format=image/jpeg&transparent=false&version=1.1.1&height={height}&width={width}&srs={srs}&bbox={bbox}",description:"Tiles from Toporama",attribution:"Map data Toporama",format:"jpeg",type:"baselayer"},Y={en:X},$={esri:q,bing:z,openstreetmap:V,toporama:Y},ee=2*Math.PI*6378137/2,re={hash:r,bboxToCenter:t,lngLatToMeters:a,metersToLngLat:o,metersToPixels:i,lngLatToTile:n,lngLatToGoogle:s,metersToTile:p,pixelsToMeters:l,pixelsToTile:m,tileToBBoxMeters:c,tileToBBox:u,googleToBBoxMeters:d,googleToBBox:g,tileToGoogle:h,googleToTile:f,googleToQuadkey:M,tileToQuadkey:y,quadkeyToTile:T,quadkeyToGoogle:S,bboxToMeters:b,validateTile:v,validateZoom:w,validateLngLat:x,resolution:E,range:I,maxBBox:N,latitude:G,longitude:O},te=$,ae=re,oe=ae.googleToBBox,ie=ae.googleToTile,ne=ae.googleToQuadkey,se=ae.bboxToMeters,pe={parse:Z,providers:te,wms:C,wmts:k,parseSwitch:R,sample:W};return pe});
!function(e,r){"object"==typeof exports&&"undefined"!=typeof module?module.exports=r():"function"==typeof define&&define.amd?define(r):e.slippyTile=r()}(this,function(){function e(r,t,o){var n,i,a,u,l,f,c,s,g,h,d=0,p=0,y="FeatureCollection"===r.type,m="Feature"===r.type,v=y?r.features.length:1;for(n=0;v>n;n++)for(g=y?r.features[n].geometry:m?r.geometry:r,h="GeometryCollection"===g.type,c=h?g.geometries.length:1,u=0;c>u;u++)if(f=h?g.geometries[u]:g,s=f.coordinates,d=!o||"Polygon"!==f.type&&"MultiPolygon"!==f.type?0:1,"Point"===f.type)t(s,p),p++;else if("LineString"===f.type||"MultiPoint"===f.type)for(i=0;i<s.length;i++)t(s[i],p),p++;else if("Polygon"===f.type||"MultiLineString"===f.type)for(i=0;i<s.length;i++)for(a=0;a<s[i].length-d;a++)t(s[i][a],p),p++;else if("MultiPolygon"===f.type)for(i=0;i<s.length;i++)for(a=0;a<s[i].length;a++)for(l=0;l<s[i][a].length-d;l++)t(s[i][a][l],p),p++;else{if("GeometryCollection"!==f.type)throw new Error("Unknown Geometry Type");for(i=0;i<f.geometries.length;i++)e(f.geometries[i],t,o)}}function r(r,t,o,n){var i=o;return e(r,function(e,r){i=0===r&&void 0===o?e:t(i,e,r)},n),i}function t(e,r){var t;switch(e.type){case"FeatureCollection":for(t=0;t<e.features.length;t++)r(e.features[t].properties,t);break;case"Feature":r(e.properties,0)}}function o(e,r,o){var n=o;return t(e,function(e,t){n=0===t&&void 0===o?e:r(n,e,t)}),n}function n(e,r){if("Feature"===e.type)r(e,0);else if("FeatureCollection"===e.type)for(var t=0;t<e.features.length;t++)r(e.features[t],t)}function i(e,r,t){var o=t;return n(e,function(e,n){o=0===n&&void 0===t?e:r(o,e,n)}),o}function a(r){var t=[];return e(r,function(e){t.push(e)}),t}function u(e,r){var t,o,n,i,a,u,l,f=0,c="FeatureCollection"===e.type,s="Feature"===e.type,g=c?e.features.length:1;for(t=0;g>t;t++)for(u=c?e.features[t].geometry:s?e.geometry:e,l="GeometryCollection"===u.type,a=l?u.geometries.length:1,n=0;a>n;n++)if(i=l?u.geometries[n]:u,"Point"===i.type||"LineString"===i.type||"MultiPoint"===i.type||"Polygon"===i.type||"MultiLineString"===i.type||"MultiPolygon"===i.type)r(i,f),f++;else{if("GeometryCollection"!==i.type)throw new Error("Unknown Geometry Type");for(o=0;o<i.geometries.length;o++)r(i.geometries[o],f),f++}}function l(e,r,t){var o=t;return u(e,function(e,n){o=0===n&&void 0===t?e:r(o,e,n)}),o}function f(e,r){if(!e)throw new Error("No geometry passed");return{type:"Feature",properties:r||{},geometry:e}}function c(e){if(!e)throw new Error("bbox is required");if(Array.isArray(e)||(e=Me(e)),4!==e.length)throw new Error("bbox must have 4 numbers");var r=e[0],t=e[1],o=e[2],n=e[3];return-180>r&&o>180&&(r=-180,o=180),-180>o&&r>180&&(r=-180,o=180),-90>t&&n>90&&(t=-90,n=90),-90>n&&t>90&&(t=-90,n=90),n>90&&(n=90),-90>t&&(t=-90),Math.abs(e[0]-e[2])>360&&(r=-180,o=180),Math.abs(e[1]-e[3])>180&&(t=-90,n=90),r=h(r),t=g(t),o=h(o),n=g(n),[r,t,o,n]}function s(e){var r;if(!e)throw new Error("center is required");if(Array.isArray(e))if(4===e.length){var t=e,o=t[0],n=t[1],i=t[2],a=t[3];r=[(o+i)/2,(n+a)/2]}else r=[e[0],e[1]];else r=Te(e).geometry.coordinates;if(2!==r.length)throw new Error("center must have 2 numbers");var u=h(r[0]),l=g(r[1]);return[u,l]}function g(e){if(void 0===e||null===e)throw new Error("lat is required");return(e>90||-90>e)&&(e%=180,e>90&&(e=-180+e),-90>e&&(e=180+e),e===-0&&(e=0)),e}function h(e){if(void 0===e||void 0===e)throw new Error("lng is required");return(e>180||-180>e)&&(e%=360,e>180&&(e=-360+e),-180>e&&(e=360+e),e===-0&&(e=0)),e}function d(e){return e=e||256,2*Math.PI*6378137/e}function p(e){var r=e[0],t=e[1],o=e[2];return(1<<o)*((1<<o)+r)+t}function y(e){var r=e[0],t=e[1],o=e[2],n=e[3],i=(r-o)/2+o,a=(t-n)/2+n;return i=Number(i.toFixed(6)),a=Number(a.toFixed(6)),[i,a]}function m(e,r){e=A(e,r);var t=e[0],o=e[1],n=t*ke/180,i=Math.log(Math.tan((90+o)*Math.PI/360))/(Math.PI/180);return i=i*ke/180,n=Number(n.toFixed(1)),i=Number(i.toFixed(1)),[n,i]}function v(e){var r=e[0],t=e[1],o=r/ke*180,n=t/ke*180;return n=180/Math.PI*(2*Math.atan(Math.exp(n*Math.PI/180))-Math.PI/2),o=Number(o.toFixed(6)),n=Number(n.toFixed(6)),[o,n]}function w(e,r,t){var o=e[0],n=e[1],i=j(r,t),a=(o+ke)/i,u=(n+ke)/i;return[a,u,r]}function b(e,r,t){e=A(e,t);var o=m(e),n=w(o,r);return x(n)}function M(e,r,t){if(e=A(e,t),0===r)return[0,0,0];var o=b(e,r);return F(o)}function T(e,r){if(0===r)return[0,0,0];var t=w(e,r);return x(t)}function E(e,r){var t=e[0],o=e[1],n=e[2],i=j(n,r),a=t*i-ke,u=o*i-ke;return a=Number(a.toFixed(1)),u=Number(u.toFixed(1)),[a,u]}function x(e,r,t){r=r||256;var o=e[0],n=e[1],i=e[2];if(0===i)return[0,0,0];z(i,t);var a=Math.ceil(o/r)-1,u=Math.ceil(n/r)-1;return 0>a&&(a=0),0>u&&(u=0),[a,u,i]}function P(e,r,t){R(e,t),r=r||256;var o=e[0],n=e[1],i=e[2],a=E([o*r,n*r,i]),u=E([(o+1)*r,(n+1)*r,i]);return[a[0],a[1],u[0],u[1]]}function k(e,r){R(e,r);var t=e[0],o=e[1],n=e[2];if(0===n)return[-180,-85.051129,180,85.051129];var i=P([t,o,n]),a=i[0],u=i[1],l=i[2],f=i[3],c=v([a,u,n]),s=v([l,f,n]);return[c[0],c[1],s[0],s[1]]}function C(e){var r=N(e);return P(r)}function S(e){var r=N(e);return k(r)}function F(e,r){R(e,r);var t=e[0],o=e[1],n=e[2];if(0===n)return[0,0,0];var i=t,a=Math.pow(2,n)-1-o;return[i,a,n]}function N(e){var r=e[0],t=e[1],o=e[2],n=r,i=Math.pow(2,o)-t-1;return[n,i,o]}function L(e){var r=N(e);return q(r)}function q(e,r){R(e,r);var t=e[0],o=e[1],n=e[2];if(0===n)return"";var i="";return o=Math.pow(2,n)-1-o,Q(n,0,-1).map(function(e){var r=0,n=1<<e-1;0!==(t&n)&&(r+=1),0!==(o&n)&&(r+=2),i=i.concat(r)}),i}function G(e){var r=I(e);return N(r)}function I(e){var r=0,t=0,o=e.length;return Q(o,0,-1).map(function(n){var i=1<<n-1;switch(parseInt(e[o-n],0)){case 0:break;case 1:r+=i;break;case 2:t+=i;break;case 3:r+=i,t+=i;break;default:throw new Error("Invalid Quadkey digit sequence")}}),[r,t,o]}function B(e){var r=m([e[0],e[1]]),t=m([e[2],e[3]]);return[r[0],r[1],t[0],t[1]]}function R(e,r){var t=e[0],o=e[1],n=e[2];if(r===!1)return e;if(z(n),void 0===t||null===t)throw new Error("<x> is required");if(void 0===o||null===o)throw new Error("<y> is required");if(0>t)throw new Error("<x> must not be less than 0");if(0>o)throw new Error("<y> must not be less than 0");var i=Math.pow(2,n);if(t>=i||o>=i)throw new Error("Illegal parameters for tile");return e}function z(e){if(e===!1)return e;if(void 0===e||null===e)throw new Error("<zoom> is required");if(0>e)throw new Error("<zoom> cannot be less than 0");if(e>30)throw new Error("<zoom> cannot be greater than 30");return e}function A(e,r){if(r===!1)return e;var t=Pe(e[0]),o=xe(e[1]);return o>85&&(o=85),-85>o&&(o=-85),[t,o]}function j(e,r){return d(r)/Math.pow(2,e)}function Q(e,r,t){null==r&&(r=e||0,e=0),t||(t=e>r?-1:1);for(var o=Math.max(Math.ceil((r-e)/t),0),n=Array(o),i=0;o>i;i++,e+=t)n[i]=e;return n}function U(e){if(e&&e[0]&&4===e.length&&void 0===e[0][0])return e;if(e&&e[0]&&void 0!==e[0][0]){var r=e[0][0],t=e[0][1],o=e[0][2],n=e[0][3];return e.map(function(e){e[0]<r&&(r=e[0]),e[1]<t&&(t=e[1]),e[2]>o&&(o=e[2]),e[3]>n&&(n=e[3])}),[r,t,o,n]}}function D(e,r){if(r.match(/{height|width|proj|srs|crs|bbox}/gi)){r=r.replace(/{height}/gi,"256"),r=r.replace(/{width}/gi,"256"),r=r.replace(/{(proj|srs|crs)}/gi,"EPSG:3857");var t;t=r.match(/EPSG:(3857|900913)/i)?qe(Fe(e)):Fe(e),r.match(/{bbox}/i)&&(r=r.replace(/{bbox}/gi,t.join(",")))}return r}function Z(e){return e.match(/{TileCol|TileRow|TileMatrix|TileMatrixSet|Style}/gi)&&(e=e.replace(/{TileCol}/gi,"{x}"),e=e.replace(/{TileRow}/gi,"{y}"),e=e.replace(/{TileMatrix}/gi,"{z}"),e=e.replace(/{TileMatrixSet}/gi,"GoogleMapsCompatible"),e=e.replace(/{Style}/gi,"default")),e}function H(e){if(e.match(/{s}/gi))return e.replace(/{s}/gi,String(J(["a","b","c"])));var r=/{switch:([a-z,\d]*)}/gi,t=e.match(r);return t?e.replace(r,String(J(t[1].split(",")))):e}function J(e){return null===e||void 0===e||0===e.length?void 0:e[Math.floor(Math.random()*e.length)]}var K=e,O=r,V=t,W=o,X=n,Y=i,$=a,_=u,ee=l,re={coordEach:K,coordReduce:O,propEach:V,propReduce:W,featureEach:X,featureReduce:Y,coordAll:$,geomEach:_,geomReduce:ee},te=re.coordEach,oe=function(e){var r=[1/0,1/0,-(1/0),-(1/0)];return te(e,function(e){r[0]>e[0]&&(r[0]=e[0]),r[1]>e[1]&&(r[1]=e[1]),r[2]<e[0]&&(r[2]=e[0]),r[3]<e[1]&&(r[3]=e[1])}),r},ne=f,ie=function(e,r){if(!e)throw new Error("No coordinates passed");if(void 0===e.length)throw new Error("Coordinates must be an array");if(e.length<2)throw new Error("Coordinates must be at least 2 numbers long");if("number"!=typeof e[0]||"number"!=typeof e[1])throw new Error("Coordinates must numbers");return f({type:"Point",coordinates:e},r)},ae=function(e,r){if(!e)throw new Error("No coordinates passed");for(var t=0;t<e.length;t++){var o=e[t];if(o.length<4)throw new Error("Each LinearRing of a Polygon must have 4 or more Positions.");for(var n=0;n<o[o.length-1].length;n++)if(o[o.length-1][n]!==o[0][n])throw new Error("First and last Position are not equivalent.")}return f({type:"Polygon",coordinates:e},r)},ue=function(e,r){if(!e)throw new Error("No coordinates passed");return f({type:"LineString",coordinates:e},r)},le=function(e){if(!e)throw new Error("No features passed");return{type:"FeatureCollection",features:e}},fe=function(e,r){if(!e)throw new Error("No coordinates passed");return f({type:"MultiLineString",coordinates:e},r)},ce=function(e,r){if(!e)throw new Error("No coordinates passed");return f({type:"MultiPoint",coordinates:e},r)},se=function(e,r){if(!e)throw new Error("No coordinates passed");return f({type:"MultiPolygon",coordinates:e},r)},ge=function(e,r){if(!e)throw new Error("No geometries passed");return f({type:"GeometryCollection",geometries:e},r)},he={miles:3960,nauticalmiles:3441.145,degrees:57.2957795,radians:1,inches:250905600,yards:6969600,meters:6373e3,metres:6373e3,kilometers:6373,kilometres:6373,feet:20908792.65},de=function(e,r){var t=he[r||"kilometers"];if(void 0===t)throw new Error("Invalid unit");return e*t},pe=function(e,r){var t=he[r||"kilometers"];if(void 0===t)throw new Error("Invalid unit");return e/t},ye=function(e,r){var t=he[r||"kilometers"];if(void 0===t)throw new Error("Invalid unit");return e/t*57.2958},me={feature:ne,point:ie,polygon:ae,lineString:ue,featureCollection:le,multiLineString:fe,multiPoint:ce,multiPolygon:se,geometryCollection:ge,radiansToDistance:de,distanceToRadians:pe,distanceToDegrees:ye},ve=oe,we=me.point,be=function(e){var r=ve(e),t=(r[0]+r[2])/2,o=(r[1]+r[3])/2;return we([t,o])},Me=oe,Te=be,Ee={bbox:c,longitude:h,latitude:g,center:s},xe=Ee.latitude,Pe=Ee.longitude,ke=2*Math.PI*6378137/2,Ce={hash:p,bboxToCenter:y,lngLatToMeters:m,metersToLngLat:v,metersToPixels:w,lngLatToTile:b,lngLatToGoogle:M,metersToTile:T,pixelsToMeters:E,pixelsToTile:x,tileToBBoxMeters:P,tileToBBox:k,googleToBBoxMeters:C,googleToBBox:S,tileToGoogle:F,googleToTile:N,googleToQuadkey:L,tileToQuadkey:q,quadkeyToTile:G,quadkeyToGoogle:I,bboxToMeters:B,validateTile:R,validateZoom:z,validateLngLat:A,resolution:j,range:Q,maxBBox:U},Se=Ce,Fe=Se.googleToBBox,Ne=Se.googleToTile,Le=Se.googleToQuadkey,qe=Se.bboxToMeters,Ge=function(e,r){var t=e[0],o=e[1],n=e[2];if(r=D(e,r),r=Z(r),r=H(r),r=r.replace(/{(zoom|z|level)}/gi,String(n)),r=r.replace(/{(x|col)}/gi,String(t)),r=r.replace(/{(y|row)}/gi,String(o)),r.match(/{-y}/)&&(r=r.replace(/{-y}/gi,String(Ne(e)[1]))),r.match(/{(quadkey|q)}/)&&(r=r.replace(/{(quadkey|q)}/gi,Le(e))),r.match(/{.*}/))throw new Error("Could not completly parse URL"+r);return r};return Ge});

@@ -1,23 +0,5 @@

export interface Provider {
attribution: string
categories: string[]
description: string
name: string
format: 'png' | 'pbf' | 'webp' | 'jpg'
url: string
type: 'baselayer' | 'overlay'
minZoom: number
maxZoom: number
}
interface Providers {
[provider: string]: {
[service: string]: Provider
}
}
export type Tile = [number, number, number];
export function parse(tile: Tile, url: string): string;
export function wms(tile: Tile, url: string): string;
export function wmts(url: string): string;
export function parseSwitch(url: string): string;
export function sample<T extends string | number>(collection: T[]): T;
export declare const providers: Providers;
type Tile = [number, number, number];
declare function slippyTile(tile: Tile, url: string): string;
declare namespace slippyTile { }
export = slippyTile

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

var providers = require('./providers')
var mercator = require('global-mercator')

@@ -11,2 +10,3 @@ var googleToBBox = mercator.googleToBBox

*
* @name slippyTile
* @param {Tile} tile Tile [x, y, z]

@@ -16,6 +16,6 @@ * @param {string} url URL Tile scheme or provider unique key

* @example
* slippyTile.parse([10, 15, 8], 'https://{s}.tile.openstreetmap.org/{zoom}/{x}/{y}.png')
* slippyTile([10, 15, 8], 'https://{s}.tile.openstreetmap.org/{zoom}/{x}/{y}.png')
* //='https://c.tile.openstreetmap.org/8/10/15.png'
*/
function parse (tile, url) {
module.exports = function (tile, url) {
var x = tile[0]

@@ -27,8 +27,8 @@ var y = tile[1]

url = parseSwitch(url)
url = url.replace(/{(zoom|z|level)}/, String(zoom))
url = url.replace(/{(x|col)}/, String(x))
url = url.replace(/{(y|row)}/, String(y))
if (url.match(/{-y}/)) { url = url.replace(/{-y}/, String(googleToTile(tile)[1])) }
if (url.match(/{(quadkey|q)}/)) { url = url.replace(/{(quadkey|q)}/, googleToQuadkey(tile)) }
if (url.match(/{.*}/)) { throw new Error('Could not completly parse URL' + url) }
url = url.replace(/{(zoom|z|level)}/gi, String(zoom))
url = url.replace(/{(x|col)}/gi, String(x))
url = url.replace(/{(y|row)}/gi, String(y))
if (url.match(/{-y}/)) url = url.replace(/{-y}/gi, String(googleToTile(tile)[1]))
if (url.match(/{(quadkey|q)}/)) url = url.replace(/{(quadkey|q)}/gi, googleToQuadkey(tile))
if (url.match(/{.*}/)) throw new Error('Could not completly parse URL' + url)
return url

@@ -40,2 +40,3 @@ }

*
* @private
* @param {Tile} tile Tile [x, y, z]

@@ -45,17 +46,19 @@ * @param {string} url WMTS URL scheme

* @example
* slippyTile.wms([10, 15, 8], 'https://<Tile Server>/?layers=imagery&SRS={proj}&WIDTH={width}&HEIGHT={height}&BBOX={bbox}')
* wms([10, 15, 8], 'https://<Tile Server>/?layers=imagery&SRS={proj}&WIDTH={width}&HEIGHT={height}&BBOX={bbox}')
* //='https://<Tile Server>/?layers=imagery&SRS=EPSG:3857&WIDTH=256&HEIGHT=256&BBOX=-165.9375,82.676285,-164.53125,82.853382'
*/
function wms (tile, url) {
url = url.replace(/{height}/gi, '256')
url = url.replace(/{width}/gi, '256')
url = url.replace(/{(proj|srs|crs)}/gi, 'EPSG:3857')
var bbox
if (url.match(/EPSG:(3857|900913)/i)) {
bbox = bboxToMeters(googleToBBox(tile))
} else {
bbox = googleToBBox(tile)
if (url.match(/{height|width|proj|srs|crs|bbox}/gi)) {
url = url.replace(/{height}/gi, '256')
url = url.replace(/{width}/gi, '256')
url = url.replace(/{(proj|srs|crs)}/gi, 'EPSG:3857')
var bbox
if (url.match(/EPSG:(3857|900913)/i)) {
bbox = bboxToMeters(googleToBBox(tile))
} else {
bbox = googleToBBox(tile)
}
if (url.match(/{bbox}/i)) { url = url.replace(/{bbox}/gi, bbox.join(',')) }
}
if (url.match(/{bbox}/i)) { url = url.replace(/{bbox}/gi, bbox.join(',')) }
return url

@@ -67,14 +70,17 @@ }

*
* @private
* @param {string} url WMTS URL scheme
* @returns {string} parsed URL
* @example
* slippyTile.wmts('https://<Tile Server>/WMTS/tile/1.0.0/Imagery/{Style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.jpg')
* wmts('https://<Tile Server>/WMTS/tile/1.0.0/Imagery/{Style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.jpg')
* //='https://<Tile Server>/WMTS/tile/1.0.0/Imagery/default/GoogleMapsCompatible/{z}/{y}/{x}.jpg'
*/
function wmts (url) {
url = url.replace(/{TileCol}/gi, '{x}')
url = url.replace(/{TileRow}/gi, '{y}')
url = url.replace(/{TileMatrix}/gi, '{z}')
url = url.replace(/{TileMatrixSet}/gi, 'GoogleMapsCompatible')
url = url.replace(/{Style}/gi, 'default')
if (url.match(/{TileCol|TileRow|TileMatrix|TileMatrixSet|Style}/gi)) {
url = url.replace(/{TileCol}/gi, '{x}')
url = url.replace(/{TileRow}/gi, '{y}')
url = url.replace(/{TileMatrix}/gi, '{z}')
url = url.replace(/{TileMatrixSet}/gi, 'GoogleMapsCompatible')
url = url.replace(/{Style}/gi, 'default')
}
return url

@@ -86,6 +92,7 @@ }

*
* @private
* @param {string} url - URL Scheme
* @returns {string} Parsed URL with switch replaced
* @example
* slippyTile.parseSwitch('http://tile-{switch:a,b,c}.openstreetmap.fr/hot/{zoom}/{x}/{y}.png')
* parseSwitch('http://tile-{switch:a,b,c}.openstreetmap.fr/hot/{zoom}/{x}/{y}.png')
* //='http://tile-b.openstreetmap.fr/hot/{zoom}/{x}/{y}.png'

@@ -95,7 +102,7 @@ */

// Default simple switch
if (url.match(/{s}/)) {
if (url.match(/{s}/gi)) {
return url.replace(/{s}/gi, String(sample(['a', 'b', 'c'])))
}
// Custom switch
var pattern = /{switch:([a-z,\d]*)}/
var pattern = /{switch:([a-z,\d]*)}/gi
var found = url.match(pattern)

@@ -111,2 +118,3 @@ if (found) {

*
* @private
* @name sample

@@ -116,3 +124,3 @@ * @param {Array} array List of items

* @example
* slippyTile.sample(['a', 'b', 'c'])
* sample(['a', 'b', 'c'])
* //='b'

@@ -124,10 +132,1 @@ */

}
module.exports = {
parse: parse,
providers: providers,
wms: wms,
wmts: wmts,
parseSwitch: parseSwitch,
sample: sample
}
{
"name": "slippy-tile",
"version": "1.13.1",
"version": "2.0.0",
"description": "Helps convert Slippy Map url tile schemas",

@@ -10,4 +10,3 @@ "main": "index.js",

"index.js",
"docs",
"providers"
"docs"
],

@@ -17,3 +16,3 @@ "scripts": {

"pretest": "npm run lint",
"test": "jest test.js --coverage",
"test": "node test.js",
"bench": "node bench.js",

@@ -28,5 +27,14 @@ "lint": "standard index.js",

"license": "MIT",
"dependencies": {
"global-mercator": "^2.5.0"
},
"keywords": [
"gis",
"geo",
"geojs",
"geospatial",
"geography",
"map",
"url",
"slippy",
"tile",
"slippytile"
],
"devDependencies": {

@@ -44,24 +52,8 @@ "benchmark": "^2.1.3",

"standard": "^8.6.0",
"tape": "^4.6.3",
"uglifyjs": "^2.4.10"
},
"keywords": [
"gis",
"geo",
"geojs",
"geospatial",
"geography",
"map",
"url",
"slippy",
"tile",
"slippytile"
],
"testEnvironment": "node",
"jest": {
"verbose": true
},
"standard": {
"env": "jest",
"ignore": "docs"
"dependencies": {
"global-mercator": "^2.6.0"
}
}
# Slippy Tile
[![Build Status](https://travis-ci.org/DenisCarriere/slippy-tile.svg?branch=master)](https://travis-ci.org/DenisCarriere/slippy-tile)
[![Coverage Status](https://coveralls.io/repos/github/DenisCarriere/slippy-tile/badge.svg?branch=master)](https://coveralls.io/github/DenisCarriere/slippy-tile?branch=master)
[![npm version](https://badge.fury.io/js/slippy-tile.svg)](https://badge.fury.io/js/slippy-tile)

@@ -29,31 +28,9 @@ [![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/DenisCarriere/slippy-tile/master/LICENSE)

```javascript
var slippyTile = require('slippy-tile')
var tile = [10, 15, 8] // [x, y, zoom]
var scheme = 'https://{switch:a,b,c}.tile.openstreetmap.org/{zoom}/{x}/{y}.png'
var url = slippyTile.parse(tile, scheme)
var url = slippyTile(tile, scheme)
//= https://b.tile.openstreetmap.org/8/10/15.png
```
## Providers
| Name | Unique Key |
| ----------------------------- | ----------------------- |
| OpenStreetMap Standard | openstreetmap.standard |
| OpenStreetMap Cycle Map | openstreetmap.cycle |
| OpenStreetMap Humanitarian | openstreetmap.hot |
| OpenStreetMap Transport | openstreetmap.transport |
| OpenStreetMap Wikimedia | openstreetmap.wikimedia |
| OpenStreetMap Lyrk | openstreetmap.lyrk |
| Bing Imagery | bing.imagery |
| Strava Cycling & Running | strava.both |
| National Geographic World Map | esri.natgeo |
| ESRI Imagery | esri.imagery |
| ESRI Ocean Basemap | esri.ocean |
| ESRI USA Topo Maps | esri.usatopo |
| ESRI World Street Map | esri.street |
| ESRI World Topographic Map | esri.topo |
| DigitalGlobe Imagery | digitalglobe.imagery |
| DigitalGlobe Hybrid | digitalglobe.hybrid |
| Mapbox Imagery | mapbox.imagery |
| Mapbox Outdoors | mapbox.outdoors |
## Scheme

@@ -63,8 +40,2 @@

```javascript
const scheme = 'https://{switch:a,b,c}.tile.openstreetmap.org/{zoom}/{x}/{y}.png'
const url = slippyTile.parse([10, 15, 8], scheme)
//= https://b.tile.openstreetmap.org/8/10/15.png
```
**Options**

@@ -85,14 +56,4 @@

<!-- Generated by documentation.js. Update this documentation by updating the source code. -->
### slippyTile
#### Table of Contents
- [parse](#parse)
- [wms](#wms)
- [wmts](#wmts)
- [parseSwitch](#parseswitch)
- [sample](#sample)
### parse
Substitutes the given tile information [x, y, z] to the URL tile scheme.

@@ -108,3 +69,3 @@

```javascript
slippyTile.parse([10, 15, 8], 'https://{s}.tile.openstreetmap.org/{zoom}/{x}/{y}.png')
slippyTile([10, 15, 8], 'https://{s}.tile.openstreetmap.org/{zoom}/{x}/{y}.png')
//='https://c.tile.openstreetmap.org/8/10/15.png'

@@ -114,70 +75,1 @@ ```

Returns **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** parsed URL
### wms
Parse WMS URL to friendly SlippyTile format
**Parameters**
- `tile` **Tile** Tile [x, y, z]
- `url` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** WMTS URL scheme
**Examples**
```javascript
slippyTile.wms([10, 15, 8], 'https://<Tile Server>/?layers=imagery&SRS={proj}&WIDTH={width}&HEIGHT={height}&BBOX={bbox}')
//='https://<Tile Server>/?layers=imagery&SRS=EPSG:3857&WIDTH=256&HEIGHT=256&BBOX=-165.9375,82.676285,-164.53125,82.853382'
```
Returns **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** parsed URL
### wmts
Parse WMTS URL to friendly SlippyTile URL format
**Parameters**
- `url` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** WMTS URL scheme
**Examples**
```javascript
slippyTile.wmts('https://<Tile Server>/WMTS/tile/1.0.0/Imagery/{Style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.jpg')
//='https://<Tile Server>/WMTS/tile/1.0.0/Imagery/default/GoogleMapsCompatible/{z}/{y}/{x}.jpg'
```
Returns **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** parsed URL
### parseSwitch
Replaces {switch:a,b,c} with a random sample.
**Parameters**
- `url` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** URL Scheme
**Examples**
```javascript
slippyTile.parseSwitch('http://tile-{switch:a,b,c}.openstreetmap.fr/hot/{zoom}/{x}/{y}.png')
//='http://tile-b.openstreetmap.fr/hot/{zoom}/{x}/{y}.png'
```
Returns **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Parsed URL with switch replaced
### sample
Sample an item from a given list
**Parameters**
- `array` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)** List of items
**Examples**
```javascript
slippyTile.sample(['a', 'b', 'c'])
//='b'
```
Returns **any** Single item from the list

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

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

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc