cut-to-pack-service/target/classes/static/js/vendor/highcharts/modules/tiledwebmap.src.js

954 lines
48 KiB
JavaScript

/**
* @license Highcharts JS v11.1.0 (2023-06-05)
*
* (c) 2009-2022
*
* License: www.highcharts.com/license
*/
(function (factory) {
if (typeof module === 'object' && module.exports) {
factory['default'] = factory;
module.exports = factory;
} else if (typeof define === 'function' && define.amd) {
define('highcharts/modules/tiledwebmap', ['highcharts'], function (Highcharts) {
factory(Highcharts);
factory.Highcharts = Highcharts;
return factory;
});
} else {
factory(typeof Highcharts !== 'undefined' ? Highcharts : undefined);
}
}(function (Highcharts) {
'use strict';
var _modules = Highcharts ? Highcharts._modules : {};
function _registerModule(obj, path, args, fn) {
if (!obj.hasOwnProperty(path)) {
obj[path] = fn.apply(null, args);
if (typeof CustomEvent === 'function') {
window.dispatchEvent(
new CustomEvent(
'HighchartsModuleLoaded',
{ detail: { path: path, module: obj[path] }
})
);
}
}
}
_registerModule(_modules, 'Maps/TilesProviders/OpenStreetMap.js', [], function () {
/* *
* OpenStreetMap provider, used for tile map services
* */
class OpenStreetMap {
constructor() {
this.subdomains = ['a', 'b', 'c'];
this.themes = {
Standard: {
url: 'https://{s}.tile.openstreetmap.org/{zoom}/{x}/{y}.png',
minZoom: 0,
maxZoom: 19
},
Hot: {
url: 'https://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png',
minZoom: 0,
maxZoom: 19
},
OpenTopoMap: {
url: 'https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png',
minZoom: 0,
maxZoom: 17,
credits: `Map data: &copy; <a href="https://www.openstreetmap.org/copyright">
OpenStreetMap</a> contributors, <a href="https://viewfinderpanoramas.org">SRTM</a>
| Map style: &copy; <a href="https://opentopomap.org">OpenTopoMap</a>
(<a href="https://creativecommons.org/licenses/by-sa/3.0/">CC-BY-SA</a>)`
}
};
this.initialProjectionName = 'WebMercator';
this.defaultCredits = `Map data \u00a92023 <a href="https://www.openstreetmap.org/copyright">
OpenStreetMap</a>`;
}
}
return OpenStreetMap;
});
_registerModule(_modules, 'Maps/TilesProviders/Stamen.js', [], function () {
/* *
* Stamen provider, used for tile map services
* */
class Stamen {
constructor() {
this.subdomains = ['a', 'b', 'c', 'd'];
this.themes = {
Toner: {
url: 'https://stamen-tiles-{s}.a.ssl.fastly.net/toner/{z}/{x}/{y}.png',
minZoom: 0,
maxZoom: 20
},
TonerBackground: {
url: 'https://stamen-tiles-{s}.a.ssl.fastly.net/toner-background/{z}/{x}/{y}.png',
minZoom: 0,
maxZoom: 20
},
TonerLite: {
url: 'https://stamen-tiles-{s}.a.ssl.fastly.net/toner-lite/{z}/{x}/{y}.png',
minZoom: 0,
maxZoom: 20
},
Terrain: {
url: 'https://stamen-tiles-{s}.a.ssl.fastly.net/terrain/{z}/{x}/{y}.png',
minZoom: 0,
maxZoom: 18
},
TerrainBackground: {
url: 'https://stamen-tiles-{s}.a.ssl.fastly.net/terrain-background/{z}/{x}/{y}.png',
minZoom: 0,
maxZoom: 18
},
Watercolor: {
url: 'https://stamen-tiles-{s}.a.ssl.fastly.net/watercolor/{z}/{x}/{y}.png',
minZoom: 1,
maxZoom: 16,
credits: `\u00a9 Map tiles by <a href="https://stamen.com">Stamen Design</a>,
under <a href="https://creativecommons.org/licenses/by/3.0">CC BY 3.0</a>.
Data by <a href="https://openstreetmap.org">OpenStreetMap</a>, under
<a href="https://creativecommons.org/licenses/by-sa/3.0">CC BY SA</a>`
}
};
this.initialProjectionName = 'WebMercator';
this.defaultCredits = `\u00a9 Map tiles by <a href="https://stamen.com">Stamen Design</a>,
under <a href="https://creativecommons.org/licenses/by/3.0">CC BY 3.0</a>.
Data by <a href="https://openstreetmap.org">OpenStreetMap</a>, under
<a href="https://www.openstreetmap.org/copyright">ODbL</a>`;
}
}
return Stamen;
});
_registerModule(_modules, 'Maps/TilesProviders/LimaLabs.js', [], function () {
/* *
* LimaLabs provider, used for tile map services
* */
class LimaLabs {
constructor() {
this.themes = {
Standard: {
url: 'https://cdn.lima-labs.com/{zoom}/{x}/{y}.png?api={apikey}',
minZoom: 0,
maxZoom: 20
}
};
this.initialProjectionName = 'WebMercator';
this.defaultCredits = 'Map data \u00a92023 <a href="https://maps.lima-labs.com/">LimaLabs</a>';
this.requiresApiKey = true;
}
}
return LimaLabs;
});
_registerModule(_modules, 'Maps/TilesProviders/Thunderforest.js', [], function () {
/* *
* Thunderforest provider, used for tile map services
* */
class Thunderforest {
constructor() {
this.subdomains = ['a', 'b', 'c'];
this.themes = {
OpenCycleMap: {
url: 'https://{s}.tile.thunderforest.com/cycle/{z}/{x}/{y}.png?apikey={apikey}',
minZoom: 0,
maxZoom: 22
},
Transport: {
url: 'https://{s}.tile.thunderforest.com/transport/{z}/{x}/{y}.png?apikey={apikey}',
minZoom: 0,
maxZoom: 22
},
TransportDark: {
url: 'https://{s}.tile.thunderforest.com/transport-dark/{z}/{x}/{y}.png?apikey={apikey}',
minZoom: 0,
maxZoom: 22
},
SpinalMap: {
url: 'https://{s}.tile.thunderforest.com/spinal-map/{z}/{x}/{y}.png?apikey={apikey}',
minZoom: 0,
maxZoom: 22
},
Landscape: {
url: 'https://{s}.tile.thunderforest.com/landscape/{z}/{x}/{y}.png?apikey={apikey}',
minZoom: 0,
maxZoom: 22
},
Outdoors: {
url: 'https://{s}.tile.thunderforest.com/outdoors/{z}/{x}/{y}.png?apikey={apikey}',
minZoom: 0,
maxZoom: 22
},
Pioneer: {
url: 'https://{s}.tile.thunderforest.com/pioneer/{z}/{x}/{y}.png?apikey={apikey}',
minZoom: 0,
maxZoom: 22
},
MobileAtlas: {
url: 'https://{s}.tile.thunderforest.com/mobile-atlas/{z}/{x}/{y}.png?apikey={apikey}',
minZoom: 0,
maxZoom: 22
},
Neighbourhood: {
url: 'https://{s}.tile.thunderforest.com/neighbourhood/{z}/{x}/{y}.png?apikey={apikey}',
minZoom: 0,
maxZoom: 22
}
};
this.initialProjectionName = 'WebMercator';
this.defaultCredits = `Maps \u00a9 <a href="https://www.thunderforest.com">Thunderforest</a>,
Data \u00a9 <a href="https://www.openstreetmap.org/copyright">OpenStreetMap contributors</a>`;
this.requiresApiKey = true;
}
}
return Thunderforest;
});
_registerModule(_modules, 'Maps/TilesProviders/Esri.js', [], function () {
/* *
* Esri provider, used for tile map services
* */
class Esri {
constructor() {
this.themes = {
WorldStreetMap: {
url: 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}',
minZoom: 0,
maxZoom: 20
},
DeLorme: {
url: 'https://server.arcgisonline.com/ArcGIS/rest/services/Specialty/DeLorme_World_Base_Map/MapServer/tile/{z}/{y}/{x}',
minZoom: 1,
maxZoom: 11,
credits: 'Tiles &copy; Esri &mdash; Copyright: &copy;2012 DeLorme'
},
WorldTopoMap: {
url: 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}',
minZoom: 0,
maxZoom: 20,
credits: `Tiles &copy; Esri &mdash; Esri, DeLorme, NAVTEQ, TomTom,
Intermap, iPC, USGS, FAO, NPS, NRCAN, GeoBase, Kadaster NL,
Ordnance Survey, Esri Japan, METI, Esri China (Hong Kong),
and the GIS User Community`
},
WorldImagery: {
url: 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',
minZoom: 0,
maxZoom: 20,
credits: `Tiles &copy; Esri &mdash; Source: Esri, i-cubed, USDA,
USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP,
and the GIS User Community`
},
WorldTerrain: {
url: 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Terrain_Base/MapServer/tile/{z}/{y}/{x}',
minZoom: 0,
maxZoom: 13,
credits: `Tiles &copy; Esri &mdash; Source: USGS, Esri, TANA,
DeLorme, and NPS`
},
WorldShadedRelief: {
url: 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer/tile/{z}/{y}/{x}',
minZoom: 0,
maxZoom: 13,
credits: 'Tiles &copy; Esri &mdash; Source: Esri'
},
WorldPhysical: {
url: 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Physical_Map/MapServer/tile/{z}/{y}/{x}',
minZoom: 0,
maxZoom: 8,
credits: `Tiles &copy; Esri &mdash; Source: US National Park
Service`
},
NatGeoWorldMap: {
url: 'https://server.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer/tile/{z}/{y}/{x}',
minZoom: 0,
maxZoom: 16,
credits: `Tiles &copy; Esri &mdash; National Geographic, Esri,
DeLorme, NAVTEQ, UNEP-WCMC, USGS, NASA, ESA, METI, NRCAN, GEBCO,
NOAA, iPC`
},
WorldGrayCanvas: {
url: 'https://server.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer/tile/{z}/{y}/{x}',
minZoom: 0,
maxZoom: 16,
credits: 'Tiles &copy; Esri &mdash; Esri, DeLorme, NAVTEQ'
}
};
this.initialProjectionName = 'WebMercator';
this.defaultCredits = `Tiles &copy; Esri &mdash; Source: Esri, DeLorme, NAVTEQ,
USGS, Intermap, iPC, NRCAN, Esri Japan, METI, Esri China (Hong Kong),
Esri (Thailand), TomTom, 2012`;
}
}
return Esri;
});
_registerModule(_modules, 'Maps/TilesProviders/USGS.js', [], function () {
/* *
* USGS provider, used for tile map services
* */
class USGS {
constructor() {
this.themes = {
USTopo: {
url: 'https://basemap.nationalmap.gov/arcgis/rest/services/USGSTopo/MapServer/tile/{z}/{y}/{x}',
minZoom: 0,
maxZoom: 20
},
USImagery: {
url: 'https://basemap.nationalmap.gov/arcgis/rest/services/USGSImageryOnly/MapServer/tile/{z}/{y}/{x}',
minZoom: 0,
maxZoom: 20
},
USImageryTopo: {
url: 'https://basemap.nationalmap.gov/arcgis/rest/services/USGSImageryTopo/MapServer/tile/{z}/{y}/{x}',
minZoom: 0,
maxZoom: 20
}
};
this.initialProjectionName = 'WebMercator';
this.defaultCredits = `Tiles courtesy of the <a href="https://usgs.gov/">U.S.
Geological Survey</a>`;
}
}
return USGS;
});
_registerModule(_modules, 'Maps/TilesProviders/TilesProvidersRegistry.js', [_modules['Maps/TilesProviders/OpenStreetMap.js'], _modules['Maps/TilesProviders/Stamen.js'], _modules['Maps/TilesProviders/LimaLabs.js'], _modules['Maps/TilesProviders/Thunderforest.js'], _modules['Maps/TilesProviders/Esri.js'], _modules['Maps/TilesProviders/USGS.js']], function (OpenStreetMap, Stamen, LimaLabs, Thunderforest, Esri, USGS) {
/* *
*
* !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
*
* */
const registry = {
OpenStreetMap,
Stamen,
LimaLabs,
Thunderforest,
Esri,
USGS
};
return registry;
});
_registerModule(_modules, 'Series/TiledWebMap/TiledWebMapSeries.js', [_modules['Core/Series/SeriesRegistry.js'], _modules['Maps/TilesProviders/TilesProvidersRegistry.js'], _modules['Core/Chart/Chart.js'], _modules['Core/Utilities.js']], function (SeriesRegistry, TilesProvidersRegistry, Chart, U) {
/* *
*
* (c) 2010-2023 Hubert Kozik, Kamil Musiałowski
*
* License: www.highcharts.com/license
*
* !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
*
* */
const { seriesTypes: { map: MapSeries } } = SeriesRegistry;
const { addEvent, defined, error, merge, pick } = U;
/**
* The series type
*
* @private
* @class
* @name Highcharts.seriesTypes.tiledwebmap
*
* @augments Highcharts.Series
*/
class TiledWebMapSeries extends MapSeries {
constructor() {
/* *
*
* Static properties
*
* */
super(...arguments);
/* *
*
* Properties
*
* */
this.options = void 0;
this.redrawTiles = false;
this.isAnimating = false;
}
/**
*
* Functions
*
*/
/**
* Convert map coordinates in longitude/latitude to tile
*
* @function Highcharts.MapView#lonLatToTile
* @since 11.1.0
* @param {Highcharts.MapLonLatObject} lonLat
* The map coordinates
* @return {Highcharts.PositionObject}
* Array of x and y positions of the tile
*/
lonLatToTile(lonLat, zoom) {
const { lon, lat } = lonLat, xTile = Math.floor((lon + 180) / 360 * Math.pow(2, zoom)), yTile = Math.floor((1 - Math.log(Math.tan(lat * Math.PI / 180) +
1 / Math.cos(lat * Math.PI / 180)) / Math.PI) /
2 * Math.pow(2, zoom));
return { x: xTile, y: yTile };
}
/**
* Convert tile to map coordinates in longitude/latitude
*
* @function Highcharts.MapView#tileToLonLat
* @since 11.1.0
* @param xTile
* Position x of the tile
* @param yTile
* Position y of the tile
* @param zTile
* Zoom of the tile
* @return {Highcharts.MapLonLatObject}
* The map coordinates
*/
tileToLonLat(xTile, yTile, zTile) {
const lon = xTile / Math.pow(2, zTile) * 360 - 180, n = Math.PI - 2 * Math.PI * yTile / Math.pow(2, zTile), lat = (180 /
Math.PI * Math.atan(0.5 * (Math.exp(n) - Math.exp(-n))));
return { lon, lat };
}
drawPoints() {
var _a;
const { chart } = this, mapView = chart.mapView;
if (!mapView) {
return;
}
if (!this.tiles) {
this.tiles = {};
}
if (!this.transformGroups) {
this.transformGroups = [];
}
const { tiles, transformGroups } = this, series = this, options = this.options, provider = options.provider, { zoom } = mapView, lambda = pick((mapView.projection.options.rotation &&
mapView.projection.options.rotation[0]), 0), worldSize = 400.979322, tileSize = 256, duration = chart.renderer.forExport ? 0 : 200, animateTiles = (duration) => {
Object.keys(tiles).forEach((zoomKey) => {
if ((parseFloat(zoomKey) === (mapView.zoom < 0 ? 0 :
Math.floor(mapView.zoom))) ||
(series.minZoom &&
(mapView.zoom < 0 ? 0 :
Math.floor(mapView.zoom)) < series.minZoom &&
parseFloat(zoomKey) === series.minZoom) ||
(series.maxZoom &&
(mapView.zoom < 0 ? 0 :
Math.floor(mapView.zoom)) > series.maxZoom &&
parseFloat(zoomKey) === series.maxZoom)) {
Object.keys(tiles[zoomKey].tiles)
.forEach((key, i) => {
tiles[zoomKey].tiles[key].animate({
opacity: 1
}, {
duration: duration
}, function () {
if (i === Object.keys(tiles[zoomKey].tiles)
.length - 1) {
tiles[zoomKey].isActive = true;
}
});
});
}
else {
Object.keys(tiles[zoomKey].tiles)
.forEach((key, i) => {
tiles[zoomKey].tiles[key].animate({
opacity: 0
}, {
duration: duration,
defer: duration / 2
}, function () {
tiles[zoomKey].tiles[key].destroy();
delete tiles[zoomKey].tiles[key];
if (i === Object.keys(tiles[zoomKey].tiles)
.length - 1) {
tiles[zoomKey].isActive = false;
tiles[zoomKey].loaded = false;
}
});
});
}
});
};
let zoomFloor = zoom < 0 ? 0 : Math.floor(zoom), maxTile = Math.pow(2, zoomFloor), scale = ((tileSize / worldSize) * Math.pow(2, zoom)) /
((tileSize / worldSize) * Math.pow(2, zoomFloor)), scaledTileSize = scale * 256;
if (provider && (provider.type || provider.url)) {
if (provider.type && !provider.url) {
const ProviderDefinition = TilesProvidersRegistry[provider.type];
if (!defined(ProviderDefinition)) {
error('Highcharts warning: Tiles Provider \'' +
provider.type + '\' not defined in the Provider' +
'Registry.', false);
return;
}
const def = new ProviderDefinition(), { initialProjectionName: providerProjection } = def;
let theme, subdomain = '';
if (provider.theme && defined(def.themes[provider.theme])) {
theme = def.themes[provider.theme];
}
else {
// if nothing set take first theme
const firstTheme = Object.keys(def.themes)[0];
theme = def.themes[firstTheme];
error('Highcharts warning: The Tiles Provider\'s Theme \'' +
provider.theme + '\' is not defined in the Provider ' +
'definition - falling back to \'' + firstTheme + '\'.', false);
}
if (provider.subdomain &&
def.subdomains &&
def.subdomains.indexOf(provider.subdomain) !== -1) {
subdomain = provider.subdomain;
}
else if (defined(def.subdomains)) {
subdomain = pick(def.subdomains && def.subdomains[0], '');
error('Highcharts warning: The Tiles Provider\'s Subdomain ' +
'\'' + provider.subdomain + '\' is not defined in ' +
'the Provider definition - falling back to \'' +
subdomain + '\'.', false);
}
if (def.requiresApiKey) {
if (provider.apiKey) {
theme.url =
theme.url.replace('{apikey}', provider.apiKey);
}
else {
error('Highcharts warning: The Tiles Provider requires ' +
'API Key to use tiles, use provider.apiKey to ' +
'provide a token.', false);
theme.url = theme.url.replace('?apikey={apikey}', '');
}
}
provider.url = theme.url
.replace('{s}', subdomain);
this.minZoom = theme.minZoom;
this.maxZoom = theme.maxZoom;
// Add as credits.text, to prevent changing the default mapText
const creditsText = pick(chart.userOptions.credits && chart.userOptions.credits.text, 'Highcharts.com ' + pick(theme.credits, def.defaultCredits));
if (chart.credits) {
chart.credits.update({
text: creditsText
});
}
else {
chart.addCredits({
text: creditsText,
style: pick((_a = chart.options.credits) === null || _a === void 0 ? void 0 : _a.style, {})
});
}
if (mapView.projection.options.name !== providerProjection) {
error('Highcharts warning: The set projection is different ' +
'than supported by Tiles Provider.', false);
}
}
else {
if (!mapView.projection.options.name) {
error('Highcharts warning: The set projection is different ' +
'than supported by Tiles Provider.', false);
}
}
// if zoom is smaller/higher than supported by provider
if (defined(this.minZoom) && zoomFloor < this.minZoom) {
zoomFloor = this.minZoom;
maxTile = Math.pow(2, zoomFloor);
scale = ((tileSize / worldSize) * Math.pow(2, zoom)) /
((tileSize / worldSize) * Math.pow(2, zoomFloor));
scaledTileSize = scale * 256;
}
else if (defined(this.maxZoom) && zoomFloor > this.maxZoom) {
zoomFloor = this.maxZoom;
maxTile = Math.pow(2, zoomFloor);
scale = ((tileSize / worldSize) * Math.pow(2, zoom)) /
((tileSize / worldSize) * Math.pow(2, zoomFloor));
scaledTileSize = scale * 256;
}
if (mapView.projection && mapView.projection.def) {
// Always true for tile maps
mapView.projection.hasCoordinates = true;
if (!transformGroups[zoomFloor]) {
transformGroups[zoomFloor] =
chart.renderer.g().add(this.group);
}
const replaceVariables = (url, x, y, zoom) => url
.replace('{x}', x.toString())
.replace('{y}', y.toString())
.replace('{zoom}', zoom.toString())
.replace('{z}', zoom.toString());
const addTile = (x, y, givenZoom, translateX, translateY) => {
const modX = x % maxTile, modY = y % maxTile, tileX = modX < 0 ? modX + maxTile : modX, tileY = modY < 0 ? modY + maxTile : modY;
if (!tiles[`${givenZoom}`].tiles[`${x},${y}`]) {
if (provider.url) {
const url = replaceVariables(provider.url, tileX, tileY, givenZoom);
tiles[givenZoom].loaded = false;
tiles[`${givenZoom}`].tiles[`${x},${y}`] =
chart.renderer.image(url, (x * scaledTileSize) - translateX, (y * scaledTileSize) - translateY, scaledTileSize, scaledTileSize)
.attr({
zIndex: 2,
opacity: 0
})
.on('load', function () {
if (provider.onload) {
provider.onload.apply(this);
}
if ((givenZoom ===
(mapView.zoom < 0 ? 0 :
Math.floor(mapView.zoom))) ||
givenZoom === series.minZoom) {
tiles[`${givenZoom}`]
.actualTilesCount++;
// if last tile
if (tiles[`${givenZoom}`]
.howManyTiles ===
tiles[`${givenZoom}`]
.actualTilesCount) {
tiles[givenZoom].loaded = true;
// fade-in new tiles if there is
// no other animation
if (!series.isAnimating) {
series.redrawTiles = false;
animateTiles(duration);
}
else {
series.redrawTiles = true;
}
tiles[`${givenZoom}`]
.actualTilesCount = 0;
}
}
})
.add(transformGroups[givenZoom]);
tiles[`${givenZoom}`].tiles[`${x},${y}`].posX = x;
tiles[`${givenZoom}`].tiles[`${x},${y}`].posY = y;
tiles[`${givenZoom}`].tiles[`${x},${y}`]
.originalURL = url;
}
}
};
// calculate topLeft and bottomRight corners without normalize
const topLeftUnits = mapView.pixelsToProjectedUnits({
x: 0,
y: 0
}), topLeftArr = mapView.projection.def.inverse([topLeftUnits.x, topLeftUnits.y]), topLeft = {
lon: topLeftArr[0] - lambda,
lat: topLeftArr[1]
}, bottomRightUnits = mapView.pixelsToProjectedUnits({
x: chart.plotWidth,
y: chart.plotHeight
}), bottomRightArr = mapView.projection.def.inverse([bottomRightUnits.x, bottomRightUnits.y]), bottomRight = {
lon: bottomRightArr[0] - lambda,
lat: bottomRightArr[1]
};
// do not support vertical looping
if (topLeft.lat > mapView.projection.maxLatitude ||
bottomRight.lat < -1 * mapView.projection.maxLatitude) {
topLeft.lat = mapView.projection.maxLatitude;
bottomRight.lat = -1 * mapView.projection.maxLatitude;
}
const startPos = this.lonLatToTile(topLeft, zoomFloor), endPos = this.lonLatToTile(bottomRight, zoomFloor);
// calculate group translations based on first loaded tile
const firstTileLonLat = this.tileToLonLat(startPos.x, startPos.y, zoomFloor), units = mapView.projection.def.forward([
firstTileLonLat.lon + lambda,
firstTileLonLat.lat
]), firstTilePx = mapView.projectedUnitsToPixels({
x: units[0], y: units[1]
}), translateX = (startPos.x * scaledTileSize - firstTilePx.x), translateY = (startPos.y * scaledTileSize - firstTilePx.y);
if (!tiles[`${zoomFloor}`]) {
tiles[`${zoomFloor}`] = {
tiles: {},
isActive: false,
howManyTiles: 0,
actualTilesCount: 0,
loaded: false
};
}
tiles[`${zoomFloor}`].howManyTiles =
(endPos.x - startPos.x + 1) * (endPos.y - startPos.y + 1);
tiles[`${zoomFloor}`].actualTilesCount = 0;
for (let x = startPos.x; x <= endPos.x; x++) {
for (let y = startPos.y; y <= endPos.y; y++) {
addTile(x, y, zoomFloor, translateX, translateY);
}
}
}
Object.keys(tiles).forEach((zoomKey) => {
Object.keys(tiles[zoomKey].tiles).forEach((key) => {
if (mapView.projection && mapView.projection.def) {
// calculate group translations based on first loaded
// tile
const scale = ((tileSize / worldSize) *
Math.pow(2, zoom)) / ((tileSize / worldSize) *
Math.pow(2, parseFloat(zoomKey))), scaledTileSize = scale * 256, firstTile = tiles[zoomKey].tiles[Object.keys(tiles[zoomKey].tiles)[0]], { posX, posY } = tiles[zoomKey].tiles[key];
if (defined(posX) &&
defined(posY) &&
defined(firstTile.posX) &&
defined(firstTile.posY)) {
const firstTileLonLat = this.tileToLonLat(firstTile.posX, firstTile.posY, parseFloat(zoomKey)), units = mapView.projection.def.forward([
firstTileLonLat.lon + lambda,
firstTileLonLat.lat
]), firstTilePx = mapView.projectedUnitsToPixels({
x: units[0], y: units[1]
}), tilesOffsetX = (firstTile.posX * scaledTileSize) -
firstTilePx.x, tilesOffsetY = (firstTile.posY * scaledTileSize) -
firstTilePx.y;
if (chart.renderer.globalAnimation &&
chart.hasRendered) {
const startX = Number(tiles[zoomKey].tiles[key].attr('x')), startY = Number(tiles[zoomKey].tiles[key].attr('y')), startWidth = Number(tiles[zoomKey].tiles[key].attr('width')), startHeight = Number(tiles[zoomKey].tiles[key].attr('height'));
const step = (now, fx) => {
tiles[zoomKey].tiles[key].attr({
x: (startX + (((posX * scaledTileSize) -
tilesOffsetX - startX) * fx.pos)),
y: (startY + (((posY * scaledTileSize) -
tilesOffsetY - startY) * fx.pos)),
width: (startWidth + ((Math.ceil(scaledTileSize) + 1 -
startWidth) * fx.pos)),
height: (startHeight + ((Math.ceil(scaledTileSize) + 1 -
startHeight) * fx.pos))
});
};
series.isAnimating = true;
tiles[zoomKey].tiles[key]
.attr({ animator: 0 })
.animate({ animator: 1 }, { step }, function () {
series.isAnimating = false;
// if animate ended after loading
// the tiles
if (series.redrawTiles) {
series.redrawTiles = false;
animateTiles(duration);
}
});
// When dragging or first rendering,
// animation is off
}
else {
// animate tiles if something broke
if (series.redrawTiles ||
parseFloat(zoomKey) !== zoomFloor ||
((tiles[zoomKey].isActive ||
parseFloat(zoomKey) === zoomFloor) &&
Object.keys(tiles[zoomKey].tiles)
.map((key) => tiles[zoomKey].tiles[key])
.some((tile) => tile.opacity === 0))) {
series.redrawTiles = false;
animateTiles(duration);
}
tiles[zoomKey].tiles[key].attr({
x: (posX * scaledTileSize) - tilesOffsetX,
y: (posY * scaledTileSize) - tilesOffsetY,
width: Math.ceil(scaledTileSize) + 1,
height: Math.ceil(scaledTileSize) + 1
});
}
}
}
});
});
}
else {
error('Highcharts warning: Tiles Provider not defined in the ' +
'Provider Registry.', false);
}
}
update() {
const series = this, { transformGroups } = series, chart = this.chart, mapView = chart.mapView, options = arguments[0], { provider } = options;
if (transformGroups) {
transformGroups.forEach((group) => {
if (Object.keys(group).length !== 0) {
group.destroy();
}
});
this.transformGroups = [];
}
if (mapView &&
!defined(mapView.options.projection) &&
provider &&
provider.type) {
const ProviderDefinition = TilesProvidersRegistry[provider.type];
if (ProviderDefinition) {
const def = new ProviderDefinition(), { initialProjectionName: providerProjectionName } = def;
mapView.update({
projection: {
name: providerProjectionName
}
});
}
}
super.update.apply(series, arguments);
}
}
/**
* A tiledwebmap series allows user to display dynamically joined individual
* images (tiles) and join them together to create a map.
*
* @sample maps/series-tiledwebmap/simple-demo-norway
* Simple demo of data for Norway on TiledWebMap
* @sample maps/series-tiledwebmap/only-twm
* OpenStreetMap demo
*
* @extends plotOptions.map
* @excluding affectsMapView, allAreas, allowPointSelect, animation,
* animationLimit, boostBlending, boostThreshold, borderColor, borderWidth,
* clip, color, colorAxis, colorByPoint, colorIndex, colorKey, colors,
* cursor, dashStyle, dataLabels, dataParser, dataURL, dragDrop,
* enableMouseTracking, findNearestPointBy, joinBy, keys, marker,
* negativeColor, nullColor, nullInteraction, onPoint, point,
* pointDescriptionFormatter, selected, shadow, showCheckbox,
* sonification, stickyTracking, tooltip, type
* @product highmaps
* @optionparent plotOptions.tiledwebmap
*/
TiledWebMapSeries.defaultOptions = merge(MapSeries.defaultOptions, {
states: {
inactive: {
enabled: false
}
}
});
addEvent(Chart, 'beforeMapViewInit', function (e) {
const twm = (this.options.series || []).filter((s) => s.type === 'tiledwebmap')[0], { geoBounds } = e;
if (twm && twm.provider && twm.provider.type && !twm.provider.url) {
const ProviderDefinition = TilesProvidersRegistry[twm.provider.type];
if (!defined(ProviderDefinition)) {
error('Highcharts warning: Tiles Provider not defined in the ' +
'Provider Registry.', false);
}
else {
const def = new ProviderDefinition(), { initialProjectionName: providerProjectionName } = def;
if (this.options.mapView) {
if (geoBounds) {
const { x1, y1, x2, y2 } = geoBounds;
this.options.mapView.recommendedMapView = {
projection: {
name: providerProjectionName,
parallels: [y1, y2],
rotation: [-(x1 + x2) / 2]
}
};
}
else {
this.options.mapView.recommendedMapView = {
projection: {
name: providerProjectionName
},
minZoom: 0
};
}
}
return false;
}
}
return true;
});
SeriesRegistry.registerSeriesType('tiledwebmap', TiledWebMapSeries);
/* *
*
* Default export
*
* */
/* *
*
* API options
*
* */
/**
* A `tiledwebmap` series. The [type](#series.tiledwebmap.type) option is
* not specified, it is inherited from [chart.type](#chart.type).
*
* @sample maps/series-tiledwebmap/simple-demo-norway
* Simple demo of data for Norway on TiledWebMap
* @sample maps/series-tiledwebmap/only-twm
* OpenStreetMap demo
*
* @extends series,plotOptions.tiledwebmap
* @excluding affectsMapView, allAreas, allowPointSelect, animation,
* animationLimit, boostBlending, boostThreshold, borderColor, borderWidth,
* clip, color, colorAxis, colorByPoint, colorIndex, colorKey, colors, cursor,
* dashStyle, dataLabels, dataParser, dataURL, dragDrop, enableMouseTracking,
* findNearestPointBy, joinBy, keys, marker, negativeColor, nullColor,
* nullInteraction, onPoint, point, pointDescriptionFormatter, selected, shadow,
* showCheckbox, stickyTracking, tooltip, type
* @product highmaps
* @apioption series.tiledwebmap
*/
/**
* Provider options for the series.
*
* @sample maps/series-tiledwebmap/human-anatomy
* Human Anatomy Explorer - Custom TiledWebMap Provider
*
* @since 11.1.0
* @product highmaps
* @apioption plotOptions.tiledwebmap.provider
*/
/**
* Provider type to pull data (tiles) from.
*
* @sample maps/series-tiledwebmap/basic-configuration
* Basic configuration for TiledWebMap
*
* @type {string}
* @since 11.1.0
* @product highmaps
* @apioption plotOptions.tiledwebmap.provider.type
*/
/**
* Set a tiles theme. Check the [providers documentation](https://www.highcharts.com/docs/maps/tiledwebmap)
* for official list of available themes.
*
* @sample maps/series-tiledwebmap/europe-timezones
* Imagery basemap for Europe
* @sample maps/series-tiledwebmap/hiking-trail
* Topo basemap and MapLine
*
* @type {string}
* @since 11.1.0
* @product highmaps
* @apioption plotOptions.tiledwebmap.provider.theme
*/
/**
* Subdomain required by each provider. Check the [providers documentation](https://www.highcharts.com/docs/maps/tiledwebmap)
* for available subdomains.
*
* @sample maps/series-tiledwebmap/basic-configuration
* Basic configuration for TiledWebMap
*
* @type {string}
* @since 11.1.0
* @product highmaps
* @apioption plotOptions.tiledwebmap.provider.subdomain
*/
/**
* API key for providers that require using one.
*
* @type {string}
* @since 11.1.0
* @product highmaps
* @apioption plotOptions.tiledwebmap.provider.apiKey
*/
/**
* Custom URL for providers not specified in [providers type](#series.
* tiledwebmap.provider.type). Available variables to use in URL are: `{x}`,
* `{y}`, `{z}` or `{zoom}`. Remember to always specify a projection, when
* using a custom URL.
*
* @sample maps/series-tiledwebmap/custom-url
* Custom URL with projection in TiledWebMap configuration
*
* @type {string}
* @since 11.1.0
* @product highmaps
* @apioption plotOptions.tiledwebmap.provider.url
*/
''; // adds doclets above to transpiled file
return TiledWebMapSeries;
});
_registerModule(_modules, 'masters/modules/tiledwebmap.src.js', [_modules['Core/Globals.js'], _modules['Maps/TilesProviders/TilesProvidersRegistry.js']], function (Highcharts, TilesProvidersRegistry) {
const G = Highcharts;
G.TilesProvidersRegistry = TilesProvidersRegistry;
});
}));