@provoly/dashboard 0.14.5 → 0.14.6

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.
Files changed (90) hide show
  1. package/admin/admin.module.d.ts +2 -1
  2. package/admin/components/admin-classes/admin-classes-view/admin-attributes-form/admin-attributes-form.component.d.ts +5 -2
  3. package/admin/components/admin-fields/admin-fields-form/admin-fields-form.component.d.ts +7 -3
  4. package/admin/i18n/en.translations.d.ts +15 -0
  5. package/admin/i18n/fr.translations.d.ts +15 -0
  6. package/esm2022/admin/admin.module.mjs +8 -4
  7. package/esm2022/admin/components/admin-classes/admin-classes-form/admin-classes-form.component.mjs +3 -3
  8. package/esm2022/admin/components/admin-classes/admin-classes-view/admin-attributes-form/admin-attributes-form.component.mjs +19 -14
  9. package/esm2022/admin/components/admin-dataset/shared/admin-form-dataset/admin-form-dataset.component.mjs +3 -5
  10. package/esm2022/admin/components/admin-fields/admin-fields-form/admin-fields-form.component.mjs +23 -12
  11. package/esm2022/admin/i18n/en.translations.mjs +17 -2
  12. package/esm2022/admin/i18n/fr.translations.mjs +19 -4
  13. package/esm2022/dataset/components/dataset-detail/dataset-detail.component.mjs +4 -3
  14. package/esm2022/import/components/import.component.mjs +12 -5
  15. package/esm2022/import/i18n/en.translations.mjs +3 -2
  16. package/esm2022/import/i18n/fr.translations.mjs +3 -2
  17. package/esm2022/import/import.module.mjs +7 -4
  18. package/esm2022/import/store/import.actions.mjs +1 -1
  19. package/esm2022/import/store/import.effects.mjs +2 -2
  20. package/esm2022/import/store/import.service.mjs +3 -2
  21. package/esm2022/lib/core/components/translate-id/translate-id.pipe.mjs +9 -9
  22. package/esm2022/lib/core/i18n/en.translations.mjs +2 -1
  23. package/esm2022/lib/core/i18n/fr.translations.mjs +2 -1
  24. package/esm2022/lib/core/model/admin-api.model.mjs +66 -14
  25. package/esm2022/lib/core/model/widget-map-manifest.interface.mjs +1 -1
  26. package/esm2022/lib/core/store/field/field.interface.mjs +10 -1
  27. package/esm2022/lib/core/symbol/symbol.service.mjs +7 -3
  28. package/esm2022/lib/core/toolbox/toolbox-manifest.service.mjs +17 -1
  29. package/esm2022/lib/core/toolbox/toolbox-menu.service.mjs +2 -1
  30. package/esm2022/lib/dashboard/components/dashboard.component.mjs +5 -5
  31. package/esm2022/lib/dashboard/components/widgets/header/widget-header.component.mjs +9 -3
  32. package/esm2022/pipeline/components/pipeline-list/pipeline-list.component.mjs +25 -13
  33. package/esm2022/pipeline/pipeline.module.mjs +8 -4
  34. package/esm2022/supervision/store/supervision.reducer.mjs +2 -7
  35. package/esm2022/widgets/widget-map/component/widget-map-layer.service.mjs +34 -3
  36. package/esm2022/widgets/widget-map/component/widget-map.component.mjs +68 -10
  37. package/esm2022/widgets/widget-map/i18n/en.translations.mjs +3 -2
  38. package/esm2022/widgets/widget-map/i18n/fr.translations.mjs +3 -2
  39. package/esm2022/widgets/widget-map/utils/widget-map.utils.mjs +14 -8
  40. package/fesm2022/provoly-dashboard-admin.mjs +79 -31
  41. package/fesm2022/provoly-dashboard-admin.mjs.map +1 -1
  42. package/fesm2022/provoly-dashboard-dataset.mjs +3 -2
  43. package/fesm2022/provoly-dashboard-dataset.mjs.map +1 -1
  44. package/fesm2022/provoly-dashboard-import.mjs +23 -10
  45. package/fesm2022/provoly-dashboard-import.mjs.map +1 -1
  46. package/fesm2022/provoly-dashboard-pipeline.mjs +27 -11
  47. package/fesm2022/provoly-dashboard-pipeline.mjs.map +1 -1
  48. package/fesm2022/provoly-dashboard-supervision.mjs +1 -6
  49. package/fesm2022/provoly-dashboard-supervision.mjs.map +1 -1
  50. package/fesm2022/provoly-dashboard-widgets-widget-map.mjs +536 -440
  51. package/fesm2022/provoly-dashboard-widgets-widget-map.mjs.map +1 -1
  52. package/fesm2022/provoly-dashboard.mjs +174 -85
  53. package/fesm2022/provoly-dashboard.mjs.map +1 -1
  54. package/import/components/import.component.d.ts +1 -0
  55. package/import/i18n/en.translations.d.ts +1 -0
  56. package/import/i18n/fr.translations.d.ts +1 -0
  57. package/import/import.module.d.ts +2 -1
  58. package/import/store/import.actions.d.ts +2 -0
  59. package/import/store/import.service.d.ts +1 -1
  60. package/lib/core/components/translate-id/translate-id.pipe.d.ts +1 -1
  61. package/lib/core/i18n/en.translations.d.ts +1 -0
  62. package/lib/core/i18n/fr.translations.d.ts +1 -0
  63. package/lib/core/model/admin-api.model.d.ts +1 -0
  64. package/lib/core/model/widget-map-manifest.interface.d.ts +11 -1
  65. package/lib/core/store/field/field.interface.d.ts +1 -0
  66. package/lib/core/symbol/symbol.service.d.ts +1 -1
  67. package/lib/dashboard/components/dashboard.component.d.ts +1 -1
  68. package/lib/dashboard/components/widgets/header/widget-header.component.d.ts +3 -1
  69. package/package.json +36 -36
  70. package/pipeline/components/pipeline-list/pipeline-list.component.d.ts +1 -0
  71. package/pipeline/pipeline.module.d.ts +2 -1
  72. package/schematics/migration.json +5 -0
  73. package/schematics/ng-update/utils/replaceStrings.function.d.ts +7 -0
  74. package/schematics/ng-update/utils/replaceStrings.function.js +15 -0
  75. package/schematics/ng-update/utils/replaceStrings.function.js.map +1 -0
  76. package/schematics/ng-update/version-0-13/index.spec.js +11 -0
  77. package/schematics/ng-update/version-0-13/index.spec.js.map +1 -1
  78. package/schematics/ng-update/version-0-14/index.d.ts +2 -0
  79. package/schematics/ng-update/version-0-14/index.js +49 -0
  80. package/schematics/ng-update/version-0-14/index.js.map +1 -0
  81. package/schematics/ng-update/version-0-14/index.spec.d.ts +1 -0
  82. package/schematics/ng-update/version-0-14/index.spec.js +52 -0
  83. package/schematics/ng-update/version-0-14/index.spec.js.map +1 -0
  84. package/styles/components/_m-context-menu.scss +4 -0
  85. package/styles/components/_o-pry-admin-classes-customize.scss +48 -0
  86. package/widgets/widget-map/component/widget-map-layer.service.d.ts +6 -1
  87. package/widgets/widget-map/component/widget-map.component.d.ts +4 -2
  88. package/widgets/widget-map/i18n/en.translations.d.ts +1 -0
  89. package/widgets/widget-map/i18n/fr.translations.d.ts +1 -0
  90. package/widgets/widget-map/utils/widget-map.utils.d.ts +2 -5
@@ -7,7 +7,7 @@ import { Injectable, Component, ViewEncapsulation, Pipe, ViewContainerRef, Templ
7
7
  import * as i7 from '@angular/forms';
8
8
  import { FormsModule } from '@angular/forms';
9
9
  import * as i2 from '@provoly/dashboard';
10
- import { widgetMapConfig, DashboardActions, ContextMenuActions, TooltipMode, FieldType, ItemUtils, ClassSelectors, FieldSelectors, DataWidgetComponent, WIDGET_HEADER_HEIGHT, ConfigSelectors, DashboardSelectors, GeoMetadata, DataSourceSelectors, ResultsetUtils, BaseWidgetModule, PryCoreModule, PryDashboardModule, PrySelectModule, PryIconModule, PryToggleModule, PryOverlayModule, PryI18nModule, PryRangeModule } from '@provoly/dashboard';
10
+ import { widgetMapConfig, DashboardActions, ContextMenuActions, TooltipMode, ItemUtils, FieldType, ClassSelectors, FieldSelectors, DataWidgetComponent, WIDGET_HEADER_HEIGHT, ConfigSelectors, DashboardSelectors, GeoMetadata, GeometricFieldTypes, DataSourceSelectors, ResultsetUtils, BaseWidgetModule, PryCoreModule, PryDashboardModule, PrySelectModule, PryIconModule, PryToggleModule, PryOverlayModule, PryI18nModule, PryRangeModule } from '@provoly/dashboard';
11
11
  import * as i8 from '@provoly/dashboard/components/checkbox';
12
12
  import { PryCheckboxModule } from '@provoly/dashboard/components/checkbox';
13
13
  import equal from 'fast-deep-equal/es6';
@@ -22,20 +22,20 @@ import { Vector, TileWMS, WMTS, XYZ, Cluster } from 'ol/source';
22
22
  import proj4 from 'proj4';
23
23
  import { map, of, combineLatest, filter, BehaviorSubject, startWith, debounceTime, distinctUntilChanged, switchMap, delay, mergeMap, from } from 'rxjs';
24
24
  import { ScaleLine } from 'ol/control';
25
- import { Polygon, Circle, LineString } from 'ol/geom';
25
+ import { Polygon, Circle as Circle$1, LineString } from 'ol/geom';
26
26
  import PointerInteraction from 'ol/interaction/Pointer';
27
27
  import TileLayer from 'ol/layer/Tile';
28
28
  import VectorLayer from 'ol/layer/Vector';
29
29
  import RenderBox from 'ol/render/Box';
30
30
  import VectorSource from 'ol/source/Vector';
31
- import { Style, Fill, Stroke, Circle as Circle$1, Text } from 'ol/style';
32
- import * as i1 from '@angular/common/http';
33
- import { HttpHeaders } from '@angular/common/http';
34
- import * as i1$1 from '@ngrx/store';
31
+ import { Style, Fill, Stroke, Circle, Text } from 'ol/style';
35
32
  import { GeoJSON, MVT } from 'ol/format';
36
33
  import VectorTile from 'ol/source/VectorTile';
37
34
  import CircleStyle from 'ol/style/Circle';
38
35
  import WMTSTileGrid from 'ol/tilegrid/WMTS';
36
+ import * as i1 from '@angular/common/http';
37
+ import { HttpHeaders } from '@angular/common/http';
38
+ import * as i1$1 from '@ngrx/store';
39
39
 
40
40
  class SelectionInteraction extends PointerInteraction {
41
41
  constructor() {
@@ -352,319 +352,58 @@ class CqlUtils {
352
352
  }
353
353
  }
354
354
 
355
- const populateLocationAttribute = (layer, resultSet, classesNotFiltered, fields) => {
356
- if (['heatmap', 'marker', 'bubble', 'point', 'line', 'polygon', 'multi-line', 'multi-polygon'].includes(layer.type) &&
357
- !!resultSet &&
358
- !!classesNotFiltered &&
359
- classesNotFiltered.length > 0) {
360
- const specificLayer = layer;
361
- const classes = classesNotFiltered.filter((cl) => specificLayer.classes?.includes(cl.id) || !specificLayer.classes || specificLayer.classes.length === 0);
362
- if (!specificLayer.attribute) {
363
- // No location attribute available, then try to guess one that will be ok
364
- const geometry = geometryForLayer(layer);
365
- let candidates = [];
366
- if (Object.keys(resultSet.items).length > 0) {
367
- // Based on items that we have to display
368
- candidates = Object.keys(resultSet.items)
369
- .map((key) => ({ items: resultSet.items[key], oClass: classes.find((cl) => cl.id === key) }))
370
- .map(({ items, oClass }) => (oClass ?? { attributes: [] }).attributes
371
- .map((attr) => ({ attr, field: fields.find((f) => f.id === attr.field) }))
372
- .filter((attr) => attr.field?.type === geometry))
373
- .reduce((p, c) => [...p, ...c], []);
374
- }
375
- else {
376
- // We don't have any items to display, so allow all corresponding geometry fields
377
- candidates = classesNotFiltered
378
- .map((clazz) => clazz.attributes)
379
- .reduce((p, c) => [...p, ...c], [])
380
- .map((attr) => fields.filter((field) => field?.type === geometry).map((field) => ({ attr, field })))
381
- .reduce((p, c) => [...p, ...c], []);
382
- }
383
- if (candidates.length > 0) {
384
- specificLayer.attribute = candidates[0].attr.name;
385
- }
386
- }
387
- }
388
- };
389
- const populateIntensityAttribute = (layer, resultSet, classesNotFiltered, fields) => {
390
- if (['heatmap', 'bubble'].includes(layer.type) &&
391
- !!resultSet &&
392
- !!classesNotFiltered &&
393
- classesNotFiltered.length > 0) {
394
- const specificLayer = layer;
395
- const classes = classesNotFiltered.filter((cl) => (specificLayer.classes?.includes(cl.id) || !specificLayer.classes || specificLayer.classes.length === 0) &&
396
- cl.attributes.find((attr) => attr.name === (specificLayer?.attribute ?? [])));
397
- if (!specificLayer.intensityAttribute) {
398
- // No intensity attribute available, then take the maximum intensity matching attribute
399
- const candidatesDry = Object.keys(resultSet.items)
400
- .map((key) => ({ items: resultSet.items[key], oClass: classes.find((cl) => cl.id === key) }))
401
- .map(({ items, oClass }) => {
402
- return (oClass ?? { attributes: [] }).attributes
403
- .map((attr) => ({ attr, field: fields.find((f) => f.id === attr.field) }))
404
- .filter((attr) => attr.field?.type === FieldType.DECIMAL || attr.field?.type === FieldType.INTEGER)
405
- .map((attr) => {
406
- const attrValues = ItemUtils.pertinentValue(items, attr.attr);
407
- return {
408
- min: Math.min(...attrValues),
409
- max: Math.max(...attrValues),
410
- name: attr.attr.name
411
- };
412
- });
355
+ class WidgetMapLayerService {
356
+ constructor() {
357
+ this.styleCache = {};
358
+ this.circleStyle = new Style({
359
+ fill: new Fill({
360
+ color: 'rgba(37,89,163,0.24)'
361
+ }),
362
+ stroke: new Stroke({
363
+ color: 'rgb(37,89,163)',
364
+ width: 2
413
365
  })
414
- .reduce((p, c) => [...p, ...c], [])
415
- .sort((a, b) => b.max - a.max);
416
- if (candidatesDry.length > 0) {
417
- specificLayer.intensityAttribute = candidatesDry[0].name;
418
- specificLayer.intensityAsc = true;
419
- }
420
- }
421
- }
422
- };
423
- const getFeatureFromItem = (item, type, locationAttribute, iconStyle, selectedIconStyle) => {
424
- return new Feature({
425
- ...item,
426
- type,
427
- geometry: ItemUtils.readGeometry(item, 'point', locationAttribute),
428
- classicStyle: iconStyle ?? null,
429
- selectedStyle: selectedIconStyle ?? null
430
- });
431
- };
432
- const getCircleFeatureFromItem = (item, locationAttribute, radius, iconStyle, selectedIconStyle) => {
433
- return new Feature({
434
- ...item,
435
- geometry: new Circle(ItemUtils.readGeometry(item, 'point', locationAttribute).getCoordinates(), radius),
436
- classicStyle: iconStyle,
437
- selectedStyle: selectedIconStyle,
438
- type: 'bubble'
439
- });
440
- };
441
- const getLinkFeature = (relation, featureSource, featureDestination) => {
442
- return new Feature({
443
- ...relation,
444
- geometry: new LineString([
445
- featureSource.getGeometry()?.getCoordinates() ?? [0, 0],
446
- featureDestination.getGeometry()?.getCoordinates() ?? [0, 0]
447
- ]),
448
- source: featureSource,
449
- destination: featureDestination,
450
- type: 'link'
451
- });
452
- };
453
- const getMapAsPng = (map) => {
454
- return new Promise((resolve, reject) => {
455
- map.once('rendercomplete', function () {
456
- const mapCanvas = document.createElement('canvas');
457
- const size = map.getSize() || [100, 100];
458
- mapCanvas.width = size[0];
459
- mapCanvas.height = size[1];
460
- const mapContext = mapCanvas.getContext('2d') || null;
461
- Array.prototype.forEach.call(document.querySelectorAll('.ol-layer canvas, canvas.ol-layer'), (canvas) => {
462
- if (canvas.width > 0) {
463
- const opacity = canvas.parentNode.style.opacity || canvas.style.opacity;
464
- mapContext.globalAlpha = opacity === '' ? 1 : Number(opacity);
465
- const backgroundColor = canvas.parentNode.style.backgroundColor;
466
- if (backgroundColor) {
467
- mapContext.fillStyle = backgroundColor;
468
- mapContext.fillRect(0, 0, canvas.width, canvas.height);
469
- }
470
- let matrix;
471
- const transform = canvas.style.transform;
472
- if (transform) {
473
- // Get the transform parameters from the style's transform matrix
474
- matrix = transform
475
- .match(/^matrix\(([^(]*)\)$/)[1]
476
- .split(',')
477
- .map(Number);
478
- }
479
- else {
480
- matrix = [
481
- parseFloat(canvas.style.width) / canvas.width,
482
- 0,
483
- 0,
484
- parseFloat(canvas.style.height) / canvas.height,
485
- 0,
486
- 0
487
- ];
488
- }
489
- // Apply the transform to the export map context
490
- CanvasRenderingContext2D.prototype.setTransform.apply(mapContext, matrix);
491
- mapContext.drawImage(canvas, 0, 0);
492
- }
493
- });
494
- mapContext.globalAlpha = 1;
495
- resolve(mapCanvas.toDataURL('image/png'));
496
366
  });
497
- map.renderSync();
498
- });
499
- };
500
- const exportMapAsImage = (map, filename) => {
501
- getMapAsPng(map).then((data) => {
502
- const link = document.createElement('a');
503
- link.download = filename;
504
- link.href = data;
505
- link.click();
506
- });
507
- };
508
- const geometryForLayer = (layer) => {
509
- switch (layer.type) {
510
- case 'marker':
511
- case 'heatmap':
512
- case 'bubble':
513
- case 'point':
514
- return FieldType.POINT;
515
- case 'line':
516
- return FieldType.LINE;
517
- case 'polygon':
518
- return FieldType.POLYGON;
519
- case 'multi-line':
520
- return FieldType.MULTILINE;
521
- case 'multi-polygon':
522
- return FieldType.MULTIPOLYGON;
523
- default:
524
- return FieldType.POINT;
525
- }
526
- };
527
- const DEFAULT_HEATMAP_RADIUS = 25;
528
- const DEFAULT_RADIUS_INTENSITY_FACTOR = 10000;
529
- const DEFAULT_ZOOM_MIN = 3;
530
- const DEFAULT_ZOOM_START = 10;
531
- const DEFAULT_ZOOM_MAX = 18;
532
- const DEFAULT_MAP_CENTER = [2.2827217347381525, 48.864706031557716];
533
- const EMPTY_MAP_STYLE = { layers: [] };
534
-
535
- class XMLUtils {
536
- static find(childs, name) {
537
- if (!!childs) {
538
- for (let i = 0; i < childs.length; i++) {
539
- const node = childs[i];
540
- if (node.nodeName === name) {
541
- return node;
542
- }
543
- }
544
- }
545
- return null;
546
- }
547
- static findAll(childs, name) {
548
- const result = [];
549
- for (let i = 0; i < childs.length; i++) {
550
- const node = childs[i];
551
- if (node.nodeName === name) {
552
- result.push(node);
553
- }
554
- }
555
- return result;
556
- }
557
- static findWith(childs, attribute, value) {
558
- for (let i = 0; i < childs.length; i++) {
559
- const node = childs[i];
560
- const attrNode = XMLUtils.find(node.childNodes, attribute);
561
- if (attrNode?.textContent === value) {
562
- return node;
563
- }
564
- }
565
- return null;
566
- }
567
- }
568
-
569
- class WmsService {
570
- constructor(httpClient) {
571
- this.httpClient = httpClient;
572
- this.parser = new DOMParser();
573
- }
574
- getCapabilities(wmsLayer) {
575
- if (wmsLayer && wmsLayer.url) {
576
- const layerUrlWithQmark = wmsLayer.url.indexOf('?') === -1 ? wmsLayer.url + '?' : wmsLayer.url;
577
- const layerUrlWithService = layerUrlWithQmark.indexOf('&SERVICE=') === -1 ? layerUrlWithQmark + '&SERVICE=WMS' : layerUrlWithQmark;
578
- const layerUrlWithVersion = layerUrlWithService.indexOf('&VERSION=') === -1 ? layerUrlWithService + '&VERSION=1.3.0' : layerUrlWithService;
579
- return this.httpClient
580
- .get(`${layerUrlWithVersion}&REQUEST=GetCapabilities`, {
581
- headers: new HttpHeaders({
582
- Accept: 'text/html, application/xhtml+xml, */*',
583
- 'Content-Type': 'application/x-www-form-urlencoded'
584
- }),
585
- responseType: 'text'
586
- })
587
- .pipe(map((response) => {
588
- const doc = this.parser.parseFromString(response, 'application/xml');
589
- const errorNode = doc.querySelector('parsererror');
590
- if (errorNode) {
591
- console.error(`Cannot getCapabilities for ${wmsLayer.url}[${wmsLayer.paramLayer}]`);
592
- return null;
593
- }
594
- else {
595
- return { url: wmsLayer.url, paramLayer: wmsLayer.paramLayer, doc };
596
- }
597
- }));
598
- }
599
- return of(null);
600
- }
601
- static getMatchingLayer(paramLayer, doc) {
602
- const WMSCapability = XMLUtils.find(doc.childNodes, 'WMS_Capabilities');
603
- if (WMSCapability) {
604
- const Capabilities = XMLUtils.find(WMSCapability.childNodes, 'Capability');
605
- if (Capabilities) {
606
- const Layer = XMLUtils.find(Capabilities.childNodes, 'Layer');
607
- if (Layer) {
608
- let matchingLayer = XMLUtils.findWith(Layer.childNodes, 'Name', paramLayer);
609
- const split = paramLayer.split(':');
610
- if (!matchingLayer && split.length >= 2) {
611
- // Try again, splitting on ":" in the name to ignore namespace if present
612
- matchingLayer = XMLUtils.findWith(Layer.childNodes, 'Name', split[split.length - 1]);
613
- }
614
- return matchingLayer;
615
- }
616
- }
617
- }
618
- return null;
619
- }
620
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.6", ngImport: i0, type: WmsService, deps: [{ token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable }); }
621
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.1.6", ngImport: i0, type: WmsService, providedIn: 'root' }); }
622
- }
623
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.6", ngImport: i0, type: WmsService, decorators: [{
624
- type: Injectable,
625
- args: [{
626
- providedIn: 'root'
627
- }]
628
- }], ctorParameters: function () { return [{ type: i1.HttpClient }]; } });
629
-
630
- class WidgetMapLayerService {
631
- constructor() {
632
- this.styleCache = {};
633
- this.circleStyle = new Style({
634
- fill: new Fill({
635
- color: 'rgba(37,89,163,0.24)'
636
- }),
637
- stroke: new Stroke({
638
- color: 'rgb(37,89,163)',
639
- width: 2
640
- })
641
- });
642
- this.selectedCircleStyle = new Style({
643
- fill: new Fill({
644
- color: 'rgba(37,163,58,0.24)'
645
- }),
646
- stroke: new Stroke({
647
- color: 'rgb(37,163,58)',
648
- width: 2
367
+ this.selectedCircleStyle = new Style({
368
+ fill: new Fill({
369
+ color: 'rgba(37,163,58,0.24)'
370
+ }),
371
+ stroke: new Stroke({
372
+ color: 'rgb(37,163,58)',
373
+ width: 2
649
374
  })
650
375
  });
651
376
  this.pointStyle = new Style({
652
- image: new Circle$1({
377
+ image: new Circle({
653
378
  fill: new Fill({ color: 'rgba(37,89,163,0.24)' }),
654
379
  stroke: new Stroke({ color: 'rgb(37,89,163)', width: 2 }),
655
380
  radius: 10
656
381
  })
657
382
  });
658
383
  this.selectedPointStyle = new Style({
659
- image: new Circle$1({
384
+ image: new Circle({
660
385
  fill: new Fill({ color: 'rgba(37,163,58,0.24)' }),
661
386
  stroke: new Stroke({ color: 'rgb(37,163,58)', width: 2 }),
662
387
  radius: 10
663
388
  })
664
389
  });
665
390
  this.dontNeedLocation = ['relation', 'wms', 'wmts', 'geoserver', 'featurelayer', 'vectortile', 'rastertile'];
666
- this.dontNeedIntensity = [...this.dontNeedLocation, 'marker', 'point', 'line', 'polygon', 'multi-line', 'multi-polygon'];
391
+ this.dontNeedIntensity = [
392
+ ...this.dontNeedLocation,
393
+ 'marker',
394
+ 'point',
395
+ 'line',
396
+ 'polygon',
397
+ 'multi-line',
398
+ 'multi-polygon',
399
+ 'auto'
400
+ ];
667
401
  this.layersImplementation = {
402
+ auto: (layer, attributesForClass, layerClassesId, resultSet, range, itemStyles, map) => {
403
+ return this.layersImplementation[WidgetMapLayerService.translateFieldTypeToLayerType(layer.subType)](
404
+ // @ts-ignore
405
+ layer, attributesForClass, layerClassesId, resultSet, range, itemStyles, map);
406
+ },
668
407
  heatmap: (layer, attributesForClass, layerClassesId, resultSet, range, itemStyles, map) => {
669
408
  const heatmap = new Heatmap({
670
409
  minZoom: layer.minZoom ?? DEFAULT_ZOOM_MIN,
@@ -786,147 +525,444 @@ class WidgetMapLayerService {
786
525
  resolutions[z] = size / Math.pow(2, z);
787
526
  matrixIds[z] = z;
788
527
  }
789
- return new Tile({
790
- minZoom: layer.minZoom ?? DEFAULT_ZOOM_MIN,
791
- maxZoom: layer.maxZoom ?? DEFAULT_ZOOM_MAX,
792
- opacity: (layer.opacity ?? 100) / 100,
793
- source: new WMTS({
794
- attributions: [layer.attribution ?? ''],
795
- crossOrigin: 'anonymous',
796
- url: layer.url,
797
- layer: layer.paramLayer,
798
- matrixSet: layer.matrixSet,
799
- projection,
800
- tileGrid: new WMTSTileGrid({
801
- origin: getTopLeft(projectionExtent),
802
- resolutions: resolutions,
803
- matrixIds: matrixIds
804
- }),
805
- style: layer.style
806
- })
807
- });
808
- },
809
- geoserver: (layer, attributesForClass, layerClassesId, resultSet, range, itemStyles, map) => {
810
- const impl = this.layersImplementation['wms']({ ...layer, type: 'wms', oClass: layer.oClass }, attributesForClass, layerClassesId, resultSet, range, itemStyles, map);
811
- impl.set('title', layer.title);
812
- impl.set('oClass', layer.oClass);
813
- return impl;
814
- },
815
- featurelayer: (layer, attributesForClass, layerClassesId, resultSet, range, itemStyles, map) => {
816
- return new VectorLayer({
817
- minZoom: layer.minZoom ?? DEFAULT_ZOOM_MIN,
818
- maxZoom: layer.maxZoom ?? DEFAULT_ZOOM_MAX,
819
- opacity: (layer.opacity ?? 100) / 100,
820
- source: new VectorSource({
821
- attributions: [layer.attribution ?? ''],
822
- format: new GeoJSON(),
823
- url: layer.url
824
- })
825
- });
826
- },
827
- vectortile: (layer, attributesForClass, layerClassesId, resultSet, range, itemStyles, map) => {
828
- return new VectorTileLayer({
829
- minZoom: layer.minZoom ?? DEFAULT_ZOOM_MIN,
830
- maxZoom: layer.maxZoom ?? DEFAULT_ZOOM_MAX,
831
- opacity: (layer.opacity ?? 100) / 100,
832
- source: new VectorTile({
833
- attributions: [layer.attribution ?? ''],
834
- format: new MVT(),
835
- url: layer.url
836
- })
837
- });
838
- },
839
- rastertile: (layer, attributesForClass, layerClassesId, resultSet, range, itemStyles, map) => {
840
- return new Tile({
841
- minZoom: layer.minZoom ?? DEFAULT_ZOOM_MIN,
842
- maxZoom: layer.maxZoom ?? DEFAULT_ZOOM_MAX,
843
- opacity: (layer.opacity ?? 100) / 100,
844
- source: new XYZ({
845
- url: layer.url,
846
- attributions: [layer.attribution ?? '']
847
- })
848
- });
528
+ return new Tile({
529
+ minZoom: layer.minZoom ?? DEFAULT_ZOOM_MIN,
530
+ maxZoom: layer.maxZoom ?? DEFAULT_ZOOM_MAX,
531
+ opacity: (layer.opacity ?? 100) / 100,
532
+ source: new WMTS({
533
+ attributions: [layer.attribution ?? ''],
534
+ crossOrigin: 'anonymous',
535
+ url: layer.url,
536
+ layer: layer.paramLayer,
537
+ matrixSet: layer.matrixSet,
538
+ projection,
539
+ tileGrid: new WMTSTileGrid({
540
+ origin: getTopLeft(projectionExtent),
541
+ resolutions: resolutions,
542
+ matrixIds: matrixIds
543
+ }),
544
+ style: layer.style
545
+ })
546
+ });
547
+ },
548
+ geoserver: (layer, attributesForClass, layerClassesId, resultSet, range, itemStyles, map) => {
549
+ const impl = this.layersImplementation['wms']({ ...layer, type: 'wms', oClass: layer.oClass }, attributesForClass, layerClassesId, resultSet, range, itemStyles, map);
550
+ impl.set('title', layer.title);
551
+ impl.set('oClass', layer.oClass);
552
+ return impl;
553
+ },
554
+ featurelayer: (layer, attributesForClass, layerClassesId, resultSet, range, itemStyles, map) => {
555
+ return new VectorLayer({
556
+ minZoom: layer.minZoom ?? DEFAULT_ZOOM_MIN,
557
+ maxZoom: layer.maxZoom ?? DEFAULT_ZOOM_MAX,
558
+ opacity: (layer.opacity ?? 100) / 100,
559
+ source: new VectorSource({
560
+ attributions: [layer.attribution ?? ''],
561
+ format: new GeoJSON(),
562
+ url: layer.url
563
+ })
564
+ });
565
+ },
566
+ vectortile: (layer, attributesForClass, layerClassesId, resultSet, range, itemStyles, map) => {
567
+ return new VectorTileLayer({
568
+ minZoom: layer.minZoom ?? DEFAULT_ZOOM_MIN,
569
+ maxZoom: layer.maxZoom ?? DEFAULT_ZOOM_MAX,
570
+ opacity: (layer.opacity ?? 100) / 100,
571
+ source: new VectorTile({
572
+ attributions: [layer.attribution ?? ''],
573
+ format: new MVT(),
574
+ url: layer.url
575
+ })
576
+ });
577
+ },
578
+ rastertile: (layer, attributesForClass, layerClassesId, resultSet, range, itemStyles, map) => {
579
+ return new Tile({
580
+ minZoom: layer.minZoom ?? DEFAULT_ZOOM_MIN,
581
+ maxZoom: layer.maxZoom ?? DEFAULT_ZOOM_MAX,
582
+ opacity: (layer.opacity ?? 100) / 100,
583
+ source: new XYZ({
584
+ url: layer.url,
585
+ attributions: [layer.attribution ?? '']
586
+ })
587
+ });
588
+ }
589
+ };
590
+ }
591
+ get implementationList() {
592
+ return Object.keys(this.layersImplementation).filter((implementation) => implementation !== 'geoserver');
593
+ }
594
+ layerFromGeoJsonGeometry(layer, layerClassesId, resultSet, attributesForClass, type) {
595
+ const vectorLayer = new VectorLayer({
596
+ minZoom: layer.minZoom ?? DEFAULT_ZOOM_MIN,
597
+ maxZoom: layer.maxZoom ?? DEFAULT_ZOOM_MAX,
598
+ opacity: (layer.opacity ?? 100) / 100,
599
+ source: new VectorSource({ attributions: [layer.attribution ?? ''] })
600
+ });
601
+ layerClassesId.forEach((classId) => {
602
+ (resultSet.items[classId] || [])
603
+ .map((item) => ({
604
+ item,
605
+ location: ItemUtils.readGeometry(item, type, attributesForClass[item.oClass].locationAttribute)
606
+ }))
607
+ .filter(({ location }) => !!location)
608
+ .forEach(async (subItem) => {
609
+ const itemFeature = new Feature({
610
+ ...subItem.item,
611
+ type,
612
+ geometry: subItem.location,
613
+ classicStyle: type === 'point' ? this.pointStyle : this.circleStyle,
614
+ selectedStyle: type === 'point' ? this.selectedPointStyle : this.selectedCircleStyle
615
+ });
616
+ itemFeature.setStyle(itemFeature.get('classicStyle'));
617
+ vectorLayer.getSource()?.addFeature(itemFeature);
618
+ });
619
+ });
620
+ return this.makeClustered(vectorLayer, layer);
621
+ }
622
+ makeClustered(layer, layerOptions) {
623
+ if (!['marker', 'bubble'].includes(layerOptions.type) || !('clustered' in layerOptions && layerOptions.clustered)) {
624
+ return layer;
625
+ }
626
+ // Clustering source
627
+ const vectorLayer = layer;
628
+ vectorLayer.setSource(new Cluster({
629
+ distance: layerOptions.clusterDistance,
630
+ minDistance: 10,
631
+ source: vectorLayer.getSource()
632
+ }));
633
+ vectorLayer.setStyle((feature) => {
634
+ const size = feature.get('features').length;
635
+ if (size > 1) {
636
+ let style = this.styleCache[size];
637
+ if (!style) {
638
+ style = new Style({
639
+ image: new CircleStyle({
640
+ radius: 10,
641
+ stroke: new Stroke({
642
+ color: '#fff'
643
+ }),
644
+ fill: new Fill({
645
+ color: '#3399CC'
646
+ })
647
+ }),
648
+ text: new Text({ text: `${size}` })
649
+ });
650
+ this.styleCache[size] = style;
651
+ }
652
+ return style;
653
+ }
654
+ else {
655
+ return size === 1 ? feature.get('features')[0].get('classicStyle') : null;
656
+ }
657
+ });
658
+ return layer;
659
+ }
660
+ static translateFieldTypeToLayerType(subType) {
661
+ switch (subType) {
662
+ case FieldType.POINT:
663
+ return 'marker';
664
+ case FieldType.LINE:
665
+ return 'line';
666
+ case FieldType.POLYGON:
667
+ return 'polygon';
668
+ case FieldType.MULTILINE:
669
+ return 'multi-line';
670
+ case FieldType.MULTIPOLYGON:
671
+ return 'multi-polygon';
672
+ default:
673
+ console.warn(`wrong type ${subType} for auto options`);
674
+ return 'marker';
675
+ }
676
+ }
677
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.6", ngImport: i0, type: WidgetMapLayerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
678
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.1.6", ngImport: i0, type: WidgetMapLayerService, providedIn: 'root' }); }
679
+ }
680
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.6", ngImport: i0, type: WidgetMapLayerService, decorators: [{
681
+ type: Injectable,
682
+ args: [{
683
+ providedIn: 'root'
684
+ }]
685
+ }] });
686
+
687
+ const populateLocationAttribute = (layer, resultSet, classesNotFiltered, fields) => {
688
+ if (['heatmap', 'marker', 'bubble', 'point', 'line', 'polygon', 'multi-line', 'multi-polygon', 'auto'].includes(layer.type) &&
689
+ !!resultSet &&
690
+ !!classesNotFiltered &&
691
+ classesNotFiltered.length > 0) {
692
+ const specificLayer = layer;
693
+ const classes = classesNotFiltered.filter((cl) => specificLayer.classes?.includes(cl.id) || !specificLayer.classes || specificLayer.classes.length === 0);
694
+ if (!specificLayer.attribute) {
695
+ // No location attribute available, then try to guess one that will be ok
696
+ const geometry = geometryForLayer(layer);
697
+ let candidates = [];
698
+ if (Object.keys(resultSet.items).length > 0) {
699
+ // Based on items that we have to display
700
+ candidates = Object.keys(resultSet.items)
701
+ .map((key) => ({ items: resultSet.items[key], oClass: classes.find((cl) => cl.id === key) }))
702
+ .map(({ items, oClass }) => (oClass ?? { attributes: [] }).attributes
703
+ .map((attr) => ({ attr, field: fields.find((f) => f.id === attr.field) }))
704
+ .filter((attr) => attr.field?.type === geometry))
705
+ .reduce((p, c) => [...p, ...c], []);
706
+ }
707
+ else {
708
+ // We don't have any items to display, so allow all corresponding geometry fields
709
+ candidates = classesNotFiltered
710
+ .map((clazz) => clazz.attributes)
711
+ .flat()
712
+ .map((attr) => ({ attr, field: fields.find((field) => field.id === attr.field) }))
713
+ .filter(({ attr, field }) => field?.type === geometry);
714
+ }
715
+ if (candidates.length > 0) {
716
+ specificLayer.attribute = candidates[0].attr.name;
717
+ }
718
+ }
719
+ }
720
+ };
721
+ const populateIntensityAttribute = (layer, resultSet, classesNotFiltered, fields) => {
722
+ if (['heatmap', 'bubble'].includes(layer.type) &&
723
+ !!resultSet &&
724
+ !!classesNotFiltered &&
725
+ classesNotFiltered.length > 0) {
726
+ const specificLayer = layer;
727
+ const classes = classesNotFiltered.filter((cl) => (specificLayer.classes?.includes(cl.id) || !specificLayer.classes || specificLayer.classes.length === 0) &&
728
+ cl.attributes.find((attr) => attr.name === (specificLayer?.attribute ?? [])));
729
+ if (!specificLayer.intensityAttribute) {
730
+ // No intensity attribute available, then take the maximum intensity matching attribute
731
+ const candidatesDry = Object.keys(resultSet.items)
732
+ .map((key) => ({ items: resultSet.items[key], oClass: classes.find((cl) => cl.id === key) }))
733
+ .map(({ items, oClass }) => {
734
+ return (oClass ?? { attributes: [] }).attributes
735
+ .map((attr) => ({ attr, field: fields.find((f) => f.id === attr.field) }))
736
+ .filter((attr) => attr.field?.type === FieldType.DECIMAL || attr.field?.type === FieldType.INTEGER)
737
+ .map((attr) => {
738
+ const attrValues = ItemUtils.pertinentValue(items, attr.attr);
739
+ return {
740
+ min: Math.min(...attrValues),
741
+ max: Math.max(...attrValues),
742
+ name: attr.attr.name
743
+ };
744
+ });
745
+ })
746
+ .reduce((p, c) => [...p, ...c], [])
747
+ .sort((a, b) => b.max - a.max);
748
+ if (candidatesDry.length > 0) {
749
+ specificLayer.intensityAttribute = candidatesDry[0].name;
750
+ specificLayer.intensityAsc = true;
751
+ }
752
+ }
753
+ }
754
+ };
755
+ const getFeatureFromItem = (item, type, locationAttribute, iconStyle, selectedIconStyle) => {
756
+ return new Feature({
757
+ ...item,
758
+ type,
759
+ geometry: ItemUtils.readGeometry(item, 'point', locationAttribute),
760
+ classicStyle: iconStyle ?? null,
761
+ selectedStyle: selectedIconStyle ?? null
762
+ });
763
+ };
764
+ const getCircleFeatureFromItem = (item, locationAttribute, radius, iconStyle, selectedIconStyle) => {
765
+ return new Feature({
766
+ ...item,
767
+ geometry: new Circle$1(ItemUtils.readGeometry(item, 'point', locationAttribute).getCoordinates(), radius),
768
+ classicStyle: iconStyle,
769
+ selectedStyle: selectedIconStyle,
770
+ type: 'bubble'
771
+ });
772
+ };
773
+ const getLinkFeature = (relation, featureSource, featureDestination) => {
774
+ return new Feature({
775
+ ...relation,
776
+ geometry: new LineString([
777
+ // @ts-ignore
778
+ featureSource.getGeometry()?.getCoordinates() ?? featureSource.getGeometry()?.getCenter() ?? [0, 0],
779
+ // @ts-ignore
780
+ featureDestination.getGeometry()?.getCoordinates() ?? featureDestination.getGeometry()?.getCenter() ?? [0, 0]
781
+ ]),
782
+ source: featureSource,
783
+ destination: featureDestination,
784
+ type: 'link'
785
+ });
786
+ };
787
+ const getMapAsPng = (map) => {
788
+ return new Promise((resolve, reject) => {
789
+ map.once('rendercomplete', function () {
790
+ const mapCanvas = document.createElement('canvas');
791
+ const size = map.getSize() || [100, 100];
792
+ mapCanvas.width = size[0];
793
+ mapCanvas.height = size[1];
794
+ const mapContext = mapCanvas.getContext('2d') || null;
795
+ Array.prototype.forEach.call(document.querySelectorAll('.ol-layer canvas, canvas.ol-layer'), (canvas) => {
796
+ if (canvas.width > 0) {
797
+ const opacity = canvas.parentNode.style.opacity || canvas.style.opacity;
798
+ mapContext.globalAlpha = opacity === '' ? 1 : Number(opacity);
799
+ const backgroundColor = canvas.parentNode.style.backgroundColor;
800
+ if (backgroundColor) {
801
+ mapContext.fillStyle = backgroundColor;
802
+ mapContext.fillRect(0, 0, canvas.width, canvas.height);
803
+ }
804
+ let matrix;
805
+ const transform = canvas.style.transform;
806
+ if (transform) {
807
+ // Get the transform parameters from the style's transform matrix
808
+ matrix = transform
809
+ .match(/^matrix\(([^(]*)\)$/)[1]
810
+ .split(',')
811
+ .map(Number);
812
+ }
813
+ else {
814
+ matrix = [
815
+ parseFloat(canvas.style.width) / canvas.width,
816
+ 0,
817
+ 0,
818
+ parseFloat(canvas.style.height) / canvas.height,
819
+ 0,
820
+ 0
821
+ ];
822
+ }
823
+ // Apply the transform to the export map context
824
+ CanvasRenderingContext2D.prototype.setTransform.apply(mapContext, matrix);
825
+ mapContext.drawImage(canvas, 0, 0);
826
+ }
827
+ });
828
+ mapContext.globalAlpha = 1;
829
+ resolve(mapCanvas.toDataURL('image/png'));
830
+ });
831
+ map.renderSync();
832
+ });
833
+ };
834
+ const exportMapAsImage = (map, filename) => {
835
+ getMapAsPng(map).then((data) => {
836
+ const link = document.createElement('a');
837
+ link.download = filename;
838
+ link.href = data;
839
+ link.click();
840
+ });
841
+ };
842
+ const geometryForLayer = (layer) => {
843
+ switch (layer.type) {
844
+ case 'marker':
845
+ case 'heatmap':
846
+ case 'bubble':
847
+ case 'point':
848
+ return FieldType.POINT;
849
+ case 'line':
850
+ return FieldType.LINE;
851
+ case 'polygon':
852
+ return FieldType.POLYGON;
853
+ case 'multi-line':
854
+ return FieldType.MULTILINE;
855
+ case 'multi-polygon':
856
+ return FieldType.MULTIPOLYGON;
857
+ case 'auto':
858
+ return geometryForLayer({
859
+ type: WidgetMapLayerService.translateFieldTypeToLayerType(layer.subType)
860
+ });
861
+ default:
862
+ return FieldType.POINT;
863
+ }
864
+ };
865
+ const DEFAULT_HEATMAP_RADIUS = 25;
866
+ const DEFAULT_RADIUS_INTENSITY_FACTOR = 10000;
867
+ const DEFAULT_ZOOM_MIN = 3;
868
+ const DEFAULT_ZOOM_START = 10;
869
+ const DEFAULT_ZOOM_MAX = 18;
870
+ const DEFAULT_MAP_CENTER = [2.2827217347381525, 48.864706031557716];
871
+
872
+ class XMLUtils {
873
+ static find(childs, name) {
874
+ if (!!childs) {
875
+ for (let i = 0; i < childs.length; i++) {
876
+ const node = childs[i];
877
+ if (node.nodeName === name) {
878
+ return node;
879
+ }
849
880
  }
850
- };
881
+ }
882
+ return null;
851
883
  }
852
- get implementationList() {
853
- return Object.keys(this.layersImplementation).filter((implementation) => implementation !== 'geoserver');
884
+ static findAll(childs, name) {
885
+ const result = [];
886
+ for (let i = 0; i < childs.length; i++) {
887
+ const node = childs[i];
888
+ if (node.nodeName === name) {
889
+ result.push(node);
890
+ }
891
+ }
892
+ return result;
854
893
  }
855
- layerFromGeoJsonGeometry(layer, layerClassesId, resultSet, attributesForClass, type) {
856
- const vectorLayer = new VectorLayer({
857
- minZoom: layer.minZoom ?? DEFAULT_ZOOM_MIN,
858
- maxZoom: layer.maxZoom ?? DEFAULT_ZOOM_MAX,
859
- opacity: (layer.opacity ?? 100) / 100,
860
- source: new VectorSource({ attributions: [layer.attribution ?? ''] })
861
- });
862
- layerClassesId.forEach((classId) => {
863
- (resultSet.items[classId] || [])
864
- .map((item) => ({
865
- item,
866
- location: ItemUtils.readGeometry(item, type, attributesForClass[item.oClass].locationAttribute)
867
- }))
868
- .filter(({ location }) => !!location)
869
- .forEach(async (subItem) => {
870
- const itemFeature = new Feature({
871
- ...subItem.item,
872
- type,
873
- geometry: subItem.location,
874
- classicStyle: type === 'point' ? this.pointStyle : this.circleStyle,
875
- selectedStyle: type === 'point' ? this.selectedPointStyle : this.selectedCircleStyle
876
- });
877
- itemFeature.setStyle(itemFeature.get('classicStyle'));
878
- vectorLayer.getSource()?.addFeature(itemFeature);
879
- });
880
- });
881
- return this.makeClustered(vectorLayer, layer);
894
+ static findWith(childs, attribute, value) {
895
+ for (let i = 0; i < childs.length; i++) {
896
+ const node = childs[i];
897
+ const attrNode = XMLUtils.find(node.childNodes, attribute);
898
+ if (attrNode?.textContent === value) {
899
+ return node;
900
+ }
901
+ }
902
+ return null;
882
903
  }
883
- makeClustered(layer, layerOptions) {
884
- if (!['marker', 'bubble'].includes(layerOptions.type) || !('clustered' in layerOptions && layerOptions.clustered)) {
885
- return layer;
904
+ }
905
+
906
+ class WmsService {
907
+ constructor(httpClient) {
908
+ this.httpClient = httpClient;
909
+ this.parser = new DOMParser();
910
+ }
911
+ getCapabilities(wmsLayer) {
912
+ if (wmsLayer && wmsLayer.url) {
913
+ const layerUrlWithQmark = wmsLayer.url.indexOf('?') === -1 ? wmsLayer.url + '?' : wmsLayer.url;
914
+ const layerUrlWithService = layerUrlWithQmark.indexOf('&SERVICE=') === -1 ? layerUrlWithQmark + '&SERVICE=WMS' : layerUrlWithQmark;
915
+ const layerUrlWithVersion = layerUrlWithService.indexOf('&VERSION=') === -1 ? layerUrlWithService + '&VERSION=1.3.0' : layerUrlWithService;
916
+ return this.httpClient
917
+ .get(`${layerUrlWithVersion}&REQUEST=GetCapabilities`, {
918
+ headers: new HttpHeaders({
919
+ Accept: 'text/html, application/xhtml+xml, */*',
920
+ 'Content-Type': 'application/x-www-form-urlencoded'
921
+ }),
922
+ responseType: 'text'
923
+ })
924
+ .pipe(map((response) => {
925
+ const doc = this.parser.parseFromString(response, 'application/xml');
926
+ const errorNode = doc.querySelector('parsererror');
927
+ if (errorNode) {
928
+ console.error(`Cannot getCapabilities for ${wmsLayer.url}[${wmsLayer.paramLayer}]`);
929
+ return null;
930
+ }
931
+ else {
932
+ return { url: wmsLayer.url, paramLayer: wmsLayer.paramLayer, doc };
933
+ }
934
+ }));
886
935
  }
887
- // Clustering source
888
- const vectorLayer = layer;
889
- vectorLayer.setSource(new Cluster({
890
- distance: layerOptions.clusterDistance,
891
- minDistance: 10,
892
- source: vectorLayer.getSource()
893
- }));
894
- vectorLayer.setStyle((feature) => {
895
- const size = feature.get('features').length;
896
- if (size > 1) {
897
- let style = this.styleCache[size];
898
- if (!style) {
899
- style = new Style({
900
- image: new CircleStyle({
901
- radius: 10,
902
- stroke: new Stroke({
903
- color: '#fff'
904
- }),
905
- fill: new Fill({
906
- color: '#3399CC'
907
- })
908
- }),
909
- text: new Text({ text: `${size}` })
910
- });
911
- this.styleCache[size] = style;
936
+ return of(null);
937
+ }
938
+ static getMatchingLayer(paramLayer, doc) {
939
+ const WMSCapability = XMLUtils.find(doc.childNodes, 'WMS_Capabilities');
940
+ if (WMSCapability) {
941
+ const Capabilities = XMLUtils.find(WMSCapability.childNodes, 'Capability');
942
+ if (Capabilities) {
943
+ const Layer = XMLUtils.find(Capabilities.childNodes, 'Layer');
944
+ if (Layer) {
945
+ let matchingLayer = XMLUtils.findWith(Layer.childNodes, 'Name', paramLayer);
946
+ const split = paramLayer.split(':');
947
+ if (!matchingLayer && split.length >= 2) {
948
+ // Try again, splitting on ":" in the name to ignore namespace if present
949
+ matchingLayer = XMLUtils.findWith(Layer.childNodes, 'Name', split[split.length - 1]);
950
+ }
951
+ return matchingLayer;
912
952
  }
913
- return style;
914
953
  }
915
- else {
916
- return size === 1 ? feature.get('features')[0].get('classicStyle') : null;
917
- }
918
- });
919
- return layer;
954
+ }
955
+ return null;
920
956
  }
921
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.6", ngImport: i0, type: WidgetMapLayerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
922
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.1.6", ngImport: i0, type: WidgetMapLayerService, providedIn: 'root' }); }
957
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.6", ngImport: i0, type: WmsService, deps: [{ token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable }); }
958
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.1.6", ngImport: i0, type: WmsService, providedIn: 'root' }); }
923
959
  }
924
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.6", ngImport: i0, type: WidgetMapLayerService, decorators: [{
960
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.6", ngImport: i0, type: WmsService, decorators: [{
925
961
  type: Injectable,
926
962
  args: [{
927
963
  providedIn: 'root'
928
964
  }]
929
- }] });
965
+ }], ctorParameters: function () { return [{ type: i1.HttpClient }]; } });
930
966
 
931
967
  class PryWidgetMapCssComponent {
932
968
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.6", ngImport: i0, type: PryWidgetMapCssComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
@@ -1089,6 +1125,25 @@ class WidgetMapComponent extends DataWidgetComponent {
1089
1125
  })
1090
1126
  .map((layer) => layer);
1091
1127
  }));
1128
+ this.autoDatasetLayers$ = combineLatest([
1129
+ this.classes$,
1130
+ this.fields$,
1131
+ this.usedDatasources$.pipe(startWith([]), map((datasources) => datasources.filter((ds) => ds.sourceType === 'dataset')))
1132
+ ]).pipe(map(([classes, fields, dataSets]) => dataSets
1133
+ .map((ds) => {
1134
+ const model = classes.find((clazz) => clazz.id === ds.oClass);
1135
+ const geoAttributes = (model?.attributes.map((attr) => ({ attr, field: fields.find((f) => attr.field === f.id) })) ?? []).filter(({ attr, field }) => !!field && GeometricFieldTypes.includes(field.type));
1136
+ return geoAttributes.map((geo) => ({
1137
+ type: 'auto',
1138
+ title: `${ds.name} - ${geo.attr.name} (${geo.field.type})`,
1139
+ oClass: ds.oClass,
1140
+ key: ds.id,
1141
+ subType: geo.field.type,
1142
+ classes: [ds.oClass],
1143
+ attribute: geo.attr.name
1144
+ }));
1145
+ })
1146
+ .flat()));
1092
1147
  this.wmsCapabilities$ = combineLatest([
1093
1148
  this.manifest$.pipe(map((manifest) => (manifest.options ?? { layers: [] }).layers?.filter((layer) => ['wms'].includes(layer.type)))),
1094
1149
  this.geoServerLayerDescriptions$
@@ -1102,13 +1157,28 @@ class WidgetMapComponent extends DataWidgetComponent {
1102
1157
  this.fields$,
1103
1158
  this.styles$,
1104
1159
  this.geoServerLayerDescriptions$,
1105
- this.wmsCapabilities$.pipe(startWith([]))
1106
- ]).pipe(map(([manifest, resultSet, classes, fields, mapStyles, geoLayers, capabilities]) => {
1160
+ this.wmsCapabilities$.pipe(startWith([])),
1161
+ this.autoDatasetLayers$
1162
+ ]).pipe(map(([manifest, resultSet, classes, fields, mapStyles, geoLayers, capabilities, autoDatasetLayers]) => {
1107
1163
  // auto determine layers parameters to provide a working view
1108
- const autoOptions = JSON.parse(JSON.stringify({ relations: true, ...manifest.options }));
1164
+ const autoOptions = JSON.parse(JSON.stringify(manifest.options));
1109
1165
  if (!autoOptions.tooltipMode) {
1110
1166
  autoOptions.tooltipMode = TooltipMode.CLICK;
1111
1167
  }
1168
+ autoOptions.layers = [
1169
+ ...(autoOptions.layers ?? []).filter((layer) => layer.type !== 'auto'),
1170
+ ...(autoOptions.automaticLayers
1171
+ ? autoDatasetLayers
1172
+ .filter((layer) => !autoOptions.ignoreAutoLayer ||
1173
+ !autoOptions.ignoreAutoLayer.includes(layer.key + '-' + layer.subType))
1174
+ .map((layer) => ({
1175
+ ...layer,
1176
+ ...((autoOptions.layers ?? []).find(
1177
+ // @ts-ignore
1178
+ (prevLayer) => prevLayer.key === layer.key && prevLayer.attribute === layer.attribute) ?? {})
1179
+ }))
1180
+ : [])
1181
+ ];
1112
1182
  autoOptions.layers?.forEach((layer, i) => {
1113
1183
  populateLocationAttribute(layer, resultSet, classes, fields);
1114
1184
  populateIntensityAttribute(layer, resultSet, classes, fields);
@@ -1140,8 +1210,20 @@ class WidgetMapComponent extends DataWidgetComponent {
1140
1210
  const lightStyles = mapStyles.filter((style) => !(style.identifier ?? '-').includes('dark'));
1141
1211
  autoOptions.style = lightStyles.length > 0 ? lightStyles[0].identifier : mapStyles[0].identifier;
1142
1212
  }
1213
+ if (autoOptions.ignoreAutoLayer) {
1214
+ const base = autoOptions.ignoreAutoLayer;
1215
+ // Remove from ignoreAutoLayers, values that are not necessary
1216
+ const possibleIgnoreAutoLayerKeys = autoDatasetLayers.map((layer) => layer.key + '-' + layer.subType);
1217
+ autoOptions.ignoreAutoLayer = (autoOptions.ignoreAutoLayer ?? []).filter((key) => possibleIgnoreAutoLayerKeys.includes(key));
1218
+ if (autoOptions.ignoreAutoLayer.length === 0) {
1219
+ delete autoOptions.ignoreAutoLayer;
1220
+ }
1221
+ if (!autoOptions.ignoreAutoLayer || base.length !== autoOptions.ignoreAutoLayer.length) {
1222
+ this.emitManifest();
1223
+ }
1224
+ }
1143
1225
  return autoOptions;
1144
- }));
1226
+ }), distinctUntilChanged((p, c) => equal(p, c)));
1145
1227
  this.subscriptions.add(this.options$.pipe(filter((opt) => !!opt)).subscribe((options) => {
1146
1228
  this.optionsCopy = JSON.parse(JSON.stringify(options));
1147
1229
  }));
@@ -1428,7 +1510,10 @@ class WidgetMapComponent extends DataWidgetComponent {
1428
1510
  if (matchingLayer) {
1429
1511
  const matchingTitle = XMLUtils.find(matchingLayer.childNodes, 'Title');
1430
1512
  if (matchingTitle) {
1431
- layer.title = matchingTitle.textContent ?? undefined;
1513
+ layer.title =
1514
+ !!matchingTitle.textContent && matchingTitle.textContent.length > 0
1515
+ ? matchingTitle.textContent
1516
+ : undefined;
1432
1517
  }
1433
1518
  }
1434
1519
  }
@@ -1576,8 +1661,11 @@ class WidgetMapComponent extends DataWidgetComponent {
1576
1661
  const specificLayer = layer;
1577
1662
  specificLayer.classes = $event;
1578
1663
  }
1579
- deleteLayer(i) {
1664
+ deleteLayer(i, layer) {
1580
1665
  this.optionsCopy?.layers?.splice(i, 1);
1666
+ if (layer.type === 'auto') {
1667
+ this.optionsCopy.ignoreAutoLayer = [...(this.optionsCopy.ignoreAutoLayer ?? []), layer.key + '-' + layer.subType];
1668
+ }
1581
1669
  }
1582
1670
  invertLayers(idx, idxWith) {
1583
1671
  if (!!this.optionsCopy && !!this.optionsCopy.layers) {
@@ -1724,6 +1812,12 @@ class WidgetMapComponent extends DataWidgetComponent {
1724
1812
  changeSingleLayer($event) {
1725
1813
  this.optionsCopy.singleLayer = $event;
1726
1814
  }
1815
+ changeAutoLayer($event) {
1816
+ this.optionsCopy.automaticLayers = $event;
1817
+ if (!this.optionsCopy.automaticLayers) {
1818
+ delete this.optionsCopy.ignoreAutoLayer;
1819
+ }
1820
+ }
1727
1821
  get layerVisibleIdx() {
1728
1822
  return this.mapLayers.map((layer, idx) => (layer.getVisible() ? idx : 0)).reduce((a, b) => a + b);
1729
1823
  }
@@ -1732,11 +1826,11 @@ class WidgetMapComponent extends DataWidgetComponent {
1732
1826
  this.store.dispatch(DashboardActions.resetWmsFeatures());
1733
1827
  }
1734
1828
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.6", ngImport: i0, type: WidgetMapComponent, deps: [{ token: i1$1.Store }, { token: i2.PrySnackbarService }, { token: i2.PryI18nService }, { token: i2.TooltipFactoryService }, { token: i3.Overlay }, { token: i0.ViewContainerRef }, { token: i2.SymbolService }, { token: i0.Injector }, { token: WidgetMapLayerService }, { token: i0.ElementRef }, { token: WmsService }], target: i0.ɵɵFactoryTarget.Component }); }
1735
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.6", type: WidgetMapComponent, selector: "pry-widget-map", viewQueries: [{ propertyName: "mapRef", first: true, predicate: ["mapRef"], descendants: true }, { propertyName: "popup", first: true, predicate: ["popup"], descendants: true }, { propertyName: "popupContent", first: true, predicate: ["popupContent"], descendants: true, read: ViewContainerRef }, { propertyName: "exportTypeTemplate", first: true, predicate: ["exportTypeTemplate"], descendants: true, read: TemplateRef }, { propertyName: "address", first: true, predicate: ["address"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<pry-widget-map-css></pry-widget-map-css>\n<div class=\"o-widget o-widget--map\">\n <pry-widget-header\n [datasourceIds]=\"(datasourceIds$ | async) ?? []\"\n *ngIf=\"displayHeader$ | async\"\n [widgetIndex]=\"widgetIndex\"\n [manifest]=\"manifest\"\n (manifestModified)=\"manifestModified.emit($event)\"\n [headerOptions]=\"(displayHeader$ | async) ?? {}\"\n #header\n >\n <pry-settings\n (saveTriggered)=\"emitManifest()\"\n (changeTitle)=\"changeWidgetTitle($event)\"\n [headerPresent]=\"displayHeader$ | async\"\n [widgetIndex]=\"widgetIndex\"\n [header]=\"header\"\n [open$]=\"open$\"\n class=\"o-settings\"\n >\n <div class=\"m-form-label-field\">\n <label class=\"a-label\" for=\"map_style\">{{ '@pry.widget.map.style' | i18n }}</label>\n <pry-select\n (ngModelChange)=\"changeStyle($event)\"\n [itemsAsOption]=\"true\"\n [items]=\"styles$ | async\"\n [ngModel]=\"optionsCopy.style\"\n bindLabel=\"label\"\n bindValue=\"identifier\"\n id=\"map_style\"\n class=\"a-pry-select\"\n ></pry-select>\n </div>\n\n <div class=\"m-form-label-field\" *ngIf=\"optionsCopy.style === STYLE_FROM_URL\">\n <label class=\"a-label\" for=\"style_URL\">{{ '@pry.widget.map.styleUrl' | i18n }}</label>\n <input\n id=\"style_URL\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeStyleURL($event)\"\n [value]=\"optionsCopy.styleURL ?? ''\"\n />\n </div>\n\n <pry-checkbox (ngModelChange)=\"changeSingleLayer($event)\" [ngModel]=\"optionsCopy.singleLayer ?? false\">\n {{ '@pry.widget.map.singleLayer' | i18n }}\n </pry-checkbox>\n\n <pry-checkbox (ngModelChange)=\"changeFit($event)\" [ngModel]=\"optionsCopy.fit ?? false\">\n {{ '@pry.widget.map.fit' | i18n }}\n </pry-checkbox>\n\n <pry-checkbox (ngModelChange)=\"changeAttributions($event)\" [ngModel]=\"optionsCopy.attributions ?? false\">\n {{ '@pry.widget.map.attributions' | i18n }}\n </pry-checkbox>\n\n <div class=\"o-settings__popup__content__actions -has-separator\">\n <button type=\"button\" (click)=\"addLayer()\" class=\"a-btn a-btn--icon-text -link-like\">\n <pry-icon iconSvg=\"library_add\"></pry-icon>\n {{ '@pry.widget.map.addLayer' | i18n }}\n </button>\n </div>\n\n <div *ngFor=\"let layer of optionsCopy?.layers; let i = index\" class=\"o-settings__popup__content__fields\">\n <div class=\"o-settings__popup__content__fields__head\">\n <h3 class=\"a-h3 settings-layer-title__title\">{{ '@pry.widget.map.layer' | i18n : { index: i + 1 } }}</h3>\n <div class=\"m-btn-group\">\n <button type=\"button\" class=\"a-btn a-btn--icon-only\" (click)=\"invertLayers(i, i - 1)\" *ngIf=\"i > 0\">\n <pry-icon iconSvg=\"fleche_haut\"></pry-icon>\n <span class=\"u-visually-hidden\">{{ '@pry.action.moveUp' | i18n }}</span>\n </button>\n <button\n type=\"button\"\n class=\"a-btn a-btn--icon-only\"\n (click)=\"invertLayers(i, i + 1)\"\n *ngIf=\"i < (optionsCopy?.layers?.length ?? 0) - 1\"\n >\n <pry-icon iconSvg=\"fleche_bas\"></pry-icon>\n <span class=\"u-visually-hidden\">{{ '@pry.action.moveDown' | i18n }}</span>\n </button>\n </div>\n </div>\n\n <div class=\"o-settings__popup__content__fields__content\">\n <pry-range\n [ngModel]=\"(layer?.opacity ?? 100) + ''\"\n (ngModelChange)=\"changeOpacity(layer, $event)\"\n labelTranslate=\"@pry.widget.map.opacity\"\n min=\"0\"\n max=\"100\"\n ></pry-range>\n\n <fieldset>\n <legend class=\"u-visually-hidden\">{{ '@pry.widget.map.layerOptions' | i18n : { index: i + 1 } }}</legend>\n <div class=\"m-form-label-field\">\n <label class=\"a-label\" for=\"map_layerTitle\">{{ '@pry.widget.map.layerTitle' | i18n }}</label>\n <input\n id=\"map_layerTitle\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeTitle($event, layer)\"\n [value]=\"layer.title ?? ''\"\n />\n </div>\n\n <div class=\"m-form-label-field\" *ngIf=\"layer.type !== 'geoserver'\">\n <label class=\"a-label\" for=\"map_layerType\">{{ '@pry.widget.map.layerType.title' | i18n }}</label>\n <pry-select\n (ngModelChange)=\"changeLayerType($event, i)\"\n [bindData]=\"true\"\n [itemsAsOption]=\"true\"\n [items]=\"layerTypes\"\n [labelTranslate]=\"true\"\n [ngModel]=\"layer.type\"\n baseTranslate=\"@pry.widget.map.layerType.\"\n class=\"a-pry-select\"\n id=\"map_layerType\"\n ></pry-select>\n </div>\n\n <div\n *ngIf=\"\n layer.type !== 'relation' &&\n layer.type !== 'wms' &&\n layer.type !== 'wmts' &&\n layer.type !== 'geoserver' &&\n layer.type !== 'featurelayer' &&\n layer.type !== 'vectortile' &&\n layer.type !== 'rastertile'\n \"\n class=\"m-form-label-field\"\n >\n <label class=\"a-label\" for=\"map_classes\">{{ '@pry.widget.map.classes' | i18n }}</label>\n <pry-select\n (ngModelChange)=\"changeClasses($event, layer)\"\n [itemsAsOption]=\"true\"\n [items]=\"classes$ | async\"\n [multiple]=\"true\"\n [ngModel]=\"layer.classes\"\n bindLabel=\"name\"\n bindValue=\"id\"\n class=\"a-pry-select\"\n id=\"map_classes\"\n ></pry-select>\n </div>\n </fieldset>\n </div>\n\n <fieldset\n *ngIf=\"\n layer.type !== 'relation' &&\n layer.type !== 'wms' &&\n layer.type !== 'wmts' &&\n layer.type !== 'geoserver' &&\n layer.type !== 'featurelayer' &&\n layer.type !== 'vectortile' &&\n layer.type !== 'rastertile'\n \"\n >\n <legend class=\"u-visually-hidden\">{{ '@pry.widget.map.locationAttr' | i18n }}</legend>\n <ng-container\n *ngIf=\"\n layer\n | geometryFieldsFor : { resultSet: resultSet$, classes: layer.classes, type: layer.type }\n | async as fields\n \"\n >\n <div\n *ngIf=\"\n ['heatmap', 'bubble', 'marker', 'point', 'line', 'polygon', 'multi-line', 'multi-polygon'].indexOf(\n layer.type\n ) >= 0\n \"\n >\n <div class=\"m-form-label-field\">\n <label class=\"a-label\" for=\"map_locationAttribute_both\">{{\n '@pry.widget.map.locationAttribute.both' | i18n\n }}</label>\n <pry-select\n (ngModelChange)=\"changeLocationAttributes($event, layer)\"\n [itemsAsOption]=\"true\"\n [items]=\"fields\"\n [ngModel]=\"layer.attribute\"\n bindLabel=\"name\"\n bindValue=\"name\"\n id=\"map_locationAttribute_both\"\n class=\"a-pry-select\"\n ></pry-select>\n </div>\n </div>\n\n <div *ngIf=\"['heatmap', 'bubble'].indexOf(layer.type) >= 0\">\n <div class=\"m-form-label-field\">\n <label class=\"a-label\" for=\"map_intensityAttribute\">{{\n '@pry.widget.map.intensityAttribute' | i18n\n }}</label>\n <pry-select\n (ngModelChange)=\"changeIntensityAttributes($event, layer)\"\n [itemsAsOption]=\"true\"\n [items]=\"fields\"\n [ngModel]=\"layerHasIntensity(layer).intensityAttribute\"\n bindLabel=\"name\"\n bindValue=\"name\"\n id=\"map_intensityAttribute\"\n class=\"a-pry-select\"\n ></pry-select>\n </div>\n </div>\n </ng-container>\n </fieldset>\n\n <fieldset\n *ngIf=\"\n layer.type === 'wms' ||\n layer.type === 'wmts' ||\n layer.type === 'featurelayer' ||\n layer.type === 'vectortile' ||\n layer.type === 'rastertile'\n \"\n >\n <legend class=\"u-visually-hidden\">{{ '@pry.widget.map.tile' | i18n }}</legend>\n <div class=\"m-form-label-field\">\n <label class=\"a-label\" for=\"map_wms_url\">{{ '@pry.widget.map.wms.url' | i18n }}</label>\n <input\n id=\"map_wms_url\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeUrl($event, layer)\"\n [value]=\"layer.url\"\n />\n </div>\n\n <div class=\"m-form-label-field\" *ngIf=\"layer.type === 'wms' || layer.type === 'wmts'\">\n <label class=\"a-label\" for=\"map_wms_paramLayer\">{{ '@pry.widget.map.wms.paramLayer' | i18n }}</label>\n <input\n id=\"map_wms_paramLayer\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeParamLayer($event, layer)\"\n [value]=\"layer.paramLayer\"\n />\n </div>\n\n <div class=\"m-form-label-field\" *ngIf=\"layer.type === 'wmts'\">\n <label class=\"a-label\" for=\"map_wms_matrixSet\">{{ '@pry.widget.map.wms.matrixSet' | i18n }}</label>\n <input\n id=\"map_wms_matrixSet\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeMatrixSet($event, layer)\"\n [value]=\"layer.matrixSet\"\n />\n </div>\n\n <div class=\"m-form-label-field\" *ngIf=\"layer.type === 'wmts'\">\n <label class=\"a-label\" for=\"map_wms_style\">{{ '@pry.widget.map.wms.style' | i18n }}</label>\n <input\n id=\"map_wms_style\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeParamStyle($event, layer)\"\n [value]=\"layer.style\"\n />\n </div>\n\n <div class=\"m-form-label-field\" *ngIf=\"layer.type === 'wms'\">\n <pry-checkbox (ngModelChange)=\"changeParamTiled($event, layer)\" [ngModel]=\"layer?.paramTiled ?? false\">\n {{ '@pry.widget.map.wms.paramTiled' | i18n }}\n </pry-checkbox>\n </div>\n </fieldset>\n\n <fieldset *ngIf=\"layer.type === 'marker'\">\n <legend class=\"u-visually-hidden\">{{ '@pry.widget.map.clustering' | i18n }}</legend>\n <div class=\"m-form-label-field\">\n <pry-checkbox (ngModelChange)=\"changeClustered(layer, $event)\" [ngModel]=\"layer.clustered\">\n {{ '@pry.widget.map.clustered' | i18n }}\n </pry-checkbox>\n </div>\n <div *ngIf=\"layer.clustered\">\n <pry-range\n [ngModel]=\"layer.clustered\"\n (ngModelChange)=\"changeClusterDistance(layer, $event)\"\n labelTranslate=\"@pry.widget.map.clusterDistance\"\n min=\"1\"\n max=\"500\"\n ></pry-range>\n </div>\n </fieldset>\n\n <div class=\"m-form-label-field\" *ngIf=\"optionsCopy.attributions\">\n <label class=\"a-label\" for=\"attribution\">{{ '@pry.widget.map.attribution' | i18n }}</label>\n <input\n id=\"attribution\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeAttribution($event, layer)\"\n [value]=\"layer.attribution ? layer.attribution : ''\"\n />\n </div>\n\n <button\n type=\"button\"\n (click)=\"deleteLayer(i)\"\n class=\"a-btn a-btn--icon-text -link-like\"\n *ngIf=\"layer.type !== 'geoserver'\"\n data-func=\"delete\"\n >\n <pry-icon iconSvg=\"delete\" [width]=\"19\" [height]=\"19\"></pry-icon>\n <span>{{ '@pry.widget.map.deleteLayer' | i18n }}</span>\n </button>\n </div>\n </pry-settings>\n </pry-widget-header>\n\n <div class=\"m-btn-group -selection-choice\" [style.transform]=\"bottomLeft$ | async\">\n <ng-container *ngFor=\"let action of basicActions$ | async\">\n <button\n type=\"button\"\n class=\"a-btn a-btn--icon-only\"\n (click)=\"interactionManager.selectionInteraction.changeSelection(action)\"\n [class.-selected]=\"interactionManager.selectionInteraction.selectionType === action\"\n [pryTooltip]=\"infoTooltipAction\"\n pryTooltipPosition=\"bottom\"\n aria-describedby=\"infoTooltipAction\"\n [pryTooltipContext]=\"{ action: action }\"\n >\n <pry-icon [iconSvg]=\"action\"></pry-icon>\n <span class=\"u-visually-hidden\">{{ '@pry.widget.map.' + action | i18n }}</span>\n </button>\n </ng-container>\n\n <button\n type=\"button\"\n class=\"a-btn a-btn--icon-only\"\n id=\"export_card\"\n aria-expanded=\"false\"\n aria-controls=\"export_type\"\n aria-haspopup=\"menu\"\n [pryTooltip]=\"infoTooltipDown\"\n pryTooltipPosition=\"bottom\"\n aria-describedby=\"infoTooltipDown_widgetMap\"\n *ngIf=\"(actions$ | async)?.includes('export')\"\n >\n <pry-icon iconSvg=\"file_download\" (click)=\"export()\"></pry-icon>\n <span class=\"u-visually-hidden\">{{ '@pry.widget.map.export' | i18n }}</span>\n </button>\n </div>\n\n <div\n class=\"ol-control m-layer-switcher\"\n *ngIf=\"((layers$ | async)?.length ?? 0) > 0\"\n [style.top.px]=\"layersTop$ | async\"\n >\n <button\n class=\"m-layer-switcher__toggle\"\n (click)=\"toggleLayersWindow()\"\n [title]=\"'@pry.widget.map.selectLayers' | i18n\"\n >\n <pry-icon iconSvg=\"layers\" [width]=\"22\" [height]=\"22\"></pry-icon>\n </button>\n <ng-container *ngFor=\"let layer of mapLayers; let index = index\">\n <div class=\"m-layer-switcher__title\" [class.-hidden]=\"!layersTabOpen\">\n {{ layer.get('title') }}\n <ng-container *ngIf=\"!(options$ | async)?.singleLayer; else singleLayer\">\n <pry-checkbox [ngModel]=\"layer.getVisible()\" (change)=\"changeVisibility(layer)\"></pry-checkbox>\n </ng-container>\n <ng-template #singleLayer>\n <input\n type=\"radio\"\n name=\"layer\"\n [id]=\"'radio-layer-' + layer.get('title').split(' ')[0]\"\n [ngModel]=\"layerVisibleIdx\"\n [value]=\"index\"\n (change)=\"changeVisibility(layer)\"\n />\n </ng-template>\n </div>\n </ng-container>\n </div>\n\n <div\n class=\"ol-control m-layer-legend\"\n *ngIf=\"((legendLayers$ | async)?.length ?? 0) > 0\"\n [style.top.px]=\"legendTop$ | async\"\n >\n <button class=\"m-layer-legend__toggle\" (click)=\"toggleLegendWindow()\" [title]=\"'@pry.widget.map.legends' | i18n\">\n <pry-icon iconSvg=\"legend\" [width]=\"22\" [height]=\"22\"></pry-icon>\n </button>\n <ng-container *ngFor=\"let geoLayer of legendLayers$ | async; let index = index\">\n <div class=\"m-layer-legend__title\" [class.-hidden]=\"!legendTabOpen\">\n {{ geoLayer.title }}\n <ng-container *ngIf=\"isLayerRendered(geoLayer)\">\n <button class=\"m-layer-legend__toggle\" (click)=\"toggleLegend(index)\">\n <pry-icon\n [iconSvg]=\"legendTab === index ? 'chevron_top' : 'chevron_bottom'\"\n [width]=\"22\"\n [height]=\"22\"\n ></pry-icon>\n </button>\n </ng-container>\n <ng-container *ngIf=\"!isLayerRendered(geoLayer)\">\n <pry-icon [iconSvg]=\"'close'\" [width]=\"22\" [height]=\"22\"></pry-icon>\n </ng-container>\n </div>\n <div\n class=\"m-layer-legend__image\"\n [class.-hidden]=\"!legendTabOpen || legendTab !== index || !isLayerRendered(geoLayer)\"\n [style.max-height.px]=\"legendHeight$ | async\"\n >\n <ng-container *ngIf=\"geoLayer | legendUrl : { capabilities: (wmsCapabilities$ | async) } as url\">\n <img\n [src]=\"url\"\n [alt]=\"'@pry.widget.map.legend' | i18n : { layer: geoLayer.title }\"\n (error)=\"imageNotProvided[index] = true\"\n />\n </ng-container>\n <ng-container *ngIf=\"!(geoLayer | legendUrl : { capabilities: (wmsCapabilities$ | async) })\">\n <p class=\"m-layer-legend__error\">{{ '@pry.widget.map.legendNotProvided' | i18n }}</p>\n </ng-container>\n </div>\n </ng-container>\n </div>\n\n <div [style.height.px]=\"height$ | async\" class=\"o-map-wrapper\">\n <div class=\"o-map\">\n <div #mapRef id=\"map\"></div>\n </div>\n </div>\n\n <ng-template #infoTooltipAction let-action=\"action\">\n <div class=\"m-tooltip\" role=\"tooltip\" id=\"infoTooltipAction\" aria-hidden=\"true\">\n <span class=\"m-tooltip__text\">{{ '@pry.widget.map.' + action | i18n }}</span>\n </div>\n </ng-template>\n\n <ng-template #infoTooltipDown>\n <div class=\"m-tooltip\" role=\"tooltip\" id=\"infoTooltipDown_widgetMap\" aria-hidden=\"true\">\n <span class=\"m-tooltip__text\">{{ '@pry.widget.map.export' | i18n }}</span>\n </div>\n </ng-template>\n\n <div #popup class=\"m-tooltip m-tooltip--popup\" [hidden]=\"true\" role=\"tooltip\">\n <div class=\"m-tooltip--popup__header\">\n <p>{{ this.tooltipIndex + 1 }} / {{ this.tooltipNumber }}</p>\n <button class=\"a-btn a-btn--primary a-btn--icon-only\" (click)=\"tooltipMove(-1)\" [disabled]=\"!tooltipCanMove(-1)\">\n <pry-icon iconSvg=\"arrow_back\"></pry-icon>\n </button>\n <button class=\"a-btn a-btn--primary a-btn--icon-only\" (click)=\"tooltipMove(1)\" [disabled]=\"!tooltipCanMove(1)\">\n <pry-icon iconSvg=\"arrow_right\"></pry-icon>\n </button>\n </div>\n <div class=\"m-tooltip--popup__container\">\n <ng-container #popupContent></ng-container>\n </div>\n </div>\n <div\n #address\n class=\"m-tooltip m-tooltip--address tooltip-address\"\n [style.display]=\"'none'\"\n (click)=\"hideAddress()\"\n ></div>\n</div>\n", dependencies: [{ kind: "directive", type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i7.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i7.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i7.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i2.SettingsComponent, selector: "pry-settings", inputs: ["widgetIndex", "isDisable", "headerPresent", "open$", "header"], outputs: ["saveTriggered", "changeTitle"] }, { kind: "component", type: i2.PryWidgetHeaderComponent, selector: "pry-widget-header", inputs: ["manifest", "additionalOptions", "headerOptions", "displayCount", "datasourceIds", "widgetIndex"], outputs: ["manifestModified"] }, { kind: "component", type: i2.PrySelectComponent, selector: "pry-select", inputs: ["labelTranslate", "baseTranslate", "translationFn", "translationFnArgs", "clearable", "multiple", "multipleClearRight", "closeOnSelect", "placeholder", "isForm", "required", "name", "readonly", "items", "itemsAsOption", "bindData", "bindValue", "bindLabel", "bindIcon", "iconSize", "templateLabel", "templateOption", "autocomplete"] }, { kind: "component", type: i2.PryIconComponent, selector: "pry-icon", inputs: ["color", "iconSvg", "animation", "iconImage", "alt", "width", "height", "classes"] }, { kind: "component", type: i8.PryCheckboxComponent, selector: "pry-checkbox", inputs: ["circle"] }, { kind: "directive", type: i2.PryTooltipDirective, selector: "[pryTooltip]", inputs: ["pryTooltip", "styleReversed", "pryTooltipContext", "pryTooltipPosition", "pryTooltipShowDelay"] }, { kind: "component", type: i2.PryRangeComponent, selector: "pry-range", inputs: ["min", "max", "step", "disabled", "labelTranslate"] }, { kind: "component", type: PryWidgetMapCssComponent, selector: "pry-widget-map-css" }, { kind: "pipe", type: i6.AsyncPipe, name: "async" }, { kind: "pipe", type: i2.I18nPipe, name: "i18n" }, { kind: "pipe", type: GeometryFieldsForPipe, name: "geometryFieldsFor" }, { kind: "pipe", type: WidgetMapLegendUrlPipe, name: "legendUrl" }] }); }
1829
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.6", type: WidgetMapComponent, selector: "pry-widget-map", viewQueries: [{ propertyName: "mapRef", first: true, predicate: ["mapRef"], descendants: true }, { propertyName: "popup", first: true, predicate: ["popup"], descendants: true }, { propertyName: "popupContent", first: true, predicate: ["popupContent"], descendants: true, read: ViewContainerRef }, { propertyName: "exportTypeTemplate", first: true, predicate: ["exportTypeTemplate"], descendants: true, read: TemplateRef }, { propertyName: "address", first: true, predicate: ["address"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<pry-widget-map-css></pry-widget-map-css>\n<div class=\"o-widget o-widget--map\">\n <pry-widget-header\n [datasourceIds]=\"(datasourceIds$ | async) ?? []\"\n *ngIf=\"displayHeader$ | async\"\n [widgetIndex]=\"widgetIndex\"\n [manifest]=\"manifest\"\n (manifestModified)=\"manifestModified.emit($event)\"\n [headerOptions]=\"(displayHeader$ | async) ?? {}\"\n #header\n >\n <pry-settings\n (saveTriggered)=\"emitManifest()\"\n (changeTitle)=\"changeWidgetTitle($event)\"\n [headerPresent]=\"displayHeader$ | async\"\n [widgetIndex]=\"widgetIndex\"\n [header]=\"header\"\n [open$]=\"open$\"\n class=\"o-settings\"\n >\n <div class=\"m-form-label-field\">\n <label class=\"a-label\" for=\"map_style\">{{ '@pry.widget.map.style' | i18n }}</label>\n <pry-select\n (ngModelChange)=\"changeStyle($event)\"\n [itemsAsOption]=\"true\"\n [items]=\"styles$ | async\"\n [ngModel]=\"optionsCopy.style\"\n bindLabel=\"label\"\n bindValue=\"identifier\"\n id=\"map_style\"\n class=\"a-pry-select\"\n ></pry-select>\n </div>\n\n <div class=\"m-form-label-field\" *ngIf=\"optionsCopy.style === STYLE_FROM_URL\">\n <label class=\"a-label\" for=\"style_URL\">{{ '@pry.widget.map.styleUrl' | i18n }}</label>\n <input\n id=\"style_URL\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeStyleURL($event)\"\n [value]=\"optionsCopy.styleURL ?? ''\"\n />\n </div>\n\n <pry-checkbox (ngModelChange)=\"changeSingleLayer($event)\" [ngModel]=\"optionsCopy.singleLayer ?? false\">\n {{ '@pry.widget.map.singleLayer' | i18n }}\n </pry-checkbox>\n\n <pry-checkbox (ngModelChange)=\"changeAutoLayer($event)\" [ngModel]=\"optionsCopy.automaticLayers ?? false\">\n {{ '@pry.widget.map.autoLayer' | i18n }}\n </pry-checkbox>\n\n <pry-checkbox (ngModelChange)=\"changeFit($event)\" [ngModel]=\"optionsCopy.fit ?? false\">\n {{ '@pry.widget.map.fit' | i18n }}\n </pry-checkbox>\n\n <pry-checkbox (ngModelChange)=\"changeAttributions($event)\" [ngModel]=\"optionsCopy.attributions ?? false\">\n {{ '@pry.widget.map.attributions' | i18n }}\n </pry-checkbox>\n\n <div class=\"o-settings__popup__content__actions -has-separator\">\n <button type=\"button\" (click)=\"addLayer()\" class=\"a-btn a-btn--icon-text -link-like\">\n <pry-icon iconSvg=\"library_add\"></pry-icon>\n {{ '@pry.widget.map.addLayer' | i18n }}\n </button>\n </div>\n\n <div *ngFor=\"let layer of optionsCopy?.layers; let i = index\" class=\"o-settings__popup__content__fields\">\n <div class=\"o-settings__popup__content__fields__head\">\n <h3 class=\"a-h3 settings-layer-title__title\">{{ '@pry.widget.map.layer' | i18n : { index: i + 1 } }}</h3>\n <div class=\"m-btn-group\">\n <button type=\"button\" class=\"a-btn a-btn--icon-only\" (click)=\"invertLayers(i, i - 1)\" *ngIf=\"i > 0\">\n <pry-icon iconSvg=\"fleche_haut\"></pry-icon>\n <span class=\"u-visually-hidden\">{{ '@pry.action.moveUp' | i18n }}</span>\n </button>\n <button\n type=\"button\"\n class=\"a-btn a-btn--icon-only\"\n (click)=\"invertLayers(i, i + 1)\"\n *ngIf=\"i < (optionsCopy?.layers?.length ?? 0) - 1\"\n >\n <pry-icon iconSvg=\"fleche_bas\"></pry-icon>\n <span class=\"u-visually-hidden\">{{ '@pry.action.moveDown' | i18n }}</span>\n </button>\n </div>\n </div>\n\n <div class=\"o-settings__popup__content__fields__content\">\n <pry-range\n [ngModel]=\"(layer?.opacity ?? 100) + ''\"\n (ngModelChange)=\"changeOpacity(layer, $event)\"\n labelTranslate=\"@pry.widget.map.opacity\"\n min=\"0\"\n max=\"100\"\n ></pry-range>\n\n <fieldset>\n <legend class=\"u-visually-hidden\">{{ '@pry.widget.map.layerOptions' | i18n : { index: i + 1 } }}</legend>\n <div class=\"m-form-label-field\">\n <label class=\"a-label\" for=\"map_layerTitle\">{{ '@pry.widget.map.layerTitle' | i18n }}</label>\n <input\n id=\"map_layerTitle\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeTitle($event, layer)\"\n [value]=\"layer.title ?? ''\"\n />\n </div>\n\n <div class=\"m-form-label-field\" *ngIf=\"!['geoserver', 'auto'].includes(layer.type)\">\n <label class=\"a-label\" for=\"map_layerType\">{{ '@pry.widget.map.layerType.title' | i18n }}</label>\n <pry-select\n (ngModelChange)=\"changeLayerType($event, i)\"\n [bindData]=\"true\"\n [itemsAsOption]=\"true\"\n [items]=\"layerTypes\"\n [labelTranslate]=\"true\"\n [ngModel]=\"layer.type\"\n baseTranslate=\"@pry.widget.map.layerType.\"\n class=\"a-pry-select\"\n id=\"map_layerType\"\n ></pry-select>\n </div>\n\n <div\n *ngIf=\"\n layer.type !== 'relation' &&\n layer.type !== 'wms' &&\n layer.type !== 'wmts' &&\n layer.type !== 'geoserver' &&\n layer.type !== 'featurelayer' &&\n layer.type !== 'vectortile' &&\n layer.type !== 'rastertile' &&\n layer.type !== 'auto'\n \"\n class=\"m-form-label-field\"\n >\n <label class=\"a-label\" for=\"map_classes\">{{ '@pry.widget.map.classes' | i18n }}</label>\n <pry-select\n (ngModelChange)=\"changeClasses($event, layer)\"\n [itemsAsOption]=\"true\"\n [items]=\"classes$ | async\"\n [multiple]=\"true\"\n [ngModel]=\"layer.classes\"\n bindLabel=\"name\"\n bindValue=\"id\"\n class=\"a-pry-select\"\n id=\"map_classes\"\n ></pry-select>\n </div>\n </fieldset>\n </div>\n\n <fieldset\n *ngIf=\"\n layer.type !== 'relation' &&\n layer.type !== 'wms' &&\n layer.type !== 'wmts' &&\n layer.type !== 'geoserver' &&\n layer.type !== 'featurelayer' &&\n layer.type !== 'vectortile' &&\n layer.type !== 'rastertile'\n \"\n >\n <legend class=\"u-visually-hidden\">{{ '@pry.widget.map.locationAttr' | i18n }}</legend>\n <ng-container\n *ngIf=\"\n layer\n | geometryFieldsFor : { resultSet: resultSet$, classes: layer.classes, type: layer.type }\n | async as fields\n \"\n >\n <div\n *ngIf=\"\n ['heatmap', 'bubble', 'marker', 'point', 'line', 'polygon', 'multi-line', 'multi-polygon'].indexOf(\n layer.type\n ) >= 0\n \"\n >\n <div class=\"m-form-label-field\">\n <label class=\"a-label\" for=\"map_locationAttribute_both\">{{\n '@pry.widget.map.locationAttribute.both' | i18n\n }}</label>\n <pry-select\n (ngModelChange)=\"changeLocationAttributes($event, layer)\"\n [itemsAsOption]=\"true\"\n [items]=\"fields\"\n [ngModel]=\"layer.attribute\"\n bindLabel=\"name\"\n bindValue=\"name\"\n id=\"map_locationAttribute_both\"\n class=\"a-pry-select\"\n ></pry-select>\n </div>\n </div>\n\n <div *ngIf=\"['heatmap', 'bubble'].indexOf(layer.type) >= 0\">\n <div class=\"m-form-label-field\">\n <label class=\"a-label\" for=\"map_intensityAttribute\">{{\n '@pry.widget.map.intensityAttribute' | i18n\n }}</label>\n <pry-select\n (ngModelChange)=\"changeIntensityAttributes($event, layer)\"\n [itemsAsOption]=\"true\"\n [items]=\"fields\"\n [ngModel]=\"layerHasIntensity(layer).intensityAttribute\"\n bindLabel=\"name\"\n bindValue=\"name\"\n id=\"map_intensityAttribute\"\n class=\"a-pry-select\"\n ></pry-select>\n </div>\n </div>\n </ng-container>\n </fieldset>\n\n <fieldset\n *ngIf=\"\n layer.type === 'wms' ||\n layer.type === 'wmts' ||\n layer.type === 'featurelayer' ||\n layer.type === 'vectortile' ||\n layer.type === 'rastertile'\n \"\n >\n <legend class=\"u-visually-hidden\">{{ '@pry.widget.map.tile' | i18n }}</legend>\n <div class=\"m-form-label-field\">\n <label class=\"a-label\" for=\"map_wms_url\">{{ '@pry.widget.map.wms.url' | i18n }}</label>\n <input\n id=\"map_wms_url\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeUrl($event, layer)\"\n [value]=\"layer.url\"\n />\n </div>\n\n <div class=\"m-form-label-field\" *ngIf=\"layer.type === 'wms' || layer.type === 'wmts'\">\n <label class=\"a-label\" for=\"map_wms_paramLayer\">{{ '@pry.widget.map.wms.paramLayer' | i18n }}</label>\n <input\n id=\"map_wms_paramLayer\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeParamLayer($event, layer)\"\n [value]=\"layer.paramLayer\"\n />\n </div>\n\n <div class=\"m-form-label-field\" *ngIf=\"layer.type === 'wmts'\">\n <label class=\"a-label\" for=\"map_wms_matrixSet\">{{ '@pry.widget.map.wms.matrixSet' | i18n }}</label>\n <input\n id=\"map_wms_matrixSet\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeMatrixSet($event, layer)\"\n [value]=\"layer.matrixSet\"\n />\n </div>\n\n <div class=\"m-form-label-field\" *ngIf=\"layer.type === 'wmts'\">\n <label class=\"a-label\" for=\"map_wms_style\">{{ '@pry.widget.map.wms.style' | i18n }}</label>\n <input\n id=\"map_wms_style\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeParamStyle($event, layer)\"\n [value]=\"layer.style\"\n />\n </div>\n\n <div class=\"m-form-label-field\" *ngIf=\"layer.type === 'wms'\">\n <pry-checkbox (ngModelChange)=\"changeParamTiled($event, layer)\" [ngModel]=\"layer?.paramTiled ?? false\">\n {{ '@pry.widget.map.wms.paramTiled' | i18n }}\n </pry-checkbox>\n </div>\n </fieldset>\n\n <fieldset *ngIf=\"layer.type === 'marker'\">\n <legend class=\"u-visually-hidden\">{{ '@pry.widget.map.clustering' | i18n }}</legend>\n <div class=\"m-form-label-field\">\n <pry-checkbox (ngModelChange)=\"changeClustered(layer, $event)\" [ngModel]=\"layer.clustered\">\n {{ '@pry.widget.map.clustered' | i18n }}\n </pry-checkbox>\n </div>\n <div *ngIf=\"layer.clustered\">\n <pry-range\n [ngModel]=\"layer.clustered\"\n (ngModelChange)=\"changeClusterDistance(layer, $event)\"\n labelTranslate=\"@pry.widget.map.clusterDistance\"\n min=\"1\"\n max=\"500\"\n ></pry-range>\n </div>\n </fieldset>\n\n <div class=\"m-form-label-field\" *ngIf=\"optionsCopy.attributions\">\n <label class=\"a-label\" for=\"attribution\">{{ '@pry.widget.map.attribution' | i18n }}</label>\n <input\n id=\"attribution\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeAttribution($event, layer)\"\n [value]=\"layer.attribution ? layer.attribution : ''\"\n />\n </div>\n\n <button\n type=\"button\"\n (click)=\"deleteLayer(i, layer)\"\n class=\"a-btn a-btn--icon-text -link-like\"\n *ngIf=\"layer.type !== 'geoserver'\"\n data-func=\"delete\"\n >\n <pry-icon iconSvg=\"delete\" [width]=\"19\" [height]=\"19\"></pry-icon>\n <span>{{ '@pry.widget.map.deleteLayer' | i18n }}</span>\n </button>\n </div>\n </pry-settings>\n </pry-widget-header>\n\n <div class=\"m-btn-group -selection-choice\" [style.transform]=\"bottomLeft$ | async\">\n <ng-container *ngFor=\"let action of basicActions$ | async\">\n <button\n type=\"button\"\n class=\"a-btn a-btn--icon-only\"\n (click)=\"interactionManager.selectionInteraction.changeSelection(action)\"\n [class.-selected]=\"interactionManager.selectionInteraction.selectionType === action\"\n [pryTooltip]=\"infoTooltipAction\"\n pryTooltipPosition=\"bottom\"\n aria-describedby=\"infoTooltipAction\"\n [pryTooltipContext]=\"{ action: action }\"\n >\n <pry-icon [iconSvg]=\"action\"></pry-icon>\n <span class=\"u-visually-hidden\">{{ '@pry.widget.map.' + action | i18n }}</span>\n </button>\n </ng-container>\n\n <button\n type=\"button\"\n class=\"a-btn a-btn--icon-only\"\n id=\"export_card\"\n aria-expanded=\"false\"\n aria-controls=\"export_type\"\n aria-haspopup=\"menu\"\n [pryTooltip]=\"infoTooltipDown\"\n pryTooltipPosition=\"bottom\"\n aria-describedby=\"infoTooltipDown_widgetMap\"\n *ngIf=\"(actions$ | async)?.includes('export')\"\n >\n <pry-icon iconSvg=\"file_download\" (click)=\"export()\"></pry-icon>\n <span class=\"u-visually-hidden\">{{ '@pry.widget.map.export' | i18n }}</span>\n </button>\n </div>\n\n <div\n class=\"ol-control m-layer-switcher\"\n *ngIf=\"((layers$ | async)?.length ?? 0) > 0\"\n [style.top.px]=\"layersTop$ | async\"\n >\n <button\n class=\"m-layer-switcher__toggle\"\n (click)=\"toggleLayersWindow()\"\n [title]=\"'@pry.widget.map.selectLayers' | i18n\"\n >\n <pry-icon iconSvg=\"layers\" [width]=\"22\" [height]=\"22\"></pry-icon>\n </button>\n <ng-container *ngFor=\"let layer of mapLayers; let index = index\">\n <div class=\"m-layer-switcher__title\" [class.-hidden]=\"!layersTabOpen\">\n {{ layer.get('title') }}\n <ng-container *ngIf=\"!(options$ | async)?.singleLayer; else singleLayer\">\n <pry-checkbox [ngModel]=\"layer.getVisible()\" (change)=\"changeVisibility(layer)\"></pry-checkbox>\n </ng-container>\n <ng-template #singleLayer>\n <input\n type=\"radio\"\n name=\"layer\"\n [id]=\"'radio-layer-' + layer.get('title').split(' ')[0]\"\n [ngModel]=\"layerVisibleIdx\"\n [value]=\"index\"\n (change)=\"changeVisibility(layer)\"\n />\n </ng-template>\n </div>\n </ng-container>\n </div>\n\n <div\n class=\"ol-control m-layer-legend\"\n *ngIf=\"((legendLayers$ | async)?.length ?? 0) > 0\"\n [style.top.px]=\"legendTop$ | async\"\n >\n <button class=\"m-layer-legend__toggle\" (click)=\"toggleLegendWindow()\" [title]=\"'@pry.widget.map.legends' | i18n\">\n <pry-icon iconSvg=\"legend\" [width]=\"22\" [height]=\"22\"></pry-icon>\n </button>\n <ng-container *ngFor=\"let geoLayer of legendLayers$ | async; let index = index\">\n <div class=\"m-layer-legend__title\" [class.-hidden]=\"!legendTabOpen\">\n {{ geoLayer.title }}\n <ng-container *ngIf=\"isLayerRendered(geoLayer)\">\n <button class=\"m-layer-legend__toggle\" (click)=\"toggleLegend(index)\">\n <pry-icon\n [iconSvg]=\"legendTab === index ? 'chevron_top' : 'chevron_bottom'\"\n [width]=\"22\"\n [height]=\"22\"\n ></pry-icon>\n </button>\n </ng-container>\n <ng-container *ngIf=\"!isLayerRendered(geoLayer)\">\n <pry-icon [iconSvg]=\"'close'\" [width]=\"22\" [height]=\"22\"></pry-icon>\n </ng-container>\n </div>\n <div\n class=\"m-layer-legend__image\"\n [class.-hidden]=\"!legendTabOpen || legendTab !== index || !isLayerRendered(geoLayer)\"\n [style.max-height.px]=\"legendHeight$ | async\"\n >\n <ng-container *ngIf=\"geoLayer | legendUrl : { capabilities: (wmsCapabilities$ | async) } as url\">\n <img\n [src]=\"url\"\n [alt]=\"'@pry.widget.map.legend' | i18n : { layer: geoLayer.title }\"\n (error)=\"imageNotProvided[index] = true\"\n />\n </ng-container>\n <ng-container *ngIf=\"!(geoLayer | legendUrl : { capabilities: (wmsCapabilities$ | async) })\">\n <p class=\"m-layer-legend__error\">{{ '@pry.widget.map.legendNotProvided' | i18n }}</p>\n </ng-container>\n </div>\n </ng-container>\n </div>\n\n <div [style.height.px]=\"height$ | async\" class=\"o-map-wrapper\">\n <div class=\"o-map\">\n <div #mapRef id=\"map\"></div>\n </div>\n </div>\n\n <ng-template #infoTooltipAction let-action=\"action\">\n <div class=\"m-tooltip\" role=\"tooltip\" id=\"infoTooltipAction\" aria-hidden=\"true\">\n <span class=\"m-tooltip__text\">{{ '@pry.widget.map.' + action | i18n }}</span>\n </div>\n </ng-template>\n\n <ng-template #infoTooltipDown>\n <div class=\"m-tooltip\" role=\"tooltip\" id=\"infoTooltipDown_widgetMap\" aria-hidden=\"true\">\n <span class=\"m-tooltip__text\">{{ '@pry.widget.map.export' | i18n }}</span>\n </div>\n </ng-template>\n\n <div #popup class=\"m-tooltip m-tooltip--popup\" [hidden]=\"true\" role=\"tooltip\">\n <div class=\"m-tooltip--popup__header\">\n <p>{{ this.tooltipIndex + 1 }} / {{ this.tooltipNumber }}</p>\n <button class=\"a-btn a-btn--primary a-btn--icon-only\" (click)=\"tooltipMove(-1)\" [disabled]=\"!tooltipCanMove(-1)\">\n <pry-icon iconSvg=\"arrow_back\"></pry-icon>\n </button>\n <button class=\"a-btn a-btn--primary a-btn--icon-only\" (click)=\"tooltipMove(1)\" [disabled]=\"!tooltipCanMove(1)\">\n <pry-icon iconSvg=\"arrow_right\"></pry-icon>\n </button>\n </div>\n <div class=\"m-tooltip--popup__container\">\n <ng-container #popupContent></ng-container>\n </div>\n </div>\n <div\n #address\n class=\"m-tooltip m-tooltip--address tooltip-address\"\n [style.display]=\"'none'\"\n (click)=\"hideAddress()\"\n ></div>\n</div>\n", dependencies: [{ kind: "directive", type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i7.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i7.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i7.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i2.SettingsComponent, selector: "pry-settings", inputs: ["widgetIndex", "isDisable", "headerPresent", "open$", "header"], outputs: ["saveTriggered", "changeTitle"] }, { kind: "component", type: i2.PryWidgetHeaderComponent, selector: "pry-widget-header", inputs: ["manifest", "additionalOptions", "headerOptions", "displayCount", "datasourceIds", "widgetIndex"], outputs: ["manifestModified"] }, { kind: "component", type: i2.PrySelectComponent, selector: "pry-select", inputs: ["labelTranslate", "baseTranslate", "translationFn", "translationFnArgs", "clearable", "multiple", "multipleClearRight", "closeOnSelect", "placeholder", "isForm", "required", "name", "readonly", "items", "itemsAsOption", "bindData", "bindValue", "bindLabel", "bindIcon", "iconSize", "templateLabel", "templateOption", "autocomplete"] }, { kind: "component", type: i2.PryIconComponent, selector: "pry-icon", inputs: ["color", "iconSvg", "animation", "iconImage", "alt", "width", "height", "classes"] }, { kind: "component", type: i8.PryCheckboxComponent, selector: "pry-checkbox", inputs: ["circle"] }, { kind: "directive", type: i2.PryTooltipDirective, selector: "[pryTooltip]", inputs: ["pryTooltip", "styleReversed", "pryTooltipContext", "pryTooltipPosition", "pryTooltipShowDelay"] }, { kind: "component", type: i2.PryRangeComponent, selector: "pry-range", inputs: ["min", "max", "step", "disabled", "labelTranslate"] }, { kind: "component", type: PryWidgetMapCssComponent, selector: "pry-widget-map-css" }, { kind: "pipe", type: i6.AsyncPipe, name: "async" }, { kind: "pipe", type: i2.I18nPipe, name: "i18n" }, { kind: "pipe", type: GeometryFieldsForPipe, name: "geometryFieldsFor" }, { kind: "pipe", type: WidgetMapLegendUrlPipe, name: "legendUrl" }] }); }
1736
1830
  }
1737
1831
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.6", ngImport: i0, type: WidgetMapComponent, decorators: [{
1738
1832
  type: Component,
1739
- args: [{ selector: 'pry-widget-map', template: "<pry-widget-map-css></pry-widget-map-css>\n<div class=\"o-widget o-widget--map\">\n <pry-widget-header\n [datasourceIds]=\"(datasourceIds$ | async) ?? []\"\n *ngIf=\"displayHeader$ | async\"\n [widgetIndex]=\"widgetIndex\"\n [manifest]=\"manifest\"\n (manifestModified)=\"manifestModified.emit($event)\"\n [headerOptions]=\"(displayHeader$ | async) ?? {}\"\n #header\n >\n <pry-settings\n (saveTriggered)=\"emitManifest()\"\n (changeTitle)=\"changeWidgetTitle($event)\"\n [headerPresent]=\"displayHeader$ | async\"\n [widgetIndex]=\"widgetIndex\"\n [header]=\"header\"\n [open$]=\"open$\"\n class=\"o-settings\"\n >\n <div class=\"m-form-label-field\">\n <label class=\"a-label\" for=\"map_style\">{{ '@pry.widget.map.style' | i18n }}</label>\n <pry-select\n (ngModelChange)=\"changeStyle($event)\"\n [itemsAsOption]=\"true\"\n [items]=\"styles$ | async\"\n [ngModel]=\"optionsCopy.style\"\n bindLabel=\"label\"\n bindValue=\"identifier\"\n id=\"map_style\"\n class=\"a-pry-select\"\n ></pry-select>\n </div>\n\n <div class=\"m-form-label-field\" *ngIf=\"optionsCopy.style === STYLE_FROM_URL\">\n <label class=\"a-label\" for=\"style_URL\">{{ '@pry.widget.map.styleUrl' | i18n }}</label>\n <input\n id=\"style_URL\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeStyleURL($event)\"\n [value]=\"optionsCopy.styleURL ?? ''\"\n />\n </div>\n\n <pry-checkbox (ngModelChange)=\"changeSingleLayer($event)\" [ngModel]=\"optionsCopy.singleLayer ?? false\">\n {{ '@pry.widget.map.singleLayer' | i18n }}\n </pry-checkbox>\n\n <pry-checkbox (ngModelChange)=\"changeFit($event)\" [ngModel]=\"optionsCopy.fit ?? false\">\n {{ '@pry.widget.map.fit' | i18n }}\n </pry-checkbox>\n\n <pry-checkbox (ngModelChange)=\"changeAttributions($event)\" [ngModel]=\"optionsCopy.attributions ?? false\">\n {{ '@pry.widget.map.attributions' | i18n }}\n </pry-checkbox>\n\n <div class=\"o-settings__popup__content__actions -has-separator\">\n <button type=\"button\" (click)=\"addLayer()\" class=\"a-btn a-btn--icon-text -link-like\">\n <pry-icon iconSvg=\"library_add\"></pry-icon>\n {{ '@pry.widget.map.addLayer' | i18n }}\n </button>\n </div>\n\n <div *ngFor=\"let layer of optionsCopy?.layers; let i = index\" class=\"o-settings__popup__content__fields\">\n <div class=\"o-settings__popup__content__fields__head\">\n <h3 class=\"a-h3 settings-layer-title__title\">{{ '@pry.widget.map.layer' | i18n : { index: i + 1 } }}</h3>\n <div class=\"m-btn-group\">\n <button type=\"button\" class=\"a-btn a-btn--icon-only\" (click)=\"invertLayers(i, i - 1)\" *ngIf=\"i > 0\">\n <pry-icon iconSvg=\"fleche_haut\"></pry-icon>\n <span class=\"u-visually-hidden\">{{ '@pry.action.moveUp' | i18n }}</span>\n </button>\n <button\n type=\"button\"\n class=\"a-btn a-btn--icon-only\"\n (click)=\"invertLayers(i, i + 1)\"\n *ngIf=\"i < (optionsCopy?.layers?.length ?? 0) - 1\"\n >\n <pry-icon iconSvg=\"fleche_bas\"></pry-icon>\n <span class=\"u-visually-hidden\">{{ '@pry.action.moveDown' | i18n }}</span>\n </button>\n </div>\n </div>\n\n <div class=\"o-settings__popup__content__fields__content\">\n <pry-range\n [ngModel]=\"(layer?.opacity ?? 100) + ''\"\n (ngModelChange)=\"changeOpacity(layer, $event)\"\n labelTranslate=\"@pry.widget.map.opacity\"\n min=\"0\"\n max=\"100\"\n ></pry-range>\n\n <fieldset>\n <legend class=\"u-visually-hidden\">{{ '@pry.widget.map.layerOptions' | i18n : { index: i + 1 } }}</legend>\n <div class=\"m-form-label-field\">\n <label class=\"a-label\" for=\"map_layerTitle\">{{ '@pry.widget.map.layerTitle' | i18n }}</label>\n <input\n id=\"map_layerTitle\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeTitle($event, layer)\"\n [value]=\"layer.title ?? ''\"\n />\n </div>\n\n <div class=\"m-form-label-field\" *ngIf=\"layer.type !== 'geoserver'\">\n <label class=\"a-label\" for=\"map_layerType\">{{ '@pry.widget.map.layerType.title' | i18n }}</label>\n <pry-select\n (ngModelChange)=\"changeLayerType($event, i)\"\n [bindData]=\"true\"\n [itemsAsOption]=\"true\"\n [items]=\"layerTypes\"\n [labelTranslate]=\"true\"\n [ngModel]=\"layer.type\"\n baseTranslate=\"@pry.widget.map.layerType.\"\n class=\"a-pry-select\"\n id=\"map_layerType\"\n ></pry-select>\n </div>\n\n <div\n *ngIf=\"\n layer.type !== 'relation' &&\n layer.type !== 'wms' &&\n layer.type !== 'wmts' &&\n layer.type !== 'geoserver' &&\n layer.type !== 'featurelayer' &&\n layer.type !== 'vectortile' &&\n layer.type !== 'rastertile'\n \"\n class=\"m-form-label-field\"\n >\n <label class=\"a-label\" for=\"map_classes\">{{ '@pry.widget.map.classes' | i18n }}</label>\n <pry-select\n (ngModelChange)=\"changeClasses($event, layer)\"\n [itemsAsOption]=\"true\"\n [items]=\"classes$ | async\"\n [multiple]=\"true\"\n [ngModel]=\"layer.classes\"\n bindLabel=\"name\"\n bindValue=\"id\"\n class=\"a-pry-select\"\n id=\"map_classes\"\n ></pry-select>\n </div>\n </fieldset>\n </div>\n\n <fieldset\n *ngIf=\"\n layer.type !== 'relation' &&\n layer.type !== 'wms' &&\n layer.type !== 'wmts' &&\n layer.type !== 'geoserver' &&\n layer.type !== 'featurelayer' &&\n layer.type !== 'vectortile' &&\n layer.type !== 'rastertile'\n \"\n >\n <legend class=\"u-visually-hidden\">{{ '@pry.widget.map.locationAttr' | i18n }}</legend>\n <ng-container\n *ngIf=\"\n layer\n | geometryFieldsFor : { resultSet: resultSet$, classes: layer.classes, type: layer.type }\n | async as fields\n \"\n >\n <div\n *ngIf=\"\n ['heatmap', 'bubble', 'marker', 'point', 'line', 'polygon', 'multi-line', 'multi-polygon'].indexOf(\n layer.type\n ) >= 0\n \"\n >\n <div class=\"m-form-label-field\">\n <label class=\"a-label\" for=\"map_locationAttribute_both\">{{\n '@pry.widget.map.locationAttribute.both' | i18n\n }}</label>\n <pry-select\n (ngModelChange)=\"changeLocationAttributes($event, layer)\"\n [itemsAsOption]=\"true\"\n [items]=\"fields\"\n [ngModel]=\"layer.attribute\"\n bindLabel=\"name\"\n bindValue=\"name\"\n id=\"map_locationAttribute_both\"\n class=\"a-pry-select\"\n ></pry-select>\n </div>\n </div>\n\n <div *ngIf=\"['heatmap', 'bubble'].indexOf(layer.type) >= 0\">\n <div class=\"m-form-label-field\">\n <label class=\"a-label\" for=\"map_intensityAttribute\">{{\n '@pry.widget.map.intensityAttribute' | i18n\n }}</label>\n <pry-select\n (ngModelChange)=\"changeIntensityAttributes($event, layer)\"\n [itemsAsOption]=\"true\"\n [items]=\"fields\"\n [ngModel]=\"layerHasIntensity(layer).intensityAttribute\"\n bindLabel=\"name\"\n bindValue=\"name\"\n id=\"map_intensityAttribute\"\n class=\"a-pry-select\"\n ></pry-select>\n </div>\n </div>\n </ng-container>\n </fieldset>\n\n <fieldset\n *ngIf=\"\n layer.type === 'wms' ||\n layer.type === 'wmts' ||\n layer.type === 'featurelayer' ||\n layer.type === 'vectortile' ||\n layer.type === 'rastertile'\n \"\n >\n <legend class=\"u-visually-hidden\">{{ '@pry.widget.map.tile' | i18n }}</legend>\n <div class=\"m-form-label-field\">\n <label class=\"a-label\" for=\"map_wms_url\">{{ '@pry.widget.map.wms.url' | i18n }}</label>\n <input\n id=\"map_wms_url\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeUrl($event, layer)\"\n [value]=\"layer.url\"\n />\n </div>\n\n <div class=\"m-form-label-field\" *ngIf=\"layer.type === 'wms' || layer.type === 'wmts'\">\n <label class=\"a-label\" for=\"map_wms_paramLayer\">{{ '@pry.widget.map.wms.paramLayer' | i18n }}</label>\n <input\n id=\"map_wms_paramLayer\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeParamLayer($event, layer)\"\n [value]=\"layer.paramLayer\"\n />\n </div>\n\n <div class=\"m-form-label-field\" *ngIf=\"layer.type === 'wmts'\">\n <label class=\"a-label\" for=\"map_wms_matrixSet\">{{ '@pry.widget.map.wms.matrixSet' | i18n }}</label>\n <input\n id=\"map_wms_matrixSet\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeMatrixSet($event, layer)\"\n [value]=\"layer.matrixSet\"\n />\n </div>\n\n <div class=\"m-form-label-field\" *ngIf=\"layer.type === 'wmts'\">\n <label class=\"a-label\" for=\"map_wms_style\">{{ '@pry.widget.map.wms.style' | i18n }}</label>\n <input\n id=\"map_wms_style\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeParamStyle($event, layer)\"\n [value]=\"layer.style\"\n />\n </div>\n\n <div class=\"m-form-label-field\" *ngIf=\"layer.type === 'wms'\">\n <pry-checkbox (ngModelChange)=\"changeParamTiled($event, layer)\" [ngModel]=\"layer?.paramTiled ?? false\">\n {{ '@pry.widget.map.wms.paramTiled' | i18n }}\n </pry-checkbox>\n </div>\n </fieldset>\n\n <fieldset *ngIf=\"layer.type === 'marker'\">\n <legend class=\"u-visually-hidden\">{{ '@pry.widget.map.clustering' | i18n }}</legend>\n <div class=\"m-form-label-field\">\n <pry-checkbox (ngModelChange)=\"changeClustered(layer, $event)\" [ngModel]=\"layer.clustered\">\n {{ '@pry.widget.map.clustered' | i18n }}\n </pry-checkbox>\n </div>\n <div *ngIf=\"layer.clustered\">\n <pry-range\n [ngModel]=\"layer.clustered\"\n (ngModelChange)=\"changeClusterDistance(layer, $event)\"\n labelTranslate=\"@pry.widget.map.clusterDistance\"\n min=\"1\"\n max=\"500\"\n ></pry-range>\n </div>\n </fieldset>\n\n <div class=\"m-form-label-field\" *ngIf=\"optionsCopy.attributions\">\n <label class=\"a-label\" for=\"attribution\">{{ '@pry.widget.map.attribution' | i18n }}</label>\n <input\n id=\"attribution\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeAttribution($event, layer)\"\n [value]=\"layer.attribution ? layer.attribution : ''\"\n />\n </div>\n\n <button\n type=\"button\"\n (click)=\"deleteLayer(i)\"\n class=\"a-btn a-btn--icon-text -link-like\"\n *ngIf=\"layer.type !== 'geoserver'\"\n data-func=\"delete\"\n >\n <pry-icon iconSvg=\"delete\" [width]=\"19\" [height]=\"19\"></pry-icon>\n <span>{{ '@pry.widget.map.deleteLayer' | i18n }}</span>\n </button>\n </div>\n </pry-settings>\n </pry-widget-header>\n\n <div class=\"m-btn-group -selection-choice\" [style.transform]=\"bottomLeft$ | async\">\n <ng-container *ngFor=\"let action of basicActions$ | async\">\n <button\n type=\"button\"\n class=\"a-btn a-btn--icon-only\"\n (click)=\"interactionManager.selectionInteraction.changeSelection(action)\"\n [class.-selected]=\"interactionManager.selectionInteraction.selectionType === action\"\n [pryTooltip]=\"infoTooltipAction\"\n pryTooltipPosition=\"bottom\"\n aria-describedby=\"infoTooltipAction\"\n [pryTooltipContext]=\"{ action: action }\"\n >\n <pry-icon [iconSvg]=\"action\"></pry-icon>\n <span class=\"u-visually-hidden\">{{ '@pry.widget.map.' + action | i18n }}</span>\n </button>\n </ng-container>\n\n <button\n type=\"button\"\n class=\"a-btn a-btn--icon-only\"\n id=\"export_card\"\n aria-expanded=\"false\"\n aria-controls=\"export_type\"\n aria-haspopup=\"menu\"\n [pryTooltip]=\"infoTooltipDown\"\n pryTooltipPosition=\"bottom\"\n aria-describedby=\"infoTooltipDown_widgetMap\"\n *ngIf=\"(actions$ | async)?.includes('export')\"\n >\n <pry-icon iconSvg=\"file_download\" (click)=\"export()\"></pry-icon>\n <span class=\"u-visually-hidden\">{{ '@pry.widget.map.export' | i18n }}</span>\n </button>\n </div>\n\n <div\n class=\"ol-control m-layer-switcher\"\n *ngIf=\"((layers$ | async)?.length ?? 0) > 0\"\n [style.top.px]=\"layersTop$ | async\"\n >\n <button\n class=\"m-layer-switcher__toggle\"\n (click)=\"toggleLayersWindow()\"\n [title]=\"'@pry.widget.map.selectLayers' | i18n\"\n >\n <pry-icon iconSvg=\"layers\" [width]=\"22\" [height]=\"22\"></pry-icon>\n </button>\n <ng-container *ngFor=\"let layer of mapLayers; let index = index\">\n <div class=\"m-layer-switcher__title\" [class.-hidden]=\"!layersTabOpen\">\n {{ layer.get('title') }}\n <ng-container *ngIf=\"!(options$ | async)?.singleLayer; else singleLayer\">\n <pry-checkbox [ngModel]=\"layer.getVisible()\" (change)=\"changeVisibility(layer)\"></pry-checkbox>\n </ng-container>\n <ng-template #singleLayer>\n <input\n type=\"radio\"\n name=\"layer\"\n [id]=\"'radio-layer-' + layer.get('title').split(' ')[0]\"\n [ngModel]=\"layerVisibleIdx\"\n [value]=\"index\"\n (change)=\"changeVisibility(layer)\"\n />\n </ng-template>\n </div>\n </ng-container>\n </div>\n\n <div\n class=\"ol-control m-layer-legend\"\n *ngIf=\"((legendLayers$ | async)?.length ?? 0) > 0\"\n [style.top.px]=\"legendTop$ | async\"\n >\n <button class=\"m-layer-legend__toggle\" (click)=\"toggleLegendWindow()\" [title]=\"'@pry.widget.map.legends' | i18n\">\n <pry-icon iconSvg=\"legend\" [width]=\"22\" [height]=\"22\"></pry-icon>\n </button>\n <ng-container *ngFor=\"let geoLayer of legendLayers$ | async; let index = index\">\n <div class=\"m-layer-legend__title\" [class.-hidden]=\"!legendTabOpen\">\n {{ geoLayer.title }}\n <ng-container *ngIf=\"isLayerRendered(geoLayer)\">\n <button class=\"m-layer-legend__toggle\" (click)=\"toggleLegend(index)\">\n <pry-icon\n [iconSvg]=\"legendTab === index ? 'chevron_top' : 'chevron_bottom'\"\n [width]=\"22\"\n [height]=\"22\"\n ></pry-icon>\n </button>\n </ng-container>\n <ng-container *ngIf=\"!isLayerRendered(geoLayer)\">\n <pry-icon [iconSvg]=\"'close'\" [width]=\"22\" [height]=\"22\"></pry-icon>\n </ng-container>\n </div>\n <div\n class=\"m-layer-legend__image\"\n [class.-hidden]=\"!legendTabOpen || legendTab !== index || !isLayerRendered(geoLayer)\"\n [style.max-height.px]=\"legendHeight$ | async\"\n >\n <ng-container *ngIf=\"geoLayer | legendUrl : { capabilities: (wmsCapabilities$ | async) } as url\">\n <img\n [src]=\"url\"\n [alt]=\"'@pry.widget.map.legend' | i18n : { layer: geoLayer.title }\"\n (error)=\"imageNotProvided[index] = true\"\n />\n </ng-container>\n <ng-container *ngIf=\"!(geoLayer | legendUrl : { capabilities: (wmsCapabilities$ | async) })\">\n <p class=\"m-layer-legend__error\">{{ '@pry.widget.map.legendNotProvided' | i18n }}</p>\n </ng-container>\n </div>\n </ng-container>\n </div>\n\n <div [style.height.px]=\"height$ | async\" class=\"o-map-wrapper\">\n <div class=\"o-map\">\n <div #mapRef id=\"map\"></div>\n </div>\n </div>\n\n <ng-template #infoTooltipAction let-action=\"action\">\n <div class=\"m-tooltip\" role=\"tooltip\" id=\"infoTooltipAction\" aria-hidden=\"true\">\n <span class=\"m-tooltip__text\">{{ '@pry.widget.map.' + action | i18n }}</span>\n </div>\n </ng-template>\n\n <ng-template #infoTooltipDown>\n <div class=\"m-tooltip\" role=\"tooltip\" id=\"infoTooltipDown_widgetMap\" aria-hidden=\"true\">\n <span class=\"m-tooltip__text\">{{ '@pry.widget.map.export' | i18n }}</span>\n </div>\n </ng-template>\n\n <div #popup class=\"m-tooltip m-tooltip--popup\" [hidden]=\"true\" role=\"tooltip\">\n <div class=\"m-tooltip--popup__header\">\n <p>{{ this.tooltipIndex + 1 }} / {{ this.tooltipNumber }}</p>\n <button class=\"a-btn a-btn--primary a-btn--icon-only\" (click)=\"tooltipMove(-1)\" [disabled]=\"!tooltipCanMove(-1)\">\n <pry-icon iconSvg=\"arrow_back\"></pry-icon>\n </button>\n <button class=\"a-btn a-btn--primary a-btn--icon-only\" (click)=\"tooltipMove(1)\" [disabled]=\"!tooltipCanMove(1)\">\n <pry-icon iconSvg=\"arrow_right\"></pry-icon>\n </button>\n </div>\n <div class=\"m-tooltip--popup__container\">\n <ng-container #popupContent></ng-container>\n </div>\n </div>\n <div\n #address\n class=\"m-tooltip m-tooltip--address tooltip-address\"\n [style.display]=\"'none'\"\n (click)=\"hideAddress()\"\n ></div>\n</div>\n" }]
1833
+ args: [{ selector: 'pry-widget-map', template: "<pry-widget-map-css></pry-widget-map-css>\n<div class=\"o-widget o-widget--map\">\n <pry-widget-header\n [datasourceIds]=\"(datasourceIds$ | async) ?? []\"\n *ngIf=\"displayHeader$ | async\"\n [widgetIndex]=\"widgetIndex\"\n [manifest]=\"manifest\"\n (manifestModified)=\"manifestModified.emit($event)\"\n [headerOptions]=\"(displayHeader$ | async) ?? {}\"\n #header\n >\n <pry-settings\n (saveTriggered)=\"emitManifest()\"\n (changeTitle)=\"changeWidgetTitle($event)\"\n [headerPresent]=\"displayHeader$ | async\"\n [widgetIndex]=\"widgetIndex\"\n [header]=\"header\"\n [open$]=\"open$\"\n class=\"o-settings\"\n >\n <div class=\"m-form-label-field\">\n <label class=\"a-label\" for=\"map_style\">{{ '@pry.widget.map.style' | i18n }}</label>\n <pry-select\n (ngModelChange)=\"changeStyle($event)\"\n [itemsAsOption]=\"true\"\n [items]=\"styles$ | async\"\n [ngModel]=\"optionsCopy.style\"\n bindLabel=\"label\"\n bindValue=\"identifier\"\n id=\"map_style\"\n class=\"a-pry-select\"\n ></pry-select>\n </div>\n\n <div class=\"m-form-label-field\" *ngIf=\"optionsCopy.style === STYLE_FROM_URL\">\n <label class=\"a-label\" for=\"style_URL\">{{ '@pry.widget.map.styleUrl' | i18n }}</label>\n <input\n id=\"style_URL\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeStyleURL($event)\"\n [value]=\"optionsCopy.styleURL ?? ''\"\n />\n </div>\n\n <pry-checkbox (ngModelChange)=\"changeSingleLayer($event)\" [ngModel]=\"optionsCopy.singleLayer ?? false\">\n {{ '@pry.widget.map.singleLayer' | i18n }}\n </pry-checkbox>\n\n <pry-checkbox (ngModelChange)=\"changeAutoLayer($event)\" [ngModel]=\"optionsCopy.automaticLayers ?? false\">\n {{ '@pry.widget.map.autoLayer' | i18n }}\n </pry-checkbox>\n\n <pry-checkbox (ngModelChange)=\"changeFit($event)\" [ngModel]=\"optionsCopy.fit ?? false\">\n {{ '@pry.widget.map.fit' | i18n }}\n </pry-checkbox>\n\n <pry-checkbox (ngModelChange)=\"changeAttributions($event)\" [ngModel]=\"optionsCopy.attributions ?? false\">\n {{ '@pry.widget.map.attributions' | i18n }}\n </pry-checkbox>\n\n <div class=\"o-settings__popup__content__actions -has-separator\">\n <button type=\"button\" (click)=\"addLayer()\" class=\"a-btn a-btn--icon-text -link-like\">\n <pry-icon iconSvg=\"library_add\"></pry-icon>\n {{ '@pry.widget.map.addLayer' | i18n }}\n </button>\n </div>\n\n <div *ngFor=\"let layer of optionsCopy?.layers; let i = index\" class=\"o-settings__popup__content__fields\">\n <div class=\"o-settings__popup__content__fields__head\">\n <h3 class=\"a-h3 settings-layer-title__title\">{{ '@pry.widget.map.layer' | i18n : { index: i + 1 } }}</h3>\n <div class=\"m-btn-group\">\n <button type=\"button\" class=\"a-btn a-btn--icon-only\" (click)=\"invertLayers(i, i - 1)\" *ngIf=\"i > 0\">\n <pry-icon iconSvg=\"fleche_haut\"></pry-icon>\n <span class=\"u-visually-hidden\">{{ '@pry.action.moveUp' | i18n }}</span>\n </button>\n <button\n type=\"button\"\n class=\"a-btn a-btn--icon-only\"\n (click)=\"invertLayers(i, i + 1)\"\n *ngIf=\"i < (optionsCopy?.layers?.length ?? 0) - 1\"\n >\n <pry-icon iconSvg=\"fleche_bas\"></pry-icon>\n <span class=\"u-visually-hidden\">{{ '@pry.action.moveDown' | i18n }}</span>\n </button>\n </div>\n </div>\n\n <div class=\"o-settings__popup__content__fields__content\">\n <pry-range\n [ngModel]=\"(layer?.opacity ?? 100) + ''\"\n (ngModelChange)=\"changeOpacity(layer, $event)\"\n labelTranslate=\"@pry.widget.map.opacity\"\n min=\"0\"\n max=\"100\"\n ></pry-range>\n\n <fieldset>\n <legend class=\"u-visually-hidden\">{{ '@pry.widget.map.layerOptions' | i18n : { index: i + 1 } }}</legend>\n <div class=\"m-form-label-field\">\n <label class=\"a-label\" for=\"map_layerTitle\">{{ '@pry.widget.map.layerTitle' | i18n }}</label>\n <input\n id=\"map_layerTitle\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeTitle($event, layer)\"\n [value]=\"layer.title ?? ''\"\n />\n </div>\n\n <div class=\"m-form-label-field\" *ngIf=\"!['geoserver', 'auto'].includes(layer.type)\">\n <label class=\"a-label\" for=\"map_layerType\">{{ '@pry.widget.map.layerType.title' | i18n }}</label>\n <pry-select\n (ngModelChange)=\"changeLayerType($event, i)\"\n [bindData]=\"true\"\n [itemsAsOption]=\"true\"\n [items]=\"layerTypes\"\n [labelTranslate]=\"true\"\n [ngModel]=\"layer.type\"\n baseTranslate=\"@pry.widget.map.layerType.\"\n class=\"a-pry-select\"\n id=\"map_layerType\"\n ></pry-select>\n </div>\n\n <div\n *ngIf=\"\n layer.type !== 'relation' &&\n layer.type !== 'wms' &&\n layer.type !== 'wmts' &&\n layer.type !== 'geoserver' &&\n layer.type !== 'featurelayer' &&\n layer.type !== 'vectortile' &&\n layer.type !== 'rastertile' &&\n layer.type !== 'auto'\n \"\n class=\"m-form-label-field\"\n >\n <label class=\"a-label\" for=\"map_classes\">{{ '@pry.widget.map.classes' | i18n }}</label>\n <pry-select\n (ngModelChange)=\"changeClasses($event, layer)\"\n [itemsAsOption]=\"true\"\n [items]=\"classes$ | async\"\n [multiple]=\"true\"\n [ngModel]=\"layer.classes\"\n bindLabel=\"name\"\n bindValue=\"id\"\n class=\"a-pry-select\"\n id=\"map_classes\"\n ></pry-select>\n </div>\n </fieldset>\n </div>\n\n <fieldset\n *ngIf=\"\n layer.type !== 'relation' &&\n layer.type !== 'wms' &&\n layer.type !== 'wmts' &&\n layer.type !== 'geoserver' &&\n layer.type !== 'featurelayer' &&\n layer.type !== 'vectortile' &&\n layer.type !== 'rastertile'\n \"\n >\n <legend class=\"u-visually-hidden\">{{ '@pry.widget.map.locationAttr' | i18n }}</legend>\n <ng-container\n *ngIf=\"\n layer\n | geometryFieldsFor : { resultSet: resultSet$, classes: layer.classes, type: layer.type }\n | async as fields\n \"\n >\n <div\n *ngIf=\"\n ['heatmap', 'bubble', 'marker', 'point', 'line', 'polygon', 'multi-line', 'multi-polygon'].indexOf(\n layer.type\n ) >= 0\n \"\n >\n <div class=\"m-form-label-field\">\n <label class=\"a-label\" for=\"map_locationAttribute_both\">{{\n '@pry.widget.map.locationAttribute.both' | i18n\n }}</label>\n <pry-select\n (ngModelChange)=\"changeLocationAttributes($event, layer)\"\n [itemsAsOption]=\"true\"\n [items]=\"fields\"\n [ngModel]=\"layer.attribute\"\n bindLabel=\"name\"\n bindValue=\"name\"\n id=\"map_locationAttribute_both\"\n class=\"a-pry-select\"\n ></pry-select>\n </div>\n </div>\n\n <div *ngIf=\"['heatmap', 'bubble'].indexOf(layer.type) >= 0\">\n <div class=\"m-form-label-field\">\n <label class=\"a-label\" for=\"map_intensityAttribute\">{{\n '@pry.widget.map.intensityAttribute' | i18n\n }}</label>\n <pry-select\n (ngModelChange)=\"changeIntensityAttributes($event, layer)\"\n [itemsAsOption]=\"true\"\n [items]=\"fields\"\n [ngModel]=\"layerHasIntensity(layer).intensityAttribute\"\n bindLabel=\"name\"\n bindValue=\"name\"\n id=\"map_intensityAttribute\"\n class=\"a-pry-select\"\n ></pry-select>\n </div>\n </div>\n </ng-container>\n </fieldset>\n\n <fieldset\n *ngIf=\"\n layer.type === 'wms' ||\n layer.type === 'wmts' ||\n layer.type === 'featurelayer' ||\n layer.type === 'vectortile' ||\n layer.type === 'rastertile'\n \"\n >\n <legend class=\"u-visually-hidden\">{{ '@pry.widget.map.tile' | i18n }}</legend>\n <div class=\"m-form-label-field\">\n <label class=\"a-label\" for=\"map_wms_url\">{{ '@pry.widget.map.wms.url' | i18n }}</label>\n <input\n id=\"map_wms_url\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeUrl($event, layer)\"\n [value]=\"layer.url\"\n />\n </div>\n\n <div class=\"m-form-label-field\" *ngIf=\"layer.type === 'wms' || layer.type === 'wmts'\">\n <label class=\"a-label\" for=\"map_wms_paramLayer\">{{ '@pry.widget.map.wms.paramLayer' | i18n }}</label>\n <input\n id=\"map_wms_paramLayer\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeParamLayer($event, layer)\"\n [value]=\"layer.paramLayer\"\n />\n </div>\n\n <div class=\"m-form-label-field\" *ngIf=\"layer.type === 'wmts'\">\n <label class=\"a-label\" for=\"map_wms_matrixSet\">{{ '@pry.widget.map.wms.matrixSet' | i18n }}</label>\n <input\n id=\"map_wms_matrixSet\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeMatrixSet($event, layer)\"\n [value]=\"layer.matrixSet\"\n />\n </div>\n\n <div class=\"m-form-label-field\" *ngIf=\"layer.type === 'wmts'\">\n <label class=\"a-label\" for=\"map_wms_style\">{{ '@pry.widget.map.wms.style' | i18n }}</label>\n <input\n id=\"map_wms_style\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeParamStyle($event, layer)\"\n [value]=\"layer.style\"\n />\n </div>\n\n <div class=\"m-form-label-field\" *ngIf=\"layer.type === 'wms'\">\n <pry-checkbox (ngModelChange)=\"changeParamTiled($event, layer)\" [ngModel]=\"layer?.paramTiled ?? false\">\n {{ '@pry.widget.map.wms.paramTiled' | i18n }}\n </pry-checkbox>\n </div>\n </fieldset>\n\n <fieldset *ngIf=\"layer.type === 'marker'\">\n <legend class=\"u-visually-hidden\">{{ '@pry.widget.map.clustering' | i18n }}</legend>\n <div class=\"m-form-label-field\">\n <pry-checkbox (ngModelChange)=\"changeClustered(layer, $event)\" [ngModel]=\"layer.clustered\">\n {{ '@pry.widget.map.clustered' | i18n }}\n </pry-checkbox>\n </div>\n <div *ngIf=\"layer.clustered\">\n <pry-range\n [ngModel]=\"layer.clustered\"\n (ngModelChange)=\"changeClusterDistance(layer, $event)\"\n labelTranslate=\"@pry.widget.map.clusterDistance\"\n min=\"1\"\n max=\"500\"\n ></pry-range>\n </div>\n </fieldset>\n\n <div class=\"m-form-label-field\" *ngIf=\"optionsCopy.attributions\">\n <label class=\"a-label\" for=\"attribution\">{{ '@pry.widget.map.attribution' | i18n }}</label>\n <input\n id=\"attribution\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeAttribution($event, layer)\"\n [value]=\"layer.attribution ? layer.attribution : ''\"\n />\n </div>\n\n <button\n type=\"button\"\n (click)=\"deleteLayer(i, layer)\"\n class=\"a-btn a-btn--icon-text -link-like\"\n *ngIf=\"layer.type !== 'geoserver'\"\n data-func=\"delete\"\n >\n <pry-icon iconSvg=\"delete\" [width]=\"19\" [height]=\"19\"></pry-icon>\n <span>{{ '@pry.widget.map.deleteLayer' | i18n }}</span>\n </button>\n </div>\n </pry-settings>\n </pry-widget-header>\n\n <div class=\"m-btn-group -selection-choice\" [style.transform]=\"bottomLeft$ | async\">\n <ng-container *ngFor=\"let action of basicActions$ | async\">\n <button\n type=\"button\"\n class=\"a-btn a-btn--icon-only\"\n (click)=\"interactionManager.selectionInteraction.changeSelection(action)\"\n [class.-selected]=\"interactionManager.selectionInteraction.selectionType === action\"\n [pryTooltip]=\"infoTooltipAction\"\n pryTooltipPosition=\"bottom\"\n aria-describedby=\"infoTooltipAction\"\n [pryTooltipContext]=\"{ action: action }\"\n >\n <pry-icon [iconSvg]=\"action\"></pry-icon>\n <span class=\"u-visually-hidden\">{{ '@pry.widget.map.' + action | i18n }}</span>\n </button>\n </ng-container>\n\n <button\n type=\"button\"\n class=\"a-btn a-btn--icon-only\"\n id=\"export_card\"\n aria-expanded=\"false\"\n aria-controls=\"export_type\"\n aria-haspopup=\"menu\"\n [pryTooltip]=\"infoTooltipDown\"\n pryTooltipPosition=\"bottom\"\n aria-describedby=\"infoTooltipDown_widgetMap\"\n *ngIf=\"(actions$ | async)?.includes('export')\"\n >\n <pry-icon iconSvg=\"file_download\" (click)=\"export()\"></pry-icon>\n <span class=\"u-visually-hidden\">{{ '@pry.widget.map.export' | i18n }}</span>\n </button>\n </div>\n\n <div\n class=\"ol-control m-layer-switcher\"\n *ngIf=\"((layers$ | async)?.length ?? 0) > 0\"\n [style.top.px]=\"layersTop$ | async\"\n >\n <button\n class=\"m-layer-switcher__toggle\"\n (click)=\"toggleLayersWindow()\"\n [title]=\"'@pry.widget.map.selectLayers' | i18n\"\n >\n <pry-icon iconSvg=\"layers\" [width]=\"22\" [height]=\"22\"></pry-icon>\n </button>\n <ng-container *ngFor=\"let layer of mapLayers; let index = index\">\n <div class=\"m-layer-switcher__title\" [class.-hidden]=\"!layersTabOpen\">\n {{ layer.get('title') }}\n <ng-container *ngIf=\"!(options$ | async)?.singleLayer; else singleLayer\">\n <pry-checkbox [ngModel]=\"layer.getVisible()\" (change)=\"changeVisibility(layer)\"></pry-checkbox>\n </ng-container>\n <ng-template #singleLayer>\n <input\n type=\"radio\"\n name=\"layer\"\n [id]=\"'radio-layer-' + layer.get('title').split(' ')[0]\"\n [ngModel]=\"layerVisibleIdx\"\n [value]=\"index\"\n (change)=\"changeVisibility(layer)\"\n />\n </ng-template>\n </div>\n </ng-container>\n </div>\n\n <div\n class=\"ol-control m-layer-legend\"\n *ngIf=\"((legendLayers$ | async)?.length ?? 0) > 0\"\n [style.top.px]=\"legendTop$ | async\"\n >\n <button class=\"m-layer-legend__toggle\" (click)=\"toggleLegendWindow()\" [title]=\"'@pry.widget.map.legends' | i18n\">\n <pry-icon iconSvg=\"legend\" [width]=\"22\" [height]=\"22\"></pry-icon>\n </button>\n <ng-container *ngFor=\"let geoLayer of legendLayers$ | async; let index = index\">\n <div class=\"m-layer-legend__title\" [class.-hidden]=\"!legendTabOpen\">\n {{ geoLayer.title }}\n <ng-container *ngIf=\"isLayerRendered(geoLayer)\">\n <button class=\"m-layer-legend__toggle\" (click)=\"toggleLegend(index)\">\n <pry-icon\n [iconSvg]=\"legendTab === index ? 'chevron_top' : 'chevron_bottom'\"\n [width]=\"22\"\n [height]=\"22\"\n ></pry-icon>\n </button>\n </ng-container>\n <ng-container *ngIf=\"!isLayerRendered(geoLayer)\">\n <pry-icon [iconSvg]=\"'close'\" [width]=\"22\" [height]=\"22\"></pry-icon>\n </ng-container>\n </div>\n <div\n class=\"m-layer-legend__image\"\n [class.-hidden]=\"!legendTabOpen || legendTab !== index || !isLayerRendered(geoLayer)\"\n [style.max-height.px]=\"legendHeight$ | async\"\n >\n <ng-container *ngIf=\"geoLayer | legendUrl : { capabilities: (wmsCapabilities$ | async) } as url\">\n <img\n [src]=\"url\"\n [alt]=\"'@pry.widget.map.legend' | i18n : { layer: geoLayer.title }\"\n (error)=\"imageNotProvided[index] = true\"\n />\n </ng-container>\n <ng-container *ngIf=\"!(geoLayer | legendUrl : { capabilities: (wmsCapabilities$ | async) })\">\n <p class=\"m-layer-legend__error\">{{ '@pry.widget.map.legendNotProvided' | i18n }}</p>\n </ng-container>\n </div>\n </ng-container>\n </div>\n\n <div [style.height.px]=\"height$ | async\" class=\"o-map-wrapper\">\n <div class=\"o-map\">\n <div #mapRef id=\"map\"></div>\n </div>\n </div>\n\n <ng-template #infoTooltipAction let-action=\"action\">\n <div class=\"m-tooltip\" role=\"tooltip\" id=\"infoTooltipAction\" aria-hidden=\"true\">\n <span class=\"m-tooltip__text\">{{ '@pry.widget.map.' + action | i18n }}</span>\n </div>\n </ng-template>\n\n <ng-template #infoTooltipDown>\n <div class=\"m-tooltip\" role=\"tooltip\" id=\"infoTooltipDown_widgetMap\" aria-hidden=\"true\">\n <span class=\"m-tooltip__text\">{{ '@pry.widget.map.export' | i18n }}</span>\n </div>\n </ng-template>\n\n <div #popup class=\"m-tooltip m-tooltip--popup\" [hidden]=\"true\" role=\"tooltip\">\n <div class=\"m-tooltip--popup__header\">\n <p>{{ this.tooltipIndex + 1 }} / {{ this.tooltipNumber }}</p>\n <button class=\"a-btn a-btn--primary a-btn--icon-only\" (click)=\"tooltipMove(-1)\" [disabled]=\"!tooltipCanMove(-1)\">\n <pry-icon iconSvg=\"arrow_back\"></pry-icon>\n </button>\n <button class=\"a-btn a-btn--primary a-btn--icon-only\" (click)=\"tooltipMove(1)\" [disabled]=\"!tooltipCanMove(1)\">\n <pry-icon iconSvg=\"arrow_right\"></pry-icon>\n </button>\n </div>\n <div class=\"m-tooltip--popup__container\">\n <ng-container #popupContent></ng-container>\n </div>\n </div>\n <div\n #address\n class=\"m-tooltip m-tooltip--address tooltip-address\"\n [style.display]=\"'none'\"\n (click)=\"hideAddress()\"\n ></div>\n</div>\n" }]
1740
1834
  }], ctorParameters: function () { return [{ type: i1$1.Store }, { type: i2.PrySnackbarService }, { type: i2.PryI18nService }, { type: i2.TooltipFactoryService }, { type: i3.Overlay }, { type: i0.ViewContainerRef }, { type: i2.SymbolService }, { type: i0.Injector }, { type: WidgetMapLayerService }, { type: i0.ElementRef }, { type: WmsService }]; }, propDecorators: { mapRef: [{
1741
1835
  type: ViewChild,
1742
1836
  args: ['mapRef']
@@ -1829,7 +1923,8 @@ const enTranslations = {
1829
1923
  legendNotProvided: 'Legend not provided by server',
1830
1924
  selectLayers: 'Select layers',
1831
1925
  legends: 'Display legend',
1832
- singleLayer: 'Single layer mode'
1926
+ singleLayer: 'Single layer mode',
1927
+ autoLayer: 'Automatic datasource layers configuration'
1833
1928
  }
1834
1929
  }
1835
1930
  }
@@ -1910,7 +2005,8 @@ const frTranslations = {
1910
2005
  legendNotProvided: 'Légende non fournie par le serveur',
1911
2006
  selectLayers: 'Sélectionner les couches',
1912
2007
  legends: 'Afficher la légende',
1913
- singleLayer: 'Mode mono-couche'
2008
+ singleLayer: 'Mode mono-couche',
2009
+ autoLayer: 'Configuration automatique des sources de données'
1914
2010
  }
1915
2011
  }
1916
2012
  }
@@ -1979,5 +2075,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.6", ngImpor
1979
2075
  * Generated bundle index. Do not edit.
1980
2076
  */
1981
2077
 
1982
- export { CqlUtils, DEFAULT_HEATMAP_RADIUS, DEFAULT_MAP_CENTER, DEFAULT_RADIUS_INTENSITY_FACTOR, DEFAULT_ZOOM_MAX, DEFAULT_ZOOM_MIN, DEFAULT_ZOOM_START, EMPTY_MAP_STYLE, GeometryFieldsForPipe, InteractionManager, PryWidgetMapCssComponent, SelectionInteraction, TOOLTIP_PADDING, WidgetMapComponent, WidgetMapLayerService, WidgetMapLegendUrlPipe, WidgetMapModule, WmsService, XMLUtils, exportMapAsImage, geometryForLayer, getCircleFeatureFromItem, getFeatureFromItem, getLinkFeature, getMapAsPng, populateIntensityAttribute, populateLocationAttribute };
2078
+ export { CqlUtils, DEFAULT_HEATMAP_RADIUS, DEFAULT_MAP_CENTER, DEFAULT_RADIUS_INTENSITY_FACTOR, DEFAULT_ZOOM_MAX, DEFAULT_ZOOM_MIN, DEFAULT_ZOOM_START, GeometryFieldsForPipe, InteractionManager, PryWidgetMapCssComponent, SelectionInteraction, TOOLTIP_PADDING, WidgetMapComponent, WidgetMapLayerService, WidgetMapLegendUrlPipe, WidgetMapModule, WmsService, XMLUtils, exportMapAsImage, geometryForLayer, getCircleFeatureFromItem, getFeatureFromItem, getLinkFeature, getMapAsPng, populateIntensityAttribute, populateLocationAttribute };
1983
2079
  //# sourceMappingURL=provoly-dashboard-widgets-widget-map.mjs.map