@provoly/dashboard 0.14.4 → 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 (91) 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/action-bus/service/bus.service.mjs +1 -1
  31. package/esm2022/lib/dashboard/components/dashboard.component.mjs +5 -5
  32. package/esm2022/lib/dashboard/components/widgets/header/widget-header.component.mjs +9 -3
  33. package/esm2022/pipeline/components/pipeline-list/pipeline-list.component.mjs +25 -13
  34. package/esm2022/pipeline/pipeline.module.mjs +8 -4
  35. package/esm2022/supervision/store/supervision.reducer.mjs +2 -7
  36. package/esm2022/widgets/widget-map/component/widget-map-layer.service.mjs +34 -3
  37. package/esm2022/widgets/widget-map/component/widget-map.component.mjs +72 -16
  38. package/esm2022/widgets/widget-map/i18n/en.translations.mjs +3 -2
  39. package/esm2022/widgets/widget-map/i18n/fr.translations.mjs +3 -2
  40. package/esm2022/widgets/widget-map/utils/widget-map.utils.mjs +14 -8
  41. package/fesm2022/provoly-dashboard-admin.mjs +79 -31
  42. package/fesm2022/provoly-dashboard-admin.mjs.map +1 -1
  43. package/fesm2022/provoly-dashboard-dataset.mjs +3 -2
  44. package/fesm2022/provoly-dashboard-dataset.mjs.map +1 -1
  45. package/fesm2022/provoly-dashboard-import.mjs +23 -10
  46. package/fesm2022/provoly-dashboard-import.mjs.map +1 -1
  47. package/fesm2022/provoly-dashboard-pipeline.mjs +27 -11
  48. package/fesm2022/provoly-dashboard-pipeline.mjs.map +1 -1
  49. package/fesm2022/provoly-dashboard-supervision.mjs +1 -6
  50. package/fesm2022/provoly-dashboard-supervision.mjs.map +1 -1
  51. package/fesm2022/provoly-dashboard-widgets-widget-map.mjs +540 -446
  52. package/fesm2022/provoly-dashboard-widgets-widget-map.mjs.map +1 -1
  53. package/fesm2022/provoly-dashboard.mjs +174 -85
  54. package/fesm2022/provoly-dashboard.mjs.map +1 -1
  55. package/import/components/import.component.d.ts +1 -0
  56. package/import/i18n/en.translations.d.ts +1 -0
  57. package/import/i18n/fr.translations.d.ts +1 -0
  58. package/import/import.module.d.ts +2 -1
  59. package/import/store/import.actions.d.ts +2 -0
  60. package/import/store/import.service.d.ts +1 -1
  61. package/lib/core/components/translate-id/translate-id.pipe.d.ts +1 -1
  62. package/lib/core/i18n/en.translations.d.ts +1 -0
  63. package/lib/core/i18n/fr.translations.d.ts +1 -0
  64. package/lib/core/model/admin-api.model.d.ts +1 -0
  65. package/lib/core/model/widget-map-manifest.interface.d.ts +11 -1
  66. package/lib/core/store/field/field.interface.d.ts +1 -0
  67. package/lib/core/symbol/symbol.service.d.ts +1 -1
  68. package/lib/dashboard/components/dashboard.component.d.ts +1 -1
  69. package/lib/dashboard/components/widgets/header/widget-header.component.d.ts +3 -1
  70. package/package.json +42 -42
  71. package/pipeline/components/pipeline-list/pipeline-list.component.d.ts +1 -0
  72. package/pipeline/pipeline.module.d.ts +2 -1
  73. package/schematics/migration.json +5 -0
  74. package/schematics/ng-update/utils/replaceStrings.function.d.ts +7 -0
  75. package/schematics/ng-update/utils/replaceStrings.function.js +15 -0
  76. package/schematics/ng-update/utils/replaceStrings.function.js.map +1 -0
  77. package/schematics/ng-update/version-0-13/index.spec.js +11 -0
  78. package/schematics/ng-update/version-0-13/index.spec.js.map +1 -1
  79. package/schematics/ng-update/version-0-14/index.d.ts +2 -0
  80. package/schematics/ng-update/version-0-14/index.js +49 -0
  81. package/schematics/ng-update/version-0-14/index.js.map +1 -0
  82. package/schematics/ng-update/version-0-14/index.spec.d.ts +1 -0
  83. package/schematics/ng-update/version-0-14/index.spec.js +52 -0
  84. package/schematics/ng-update/version-0-14/index.spec.js.map +1 -0
  85. package/styles/components/_m-context-menu.scss +4 -0
  86. package/styles/components/_o-pry-admin-classes-customize.scss +48 -0
  87. package/widgets/widget-map/component/widget-map-layer.service.d.ts +6 -1
  88. package/widgets/widget-map/component/widget-map.component.d.ts +4 -2
  89. package/widgets/widget-map/i18n/en.translations.d.ts +1 -0
  90. package/widgets/widget-map/i18n/fr.translations.d.ts +1 -0
  91. 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
- }
915
- else {
916
- return size === 1 ? feature.get('features')[0].get('classicStyle') : null;
917
953
  }
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,14 +1125,31 @@ 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
- this.manifest$.pipe(map((manifest) => (manifest.options ?? { layers: [] }).layers?.filter((layer) => ['wms', 'geoserver'].includes(layer.type)))),
1148
+ this.manifest$.pipe(map((manifest) => (manifest.options ?? { layers: [] }).layers?.filter((layer) => ['wms'].includes(layer.type)))),
1094
1149
  this.geoServerLayerDescriptions$
1095
- ]).pipe(map(([wmsLayers, geoServerLayerDescriptions]) => wmsLayers.map((layer) => ({
1096
- ...layer,
1097
- // @ts-ignore
1098
- ...geoServerLayerDescriptions.find((layerDescr) => layerDescr.key === layer.key)
1099
- }))), distinctUntilChanged((p, c) => equal(p, c)), switchMap((wmsLayers) => combineLatest(wmsLayers.map((layer) => wmsService.getCapabilities(layer)))), startWith([]));
1150
+ ]).pipe(map(([wmsLayers, geoServerLayerDescriptions]) => {
1151
+ return [...wmsLayers, ...geoServerLayerDescriptions];
1152
+ }), distinctUntilChanged((p, c) => equal(p, c)), switchMap((wmsLayers) => combineLatest(wmsLayers.map((layer) => wmsService.getCapabilities(layer)))), startWith([]));
1100
1153
  this.options$ = combineLatest([
1101
1154
  this.manifest$,
1102
1155
  this.resultSet$,
@@ -1104,13 +1157,28 @@ class WidgetMapComponent extends DataWidgetComponent {
1104
1157
  this.fields$,
1105
1158
  this.styles$,
1106
1159
  this.geoServerLayerDescriptions$,
1107
- this.wmsCapabilities$.pipe(startWith([]))
1108
- ]).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]) => {
1109
1163
  // auto determine layers parameters to provide a working view
1110
- const autoOptions = JSON.parse(JSON.stringify({ relations: true, ...manifest.options }));
1164
+ const autoOptions = JSON.parse(JSON.stringify(manifest.options));
1111
1165
  if (!autoOptions.tooltipMode) {
1112
1166
  autoOptions.tooltipMode = TooltipMode.CLICK;
1113
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
+ ];
1114
1182
  autoOptions.layers?.forEach((layer, i) => {
1115
1183
  populateLocationAttribute(layer, resultSet, classes, fields);
1116
1184
  populateIntensityAttribute(layer, resultSet, classes, fields);
@@ -1142,8 +1210,20 @@ class WidgetMapComponent extends DataWidgetComponent {
1142
1210
  const lightStyles = mapStyles.filter((style) => !(style.identifier ?? '-').includes('dark'));
1143
1211
  autoOptions.style = lightStyles.length > 0 ? lightStyles[0].identifier : mapStyles[0].identifier;
1144
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
+ }
1145
1225
  return autoOptions;
1146
- }));
1226
+ }), distinctUntilChanged((p, c) => equal(p, c)));
1147
1227
  this.subscriptions.add(this.options$.pipe(filter((opt) => !!opt)).subscribe((options) => {
1148
1228
  this.optionsCopy = JSON.parse(JSON.stringify(options));
1149
1229
  }));
@@ -1430,7 +1510,10 @@ class WidgetMapComponent extends DataWidgetComponent {
1430
1510
  if (matchingLayer) {
1431
1511
  const matchingTitle = XMLUtils.find(matchingLayer.childNodes, 'Title');
1432
1512
  if (matchingTitle) {
1433
- layer.title = matchingTitle.textContent ?? undefined;
1513
+ layer.title =
1514
+ !!matchingTitle.textContent && matchingTitle.textContent.length > 0
1515
+ ? matchingTitle.textContent
1516
+ : undefined;
1434
1517
  }
1435
1518
  }
1436
1519
  }
@@ -1578,8 +1661,11 @@ class WidgetMapComponent extends DataWidgetComponent {
1578
1661
  const specificLayer = layer;
1579
1662
  specificLayer.classes = $event;
1580
1663
  }
1581
- deleteLayer(i) {
1664
+ deleteLayer(i, layer) {
1582
1665
  this.optionsCopy?.layers?.splice(i, 1);
1666
+ if (layer.type === 'auto') {
1667
+ this.optionsCopy.ignoreAutoLayer = [...(this.optionsCopy.ignoreAutoLayer ?? []), layer.key + '-' + layer.subType];
1668
+ }
1583
1669
  }
1584
1670
  invertLayers(idx, idxWith) {
1585
1671
  if (!!this.optionsCopy && !!this.optionsCopy.layers) {
@@ -1726,6 +1812,12 @@ class WidgetMapComponent extends DataWidgetComponent {
1726
1812
  changeSingleLayer($event) {
1727
1813
  this.optionsCopy.singleLayer = $event;
1728
1814
  }
1815
+ changeAutoLayer($event) {
1816
+ this.optionsCopy.automaticLayers = $event;
1817
+ if (!this.optionsCopy.automaticLayers) {
1818
+ delete this.optionsCopy.ignoreAutoLayer;
1819
+ }
1820
+ }
1729
1821
  get layerVisibleIdx() {
1730
1822
  return this.mapLayers.map((layer, idx) => (layer.getVisible() ? idx : 0)).reduce((a, b) => a + b);
1731
1823
  }
@@ -1734,11 +1826,11 @@ class WidgetMapComponent extends DataWidgetComponent {
1734
1826
  this.store.dispatch(DashboardActions.resetWmsFeatures());
1735
1827
  }
1736
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 }); }
1737
- 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" }] }); }
1738
1830
  }
1739
1831
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.6", ngImport: i0, type: WidgetMapComponent, decorators: [{
1740
1832
  type: Component,
1741
- 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" }]
1742
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: [{
1743
1835
  type: ViewChild,
1744
1836
  args: ['mapRef']
@@ -1831,7 +1923,8 @@ const enTranslations = {
1831
1923
  legendNotProvided: 'Legend not provided by server',
1832
1924
  selectLayers: 'Select layers',
1833
1925
  legends: 'Display legend',
1834
- singleLayer: 'Single layer mode'
1926
+ singleLayer: 'Single layer mode',
1927
+ autoLayer: 'Automatic datasource layers configuration'
1835
1928
  }
1836
1929
  }
1837
1930
  }
@@ -1912,7 +2005,8 @@ const frTranslations = {
1912
2005
  legendNotProvided: 'Légende non fournie par le serveur',
1913
2006
  selectLayers: 'Sélectionner les couches',
1914
2007
  legends: 'Afficher la légende',
1915
- singleLayer: 'Mode mono-couche'
2008
+ singleLayer: 'Mode mono-couche',
2009
+ autoLayer: 'Configuration automatique des sources de données'
1916
2010
  }
1917
2011
  }
1918
2012
  }
@@ -1981,5 +2075,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.6", ngImpor
1981
2075
  * Generated bundle index. Do not edit.
1982
2076
  */
1983
2077
 
1984
- 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 };
1985
2079
  //# sourceMappingURL=provoly-dashboard-widgets-widget-map.mjs.map