@elastic/ems-client 8.3.0 → 8.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -9,11 +9,23 @@ var _lodash = _interopRequireDefault(require("lodash"));
9
9
 
10
10
  var _ems_service = require("./ems_service");
11
11
 
12
+ var _utils = require("./utils");
13
+
12
14
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
15
 
14
16
  function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
15
17
 
16
18
  class TMSService extends _ems_service.AbstractEmsService {
19
+ /*
20
+ List of supported languages with labels and OMT codes extracted
21
+ from https://openmaptiles.org/languages
22
+ Keys are values for i18.locale from Kibana settings
23
+ and OMT codes for the rest.
24
+ */
25
+
26
+ /*
27
+ Suggested default operations for the different EMS styles
28
+ */
17
29
  constructor(config, emsClient, proxyPath) {
18
30
  super(config, emsClient, proxyPath);
19
31
 
@@ -91,6 +103,70 @@ class TMSService extends _ems_service.AbstractEmsService {
91
103
 
92
104
  this._config = config;
93
105
  }
106
+ /*
107
+ This method returns an array of objects with the layers and the new
108
+ layout['text-field'] to apply using map.setLayoutProperty
109
+ */
110
+
111
+
112
+ static transformLanguageProperty(layer, lang) {
113
+ const supportedLang = this.SupportedLanguages.find(l => l.key === lang);
114
+
115
+ if (layer.type === 'symbol' && layer.layout !== undefined && supportedLang !== undefined) {
116
+ const omtLang = supportedLang.omt;
117
+ const textField = layer.layout['text-field'];
118
+
119
+ if (textField && typeof textField === 'string') {
120
+ return TMSService._getTextField(textField, omtLang);
121
+ }
122
+ }
123
+
124
+ return;
125
+ }
126
+ /*
127
+ This method returns an array of objects per layer, containing a list of
128
+ properties with new colors to apply using map.setPaintProperty
129
+ */
130
+
131
+
132
+ static transformColorProperties(layer, color, operation, percentage) {
133
+ if (['background', 'fill', 'line', 'symbol'].indexOf(layer.type) !== -1 && layer.paint) {
134
+ const paint = layer.paint;
135
+
136
+ if (layer.type === 'symbol' && Object.keys(paint).length === 0) {
137
+ paint['text-color'] = 'rgb(0,0,0)';
138
+ }
139
+
140
+ const types = Object.keys(paint).filter(key => {
141
+ 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;
142
+ });
143
+ return types.map(type => {
144
+ const paintColor = paint[type];
145
+ return {
146
+ property: type,
147
+ color: paintColor ? (0, _utils.colorizeColor)(paintColor, color, operation, percentage) : paintColor
148
+ };
149
+ });
150
+ } else {
151
+ return [];
152
+ }
153
+ }
154
+
155
+ static _getTextField(label, lang) {
156
+ // Capture {name:xx} labels
157
+ const labelMatch = label.match(/\{name([:_])(.{2})\}/);
158
+
159
+ if (labelMatch && labelMatch[1] != lang) {
160
+ // Only apply if the languages are different
161
+ return ['coalesce', ['get', `name:${lang}`], ['get', `name${labelMatch[1]}${labelMatch[2]}`]];
162
+ } else if (label.includes('latin') && label.includes('nonlatin')) {
163
+ // Capture the common pattern {name:latin}\n{name:nonlatin}
164
+ return ['coalesce', ['get', `name:${lang}`], ['concat', ['get', 'name:latin'], '\n', ['get', 'name:nonlatin']]];
165
+ } // If no case is found, return the input label
166
+
167
+
168
+ return label;
169
+ }
94
170
 
95
171
  async getDefaultRasterStyle() {
96
172
  const tileJson = await this._getRasterStyleJson();
@@ -185,23 +261,49 @@ class TMSService extends _ems_service.AbstractEmsService {
185
261
  return this._emsClient.getValueInLanguage(this._config.name);
186
262
  }
187
263
 
188
- async getMinZoom() {
189
- const tileJson = await this._getRasterStyleJson();
264
+ async getMinZoom(format = 'vector') {
265
+ switch (format) {
266
+ case 'vector':
267
+ const {
268
+ sources
269
+ } = (await this._getVectorStyleJsonInlined()) || {
270
+ sources: {}
271
+ };
272
+ return Math.min(...Object.values(sources).map(({
273
+ minzoom
274
+ }) => minzoom).filter(minzoom => Number.isFinite(minzoom)));
190
275
 
191
- if (tileJson) {
192
- return tileJson.minzoom;
193
- } else {
194
- return;
276
+ case 'raster':
277
+ const {
278
+ minzoom
279
+ } = (await this._getRasterStyleJson()) || {};
280
+ return minzoom;
281
+
282
+ default:
283
+ return;
195
284
  }
196
285
  }
197
286
 
198
- async getMaxZoom() {
199
- const tileJson = await this._getRasterStyleJson();
287
+ async getMaxZoom(format = 'vector') {
288
+ switch (format) {
289
+ case 'vector':
290
+ const {
291
+ sources
292
+ } = (await this._getVectorStyleJsonInlined()) || {
293
+ sources: {}
294
+ };
295
+ return Math.max(...Object.values(sources).map(({
296
+ maxzoom
297
+ }) => maxzoom).filter(maxzoom => Number.isFinite(maxzoom)));
200
298
 
201
- if (tileJson) {
202
- return tileJson.maxzoom;
203
- } else {
204
- return;
299
+ case 'raster':
300
+ const {
301
+ maxzoom
302
+ } = (await this._getRasterStyleJson()) || {};
303
+ return maxzoom;
304
+
305
+ default:
306
+ return;
205
307
  }
206
308
  }
207
309
 
@@ -263,4 +365,197 @@ class TMSService extends _ems_service.AbstractEmsService {
263
365
 
264
366
  }
265
367
 
266
- exports.TMSService = TMSService;
368
+ exports.TMSService = TMSService;
369
+
370
+ _defineProperty(TMSService, "SupportedLanguages", [{
371
+ key: 'ar',
372
+ omt: 'ar'
373
+ }, {
374
+ key: 'az',
375
+ omt: 'az'
376
+ }, {
377
+ key: 'be',
378
+ omt: 'be'
379
+ }, {
380
+ key: 'bg',
381
+ omt: 'bg'
382
+ }, {
383
+ key: 'br',
384
+ omt: 'br'
385
+ }, {
386
+ key: 'bs',
387
+ omt: 'bs'
388
+ }, {
389
+ key: 'ca',
390
+ omt: 'ca'
391
+ }, {
392
+ key: 'cs',
393
+ omt: 'cs'
394
+ }, {
395
+ key: 'cy',
396
+ omt: 'cy'
397
+ }, {
398
+ key: 'da',
399
+ omt: 'da'
400
+ }, {
401
+ key: 'de',
402
+ omt: 'de'
403
+ }, {
404
+ key: 'el',
405
+ omt: 'el'
406
+ }, {
407
+ key: 'en',
408
+ omt: 'en'
409
+ }, {
410
+ key: 'eo',
411
+ omt: 'eo'
412
+ }, {
413
+ key: 'es',
414
+ omt: 'es'
415
+ }, {
416
+ key: 'et',
417
+ omt: 'et'
418
+ }, {
419
+ key: 'fi',
420
+ omt: 'fi'
421
+ }, {
422
+ key: 'fr-fr',
423
+ omt: 'fr'
424
+ }, {
425
+ key: 'fy',
426
+ omt: 'fy'
427
+ }, {
428
+ key: 'ga',
429
+ omt: 'ga'
430
+ }, {
431
+ key: 'gd',
432
+ omt: 'gd'
433
+ }, {
434
+ key: 'he',
435
+ omt: 'he'
436
+ }, {
437
+ key: 'hi-in',
438
+ omt: 'hi'
439
+ }, {
440
+ key: 'hr',
441
+ omt: 'hr'
442
+ }, {
443
+ key: 'hu',
444
+ omt: 'hu'
445
+ }, {
446
+ key: 'hy',
447
+ omt: 'hy'
448
+ }, {
449
+ key: 'is',
450
+ omt: 'is'
451
+ }, {
452
+ key: 'it',
453
+ omt: 'it'
454
+ }, {
455
+ key: 'ja_kana',
456
+ omt: 'ja_kana'
457
+ }, {
458
+ key: 'ja_rm',
459
+ omt: 'ja_rm'
460
+ }, {
461
+ key: 'ja-jp',
462
+ omt: 'ja'
463
+ }, {
464
+ key: 'ka',
465
+ omt: 'ka'
466
+ }, {
467
+ key: 'kk',
468
+ omt: 'kk'
469
+ }, {
470
+ key: 'kn',
471
+ omt: 'kn'
472
+ }, {
473
+ key: 'ko_rm',
474
+ omt: 'ko_rm'
475
+ }, {
476
+ key: 'ko',
477
+ omt: 'ko'
478
+ }, {
479
+ key: 'la',
480
+ omt: 'la'
481
+ }, {
482
+ key: 'lb',
483
+ omt: 'lb'
484
+ }, {
485
+ key: 'lt',
486
+ omt: 'lt'
487
+ }, {
488
+ key: 'lv',
489
+ omt: 'lv'
490
+ }, {
491
+ key: 'mk',
492
+ omt: 'mk'
493
+ }, {
494
+ key: 'mt',
495
+ omt: 'mt'
496
+ }, {
497
+ key: 'nl',
498
+ omt: 'nl'
499
+ }, {
500
+ key: 'no',
501
+ omt: 'no'
502
+ }, {
503
+ key: 'pl',
504
+ omt: 'pl'
505
+ }, {
506
+ key: 'pt-pt',
507
+ omt: 'pt'
508
+ }, {
509
+ key: 'rm',
510
+ omt: 'rm'
511
+ }, {
512
+ key: 'ro',
513
+ omt: 'ro'
514
+ }, {
515
+ key: 'ru-ru',
516
+ omt: 'ru'
517
+ }, {
518
+ key: 'sk',
519
+ omt: 'sk'
520
+ }, {
521
+ key: 'sl',
522
+ omt: 'sl'
523
+ }, {
524
+ key: 'sq',
525
+ omt: 'sq'
526
+ }, {
527
+ key: 'sr-Ltn',
528
+ omt: 'sr-Ltn'
529
+ }, {
530
+ key: 'sr',
531
+ omt: 'sr'
532
+ }, {
533
+ key: 'sv',
534
+ omt: 'sv'
535
+ }, {
536
+ key: 'th',
537
+ omt: 'th'
538
+ }, {
539
+ key: 'tr',
540
+ omt: 'tr'
541
+ }, {
542
+ key: 'uk',
543
+ omt: 'uk'
544
+ }, {
545
+ key: 'zh-cn',
546
+ omt: 'zh'
547
+ }]);
548
+
549
+ _defineProperty(TMSService, "colorOperationDefaults", [{
550
+ style: 'road_map',
551
+ operation: 'mix',
552
+ percentage: 0.25
553
+ }, {
554
+ style: 'road_map_desaturated',
555
+ operation: 'screen',
556
+ percentage: 0.25
557
+ }, {
558
+ style: 'dark_map',
559
+ operation: 'dodge',
560
+ percentage: 0.25
561
+ }]);
@@ -3,8 +3,14 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ exports.colorizeColor = colorizeColor;
7
+ exports.desaturateColor = desaturateColor;
6
8
  exports.toAbsoluteUrl = toAbsoluteUrl;
7
9
 
10
+ var _chromaJs = _interopRequireDefault(require("chroma-js"));
11
+
12
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
+
8
14
  /*
9
15
  * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
10
16
  * or more contributor license agreements. Licensed under the Elastic License
@@ -32,4 +38,58 @@ function toAbsoluteUrl(host, path) {
32
38
  } else {
33
39
  return host + '/' + path;
34
40
  }
41
+ }
42
+ /*
43
+ Type with the possible ways to define a color in maplibre
44
+ */
45
+
46
+
47
+ /*
48
+ Function to transform a maplibre color definition by a given function.
49
+ */
50
+ function transformColor(paintColor, func) {
51
+ if (typeof paintColor == 'string') {
52
+ const modifiedColor = func(paintColor);
53
+ return `rgba(${modifiedColor.rgba().join(',')})`;
54
+ } else if (typeof paintColor == 'object' && 'stops' in paintColor && Array.isArray(paintColor === null || paintColor === void 0 ? void 0 : paintColor.stops)) {
55
+ const stops = paintColor['stops'].map(stop => {
56
+ const newColor = transformColor(stop[1], func);
57
+ return [stop[0], newColor];
58
+ });
59
+ const newPaintColor = { ...paintColor,
60
+ ...stops
61
+ };
62
+ return newPaintColor;
63
+ } else return paintColor;
64
+ }
65
+ /*
66
+ This is the function used to generate the current EMS desaturated roadmap
67
+ */
68
+
69
+
70
+ function desaturateColor(paintColor) {
71
+ return transformColor(paintColor, color => {
72
+ return (0, _chromaJs.default)(color).desaturate(1.1).brighten(0.33);
73
+ });
74
+ }
75
+ /*
76
+ Blends an original maplibre color definition with a destination
77
+ color. Accepts different blending modes and an additional `mix`
78
+ option that needs a percentage.
79
+
80
+ More details:
81
+
82
+ https://gka.github.io/chroma.js/#chroma-blend
83
+ https://gka.github.io/chroma.js/#chroma-mix
84
+ */
85
+
86
+
87
+ function colorizeColor(sourceColor, destColor, operation = 'screen', percentage = 0.5) {
88
+ return transformColor(sourceColor, color => {
89
+ if (operation !== 'mix') {
90
+ return _chromaJs.default.blend((0, _chromaJs.default)(color), destColor, operation);
91
+ } else {
92
+ return _chromaJs.default.mix((0, _chromaJs.default)(color), destColor, percentage);
93
+ }
94
+ });
35
95
  }
@@ -1,6 +1,7 @@
1
- import { StyleSpecification, VectorSourceSpecification } from 'maplibre-gl';
1
+ import { DataDrivenPropertyValueSpecification, FormattedSpecification, LayerSpecification, StyleSpecification, VectorSourceSpecification } from 'maplibre-gl';
2
2
  import { EMSClient, TMSServiceConfig } from './ems_client';
3
3
  import { AbstractEmsService } from './ems_service';
4
+ import { layerPaintProperty, blendMode, mbColorDefinition } from './utils';
4
5
  export declare type EmsSprite = {
5
6
  height: number;
6
7
  pixelRatio: number;
@@ -31,11 +32,26 @@ declare type EmsRasterStyle = {
31
32
  center: number[];
32
33
  };
33
34
  export declare class TMSService extends AbstractEmsService {
35
+ static SupportedLanguages: {
36
+ key: string;
37
+ omt: string;
38
+ }[];
39
+ static colorOperationDefaults: {
40
+ style: string;
41
+ operation: string;
42
+ percentage: number;
43
+ }[];
34
44
  protected readonly _config: TMSServiceConfig;
35
45
  private _getRasterStyleJson;
36
46
  private _getVectorStyleJsonRaw;
37
47
  private _getVectorStyleJsonInlined;
38
48
  constructor(config: TMSServiceConfig, emsClient: EMSClient, proxyPath: string);
49
+ static transformLanguageProperty(layer: LayerSpecification, lang: string): DataDrivenPropertyValueSpecification<FormattedSpecification> | undefined;
50
+ static transformColorProperties(layer: LayerSpecification, color: string, operation: blendMode, percentage: number): {
51
+ property: keyof layerPaintProperty;
52
+ color: mbColorDefinition | undefined;
53
+ }[];
54
+ private static _getTextField;
39
55
  getDefaultRasterStyle(): Promise<EmsRasterStyle | undefined>;
40
56
  getUrlTemplate(): Promise<string>;
41
57
  getUrlTemplateForVector(sourceId: string): Promise<string>;
@@ -48,8 +64,8 @@ export declare class TMSService extends AbstractEmsService {
48
64
  getSpriteSheetJsonPath(isRetina?: boolean): Promise<string>;
49
65
  getSpriteSheetPngPath(isRetina?: boolean): Promise<string>;
50
66
  getDisplayName(): string;
51
- getMinZoom(): Promise<number | undefined>;
52
- getMaxZoom(): Promise<number | undefined>;
67
+ getMinZoom(format?: string): Promise<number | undefined>;
68
+ getMaxZoom(format?: string): Promise<number | undefined>;
53
69
  getId(): string;
54
70
  hasId(id: string): boolean;
55
71
  getApiUrl(): string;
package/target/utils.d.ts CHANGED
@@ -1,6 +1,25 @@
1
+ import { ChromaStatic } from 'chroma-js';
2
+ import { ColorSpecification, DataDrivenPropertyValueSpecification, PropertyValueSpecification } from 'maplibre-gl';
1
3
  /**
2
4
  * Resolves a target URL path relative to the host.
3
5
  * This is specifically useed by the Kibana proxy re-routing.
4
6
  * It also handles trailing slashes in tileApiUrl and fileApiUrl parameters.
5
7
  */
6
8
  export declare function toAbsoluteUrl(host: string | undefined, path: string): string;
9
+ export declare type mbColorDefinition = PropertyValueSpecification<ColorSpecification> | DataDrivenPropertyValueSpecification<ColorSpecification>;
10
+ export declare type layerPaintProperty = {
11
+ 'background-color'?: PropertyValueSpecification<ColorSpecification>;
12
+ 'circle-color'?: DataDrivenPropertyValueSpecification<ColorSpecification>;
13
+ 'circle-stroke-color'?: DataDrivenPropertyValueSpecification<ColorSpecification>;
14
+ 'fill-color'?: DataDrivenPropertyValueSpecification<ColorSpecification>;
15
+ 'fill-extrusion-color'?: DataDrivenPropertyValueSpecification<ColorSpecification>;
16
+ 'fill-outline-color'?: DataDrivenPropertyValueSpecification<ColorSpecification>;
17
+ 'icon-color'?: DataDrivenPropertyValueSpecification<ColorSpecification>;
18
+ 'icon-halo-color'?: DataDrivenPropertyValueSpecification<ColorSpecification>;
19
+ 'line-color'?: DataDrivenPropertyValueSpecification<ColorSpecification>;
20
+ 'text-color'?: DataDrivenPropertyValueSpecification<ColorSpecification>;
21
+ 'text-halo-color'?: DataDrivenPropertyValueSpecification<ColorSpecification>;
22
+ };
23
+ export declare type blendMode = Parameters<ChromaStatic['blend']>[2] | 'mix';
24
+ export declare function desaturateColor(paintColor: mbColorDefinition): mbColorDefinition;
25
+ export declare function colorizeColor(sourceColor: mbColorDefinition, destColor: string, operation?: blendMode, percentage?: number): mbColorDefinition;