@elastic/ems-client
Version:
JavaScript client library for the Elastic Maps Service
514 lines (510 loc) • 13.6 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.TMSService = void 0;
var _lodash = _interopRequireDefault(require("lodash"));
var _ems_service = require("./ems_service");
var _utils = require("./utils");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } /*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
class TMSService extends _ems_service.AbstractEmsService {
constructor(config, emsClient, proxyPath) {
super(config, emsClient, proxyPath);
_defineProperty(this, "_config", void 0);
_defineProperty(this, "_getRasterStyleJson", _lodash.default.once(async () => {
const rasterUrl = this._getStyleUrlForLocale('raster');
if (rasterUrl) {
const url = this._proxyPath + this._getAbsoluteUrl(rasterUrl);
return this._emsClient.getManifest(this._emsClient.extendUrlWithParams(url));
} else {
return;
}
}));
_defineProperty(this, "_getVectorStyleJsonRaw", _lodash.default.once(async () => {
const vectorUrl = this._getStyleUrlForLocale('vector');
if (vectorUrl) {
const url = this._proxyPath + this._getAbsoluteUrl(vectorUrl);
const vectorJson = await this._emsClient.getManifest(this._emsClient.extendUrlWithParams(url));
return {
...vectorJson
};
} else {
return;
}
}));
_defineProperty(this, "_getVectorStyleJsonInlined", _lodash.default.once(async () => {
const vectorJson = await this._getVectorStyleJsonRaw();
if (vectorJson) {
const inlinedSources = {};
const {
sources
} = vectorJson;
for (const sourceName of Object.getOwnPropertyNames(sources)) {
const {
url
} = sources[sourceName];
if (url) {
const sourceUrl = this._proxyPath + this._getAbsoluteUrl(url);
const extendedUrl = this._emsClient.extendUrlWithParams(sourceUrl);
const sourceJson = await this._emsClient.getManifest(extendedUrl);
const tiles = sourceJson?.tiles?.map(tileUrl => {
const directUrl = this._proxyPath + this._getAbsoluteUrl(tileUrl);
return this._emsClient.extendUrlWithParams(directUrl);
});
inlinedSources[sourceName] = {
...sourceJson,
type: 'vector',
tiles
};
}
}
return {
...vectorJson,
sources: inlinedSources,
sprite: await this._getSpriteSheetRootPath(),
glyphs: await this._getUrlTemplateForGlyphs()
};
} else {
return;
}
}));
this._config = config;
}
/*
This method returns an array of objects with the layers and the new
layout['text-field'] to apply using map.setLayoutProperty
*/
static transformLanguageProperty(layer, lang) {
const supportedLang = this.SupportedLanguages.find(l => l.key === lang);
if (layer.type === 'symbol' && layer.layout !== undefined && supportedLang !== undefined) {
const omtLang = supportedLang.omt;
const textField = layer.layout['text-field'];
if (textField && typeof textField === 'string') {
return TMSService._getTextField(textField, omtLang);
}
}
return;
}
/*
This method returns an array of objects per layer, containing a list of
properties with new colors to apply using map.setPaintProperty
*/
static transformColorProperties(layer, color, operation, percentage) {
if (['background', 'fill', 'line', 'symbol'].indexOf(layer.type) !== -1 && layer.paint) {
const paint = layer.paint;
if (layer.type === 'symbol' && Object.keys(paint).length === 0) {
paint['text-color'] = 'rgb(0,0,0)';
}
const types = Object.keys(paint).filter(key => {
return ['background-color', 'circle-color', 'circle-stroke-color', 'fill-color', 'fill-extrusion-color', 'fill-outline-color', 'icon-color', 'icon-halo-color', 'line-color', 'text-color', 'text-halo-color'].indexOf(key) !== -1;
});
return types.map(type => {
const paintColor = paint[type];
return {
property: type,
color: paintColor && color ? (0, _utils.colorizeColor)(paintColor, color, operation, percentage) : paintColor
};
});
} else {
return [];
}
}
static _getTextField(label, lang) {
// Capture {name:xx} labels
const labelMatch = label.match(/\{name([:_])(.{2})\}/);
if (labelMatch && labelMatch[1] != lang) {
// Only apply if the languages are different
return ['coalesce', ['get', `name:${lang}`], ['get', `name${labelMatch[1]}${labelMatch[2]}`]];
} else if (label.includes('latin') && label.includes('nonlatin')) {
// Capture the common pattern {name:latin}\n{name:nonlatin}
return ['coalesce', ['get', `name:${lang}`], ['concat', ['get', 'name:latin'], '\n', ['get', 'name:nonlatin']]];
}
// If no case is found, return the input label
return label;
}
async getDefaultRasterStyle() {
const tileJson = await this._getRasterStyleJson();
if (tileJson) {
const tiles = tileJson.tiles.map(tile => this._proxyPath + this._getAbsoluteUrl(tile));
return {
...tileJson,
...{
tiles
}
};
} else {
return;
}
}
async getUrlTemplate() {
const tileJson = await this._getRasterStyleJson();
if (tileJson) {
const directUrl = this._proxyPath + this._getAbsoluteUrl(tileJson.tiles[0]);
return this._emsClient.extendUrlWithParams(directUrl);
} else {
return '';
}
}
async getUrlTemplateForVector(sourceId) {
const tileJson = await this._getVectorStyleJsonInlined();
const url = tileJson?.sources[sourceId]?.tiles?.pop();
if (url) {
const directUrl = this._proxyPath + this._getAbsoluteUrl(url);
return this._emsClient.extendUrlWithParams(directUrl);
} else {
return '';
}
}
async getVectorStyleSheet() {
return await this._getVectorStyleJsonInlined();
}
async getVectorStyleSheetRaw() {
return await this._getVectorStyleJsonRaw();
}
async getSpriteSheetMeta(isRetina = false) {
const metaUrl = await this.getSpriteSheetJsonPath(isRetina);
const spritePngs = await this.getSpriteSheetPngPath(isRetina);
if (metaUrl && spritePngs) {
const metaUrlExtended = this._emsClient.extendUrlWithParams(metaUrl);
const jsonMeta = await this._emsClient.getManifest(metaUrlExtended);
return {
png: spritePngs,
json: jsonMeta
};
} else {
return;
}
}
async getSpriteSheetJsonPath(isRetina = false) {
const spriteSheetRootPath = await this._getSpriteSheetRootPath();
if (spriteSheetRootPath) {
const suffix = isRetina ? '@2x' : '';
return spriteSheetRootPath + suffix + '.json';
} else {
return '';
}
}
async getSpriteSheetPngPath(isRetina = false) {
const spriteSheetRootPath = await this._getSpriteSheetRootPath();
if (spriteSheetRootPath) {
const suffix = isRetina ? '@2x' : '';
return spriteSheetRootPath + suffix + '.png';
} else {
return '';
}
}
getDisplayName() {
return this._emsClient.getValueInLanguage(this._config.name);
}
async getMinZoom(format = 'vector') {
switch (format) {
case 'vector':
{
const {
sources
} = (await this._getVectorStyleJsonInlined()) || {
sources: {}
};
return Math.min(...Object.values(sources).map(s => {
return s && s instanceof Object && 'minzoom' in s ? s['minzoom'] : null;
}).filter(minzoom => Number.isFinite(minzoom)));
}
case 'raster':
{
const {
minzoom
} = (await this._getRasterStyleJson()) || {};
return minzoom;
}
default:
return;
}
}
async getMaxZoom(format = 'vector') {
switch (format) {
case 'vector':
{
const {
sources
} = (await this._getVectorStyleJsonInlined()) || {
sources: {}
};
return Math.max(...Object.values(sources).map(s => {
return s && s instanceof Object && 'maxzoom' in s ? s['maxzoom'] : null;
}).filter(maxzoom => Number.isFinite(maxzoom)));
}
case 'raster':
{
const {
maxzoom
} = (await this._getRasterStyleJson()) || {};
return maxzoom;
}
default:
return;
}
}
getId() {
return this._config.id;
}
hasId(id) {
return this._config.id === id;
}
getApiUrl() {
return this._emsClient.getTileApiUrl();
}
_getStyleUrlForLocale(formatType) {
let vectorFormats = this._getFormats(formatType, this._emsClient.getLocale());
if (!vectorFormats.length) {
//fallback to default locale
vectorFormats = this._getFormats(formatType, this._emsClient.getDefaultLocale());
}
if (!vectorFormats.length) {
throw new Error(`Cannot find ${formatType} tile layer for locale ${this._emsClient.getLocale()} or ${this._emsClient.getDefaultLocale()}`);
}
const defaultStyle = vectorFormats[0];
if (defaultStyle && Object.prototype.hasOwnProperty.call(defaultStyle, 'url')) {
return defaultStyle.url;
}
}
_getFormats(formatType, locale) {
return this._config.formats.filter(format => format.locale === locale && format.format === formatType);
}
async _getSpriteSheetRootPath() {
const vectorStyleJson = await this._getVectorStyleJsonRaw();
if (vectorStyleJson?.sprite) {
return this._proxyPath + this._getAbsoluteUrl(vectorStyleJson.sprite.toString());
} else {
return '';
}
}
async _getUrlTemplateForGlyphs() {
const vectorStyleJson = await this._getVectorStyleJsonRaw();
if (vectorStyleJson?.glyphs) {
return this._proxyPath + this._getAbsoluteUrl(vectorStyleJson.glyphs);
} else {
return '';
}
}
}
exports.TMSService = TMSService;
/*
List of supported languages with labels and OMT codes extracted
from https://openmaptiles.org/languages
Keys are values for i18.locale from Kibana settings
and OMT codes for the rest.
*/
_defineProperty(TMSService, "SupportedLanguages", [{
key: 'ar',
omt: 'ar'
}, {
key: 'az',
omt: 'az'
}, {
key: 'be',
omt: 'be'
}, {
key: 'bg',
omt: 'bg'
}, {
key: 'br',
omt: 'br'
}, {
key: 'bs',
omt: 'bs'
}, {
key: 'ca',
omt: 'ca'
}, {
key: 'cs',
omt: 'cs'
}, {
key: 'cy',
omt: 'cy'
}, {
key: 'da',
omt: 'da'
}, {
key: 'de',
omt: 'de'
}, {
key: 'el',
omt: 'el'
}, {
key: 'en',
omt: 'en'
}, {
key: 'eo',
omt: 'eo'
}, {
key: 'es',
omt: 'es'
}, {
key: 'et',
omt: 'et'
}, {
key: 'fi',
omt: 'fi'
}, {
key: 'fr-fr',
omt: 'fr'
}, {
key: 'fy',
omt: 'fy'
}, {
key: 'ga',
omt: 'ga'
}, {
key: 'gd',
omt: 'gd'
}, {
key: 'he',
omt: 'he'
}, {
key: 'hi-in',
omt: 'hi'
}, {
key: 'hr',
omt: 'hr'
}, {
key: 'hu',
omt: 'hu'
}, {
key: 'hy',
omt: 'hy'
}, {
key: 'is',
omt: 'is'
}, {
key: 'it',
omt: 'it'
}, {
key: 'ja_kana',
omt: 'ja_kana'
}, {
key: 'ja_rm',
omt: 'ja_rm'
}, {
key: 'ja-jp',
omt: 'ja'
}, {
key: 'ka',
omt: 'ka'
}, {
key: 'kk',
omt: 'kk'
}, {
key: 'kn',
omt: 'kn'
}, {
key: 'ko_rm',
omt: 'ko_rm'
}, {
key: 'ko',
omt: 'ko'
}, {
key: 'la',
omt: 'la'
}, {
key: 'lb',
omt: 'lb'
}, {
key: 'lt',
omt: 'lt'
}, {
key: 'lv',
omt: 'lv'
}, {
key: 'mk',
omt: 'mk'
}, {
key: 'mt',
omt: 'mt'
}, {
key: 'nl',
omt: 'nl'
}, {
key: 'no',
omt: 'no'
}, {
key: 'pl',
omt: 'pl'
}, {
key: 'pt-pt',
omt: 'pt'
}, {
key: 'rm',
omt: 'rm'
}, {
key: 'ro',
omt: 'ro'
}, {
key: 'ru-ru',
omt: 'ru'
}, {
key: 'sk',
omt: 'sk'
}, {
key: 'sl',
omt: 'sl'
}, {
key: 'sq',
omt: 'sq'
}, {
key: 'sr-Ltn',
omt: 'sr-Ltn'
}, {
key: 'sr',
omt: 'sr'
}, {
key: 'sv',
omt: 'sv'
}, {
key: 'th',
omt: 'th'
}, {
key: 'tr',
omt: 'tr'
}, {
key: 'uk',
omt: 'uk'
}, {
key: 'zh-cn',
omt: 'zh'
}]);
/*
Suggested default operations for the different EMS styles
*/
_defineProperty(TMSService, "colorOperationDefaults", [{
style: 'road_map',
operation: 'mix',
percentage: 0.25
}, {
style: 'road_map_desaturated',
operation: 'screen',
percentage: 0.25
}, {
style: 'dark_map',
operation: 'dodge',
percentage: 0.25
}, {
style: 'high_contrast',
operation: 'screen',
percentage: 0.25
}, {
style: 'road_map_desaturated_v9',
operation: 'screen',
percentage: 0.25
}, {
style: 'dark_map_v9',
operation: 'dodge',
percentage: 0.25
}]);