@provoly/dashboard 0.14.5 → 0.14.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/admin/admin.module.d.ts +2 -1
- package/admin/components/admin-classes/admin-classes-view/admin-attributes-form/admin-attributes-form.component.d.ts +5 -2
- package/admin/components/admin-fields/admin-fields-form/admin-fields-form.component.d.ts +7 -3
- package/admin/i18n/en.translations.d.ts +15 -0
- package/admin/i18n/fr.translations.d.ts +15 -0
- package/esm2022/admin/admin.module.mjs +8 -4
- package/esm2022/admin/components/admin-classes/admin-classes-form/admin-classes-form.component.mjs +3 -3
- package/esm2022/admin/components/admin-classes/admin-classes-view/admin-attributes-form/admin-attributes-form.component.mjs +19 -14
- package/esm2022/admin/components/admin-dataset/shared/admin-form-dataset/admin-form-dataset.component.mjs +3 -5
- package/esm2022/admin/components/admin-fields/admin-fields-form/admin-fields-form.component.mjs +23 -12
- package/esm2022/admin/i18n/en.translations.mjs +17 -2
- package/esm2022/admin/i18n/fr.translations.mjs +19 -4
- package/esm2022/dataset/components/dataset-detail/dataset-detail.component.mjs +4 -3
- package/esm2022/import/components/import.component.mjs +12 -5
- package/esm2022/import/i18n/en.translations.mjs +3 -2
- package/esm2022/import/i18n/fr.translations.mjs +3 -2
- package/esm2022/import/import.module.mjs +7 -4
- package/esm2022/import/store/import.actions.mjs +1 -1
- package/esm2022/import/store/import.effects.mjs +2 -2
- package/esm2022/import/store/import.service.mjs +3 -2
- package/esm2022/lib/core/components/translate-id/translate-id.pipe.mjs +9 -9
- package/esm2022/lib/core/i18n/en.translations.mjs +2 -1
- package/esm2022/lib/core/i18n/fr.translations.mjs +2 -1
- package/esm2022/lib/core/model/admin-api.model.mjs +66 -14
- package/esm2022/lib/core/model/widget-map-manifest.interface.mjs +1 -1
- package/esm2022/lib/core/store/field/field.interface.mjs +10 -1
- package/esm2022/lib/core/symbol/symbol.service.mjs +7 -3
- package/esm2022/lib/core/toolbox/toolbox-manifest.service.mjs +17 -1
- package/esm2022/lib/core/toolbox/toolbox-menu.service.mjs +2 -1
- package/esm2022/lib/dashboard/components/dashboard.component.mjs +5 -5
- package/esm2022/lib/dashboard/components/widgets/header/widget-header.component.mjs +9 -3
- package/esm2022/pipeline/components/pipeline-list/pipeline-list.component.mjs +25 -13
- package/esm2022/pipeline/pipeline.module.mjs +8 -4
- package/esm2022/supervision/store/supervision.reducer.mjs +2 -7
- package/esm2022/widgets/widget-map/component/widget-map-layer.service.mjs +34 -3
- package/esm2022/widgets/widget-map/component/widget-map.component.mjs +68 -10
- package/esm2022/widgets/widget-map/i18n/en.translations.mjs +3 -2
- package/esm2022/widgets/widget-map/i18n/fr.translations.mjs +3 -2
- package/esm2022/widgets/widget-map/utils/widget-map.utils.mjs +14 -8
- package/fesm2022/provoly-dashboard-admin.mjs +79 -31
- package/fesm2022/provoly-dashboard-admin.mjs.map +1 -1
- package/fesm2022/provoly-dashboard-dataset.mjs +3 -2
- package/fesm2022/provoly-dashboard-dataset.mjs.map +1 -1
- package/fesm2022/provoly-dashboard-import.mjs +23 -10
- package/fesm2022/provoly-dashboard-import.mjs.map +1 -1
- package/fesm2022/provoly-dashboard-pipeline.mjs +27 -11
- package/fesm2022/provoly-dashboard-pipeline.mjs.map +1 -1
- package/fesm2022/provoly-dashboard-supervision.mjs +1 -6
- package/fesm2022/provoly-dashboard-supervision.mjs.map +1 -1
- package/fesm2022/provoly-dashboard-widgets-widget-map.mjs +536 -440
- package/fesm2022/provoly-dashboard-widgets-widget-map.mjs.map +1 -1
- package/fesm2022/provoly-dashboard.mjs +174 -85
- package/fesm2022/provoly-dashboard.mjs.map +1 -1
- package/import/components/import.component.d.ts +1 -0
- package/import/i18n/en.translations.d.ts +1 -0
- package/import/i18n/fr.translations.d.ts +1 -0
- package/import/import.module.d.ts +2 -1
- package/import/store/import.actions.d.ts +2 -0
- package/import/store/import.service.d.ts +1 -1
- package/lib/core/components/translate-id/translate-id.pipe.d.ts +1 -1
- package/lib/core/i18n/en.translations.d.ts +1 -0
- package/lib/core/i18n/fr.translations.d.ts +1 -0
- package/lib/core/model/admin-api.model.d.ts +1 -0
- package/lib/core/model/widget-map-manifest.interface.d.ts +11 -1
- package/lib/core/store/field/field.interface.d.ts +1 -0
- package/lib/core/symbol/symbol.service.d.ts +1 -1
- package/lib/dashboard/components/dashboard.component.d.ts +1 -1
- package/lib/dashboard/components/widgets/header/widget-header.component.d.ts +3 -1
- package/package.json +36 -36
- package/pipeline/components/pipeline-list/pipeline-list.component.d.ts +1 -0
- package/pipeline/pipeline.module.d.ts +2 -1
- package/schematics/migration.json +5 -0
- package/schematics/ng-update/utils/replaceStrings.function.d.ts +7 -0
- package/schematics/ng-update/utils/replaceStrings.function.js +15 -0
- package/schematics/ng-update/utils/replaceStrings.function.js.map +1 -0
- package/schematics/ng-update/version-0-13/index.spec.js +11 -0
- package/schematics/ng-update/version-0-13/index.spec.js.map +1 -1
- package/schematics/ng-update/version-0-14/index.d.ts +2 -0
- package/schematics/ng-update/version-0-14/index.js +49 -0
- package/schematics/ng-update/version-0-14/index.js.map +1 -0
- package/schematics/ng-update/version-0-14/index.spec.d.ts +1 -0
- package/schematics/ng-update/version-0-14/index.spec.js +52 -0
- package/schematics/ng-update/version-0-14/index.spec.js.map +1 -0
- package/styles/components/_m-context-menu.scss +4 -0
- package/styles/components/_o-pry-admin-classes-customize.scss +48 -0
- package/widgets/widget-map/component/widget-map-layer.service.d.ts +6 -1
- package/widgets/widget-map/component/widget-map.component.d.ts +4 -2
- package/widgets/widget-map/i18n/en.translations.d.ts +1 -0
- package/widgets/widget-map/i18n/fr.translations.d.ts +1 -0
- 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,
|
|
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
|
|
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
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
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
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
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
|
|
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
|
|
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 = [
|
|
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
|
-
|
|
853
|
-
|
|
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
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
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
|
-
|
|
884
|
-
|
|
885
|
-
|
|
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
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
color: '#fff'
|
|
904
|
-
}),
|
|
905
|
-
fill: new Fill({
|
|
906
|
-
color: '#3399CC'
|
|
907
|
-
})
|
|
908
|
-
}),
|
|
909
|
-
text: new Text({ text: `${size}` })
|
|
910
|
-
});
|
|
911
|
-
this.styleCache[size] = style;
|
|
936
|
+
return of(null);
|
|
937
|
+
}
|
|
938
|
+
static getMatchingLayer(paramLayer, doc) {
|
|
939
|
+
const WMSCapability = XMLUtils.find(doc.childNodes, 'WMS_Capabilities');
|
|
940
|
+
if (WMSCapability) {
|
|
941
|
+
const Capabilities = XMLUtils.find(WMSCapability.childNodes, 'Capability');
|
|
942
|
+
if (Capabilities) {
|
|
943
|
+
const Layer = XMLUtils.find(Capabilities.childNodes, 'Layer');
|
|
944
|
+
if (Layer) {
|
|
945
|
+
let matchingLayer = XMLUtils.findWith(Layer.childNodes, 'Name', paramLayer);
|
|
946
|
+
const split = paramLayer.split(':');
|
|
947
|
+
if (!matchingLayer && split.length >= 2) {
|
|
948
|
+
// Try again, splitting on ":" in the name to ignore namespace if present
|
|
949
|
+
matchingLayer = XMLUtils.findWith(Layer.childNodes, 'Name', split[split.length - 1]);
|
|
950
|
+
}
|
|
951
|
+
return matchingLayer;
|
|
912
952
|
}
|
|
913
|
-
return style;
|
|
914
953
|
}
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
}
|
|
918
|
-
});
|
|
919
|
-
return layer;
|
|
954
|
+
}
|
|
955
|
+
return null;
|
|
920
956
|
}
|
|
921
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.6", ngImport: i0, type:
|
|
922
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.1.6", ngImport: i0, type:
|
|
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:
|
|
960
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.6", ngImport: i0, type: WmsService, decorators: [{
|
|
925
961
|
type: Injectable,
|
|
926
962
|
args: [{
|
|
927
963
|
providedIn: 'root'
|
|
928
964
|
}]
|
|
929
|
-
}] });
|
|
965
|
+
}], ctorParameters: function () { return [{ type: i1.HttpClient }]; } });
|
|
930
966
|
|
|
931
967
|
class PryWidgetMapCssComponent {
|
|
932
968
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.6", ngImport: i0, type: PryWidgetMapCssComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
@@ -1089,6 +1125,25 @@ class WidgetMapComponent extends DataWidgetComponent {
|
|
|
1089
1125
|
})
|
|
1090
1126
|
.map((layer) => layer);
|
|
1091
1127
|
}));
|
|
1128
|
+
this.autoDatasetLayers$ = combineLatest([
|
|
1129
|
+
this.classes$,
|
|
1130
|
+
this.fields$,
|
|
1131
|
+
this.usedDatasources$.pipe(startWith([]), map((datasources) => datasources.filter((ds) => ds.sourceType === 'dataset')))
|
|
1132
|
+
]).pipe(map(([classes, fields, dataSets]) => dataSets
|
|
1133
|
+
.map((ds) => {
|
|
1134
|
+
const model = classes.find((clazz) => clazz.id === ds.oClass);
|
|
1135
|
+
const geoAttributes = (model?.attributes.map((attr) => ({ attr, field: fields.find((f) => attr.field === f.id) })) ?? []).filter(({ attr, field }) => !!field && GeometricFieldTypes.includes(field.type));
|
|
1136
|
+
return geoAttributes.map((geo) => ({
|
|
1137
|
+
type: 'auto',
|
|
1138
|
+
title: `${ds.name} - ${geo.attr.name} (${geo.field.type})`,
|
|
1139
|
+
oClass: ds.oClass,
|
|
1140
|
+
key: ds.id,
|
|
1141
|
+
subType: geo.field.type,
|
|
1142
|
+
classes: [ds.oClass],
|
|
1143
|
+
attribute: geo.attr.name
|
|
1144
|
+
}));
|
|
1145
|
+
})
|
|
1146
|
+
.flat()));
|
|
1092
1147
|
this.wmsCapabilities$ = combineLatest([
|
|
1093
1148
|
this.manifest$.pipe(map((manifest) => (manifest.options ?? { layers: [] }).layers?.filter((layer) => ['wms'].includes(layer.type)))),
|
|
1094
1149
|
this.geoServerLayerDescriptions$
|
|
@@ -1102,13 +1157,28 @@ class WidgetMapComponent extends DataWidgetComponent {
|
|
|
1102
1157
|
this.fields$,
|
|
1103
1158
|
this.styles$,
|
|
1104
1159
|
this.geoServerLayerDescriptions$,
|
|
1105
|
-
this.wmsCapabilities$.pipe(startWith([]))
|
|
1106
|
-
|
|
1160
|
+
this.wmsCapabilities$.pipe(startWith([])),
|
|
1161
|
+
this.autoDatasetLayers$
|
|
1162
|
+
]).pipe(map(([manifest, resultSet, classes, fields, mapStyles, geoLayers, capabilities, autoDatasetLayers]) => {
|
|
1107
1163
|
// auto determine layers parameters to provide a working view
|
|
1108
|
-
const autoOptions = JSON.parse(JSON.stringify(
|
|
1164
|
+
const autoOptions = JSON.parse(JSON.stringify(manifest.options));
|
|
1109
1165
|
if (!autoOptions.tooltipMode) {
|
|
1110
1166
|
autoOptions.tooltipMode = TooltipMode.CLICK;
|
|
1111
1167
|
}
|
|
1168
|
+
autoOptions.layers = [
|
|
1169
|
+
...(autoOptions.layers ?? []).filter((layer) => layer.type !== 'auto'),
|
|
1170
|
+
...(autoOptions.automaticLayers
|
|
1171
|
+
? autoDatasetLayers
|
|
1172
|
+
.filter((layer) => !autoOptions.ignoreAutoLayer ||
|
|
1173
|
+
!autoOptions.ignoreAutoLayer.includes(layer.key + '-' + layer.subType))
|
|
1174
|
+
.map((layer) => ({
|
|
1175
|
+
...layer,
|
|
1176
|
+
...((autoOptions.layers ?? []).find(
|
|
1177
|
+
// @ts-ignore
|
|
1178
|
+
(prevLayer) => prevLayer.key === layer.key && prevLayer.attribute === layer.attribute) ?? {})
|
|
1179
|
+
}))
|
|
1180
|
+
: [])
|
|
1181
|
+
];
|
|
1112
1182
|
autoOptions.layers?.forEach((layer, i) => {
|
|
1113
1183
|
populateLocationAttribute(layer, resultSet, classes, fields);
|
|
1114
1184
|
populateIntensityAttribute(layer, resultSet, classes, fields);
|
|
@@ -1140,8 +1210,20 @@ class WidgetMapComponent extends DataWidgetComponent {
|
|
|
1140
1210
|
const lightStyles = mapStyles.filter((style) => !(style.identifier ?? '-').includes('dark'));
|
|
1141
1211
|
autoOptions.style = lightStyles.length > 0 ? lightStyles[0].identifier : mapStyles[0].identifier;
|
|
1142
1212
|
}
|
|
1213
|
+
if (autoOptions.ignoreAutoLayer) {
|
|
1214
|
+
const base = autoOptions.ignoreAutoLayer;
|
|
1215
|
+
// Remove from ignoreAutoLayers, values that are not necessary
|
|
1216
|
+
const possibleIgnoreAutoLayerKeys = autoDatasetLayers.map((layer) => layer.key + '-' + layer.subType);
|
|
1217
|
+
autoOptions.ignoreAutoLayer = (autoOptions.ignoreAutoLayer ?? []).filter((key) => possibleIgnoreAutoLayerKeys.includes(key));
|
|
1218
|
+
if (autoOptions.ignoreAutoLayer.length === 0) {
|
|
1219
|
+
delete autoOptions.ignoreAutoLayer;
|
|
1220
|
+
}
|
|
1221
|
+
if (!autoOptions.ignoreAutoLayer || base.length !== autoOptions.ignoreAutoLayer.length) {
|
|
1222
|
+
this.emitManifest();
|
|
1223
|
+
}
|
|
1224
|
+
}
|
|
1143
1225
|
return autoOptions;
|
|
1144
|
-
}));
|
|
1226
|
+
}), distinctUntilChanged((p, c) => equal(p, c)));
|
|
1145
1227
|
this.subscriptions.add(this.options$.pipe(filter((opt) => !!opt)).subscribe((options) => {
|
|
1146
1228
|
this.optionsCopy = JSON.parse(JSON.stringify(options));
|
|
1147
1229
|
}));
|
|
@@ -1428,7 +1510,10 @@ class WidgetMapComponent extends DataWidgetComponent {
|
|
|
1428
1510
|
if (matchingLayer) {
|
|
1429
1511
|
const matchingTitle = XMLUtils.find(matchingLayer.childNodes, 'Title');
|
|
1430
1512
|
if (matchingTitle) {
|
|
1431
|
-
layer.title =
|
|
1513
|
+
layer.title =
|
|
1514
|
+
!!matchingTitle.textContent && matchingTitle.textContent.length > 0
|
|
1515
|
+
? matchingTitle.textContent
|
|
1516
|
+
: undefined;
|
|
1432
1517
|
}
|
|
1433
1518
|
}
|
|
1434
1519
|
}
|
|
@@ -1576,8 +1661,11 @@ class WidgetMapComponent extends DataWidgetComponent {
|
|
|
1576
1661
|
const specificLayer = layer;
|
|
1577
1662
|
specificLayer.classes = $event;
|
|
1578
1663
|
}
|
|
1579
|
-
deleteLayer(i) {
|
|
1664
|
+
deleteLayer(i, layer) {
|
|
1580
1665
|
this.optionsCopy?.layers?.splice(i, 1);
|
|
1666
|
+
if (layer.type === 'auto') {
|
|
1667
|
+
this.optionsCopy.ignoreAutoLayer = [...(this.optionsCopy.ignoreAutoLayer ?? []), layer.key + '-' + layer.subType];
|
|
1668
|
+
}
|
|
1581
1669
|
}
|
|
1582
1670
|
invertLayers(idx, idxWith) {
|
|
1583
1671
|
if (!!this.optionsCopy && !!this.optionsCopy.layers) {
|
|
@@ -1724,6 +1812,12 @@ class WidgetMapComponent extends DataWidgetComponent {
|
|
|
1724
1812
|
changeSingleLayer($event) {
|
|
1725
1813
|
this.optionsCopy.singleLayer = $event;
|
|
1726
1814
|
}
|
|
1815
|
+
changeAutoLayer($event) {
|
|
1816
|
+
this.optionsCopy.automaticLayers = $event;
|
|
1817
|
+
if (!this.optionsCopy.automaticLayers) {
|
|
1818
|
+
delete this.optionsCopy.ignoreAutoLayer;
|
|
1819
|
+
}
|
|
1820
|
+
}
|
|
1727
1821
|
get layerVisibleIdx() {
|
|
1728
1822
|
return this.mapLayers.map((layer, idx) => (layer.getVisible() ? idx : 0)).reduce((a, b) => a + b);
|
|
1729
1823
|
}
|
|
@@ -1732,11 +1826,11 @@ class WidgetMapComponent extends DataWidgetComponent {
|
|
|
1732
1826
|
this.store.dispatch(DashboardActions.resetWmsFeatures());
|
|
1733
1827
|
}
|
|
1734
1828
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.6", ngImport: i0, type: WidgetMapComponent, deps: [{ token: i1$1.Store }, { token: i2.PrySnackbarService }, { token: i2.PryI18nService }, { token: i2.TooltipFactoryService }, { token: i3.Overlay }, { token: i0.ViewContainerRef }, { token: i2.SymbolService }, { token: i0.Injector }, { token: WidgetMapLayerService }, { token: i0.ElementRef }, { token: WmsService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1735
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.6", type: WidgetMapComponent, selector: "pry-widget-map", viewQueries: [{ propertyName: "mapRef", first: true, predicate: ["mapRef"], descendants: true }, { propertyName: "popup", first: true, predicate: ["popup"], descendants: true }, { propertyName: "popupContent", first: true, predicate: ["popupContent"], descendants: true, read: ViewContainerRef }, { propertyName: "exportTypeTemplate", first: true, predicate: ["exportTypeTemplate"], descendants: true, read: TemplateRef }, { propertyName: "address", first: true, predicate: ["address"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<pry-widget-map-css></pry-widget-map-css>\n<div class=\"o-widget o-widget--map\">\n <pry-widget-header\n [datasourceIds]=\"(datasourceIds$ | async) ?? []\"\n *ngIf=\"displayHeader$ | async\"\n [widgetIndex]=\"widgetIndex\"\n [manifest]=\"manifest\"\n (manifestModified)=\"manifestModified.emit($event)\"\n [headerOptions]=\"(displayHeader$ | async) ?? {}\"\n #header\n >\n <pry-settings\n (saveTriggered)=\"emitManifest()\"\n (changeTitle)=\"changeWidgetTitle($event)\"\n [headerPresent]=\"displayHeader$ | async\"\n [widgetIndex]=\"widgetIndex\"\n [header]=\"header\"\n [open$]=\"open$\"\n class=\"o-settings\"\n >\n <div class=\"m-form-label-field\">\n <label class=\"a-label\" for=\"map_style\">{{ '@pry.widget.map.style' | i18n }}</label>\n <pry-select\n (ngModelChange)=\"changeStyle($event)\"\n [itemsAsOption]=\"true\"\n [items]=\"styles$ | async\"\n [ngModel]=\"optionsCopy.style\"\n bindLabel=\"label\"\n bindValue=\"identifier\"\n id=\"map_style\"\n class=\"a-pry-select\"\n ></pry-select>\n </div>\n\n <div class=\"m-form-label-field\" *ngIf=\"optionsCopy.style === STYLE_FROM_URL\">\n <label class=\"a-label\" for=\"style_URL\">{{ '@pry.widget.map.styleUrl' | i18n }}</label>\n <input\n id=\"style_URL\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeStyleURL($event)\"\n [value]=\"optionsCopy.styleURL ?? ''\"\n />\n </div>\n\n <pry-checkbox (ngModelChange)=\"changeSingleLayer($event)\" [ngModel]=\"optionsCopy.singleLayer ?? false\">\n {{ '@pry.widget.map.singleLayer' | i18n }}\n </pry-checkbox>\n\n <pry-checkbox (ngModelChange)=\"changeFit($event)\" [ngModel]=\"optionsCopy.fit ?? false\">\n {{ '@pry.widget.map.fit' | i18n }}\n </pry-checkbox>\n\n <pry-checkbox (ngModelChange)=\"changeAttributions($event)\" [ngModel]=\"optionsCopy.attributions ?? false\">\n {{ '@pry.widget.map.attributions' | i18n }}\n </pry-checkbox>\n\n <div class=\"o-settings__popup__content__actions -has-separator\">\n <button type=\"button\" (click)=\"addLayer()\" class=\"a-btn a-btn--icon-text -link-like\">\n <pry-icon iconSvg=\"library_add\"></pry-icon>\n {{ '@pry.widget.map.addLayer' | i18n }}\n </button>\n </div>\n\n <div *ngFor=\"let layer of optionsCopy?.layers; let i = index\" class=\"o-settings__popup__content__fields\">\n <div class=\"o-settings__popup__content__fields__head\">\n <h3 class=\"a-h3 settings-layer-title__title\">{{ '@pry.widget.map.layer' | i18n : { index: i + 1 } }}</h3>\n <div class=\"m-btn-group\">\n <button type=\"button\" class=\"a-btn a-btn--icon-only\" (click)=\"invertLayers(i, i - 1)\" *ngIf=\"i > 0\">\n <pry-icon iconSvg=\"fleche_haut\"></pry-icon>\n <span class=\"u-visually-hidden\">{{ '@pry.action.moveUp' | i18n }}</span>\n </button>\n <button\n type=\"button\"\n class=\"a-btn a-btn--icon-only\"\n (click)=\"invertLayers(i, i + 1)\"\n *ngIf=\"i < (optionsCopy?.layers?.length ?? 0) - 1\"\n >\n <pry-icon iconSvg=\"fleche_bas\"></pry-icon>\n <span class=\"u-visually-hidden\">{{ '@pry.action.moveDown' | i18n }}</span>\n </button>\n </div>\n </div>\n\n <div class=\"o-settings__popup__content__fields__content\">\n <pry-range\n [ngModel]=\"(layer?.opacity ?? 100) + ''\"\n (ngModelChange)=\"changeOpacity(layer, $event)\"\n labelTranslate=\"@pry.widget.map.opacity\"\n min=\"0\"\n max=\"100\"\n ></pry-range>\n\n <fieldset>\n <legend class=\"u-visually-hidden\">{{ '@pry.widget.map.layerOptions' | i18n : { index: i + 1 } }}</legend>\n <div class=\"m-form-label-field\">\n <label class=\"a-label\" for=\"map_layerTitle\">{{ '@pry.widget.map.layerTitle' | i18n }}</label>\n <input\n id=\"map_layerTitle\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeTitle($event, layer)\"\n [value]=\"layer.title ?? ''\"\n />\n </div>\n\n <div class=\"m-form-label-field\" *ngIf=\"layer.type !== 'geoserver'\">\n <label class=\"a-label\" for=\"map_layerType\">{{ '@pry.widget.map.layerType.title' | i18n }}</label>\n <pry-select\n (ngModelChange)=\"changeLayerType($event, i)\"\n [bindData]=\"true\"\n [itemsAsOption]=\"true\"\n [items]=\"layerTypes\"\n [labelTranslate]=\"true\"\n [ngModel]=\"layer.type\"\n baseTranslate=\"@pry.widget.map.layerType.\"\n class=\"a-pry-select\"\n id=\"map_layerType\"\n ></pry-select>\n </div>\n\n <div\n *ngIf=\"\n layer.type !== 'relation' &&\n layer.type !== 'wms' &&\n layer.type !== 'wmts' &&\n layer.type !== 'geoserver' &&\n layer.type !== 'featurelayer' &&\n layer.type !== 'vectortile' &&\n layer.type !== 'rastertile'\n \"\n class=\"m-form-label-field\"\n >\n <label class=\"a-label\" for=\"map_classes\">{{ '@pry.widget.map.classes' | i18n }}</label>\n <pry-select\n (ngModelChange)=\"changeClasses($event, layer)\"\n [itemsAsOption]=\"true\"\n [items]=\"classes$ | async\"\n [multiple]=\"true\"\n [ngModel]=\"layer.classes\"\n bindLabel=\"name\"\n bindValue=\"id\"\n class=\"a-pry-select\"\n id=\"map_classes\"\n ></pry-select>\n </div>\n </fieldset>\n </div>\n\n <fieldset\n *ngIf=\"\n layer.type !== 'relation' &&\n layer.type !== 'wms' &&\n layer.type !== 'wmts' &&\n layer.type !== 'geoserver' &&\n layer.type !== 'featurelayer' &&\n layer.type !== 'vectortile' &&\n layer.type !== 'rastertile'\n \"\n >\n <legend class=\"u-visually-hidden\">{{ '@pry.widget.map.locationAttr' | i18n }}</legend>\n <ng-container\n *ngIf=\"\n layer\n | geometryFieldsFor : { resultSet: resultSet$, classes: layer.classes, type: layer.type }\n | async as fields\n \"\n >\n <div\n *ngIf=\"\n ['heatmap', 'bubble', 'marker', 'point', 'line', 'polygon', 'multi-line', 'multi-polygon'].indexOf(\n layer.type\n ) >= 0\n \"\n >\n <div class=\"m-form-label-field\">\n <label class=\"a-label\" for=\"map_locationAttribute_both\">{{\n '@pry.widget.map.locationAttribute.both' | i18n\n }}</label>\n <pry-select\n (ngModelChange)=\"changeLocationAttributes($event, layer)\"\n [itemsAsOption]=\"true\"\n [items]=\"fields\"\n [ngModel]=\"layer.attribute\"\n bindLabel=\"name\"\n bindValue=\"name\"\n id=\"map_locationAttribute_both\"\n class=\"a-pry-select\"\n ></pry-select>\n </div>\n </div>\n\n <div *ngIf=\"['heatmap', 'bubble'].indexOf(layer.type) >= 0\">\n <div class=\"m-form-label-field\">\n <label class=\"a-label\" for=\"map_intensityAttribute\">{{\n '@pry.widget.map.intensityAttribute' | i18n\n }}</label>\n <pry-select\n (ngModelChange)=\"changeIntensityAttributes($event, layer)\"\n [itemsAsOption]=\"true\"\n [items]=\"fields\"\n [ngModel]=\"layerHasIntensity(layer).intensityAttribute\"\n bindLabel=\"name\"\n bindValue=\"name\"\n id=\"map_intensityAttribute\"\n class=\"a-pry-select\"\n ></pry-select>\n </div>\n </div>\n </ng-container>\n </fieldset>\n\n <fieldset\n *ngIf=\"\n layer.type === 'wms' ||\n layer.type === 'wmts' ||\n layer.type === 'featurelayer' ||\n layer.type === 'vectortile' ||\n layer.type === 'rastertile'\n \"\n >\n <legend class=\"u-visually-hidden\">{{ '@pry.widget.map.tile' | i18n }}</legend>\n <div class=\"m-form-label-field\">\n <label class=\"a-label\" for=\"map_wms_url\">{{ '@pry.widget.map.wms.url' | i18n }}</label>\n <input\n id=\"map_wms_url\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeUrl($event, layer)\"\n [value]=\"layer.url\"\n />\n </div>\n\n <div class=\"m-form-label-field\" *ngIf=\"layer.type === 'wms' || layer.type === 'wmts'\">\n <label class=\"a-label\" for=\"map_wms_paramLayer\">{{ '@pry.widget.map.wms.paramLayer' | i18n }}</label>\n <input\n id=\"map_wms_paramLayer\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeParamLayer($event, layer)\"\n [value]=\"layer.paramLayer\"\n />\n </div>\n\n <div class=\"m-form-label-field\" *ngIf=\"layer.type === 'wmts'\">\n <label class=\"a-label\" for=\"map_wms_matrixSet\">{{ '@pry.widget.map.wms.matrixSet' | i18n }}</label>\n <input\n id=\"map_wms_matrixSet\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeMatrixSet($event, layer)\"\n [value]=\"layer.matrixSet\"\n />\n </div>\n\n <div class=\"m-form-label-field\" *ngIf=\"layer.type === 'wmts'\">\n <label class=\"a-label\" for=\"map_wms_style\">{{ '@pry.widget.map.wms.style' | i18n }}</label>\n <input\n id=\"map_wms_style\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeParamStyle($event, layer)\"\n [value]=\"layer.style\"\n />\n </div>\n\n <div class=\"m-form-label-field\" *ngIf=\"layer.type === 'wms'\">\n <pry-checkbox (ngModelChange)=\"changeParamTiled($event, layer)\" [ngModel]=\"layer?.paramTiled ?? false\">\n {{ '@pry.widget.map.wms.paramTiled' | i18n }}\n </pry-checkbox>\n </div>\n </fieldset>\n\n <fieldset *ngIf=\"layer.type === 'marker'\">\n <legend class=\"u-visually-hidden\">{{ '@pry.widget.map.clustering' | i18n }}</legend>\n <div class=\"m-form-label-field\">\n <pry-checkbox (ngModelChange)=\"changeClustered(layer, $event)\" [ngModel]=\"layer.clustered\">\n {{ '@pry.widget.map.clustered' | i18n }}\n </pry-checkbox>\n </div>\n <div *ngIf=\"layer.clustered\">\n <pry-range\n [ngModel]=\"layer.clustered\"\n (ngModelChange)=\"changeClusterDistance(layer, $event)\"\n labelTranslate=\"@pry.widget.map.clusterDistance\"\n min=\"1\"\n max=\"500\"\n ></pry-range>\n </div>\n </fieldset>\n\n <div class=\"m-form-label-field\" *ngIf=\"optionsCopy.attributions\">\n <label class=\"a-label\" for=\"attribution\">{{ '@pry.widget.map.attribution' | i18n }}</label>\n <input\n id=\"attribution\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeAttribution($event, layer)\"\n [value]=\"layer.attribution ? layer.attribution : ''\"\n />\n </div>\n\n <button\n type=\"button\"\n (click)=\"deleteLayer(i)\"\n class=\"a-btn a-btn--icon-text -link-like\"\n *ngIf=\"layer.type !== 'geoserver'\"\n data-func=\"delete\"\n >\n <pry-icon iconSvg=\"delete\" [width]=\"19\" [height]=\"19\"></pry-icon>\n <span>{{ '@pry.widget.map.deleteLayer' | i18n }}</span>\n </button>\n </div>\n </pry-settings>\n </pry-widget-header>\n\n <div class=\"m-btn-group -selection-choice\" [style.transform]=\"bottomLeft$ | async\">\n <ng-container *ngFor=\"let action of basicActions$ | async\">\n <button\n type=\"button\"\n class=\"a-btn a-btn--icon-only\"\n (click)=\"interactionManager.selectionInteraction.changeSelection(action)\"\n [class.-selected]=\"interactionManager.selectionInteraction.selectionType === action\"\n [pryTooltip]=\"infoTooltipAction\"\n pryTooltipPosition=\"bottom\"\n aria-describedby=\"infoTooltipAction\"\n [pryTooltipContext]=\"{ action: action }\"\n >\n <pry-icon [iconSvg]=\"action\"></pry-icon>\n <span class=\"u-visually-hidden\">{{ '@pry.widget.map.' + action | i18n }}</span>\n </button>\n </ng-container>\n\n <button\n type=\"button\"\n class=\"a-btn a-btn--icon-only\"\n id=\"export_card\"\n aria-expanded=\"false\"\n aria-controls=\"export_type\"\n aria-haspopup=\"menu\"\n [pryTooltip]=\"infoTooltipDown\"\n pryTooltipPosition=\"bottom\"\n aria-describedby=\"infoTooltipDown_widgetMap\"\n *ngIf=\"(actions$ | async)?.includes('export')\"\n >\n <pry-icon iconSvg=\"file_download\" (click)=\"export()\"></pry-icon>\n <span class=\"u-visually-hidden\">{{ '@pry.widget.map.export' | i18n }}</span>\n </button>\n </div>\n\n <div\n class=\"ol-control m-layer-switcher\"\n *ngIf=\"((layers$ | async)?.length ?? 0) > 0\"\n [style.top.px]=\"layersTop$ | async\"\n >\n <button\n class=\"m-layer-switcher__toggle\"\n (click)=\"toggleLayersWindow()\"\n [title]=\"'@pry.widget.map.selectLayers' | i18n\"\n >\n <pry-icon iconSvg=\"layers\" [width]=\"22\" [height]=\"22\"></pry-icon>\n </button>\n <ng-container *ngFor=\"let layer of mapLayers; let index = index\">\n <div class=\"m-layer-switcher__title\" [class.-hidden]=\"!layersTabOpen\">\n {{ layer.get('title') }}\n <ng-container *ngIf=\"!(options$ | async)?.singleLayer; else singleLayer\">\n <pry-checkbox [ngModel]=\"layer.getVisible()\" (change)=\"changeVisibility(layer)\"></pry-checkbox>\n </ng-container>\n <ng-template #singleLayer>\n <input\n type=\"radio\"\n name=\"layer\"\n [id]=\"'radio-layer-' + layer.get('title').split(' ')[0]\"\n [ngModel]=\"layerVisibleIdx\"\n [value]=\"index\"\n (change)=\"changeVisibility(layer)\"\n />\n </ng-template>\n </div>\n </ng-container>\n </div>\n\n <div\n class=\"ol-control m-layer-legend\"\n *ngIf=\"((legendLayers$ | async)?.length ?? 0) > 0\"\n [style.top.px]=\"legendTop$ | async\"\n >\n <button class=\"m-layer-legend__toggle\" (click)=\"toggleLegendWindow()\" [title]=\"'@pry.widget.map.legends' | i18n\">\n <pry-icon iconSvg=\"legend\" [width]=\"22\" [height]=\"22\"></pry-icon>\n </button>\n <ng-container *ngFor=\"let geoLayer of legendLayers$ | async; let index = index\">\n <div class=\"m-layer-legend__title\" [class.-hidden]=\"!legendTabOpen\">\n {{ geoLayer.title }}\n <ng-container *ngIf=\"isLayerRendered(geoLayer)\">\n <button class=\"m-layer-legend__toggle\" (click)=\"toggleLegend(index)\">\n <pry-icon\n [iconSvg]=\"legendTab === index ? 'chevron_top' : 'chevron_bottom'\"\n [width]=\"22\"\n [height]=\"22\"\n ></pry-icon>\n </button>\n </ng-container>\n <ng-container *ngIf=\"!isLayerRendered(geoLayer)\">\n <pry-icon [iconSvg]=\"'close'\" [width]=\"22\" [height]=\"22\"></pry-icon>\n </ng-container>\n </div>\n <div\n class=\"m-layer-legend__image\"\n [class.-hidden]=\"!legendTabOpen || legendTab !== index || !isLayerRendered(geoLayer)\"\n [style.max-height.px]=\"legendHeight$ | async\"\n >\n <ng-container *ngIf=\"geoLayer | legendUrl : { capabilities: (wmsCapabilities$ | async) } as url\">\n <img\n [src]=\"url\"\n [alt]=\"'@pry.widget.map.legend' | i18n : { layer: geoLayer.title }\"\n (error)=\"imageNotProvided[index] = true\"\n />\n </ng-container>\n <ng-container *ngIf=\"!(geoLayer | legendUrl : { capabilities: (wmsCapabilities$ | async) })\">\n <p class=\"m-layer-legend__error\">{{ '@pry.widget.map.legendNotProvided' | i18n }}</p>\n </ng-container>\n </div>\n </ng-container>\n </div>\n\n <div [style.height.px]=\"height$ | async\" class=\"o-map-wrapper\">\n <div class=\"o-map\">\n <div #mapRef id=\"map\"></div>\n </div>\n </div>\n\n <ng-template #infoTooltipAction let-action=\"action\">\n <div class=\"m-tooltip\" role=\"tooltip\" id=\"infoTooltipAction\" aria-hidden=\"true\">\n <span class=\"m-tooltip__text\">{{ '@pry.widget.map.' + action | i18n }}</span>\n </div>\n </ng-template>\n\n <ng-template #infoTooltipDown>\n <div class=\"m-tooltip\" role=\"tooltip\" id=\"infoTooltipDown_widgetMap\" aria-hidden=\"true\">\n <span class=\"m-tooltip__text\">{{ '@pry.widget.map.export' | i18n }}</span>\n </div>\n </ng-template>\n\n <div #popup class=\"m-tooltip m-tooltip--popup\" [hidden]=\"true\" role=\"tooltip\">\n <div class=\"m-tooltip--popup__header\">\n <p>{{ this.tooltipIndex + 1 }} / {{ this.tooltipNumber }}</p>\n <button class=\"a-btn a-btn--primary a-btn--icon-only\" (click)=\"tooltipMove(-1)\" [disabled]=\"!tooltipCanMove(-1)\">\n <pry-icon iconSvg=\"arrow_back\"></pry-icon>\n </button>\n <button class=\"a-btn a-btn--primary a-btn--icon-only\" (click)=\"tooltipMove(1)\" [disabled]=\"!tooltipCanMove(1)\">\n <pry-icon iconSvg=\"arrow_right\"></pry-icon>\n </button>\n </div>\n <div class=\"m-tooltip--popup__container\">\n <ng-container #popupContent></ng-container>\n </div>\n </div>\n <div\n #address\n class=\"m-tooltip m-tooltip--address tooltip-address\"\n [style.display]=\"'none'\"\n (click)=\"hideAddress()\"\n ></div>\n</div>\n", dependencies: [{ kind: "directive", type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i7.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i7.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i7.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i2.SettingsComponent, selector: "pry-settings", inputs: ["widgetIndex", "isDisable", "headerPresent", "open$", "header"], outputs: ["saveTriggered", "changeTitle"] }, { kind: "component", type: i2.PryWidgetHeaderComponent, selector: "pry-widget-header", inputs: ["manifest", "additionalOptions", "headerOptions", "displayCount", "datasourceIds", "widgetIndex"], outputs: ["manifestModified"] }, { kind: "component", type: i2.PrySelectComponent, selector: "pry-select", inputs: ["labelTranslate", "baseTranslate", "translationFn", "translationFnArgs", "clearable", "multiple", "multipleClearRight", "closeOnSelect", "placeholder", "isForm", "required", "name", "readonly", "items", "itemsAsOption", "bindData", "bindValue", "bindLabel", "bindIcon", "iconSize", "templateLabel", "templateOption", "autocomplete"] }, { kind: "component", type: i2.PryIconComponent, selector: "pry-icon", inputs: ["color", "iconSvg", "animation", "iconImage", "alt", "width", "height", "classes"] }, { kind: "component", type: i8.PryCheckboxComponent, selector: "pry-checkbox", inputs: ["circle"] }, { kind: "directive", type: i2.PryTooltipDirective, selector: "[pryTooltip]", inputs: ["pryTooltip", "styleReversed", "pryTooltipContext", "pryTooltipPosition", "pryTooltipShowDelay"] }, { kind: "component", type: i2.PryRangeComponent, selector: "pry-range", inputs: ["min", "max", "step", "disabled", "labelTranslate"] }, { kind: "component", type: PryWidgetMapCssComponent, selector: "pry-widget-map-css" }, { kind: "pipe", type: i6.AsyncPipe, name: "async" }, { kind: "pipe", type: i2.I18nPipe, name: "i18n" }, { kind: "pipe", type: GeometryFieldsForPipe, name: "geometryFieldsFor" }, { kind: "pipe", type: WidgetMapLegendUrlPipe, name: "legendUrl" }] }); }
|
|
1829
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.6", type: WidgetMapComponent, selector: "pry-widget-map", viewQueries: [{ propertyName: "mapRef", first: true, predicate: ["mapRef"], descendants: true }, { propertyName: "popup", first: true, predicate: ["popup"], descendants: true }, { propertyName: "popupContent", first: true, predicate: ["popupContent"], descendants: true, read: ViewContainerRef }, { propertyName: "exportTypeTemplate", first: true, predicate: ["exportTypeTemplate"], descendants: true, read: TemplateRef }, { propertyName: "address", first: true, predicate: ["address"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<pry-widget-map-css></pry-widget-map-css>\n<div class=\"o-widget o-widget--map\">\n <pry-widget-header\n [datasourceIds]=\"(datasourceIds$ | async) ?? []\"\n *ngIf=\"displayHeader$ | async\"\n [widgetIndex]=\"widgetIndex\"\n [manifest]=\"manifest\"\n (manifestModified)=\"manifestModified.emit($event)\"\n [headerOptions]=\"(displayHeader$ | async) ?? {}\"\n #header\n >\n <pry-settings\n (saveTriggered)=\"emitManifest()\"\n (changeTitle)=\"changeWidgetTitle($event)\"\n [headerPresent]=\"displayHeader$ | async\"\n [widgetIndex]=\"widgetIndex\"\n [header]=\"header\"\n [open$]=\"open$\"\n class=\"o-settings\"\n >\n <div class=\"m-form-label-field\">\n <label class=\"a-label\" for=\"map_style\">{{ '@pry.widget.map.style' | i18n }}</label>\n <pry-select\n (ngModelChange)=\"changeStyle($event)\"\n [itemsAsOption]=\"true\"\n [items]=\"styles$ | async\"\n [ngModel]=\"optionsCopy.style\"\n bindLabel=\"label\"\n bindValue=\"identifier\"\n id=\"map_style\"\n class=\"a-pry-select\"\n ></pry-select>\n </div>\n\n <div class=\"m-form-label-field\" *ngIf=\"optionsCopy.style === STYLE_FROM_URL\">\n <label class=\"a-label\" for=\"style_URL\">{{ '@pry.widget.map.styleUrl' | i18n }}</label>\n <input\n id=\"style_URL\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeStyleURL($event)\"\n [value]=\"optionsCopy.styleURL ?? ''\"\n />\n </div>\n\n <pry-checkbox (ngModelChange)=\"changeSingleLayer($event)\" [ngModel]=\"optionsCopy.singleLayer ?? false\">\n {{ '@pry.widget.map.singleLayer' | i18n }}\n </pry-checkbox>\n\n <pry-checkbox (ngModelChange)=\"changeAutoLayer($event)\" [ngModel]=\"optionsCopy.automaticLayers ?? false\">\n {{ '@pry.widget.map.autoLayer' | i18n }}\n </pry-checkbox>\n\n <pry-checkbox (ngModelChange)=\"changeFit($event)\" [ngModel]=\"optionsCopy.fit ?? false\">\n {{ '@pry.widget.map.fit' | i18n }}\n </pry-checkbox>\n\n <pry-checkbox (ngModelChange)=\"changeAttributions($event)\" [ngModel]=\"optionsCopy.attributions ?? false\">\n {{ '@pry.widget.map.attributions' | i18n }}\n </pry-checkbox>\n\n <div class=\"o-settings__popup__content__actions -has-separator\">\n <button type=\"button\" (click)=\"addLayer()\" class=\"a-btn a-btn--icon-text -link-like\">\n <pry-icon iconSvg=\"library_add\"></pry-icon>\n {{ '@pry.widget.map.addLayer' | i18n }}\n </button>\n </div>\n\n <div *ngFor=\"let layer of optionsCopy?.layers; let i = index\" class=\"o-settings__popup__content__fields\">\n <div class=\"o-settings__popup__content__fields__head\">\n <h3 class=\"a-h3 settings-layer-title__title\">{{ '@pry.widget.map.layer' | i18n : { index: i + 1 } }}</h3>\n <div class=\"m-btn-group\">\n <button type=\"button\" class=\"a-btn a-btn--icon-only\" (click)=\"invertLayers(i, i - 1)\" *ngIf=\"i > 0\">\n <pry-icon iconSvg=\"fleche_haut\"></pry-icon>\n <span class=\"u-visually-hidden\">{{ '@pry.action.moveUp' | i18n }}</span>\n </button>\n <button\n type=\"button\"\n class=\"a-btn a-btn--icon-only\"\n (click)=\"invertLayers(i, i + 1)\"\n *ngIf=\"i < (optionsCopy?.layers?.length ?? 0) - 1\"\n >\n <pry-icon iconSvg=\"fleche_bas\"></pry-icon>\n <span class=\"u-visually-hidden\">{{ '@pry.action.moveDown' | i18n }}</span>\n </button>\n </div>\n </div>\n\n <div class=\"o-settings__popup__content__fields__content\">\n <pry-range\n [ngModel]=\"(layer?.opacity ?? 100) + ''\"\n (ngModelChange)=\"changeOpacity(layer, $event)\"\n labelTranslate=\"@pry.widget.map.opacity\"\n min=\"0\"\n max=\"100\"\n ></pry-range>\n\n <fieldset>\n <legend class=\"u-visually-hidden\">{{ '@pry.widget.map.layerOptions' | i18n : { index: i + 1 } }}</legend>\n <div class=\"m-form-label-field\">\n <label class=\"a-label\" for=\"map_layerTitle\">{{ '@pry.widget.map.layerTitle' | i18n }}</label>\n <input\n id=\"map_layerTitle\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeTitle($event, layer)\"\n [value]=\"layer.title ?? ''\"\n />\n </div>\n\n <div class=\"m-form-label-field\" *ngIf=\"!['geoserver', 'auto'].includes(layer.type)\">\n <label class=\"a-label\" for=\"map_layerType\">{{ '@pry.widget.map.layerType.title' | i18n }}</label>\n <pry-select\n (ngModelChange)=\"changeLayerType($event, i)\"\n [bindData]=\"true\"\n [itemsAsOption]=\"true\"\n [items]=\"layerTypes\"\n [labelTranslate]=\"true\"\n [ngModel]=\"layer.type\"\n baseTranslate=\"@pry.widget.map.layerType.\"\n class=\"a-pry-select\"\n id=\"map_layerType\"\n ></pry-select>\n </div>\n\n <div\n *ngIf=\"\n layer.type !== 'relation' &&\n layer.type !== 'wms' &&\n layer.type !== 'wmts' &&\n layer.type !== 'geoserver' &&\n layer.type !== 'featurelayer' &&\n layer.type !== 'vectortile' &&\n layer.type !== 'rastertile' &&\n layer.type !== 'auto'\n \"\n class=\"m-form-label-field\"\n >\n <label class=\"a-label\" for=\"map_classes\">{{ '@pry.widget.map.classes' | i18n }}</label>\n <pry-select\n (ngModelChange)=\"changeClasses($event, layer)\"\n [itemsAsOption]=\"true\"\n [items]=\"classes$ | async\"\n [multiple]=\"true\"\n [ngModel]=\"layer.classes\"\n bindLabel=\"name\"\n bindValue=\"id\"\n class=\"a-pry-select\"\n id=\"map_classes\"\n ></pry-select>\n </div>\n </fieldset>\n </div>\n\n <fieldset\n *ngIf=\"\n layer.type !== 'relation' &&\n layer.type !== 'wms' &&\n layer.type !== 'wmts' &&\n layer.type !== 'geoserver' &&\n layer.type !== 'featurelayer' &&\n layer.type !== 'vectortile' &&\n layer.type !== 'rastertile'\n \"\n >\n <legend class=\"u-visually-hidden\">{{ '@pry.widget.map.locationAttr' | i18n }}</legend>\n <ng-container\n *ngIf=\"\n layer\n | geometryFieldsFor : { resultSet: resultSet$, classes: layer.classes, type: layer.type }\n | async as fields\n \"\n >\n <div\n *ngIf=\"\n ['heatmap', 'bubble', 'marker', 'point', 'line', 'polygon', 'multi-line', 'multi-polygon'].indexOf(\n layer.type\n ) >= 0\n \"\n >\n <div class=\"m-form-label-field\">\n <label class=\"a-label\" for=\"map_locationAttribute_both\">{{\n '@pry.widget.map.locationAttribute.both' | i18n\n }}</label>\n <pry-select\n (ngModelChange)=\"changeLocationAttributes($event, layer)\"\n [itemsAsOption]=\"true\"\n [items]=\"fields\"\n [ngModel]=\"layer.attribute\"\n bindLabel=\"name\"\n bindValue=\"name\"\n id=\"map_locationAttribute_both\"\n class=\"a-pry-select\"\n ></pry-select>\n </div>\n </div>\n\n <div *ngIf=\"['heatmap', 'bubble'].indexOf(layer.type) >= 0\">\n <div class=\"m-form-label-field\">\n <label class=\"a-label\" for=\"map_intensityAttribute\">{{\n '@pry.widget.map.intensityAttribute' | i18n\n }}</label>\n <pry-select\n (ngModelChange)=\"changeIntensityAttributes($event, layer)\"\n [itemsAsOption]=\"true\"\n [items]=\"fields\"\n [ngModel]=\"layerHasIntensity(layer).intensityAttribute\"\n bindLabel=\"name\"\n bindValue=\"name\"\n id=\"map_intensityAttribute\"\n class=\"a-pry-select\"\n ></pry-select>\n </div>\n </div>\n </ng-container>\n </fieldset>\n\n <fieldset\n *ngIf=\"\n layer.type === 'wms' ||\n layer.type === 'wmts' ||\n layer.type === 'featurelayer' ||\n layer.type === 'vectortile' ||\n layer.type === 'rastertile'\n \"\n >\n <legend class=\"u-visually-hidden\">{{ '@pry.widget.map.tile' | i18n }}</legend>\n <div class=\"m-form-label-field\">\n <label class=\"a-label\" for=\"map_wms_url\">{{ '@pry.widget.map.wms.url' | i18n }}</label>\n <input\n id=\"map_wms_url\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeUrl($event, layer)\"\n [value]=\"layer.url\"\n />\n </div>\n\n <div class=\"m-form-label-field\" *ngIf=\"layer.type === 'wms' || layer.type === 'wmts'\">\n <label class=\"a-label\" for=\"map_wms_paramLayer\">{{ '@pry.widget.map.wms.paramLayer' | i18n }}</label>\n <input\n id=\"map_wms_paramLayer\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeParamLayer($event, layer)\"\n [value]=\"layer.paramLayer\"\n />\n </div>\n\n <div class=\"m-form-label-field\" *ngIf=\"layer.type === 'wmts'\">\n <label class=\"a-label\" for=\"map_wms_matrixSet\">{{ '@pry.widget.map.wms.matrixSet' | i18n }}</label>\n <input\n id=\"map_wms_matrixSet\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeMatrixSet($event, layer)\"\n [value]=\"layer.matrixSet\"\n />\n </div>\n\n <div class=\"m-form-label-field\" *ngIf=\"layer.type === 'wmts'\">\n <label class=\"a-label\" for=\"map_wms_style\">{{ '@pry.widget.map.wms.style' | i18n }}</label>\n <input\n id=\"map_wms_style\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeParamStyle($event, layer)\"\n [value]=\"layer.style\"\n />\n </div>\n\n <div class=\"m-form-label-field\" *ngIf=\"layer.type === 'wms'\">\n <pry-checkbox (ngModelChange)=\"changeParamTiled($event, layer)\" [ngModel]=\"layer?.paramTiled ?? false\">\n {{ '@pry.widget.map.wms.paramTiled' | i18n }}\n </pry-checkbox>\n </div>\n </fieldset>\n\n <fieldset *ngIf=\"layer.type === 'marker'\">\n <legend class=\"u-visually-hidden\">{{ '@pry.widget.map.clustering' | i18n }}</legend>\n <div class=\"m-form-label-field\">\n <pry-checkbox (ngModelChange)=\"changeClustered(layer, $event)\" [ngModel]=\"layer.clustered\">\n {{ '@pry.widget.map.clustered' | i18n }}\n </pry-checkbox>\n </div>\n <div *ngIf=\"layer.clustered\">\n <pry-range\n [ngModel]=\"layer.clustered\"\n (ngModelChange)=\"changeClusterDistance(layer, $event)\"\n labelTranslate=\"@pry.widget.map.clusterDistance\"\n min=\"1\"\n max=\"500\"\n ></pry-range>\n </div>\n </fieldset>\n\n <div class=\"m-form-label-field\" *ngIf=\"optionsCopy.attributions\">\n <label class=\"a-label\" for=\"attribution\">{{ '@pry.widget.map.attribution' | i18n }}</label>\n <input\n id=\"attribution\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeAttribution($event, layer)\"\n [value]=\"layer.attribution ? layer.attribution : ''\"\n />\n </div>\n\n <button\n type=\"button\"\n (click)=\"deleteLayer(i, layer)\"\n class=\"a-btn a-btn--icon-text -link-like\"\n *ngIf=\"layer.type !== 'geoserver'\"\n data-func=\"delete\"\n >\n <pry-icon iconSvg=\"delete\" [width]=\"19\" [height]=\"19\"></pry-icon>\n <span>{{ '@pry.widget.map.deleteLayer' | i18n }}</span>\n </button>\n </div>\n </pry-settings>\n </pry-widget-header>\n\n <div class=\"m-btn-group -selection-choice\" [style.transform]=\"bottomLeft$ | async\">\n <ng-container *ngFor=\"let action of basicActions$ | async\">\n <button\n type=\"button\"\n class=\"a-btn a-btn--icon-only\"\n (click)=\"interactionManager.selectionInteraction.changeSelection(action)\"\n [class.-selected]=\"interactionManager.selectionInteraction.selectionType === action\"\n [pryTooltip]=\"infoTooltipAction\"\n pryTooltipPosition=\"bottom\"\n aria-describedby=\"infoTooltipAction\"\n [pryTooltipContext]=\"{ action: action }\"\n >\n <pry-icon [iconSvg]=\"action\"></pry-icon>\n <span class=\"u-visually-hidden\">{{ '@pry.widget.map.' + action | i18n }}</span>\n </button>\n </ng-container>\n\n <button\n type=\"button\"\n class=\"a-btn a-btn--icon-only\"\n id=\"export_card\"\n aria-expanded=\"false\"\n aria-controls=\"export_type\"\n aria-haspopup=\"menu\"\n [pryTooltip]=\"infoTooltipDown\"\n pryTooltipPosition=\"bottom\"\n aria-describedby=\"infoTooltipDown_widgetMap\"\n *ngIf=\"(actions$ | async)?.includes('export')\"\n >\n <pry-icon iconSvg=\"file_download\" (click)=\"export()\"></pry-icon>\n <span class=\"u-visually-hidden\">{{ '@pry.widget.map.export' | i18n }}</span>\n </button>\n </div>\n\n <div\n class=\"ol-control m-layer-switcher\"\n *ngIf=\"((layers$ | async)?.length ?? 0) > 0\"\n [style.top.px]=\"layersTop$ | async\"\n >\n <button\n class=\"m-layer-switcher__toggle\"\n (click)=\"toggleLayersWindow()\"\n [title]=\"'@pry.widget.map.selectLayers' | i18n\"\n >\n <pry-icon iconSvg=\"layers\" [width]=\"22\" [height]=\"22\"></pry-icon>\n </button>\n <ng-container *ngFor=\"let layer of mapLayers; let index = index\">\n <div class=\"m-layer-switcher__title\" [class.-hidden]=\"!layersTabOpen\">\n {{ layer.get('title') }}\n <ng-container *ngIf=\"!(options$ | async)?.singleLayer; else singleLayer\">\n <pry-checkbox [ngModel]=\"layer.getVisible()\" (change)=\"changeVisibility(layer)\"></pry-checkbox>\n </ng-container>\n <ng-template #singleLayer>\n <input\n type=\"radio\"\n name=\"layer\"\n [id]=\"'radio-layer-' + layer.get('title').split(' ')[0]\"\n [ngModel]=\"layerVisibleIdx\"\n [value]=\"index\"\n (change)=\"changeVisibility(layer)\"\n />\n </ng-template>\n </div>\n </ng-container>\n </div>\n\n <div\n class=\"ol-control m-layer-legend\"\n *ngIf=\"((legendLayers$ | async)?.length ?? 0) > 0\"\n [style.top.px]=\"legendTop$ | async\"\n >\n <button class=\"m-layer-legend__toggle\" (click)=\"toggleLegendWindow()\" [title]=\"'@pry.widget.map.legends' | i18n\">\n <pry-icon iconSvg=\"legend\" [width]=\"22\" [height]=\"22\"></pry-icon>\n </button>\n <ng-container *ngFor=\"let geoLayer of legendLayers$ | async; let index = index\">\n <div class=\"m-layer-legend__title\" [class.-hidden]=\"!legendTabOpen\">\n {{ geoLayer.title }}\n <ng-container *ngIf=\"isLayerRendered(geoLayer)\">\n <button class=\"m-layer-legend__toggle\" (click)=\"toggleLegend(index)\">\n <pry-icon\n [iconSvg]=\"legendTab === index ? 'chevron_top' : 'chevron_bottom'\"\n [width]=\"22\"\n [height]=\"22\"\n ></pry-icon>\n </button>\n </ng-container>\n <ng-container *ngIf=\"!isLayerRendered(geoLayer)\">\n <pry-icon [iconSvg]=\"'close'\" [width]=\"22\" [height]=\"22\"></pry-icon>\n </ng-container>\n </div>\n <div\n class=\"m-layer-legend__image\"\n [class.-hidden]=\"!legendTabOpen || legendTab !== index || !isLayerRendered(geoLayer)\"\n [style.max-height.px]=\"legendHeight$ | async\"\n >\n <ng-container *ngIf=\"geoLayer | legendUrl : { capabilities: (wmsCapabilities$ | async) } as url\">\n <img\n [src]=\"url\"\n [alt]=\"'@pry.widget.map.legend' | i18n : { layer: geoLayer.title }\"\n (error)=\"imageNotProvided[index] = true\"\n />\n </ng-container>\n <ng-container *ngIf=\"!(geoLayer | legendUrl : { capabilities: (wmsCapabilities$ | async) })\">\n <p class=\"m-layer-legend__error\">{{ '@pry.widget.map.legendNotProvided' | i18n }}</p>\n </ng-container>\n </div>\n </ng-container>\n </div>\n\n <div [style.height.px]=\"height$ | async\" class=\"o-map-wrapper\">\n <div class=\"o-map\">\n <div #mapRef id=\"map\"></div>\n </div>\n </div>\n\n <ng-template #infoTooltipAction let-action=\"action\">\n <div class=\"m-tooltip\" role=\"tooltip\" id=\"infoTooltipAction\" aria-hidden=\"true\">\n <span class=\"m-tooltip__text\">{{ '@pry.widget.map.' + action | i18n }}</span>\n </div>\n </ng-template>\n\n <ng-template #infoTooltipDown>\n <div class=\"m-tooltip\" role=\"tooltip\" id=\"infoTooltipDown_widgetMap\" aria-hidden=\"true\">\n <span class=\"m-tooltip__text\">{{ '@pry.widget.map.export' | i18n }}</span>\n </div>\n </ng-template>\n\n <div #popup class=\"m-tooltip m-tooltip--popup\" [hidden]=\"true\" role=\"tooltip\">\n <div class=\"m-tooltip--popup__header\">\n <p>{{ this.tooltipIndex + 1 }} / {{ this.tooltipNumber }}</p>\n <button class=\"a-btn a-btn--primary a-btn--icon-only\" (click)=\"tooltipMove(-1)\" [disabled]=\"!tooltipCanMove(-1)\">\n <pry-icon iconSvg=\"arrow_back\"></pry-icon>\n </button>\n <button class=\"a-btn a-btn--primary a-btn--icon-only\" (click)=\"tooltipMove(1)\" [disabled]=\"!tooltipCanMove(1)\">\n <pry-icon iconSvg=\"arrow_right\"></pry-icon>\n </button>\n </div>\n <div class=\"m-tooltip--popup__container\">\n <ng-container #popupContent></ng-container>\n </div>\n </div>\n <div\n #address\n class=\"m-tooltip m-tooltip--address tooltip-address\"\n [style.display]=\"'none'\"\n (click)=\"hideAddress()\"\n ></div>\n</div>\n", dependencies: [{ kind: "directive", type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i7.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i7.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i7.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i2.SettingsComponent, selector: "pry-settings", inputs: ["widgetIndex", "isDisable", "headerPresent", "open$", "header"], outputs: ["saveTriggered", "changeTitle"] }, { kind: "component", type: i2.PryWidgetHeaderComponent, selector: "pry-widget-header", inputs: ["manifest", "additionalOptions", "headerOptions", "displayCount", "datasourceIds", "widgetIndex"], outputs: ["manifestModified"] }, { kind: "component", type: i2.PrySelectComponent, selector: "pry-select", inputs: ["labelTranslate", "baseTranslate", "translationFn", "translationFnArgs", "clearable", "multiple", "multipleClearRight", "closeOnSelect", "placeholder", "isForm", "required", "name", "readonly", "items", "itemsAsOption", "bindData", "bindValue", "bindLabel", "bindIcon", "iconSize", "templateLabel", "templateOption", "autocomplete"] }, { kind: "component", type: i2.PryIconComponent, selector: "pry-icon", inputs: ["color", "iconSvg", "animation", "iconImage", "alt", "width", "height", "classes"] }, { kind: "component", type: i8.PryCheckboxComponent, selector: "pry-checkbox", inputs: ["circle"] }, { kind: "directive", type: i2.PryTooltipDirective, selector: "[pryTooltip]", inputs: ["pryTooltip", "styleReversed", "pryTooltipContext", "pryTooltipPosition", "pryTooltipShowDelay"] }, { kind: "component", type: i2.PryRangeComponent, selector: "pry-range", inputs: ["min", "max", "step", "disabled", "labelTranslate"] }, { kind: "component", type: PryWidgetMapCssComponent, selector: "pry-widget-map-css" }, { kind: "pipe", type: i6.AsyncPipe, name: "async" }, { kind: "pipe", type: i2.I18nPipe, name: "i18n" }, { kind: "pipe", type: GeometryFieldsForPipe, name: "geometryFieldsFor" }, { kind: "pipe", type: WidgetMapLegendUrlPipe, name: "legendUrl" }] }); }
|
|
1736
1830
|
}
|
|
1737
1831
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.6", ngImport: i0, type: WidgetMapComponent, decorators: [{
|
|
1738
1832
|
type: Component,
|
|
1739
|
-
args: [{ selector: 'pry-widget-map', template: "<pry-widget-map-css></pry-widget-map-css>\n<div class=\"o-widget o-widget--map\">\n <pry-widget-header\n [datasourceIds]=\"(datasourceIds$ | async) ?? []\"\n *ngIf=\"displayHeader$ | async\"\n [widgetIndex]=\"widgetIndex\"\n [manifest]=\"manifest\"\n (manifestModified)=\"manifestModified.emit($event)\"\n [headerOptions]=\"(displayHeader$ | async) ?? {}\"\n #header\n >\n <pry-settings\n (saveTriggered)=\"emitManifest()\"\n (changeTitle)=\"changeWidgetTitle($event)\"\n [headerPresent]=\"displayHeader$ | async\"\n [widgetIndex]=\"widgetIndex\"\n [header]=\"header\"\n [open$]=\"open$\"\n class=\"o-settings\"\n >\n <div class=\"m-form-label-field\">\n <label class=\"a-label\" for=\"map_style\">{{ '@pry.widget.map.style' | i18n }}</label>\n <pry-select\n (ngModelChange)=\"changeStyle($event)\"\n [itemsAsOption]=\"true\"\n [items]=\"styles$ | async\"\n [ngModel]=\"optionsCopy.style\"\n bindLabel=\"label\"\n bindValue=\"identifier\"\n id=\"map_style\"\n class=\"a-pry-select\"\n ></pry-select>\n </div>\n\n <div class=\"m-form-label-field\" *ngIf=\"optionsCopy.style === STYLE_FROM_URL\">\n <label class=\"a-label\" for=\"style_URL\">{{ '@pry.widget.map.styleUrl' | i18n }}</label>\n <input\n id=\"style_URL\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeStyleURL($event)\"\n [value]=\"optionsCopy.styleURL ?? ''\"\n />\n </div>\n\n <pry-checkbox (ngModelChange)=\"changeSingleLayer($event)\" [ngModel]=\"optionsCopy.singleLayer ?? false\">\n {{ '@pry.widget.map.singleLayer' | i18n }}\n </pry-checkbox>\n\n <pry-checkbox (ngModelChange)=\"changeFit($event)\" [ngModel]=\"optionsCopy.fit ?? false\">\n {{ '@pry.widget.map.fit' | i18n }}\n </pry-checkbox>\n\n <pry-checkbox (ngModelChange)=\"changeAttributions($event)\" [ngModel]=\"optionsCopy.attributions ?? false\">\n {{ '@pry.widget.map.attributions' | i18n }}\n </pry-checkbox>\n\n <div class=\"o-settings__popup__content__actions -has-separator\">\n <button type=\"button\" (click)=\"addLayer()\" class=\"a-btn a-btn--icon-text -link-like\">\n <pry-icon iconSvg=\"library_add\"></pry-icon>\n {{ '@pry.widget.map.addLayer' | i18n }}\n </button>\n </div>\n\n <div *ngFor=\"let layer of optionsCopy?.layers; let i = index\" class=\"o-settings__popup__content__fields\">\n <div class=\"o-settings__popup__content__fields__head\">\n <h3 class=\"a-h3 settings-layer-title__title\">{{ '@pry.widget.map.layer' | i18n : { index: i + 1 } }}</h3>\n <div class=\"m-btn-group\">\n <button type=\"button\" class=\"a-btn a-btn--icon-only\" (click)=\"invertLayers(i, i - 1)\" *ngIf=\"i > 0\">\n <pry-icon iconSvg=\"fleche_haut\"></pry-icon>\n <span class=\"u-visually-hidden\">{{ '@pry.action.moveUp' | i18n }}</span>\n </button>\n <button\n type=\"button\"\n class=\"a-btn a-btn--icon-only\"\n (click)=\"invertLayers(i, i + 1)\"\n *ngIf=\"i < (optionsCopy?.layers?.length ?? 0) - 1\"\n >\n <pry-icon iconSvg=\"fleche_bas\"></pry-icon>\n <span class=\"u-visually-hidden\">{{ '@pry.action.moveDown' | i18n }}</span>\n </button>\n </div>\n </div>\n\n <div class=\"o-settings__popup__content__fields__content\">\n <pry-range\n [ngModel]=\"(layer?.opacity ?? 100) + ''\"\n (ngModelChange)=\"changeOpacity(layer, $event)\"\n labelTranslate=\"@pry.widget.map.opacity\"\n min=\"0\"\n max=\"100\"\n ></pry-range>\n\n <fieldset>\n <legend class=\"u-visually-hidden\">{{ '@pry.widget.map.layerOptions' | i18n : { index: i + 1 } }}</legend>\n <div class=\"m-form-label-field\">\n <label class=\"a-label\" for=\"map_layerTitle\">{{ '@pry.widget.map.layerTitle' | i18n }}</label>\n <input\n id=\"map_layerTitle\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeTitle($event, layer)\"\n [value]=\"layer.title ?? ''\"\n />\n </div>\n\n <div class=\"m-form-label-field\" *ngIf=\"layer.type !== 'geoserver'\">\n <label class=\"a-label\" for=\"map_layerType\">{{ '@pry.widget.map.layerType.title' | i18n }}</label>\n <pry-select\n (ngModelChange)=\"changeLayerType($event, i)\"\n [bindData]=\"true\"\n [itemsAsOption]=\"true\"\n [items]=\"layerTypes\"\n [labelTranslate]=\"true\"\n [ngModel]=\"layer.type\"\n baseTranslate=\"@pry.widget.map.layerType.\"\n class=\"a-pry-select\"\n id=\"map_layerType\"\n ></pry-select>\n </div>\n\n <div\n *ngIf=\"\n layer.type !== 'relation' &&\n layer.type !== 'wms' &&\n layer.type !== 'wmts' &&\n layer.type !== 'geoserver' &&\n layer.type !== 'featurelayer' &&\n layer.type !== 'vectortile' &&\n layer.type !== 'rastertile'\n \"\n class=\"m-form-label-field\"\n >\n <label class=\"a-label\" for=\"map_classes\">{{ '@pry.widget.map.classes' | i18n }}</label>\n <pry-select\n (ngModelChange)=\"changeClasses($event, layer)\"\n [itemsAsOption]=\"true\"\n [items]=\"classes$ | async\"\n [multiple]=\"true\"\n [ngModel]=\"layer.classes\"\n bindLabel=\"name\"\n bindValue=\"id\"\n class=\"a-pry-select\"\n id=\"map_classes\"\n ></pry-select>\n </div>\n </fieldset>\n </div>\n\n <fieldset\n *ngIf=\"\n layer.type !== 'relation' &&\n layer.type !== 'wms' &&\n layer.type !== 'wmts' &&\n layer.type !== 'geoserver' &&\n layer.type !== 'featurelayer' &&\n layer.type !== 'vectortile' &&\n layer.type !== 'rastertile'\n \"\n >\n <legend class=\"u-visually-hidden\">{{ '@pry.widget.map.locationAttr' | i18n }}</legend>\n <ng-container\n *ngIf=\"\n layer\n | geometryFieldsFor : { resultSet: resultSet$, classes: layer.classes, type: layer.type }\n | async as fields\n \"\n >\n <div\n *ngIf=\"\n ['heatmap', 'bubble', 'marker', 'point', 'line', 'polygon', 'multi-line', 'multi-polygon'].indexOf(\n layer.type\n ) >= 0\n \"\n >\n <div class=\"m-form-label-field\">\n <label class=\"a-label\" for=\"map_locationAttribute_both\">{{\n '@pry.widget.map.locationAttribute.both' | i18n\n }}</label>\n <pry-select\n (ngModelChange)=\"changeLocationAttributes($event, layer)\"\n [itemsAsOption]=\"true\"\n [items]=\"fields\"\n [ngModel]=\"layer.attribute\"\n bindLabel=\"name\"\n bindValue=\"name\"\n id=\"map_locationAttribute_both\"\n class=\"a-pry-select\"\n ></pry-select>\n </div>\n </div>\n\n <div *ngIf=\"['heatmap', 'bubble'].indexOf(layer.type) >= 0\">\n <div class=\"m-form-label-field\">\n <label class=\"a-label\" for=\"map_intensityAttribute\">{{\n '@pry.widget.map.intensityAttribute' | i18n\n }}</label>\n <pry-select\n (ngModelChange)=\"changeIntensityAttributes($event, layer)\"\n [itemsAsOption]=\"true\"\n [items]=\"fields\"\n [ngModel]=\"layerHasIntensity(layer).intensityAttribute\"\n bindLabel=\"name\"\n bindValue=\"name\"\n id=\"map_intensityAttribute\"\n class=\"a-pry-select\"\n ></pry-select>\n </div>\n </div>\n </ng-container>\n </fieldset>\n\n <fieldset\n *ngIf=\"\n layer.type === 'wms' ||\n layer.type === 'wmts' ||\n layer.type === 'featurelayer' ||\n layer.type === 'vectortile' ||\n layer.type === 'rastertile'\n \"\n >\n <legend class=\"u-visually-hidden\">{{ '@pry.widget.map.tile' | i18n }}</legend>\n <div class=\"m-form-label-field\">\n <label class=\"a-label\" for=\"map_wms_url\">{{ '@pry.widget.map.wms.url' | i18n }}</label>\n <input\n id=\"map_wms_url\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeUrl($event, layer)\"\n [value]=\"layer.url\"\n />\n </div>\n\n <div class=\"m-form-label-field\" *ngIf=\"layer.type === 'wms' || layer.type === 'wmts'\">\n <label class=\"a-label\" for=\"map_wms_paramLayer\">{{ '@pry.widget.map.wms.paramLayer' | i18n }}</label>\n <input\n id=\"map_wms_paramLayer\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeParamLayer($event, layer)\"\n [value]=\"layer.paramLayer\"\n />\n </div>\n\n <div class=\"m-form-label-field\" *ngIf=\"layer.type === 'wmts'\">\n <label class=\"a-label\" for=\"map_wms_matrixSet\">{{ '@pry.widget.map.wms.matrixSet' | i18n }}</label>\n <input\n id=\"map_wms_matrixSet\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeMatrixSet($event, layer)\"\n [value]=\"layer.matrixSet\"\n />\n </div>\n\n <div class=\"m-form-label-field\" *ngIf=\"layer.type === 'wmts'\">\n <label class=\"a-label\" for=\"map_wms_style\">{{ '@pry.widget.map.wms.style' | i18n }}</label>\n <input\n id=\"map_wms_style\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeParamStyle($event, layer)\"\n [value]=\"layer.style\"\n />\n </div>\n\n <div class=\"m-form-label-field\" *ngIf=\"layer.type === 'wms'\">\n <pry-checkbox (ngModelChange)=\"changeParamTiled($event, layer)\" [ngModel]=\"layer?.paramTiled ?? false\">\n {{ '@pry.widget.map.wms.paramTiled' | i18n }}\n </pry-checkbox>\n </div>\n </fieldset>\n\n <fieldset *ngIf=\"layer.type === 'marker'\">\n <legend class=\"u-visually-hidden\">{{ '@pry.widget.map.clustering' | i18n }}</legend>\n <div class=\"m-form-label-field\">\n <pry-checkbox (ngModelChange)=\"changeClustered(layer, $event)\" [ngModel]=\"layer.clustered\">\n {{ '@pry.widget.map.clustered' | i18n }}\n </pry-checkbox>\n </div>\n <div *ngIf=\"layer.clustered\">\n <pry-range\n [ngModel]=\"layer.clustered\"\n (ngModelChange)=\"changeClusterDistance(layer, $event)\"\n labelTranslate=\"@pry.widget.map.clusterDistance\"\n min=\"1\"\n max=\"500\"\n ></pry-range>\n </div>\n </fieldset>\n\n <div class=\"m-form-label-field\" *ngIf=\"optionsCopy.attributions\">\n <label class=\"a-label\" for=\"attribution\">{{ '@pry.widget.map.attribution' | i18n }}</label>\n <input\n id=\"attribution\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeAttribution($event, layer)\"\n [value]=\"layer.attribution ? layer.attribution : ''\"\n />\n </div>\n\n <button\n type=\"button\"\n (click)=\"deleteLayer(i)\"\n class=\"a-btn a-btn--icon-text -link-like\"\n *ngIf=\"layer.type !== 'geoserver'\"\n data-func=\"delete\"\n >\n <pry-icon iconSvg=\"delete\" [width]=\"19\" [height]=\"19\"></pry-icon>\n <span>{{ '@pry.widget.map.deleteLayer' | i18n }}</span>\n </button>\n </div>\n </pry-settings>\n </pry-widget-header>\n\n <div class=\"m-btn-group -selection-choice\" [style.transform]=\"bottomLeft$ | async\">\n <ng-container *ngFor=\"let action of basicActions$ | async\">\n <button\n type=\"button\"\n class=\"a-btn a-btn--icon-only\"\n (click)=\"interactionManager.selectionInteraction.changeSelection(action)\"\n [class.-selected]=\"interactionManager.selectionInteraction.selectionType === action\"\n [pryTooltip]=\"infoTooltipAction\"\n pryTooltipPosition=\"bottom\"\n aria-describedby=\"infoTooltipAction\"\n [pryTooltipContext]=\"{ action: action }\"\n >\n <pry-icon [iconSvg]=\"action\"></pry-icon>\n <span class=\"u-visually-hidden\">{{ '@pry.widget.map.' + action | i18n }}</span>\n </button>\n </ng-container>\n\n <button\n type=\"button\"\n class=\"a-btn a-btn--icon-only\"\n id=\"export_card\"\n aria-expanded=\"false\"\n aria-controls=\"export_type\"\n aria-haspopup=\"menu\"\n [pryTooltip]=\"infoTooltipDown\"\n pryTooltipPosition=\"bottom\"\n aria-describedby=\"infoTooltipDown_widgetMap\"\n *ngIf=\"(actions$ | async)?.includes('export')\"\n >\n <pry-icon iconSvg=\"file_download\" (click)=\"export()\"></pry-icon>\n <span class=\"u-visually-hidden\">{{ '@pry.widget.map.export' | i18n }}</span>\n </button>\n </div>\n\n <div\n class=\"ol-control m-layer-switcher\"\n *ngIf=\"((layers$ | async)?.length ?? 0) > 0\"\n [style.top.px]=\"layersTop$ | async\"\n >\n <button\n class=\"m-layer-switcher__toggle\"\n (click)=\"toggleLayersWindow()\"\n [title]=\"'@pry.widget.map.selectLayers' | i18n\"\n >\n <pry-icon iconSvg=\"layers\" [width]=\"22\" [height]=\"22\"></pry-icon>\n </button>\n <ng-container *ngFor=\"let layer of mapLayers; let index = index\">\n <div class=\"m-layer-switcher__title\" [class.-hidden]=\"!layersTabOpen\">\n {{ layer.get('title') }}\n <ng-container *ngIf=\"!(options$ | async)?.singleLayer; else singleLayer\">\n <pry-checkbox [ngModel]=\"layer.getVisible()\" (change)=\"changeVisibility(layer)\"></pry-checkbox>\n </ng-container>\n <ng-template #singleLayer>\n <input\n type=\"radio\"\n name=\"layer\"\n [id]=\"'radio-layer-' + layer.get('title').split(' ')[0]\"\n [ngModel]=\"layerVisibleIdx\"\n [value]=\"index\"\n (change)=\"changeVisibility(layer)\"\n />\n </ng-template>\n </div>\n </ng-container>\n </div>\n\n <div\n class=\"ol-control m-layer-legend\"\n *ngIf=\"((legendLayers$ | async)?.length ?? 0) > 0\"\n [style.top.px]=\"legendTop$ | async\"\n >\n <button class=\"m-layer-legend__toggle\" (click)=\"toggleLegendWindow()\" [title]=\"'@pry.widget.map.legends' | i18n\">\n <pry-icon iconSvg=\"legend\" [width]=\"22\" [height]=\"22\"></pry-icon>\n </button>\n <ng-container *ngFor=\"let geoLayer of legendLayers$ | async; let index = index\">\n <div class=\"m-layer-legend__title\" [class.-hidden]=\"!legendTabOpen\">\n {{ geoLayer.title }}\n <ng-container *ngIf=\"isLayerRendered(geoLayer)\">\n <button class=\"m-layer-legend__toggle\" (click)=\"toggleLegend(index)\">\n <pry-icon\n [iconSvg]=\"legendTab === index ? 'chevron_top' : 'chevron_bottom'\"\n [width]=\"22\"\n [height]=\"22\"\n ></pry-icon>\n </button>\n </ng-container>\n <ng-container *ngIf=\"!isLayerRendered(geoLayer)\">\n <pry-icon [iconSvg]=\"'close'\" [width]=\"22\" [height]=\"22\"></pry-icon>\n </ng-container>\n </div>\n <div\n class=\"m-layer-legend__image\"\n [class.-hidden]=\"!legendTabOpen || legendTab !== index || !isLayerRendered(geoLayer)\"\n [style.max-height.px]=\"legendHeight$ | async\"\n >\n <ng-container *ngIf=\"geoLayer | legendUrl : { capabilities: (wmsCapabilities$ | async) } as url\">\n <img\n [src]=\"url\"\n [alt]=\"'@pry.widget.map.legend' | i18n : { layer: geoLayer.title }\"\n (error)=\"imageNotProvided[index] = true\"\n />\n </ng-container>\n <ng-container *ngIf=\"!(geoLayer | legendUrl : { capabilities: (wmsCapabilities$ | async) })\">\n <p class=\"m-layer-legend__error\">{{ '@pry.widget.map.legendNotProvided' | i18n }}</p>\n </ng-container>\n </div>\n </ng-container>\n </div>\n\n <div [style.height.px]=\"height$ | async\" class=\"o-map-wrapper\">\n <div class=\"o-map\">\n <div #mapRef id=\"map\"></div>\n </div>\n </div>\n\n <ng-template #infoTooltipAction let-action=\"action\">\n <div class=\"m-tooltip\" role=\"tooltip\" id=\"infoTooltipAction\" aria-hidden=\"true\">\n <span class=\"m-tooltip__text\">{{ '@pry.widget.map.' + action | i18n }}</span>\n </div>\n </ng-template>\n\n <ng-template #infoTooltipDown>\n <div class=\"m-tooltip\" role=\"tooltip\" id=\"infoTooltipDown_widgetMap\" aria-hidden=\"true\">\n <span class=\"m-tooltip__text\">{{ '@pry.widget.map.export' | i18n }}</span>\n </div>\n </ng-template>\n\n <div #popup class=\"m-tooltip m-tooltip--popup\" [hidden]=\"true\" role=\"tooltip\">\n <div class=\"m-tooltip--popup__header\">\n <p>{{ this.tooltipIndex + 1 }} / {{ this.tooltipNumber }}</p>\n <button class=\"a-btn a-btn--primary a-btn--icon-only\" (click)=\"tooltipMove(-1)\" [disabled]=\"!tooltipCanMove(-1)\">\n <pry-icon iconSvg=\"arrow_back\"></pry-icon>\n </button>\n <button class=\"a-btn a-btn--primary a-btn--icon-only\" (click)=\"tooltipMove(1)\" [disabled]=\"!tooltipCanMove(1)\">\n <pry-icon iconSvg=\"arrow_right\"></pry-icon>\n </button>\n </div>\n <div class=\"m-tooltip--popup__container\">\n <ng-container #popupContent></ng-container>\n </div>\n </div>\n <div\n #address\n class=\"m-tooltip m-tooltip--address tooltip-address\"\n [style.display]=\"'none'\"\n (click)=\"hideAddress()\"\n ></div>\n</div>\n" }]
|
|
1833
|
+
args: [{ selector: 'pry-widget-map', template: "<pry-widget-map-css></pry-widget-map-css>\n<div class=\"o-widget o-widget--map\">\n <pry-widget-header\n [datasourceIds]=\"(datasourceIds$ | async) ?? []\"\n *ngIf=\"displayHeader$ | async\"\n [widgetIndex]=\"widgetIndex\"\n [manifest]=\"manifest\"\n (manifestModified)=\"manifestModified.emit($event)\"\n [headerOptions]=\"(displayHeader$ | async) ?? {}\"\n #header\n >\n <pry-settings\n (saveTriggered)=\"emitManifest()\"\n (changeTitle)=\"changeWidgetTitle($event)\"\n [headerPresent]=\"displayHeader$ | async\"\n [widgetIndex]=\"widgetIndex\"\n [header]=\"header\"\n [open$]=\"open$\"\n class=\"o-settings\"\n >\n <div class=\"m-form-label-field\">\n <label class=\"a-label\" for=\"map_style\">{{ '@pry.widget.map.style' | i18n }}</label>\n <pry-select\n (ngModelChange)=\"changeStyle($event)\"\n [itemsAsOption]=\"true\"\n [items]=\"styles$ | async\"\n [ngModel]=\"optionsCopy.style\"\n bindLabel=\"label\"\n bindValue=\"identifier\"\n id=\"map_style\"\n class=\"a-pry-select\"\n ></pry-select>\n </div>\n\n <div class=\"m-form-label-field\" *ngIf=\"optionsCopy.style === STYLE_FROM_URL\">\n <label class=\"a-label\" for=\"style_URL\">{{ '@pry.widget.map.styleUrl' | i18n }}</label>\n <input\n id=\"style_URL\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeStyleURL($event)\"\n [value]=\"optionsCopy.styleURL ?? ''\"\n />\n </div>\n\n <pry-checkbox (ngModelChange)=\"changeSingleLayer($event)\" [ngModel]=\"optionsCopy.singleLayer ?? false\">\n {{ '@pry.widget.map.singleLayer' | i18n }}\n </pry-checkbox>\n\n <pry-checkbox (ngModelChange)=\"changeAutoLayer($event)\" [ngModel]=\"optionsCopy.automaticLayers ?? false\">\n {{ '@pry.widget.map.autoLayer' | i18n }}\n </pry-checkbox>\n\n <pry-checkbox (ngModelChange)=\"changeFit($event)\" [ngModel]=\"optionsCopy.fit ?? false\">\n {{ '@pry.widget.map.fit' | i18n }}\n </pry-checkbox>\n\n <pry-checkbox (ngModelChange)=\"changeAttributions($event)\" [ngModel]=\"optionsCopy.attributions ?? false\">\n {{ '@pry.widget.map.attributions' | i18n }}\n </pry-checkbox>\n\n <div class=\"o-settings__popup__content__actions -has-separator\">\n <button type=\"button\" (click)=\"addLayer()\" class=\"a-btn a-btn--icon-text -link-like\">\n <pry-icon iconSvg=\"library_add\"></pry-icon>\n {{ '@pry.widget.map.addLayer' | i18n }}\n </button>\n </div>\n\n <div *ngFor=\"let layer of optionsCopy?.layers; let i = index\" class=\"o-settings__popup__content__fields\">\n <div class=\"o-settings__popup__content__fields__head\">\n <h3 class=\"a-h3 settings-layer-title__title\">{{ '@pry.widget.map.layer' | i18n : { index: i + 1 } }}</h3>\n <div class=\"m-btn-group\">\n <button type=\"button\" class=\"a-btn a-btn--icon-only\" (click)=\"invertLayers(i, i - 1)\" *ngIf=\"i > 0\">\n <pry-icon iconSvg=\"fleche_haut\"></pry-icon>\n <span class=\"u-visually-hidden\">{{ '@pry.action.moveUp' | i18n }}</span>\n </button>\n <button\n type=\"button\"\n class=\"a-btn a-btn--icon-only\"\n (click)=\"invertLayers(i, i + 1)\"\n *ngIf=\"i < (optionsCopy?.layers?.length ?? 0) - 1\"\n >\n <pry-icon iconSvg=\"fleche_bas\"></pry-icon>\n <span class=\"u-visually-hidden\">{{ '@pry.action.moveDown' | i18n }}</span>\n </button>\n </div>\n </div>\n\n <div class=\"o-settings__popup__content__fields__content\">\n <pry-range\n [ngModel]=\"(layer?.opacity ?? 100) + ''\"\n (ngModelChange)=\"changeOpacity(layer, $event)\"\n labelTranslate=\"@pry.widget.map.opacity\"\n min=\"0\"\n max=\"100\"\n ></pry-range>\n\n <fieldset>\n <legend class=\"u-visually-hidden\">{{ '@pry.widget.map.layerOptions' | i18n : { index: i + 1 } }}</legend>\n <div class=\"m-form-label-field\">\n <label class=\"a-label\" for=\"map_layerTitle\">{{ '@pry.widget.map.layerTitle' | i18n }}</label>\n <input\n id=\"map_layerTitle\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeTitle($event, layer)\"\n [value]=\"layer.title ?? ''\"\n />\n </div>\n\n <div class=\"m-form-label-field\" *ngIf=\"!['geoserver', 'auto'].includes(layer.type)\">\n <label class=\"a-label\" for=\"map_layerType\">{{ '@pry.widget.map.layerType.title' | i18n }}</label>\n <pry-select\n (ngModelChange)=\"changeLayerType($event, i)\"\n [bindData]=\"true\"\n [itemsAsOption]=\"true\"\n [items]=\"layerTypes\"\n [labelTranslate]=\"true\"\n [ngModel]=\"layer.type\"\n baseTranslate=\"@pry.widget.map.layerType.\"\n class=\"a-pry-select\"\n id=\"map_layerType\"\n ></pry-select>\n </div>\n\n <div\n *ngIf=\"\n layer.type !== 'relation' &&\n layer.type !== 'wms' &&\n layer.type !== 'wmts' &&\n layer.type !== 'geoserver' &&\n layer.type !== 'featurelayer' &&\n layer.type !== 'vectortile' &&\n layer.type !== 'rastertile' &&\n layer.type !== 'auto'\n \"\n class=\"m-form-label-field\"\n >\n <label class=\"a-label\" for=\"map_classes\">{{ '@pry.widget.map.classes' | i18n }}</label>\n <pry-select\n (ngModelChange)=\"changeClasses($event, layer)\"\n [itemsAsOption]=\"true\"\n [items]=\"classes$ | async\"\n [multiple]=\"true\"\n [ngModel]=\"layer.classes\"\n bindLabel=\"name\"\n bindValue=\"id\"\n class=\"a-pry-select\"\n id=\"map_classes\"\n ></pry-select>\n </div>\n </fieldset>\n </div>\n\n <fieldset\n *ngIf=\"\n layer.type !== 'relation' &&\n layer.type !== 'wms' &&\n layer.type !== 'wmts' &&\n layer.type !== 'geoserver' &&\n layer.type !== 'featurelayer' &&\n layer.type !== 'vectortile' &&\n layer.type !== 'rastertile'\n \"\n >\n <legend class=\"u-visually-hidden\">{{ '@pry.widget.map.locationAttr' | i18n }}</legend>\n <ng-container\n *ngIf=\"\n layer\n | geometryFieldsFor : { resultSet: resultSet$, classes: layer.classes, type: layer.type }\n | async as fields\n \"\n >\n <div\n *ngIf=\"\n ['heatmap', 'bubble', 'marker', 'point', 'line', 'polygon', 'multi-line', 'multi-polygon'].indexOf(\n layer.type\n ) >= 0\n \"\n >\n <div class=\"m-form-label-field\">\n <label class=\"a-label\" for=\"map_locationAttribute_both\">{{\n '@pry.widget.map.locationAttribute.both' | i18n\n }}</label>\n <pry-select\n (ngModelChange)=\"changeLocationAttributes($event, layer)\"\n [itemsAsOption]=\"true\"\n [items]=\"fields\"\n [ngModel]=\"layer.attribute\"\n bindLabel=\"name\"\n bindValue=\"name\"\n id=\"map_locationAttribute_both\"\n class=\"a-pry-select\"\n ></pry-select>\n </div>\n </div>\n\n <div *ngIf=\"['heatmap', 'bubble'].indexOf(layer.type) >= 0\">\n <div class=\"m-form-label-field\">\n <label class=\"a-label\" for=\"map_intensityAttribute\">{{\n '@pry.widget.map.intensityAttribute' | i18n\n }}</label>\n <pry-select\n (ngModelChange)=\"changeIntensityAttributes($event, layer)\"\n [itemsAsOption]=\"true\"\n [items]=\"fields\"\n [ngModel]=\"layerHasIntensity(layer).intensityAttribute\"\n bindLabel=\"name\"\n bindValue=\"name\"\n id=\"map_intensityAttribute\"\n class=\"a-pry-select\"\n ></pry-select>\n </div>\n </div>\n </ng-container>\n </fieldset>\n\n <fieldset\n *ngIf=\"\n layer.type === 'wms' ||\n layer.type === 'wmts' ||\n layer.type === 'featurelayer' ||\n layer.type === 'vectortile' ||\n layer.type === 'rastertile'\n \"\n >\n <legend class=\"u-visually-hidden\">{{ '@pry.widget.map.tile' | i18n }}</legend>\n <div class=\"m-form-label-field\">\n <label class=\"a-label\" for=\"map_wms_url\">{{ '@pry.widget.map.wms.url' | i18n }}</label>\n <input\n id=\"map_wms_url\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeUrl($event, layer)\"\n [value]=\"layer.url\"\n />\n </div>\n\n <div class=\"m-form-label-field\" *ngIf=\"layer.type === 'wms' || layer.type === 'wmts'\">\n <label class=\"a-label\" for=\"map_wms_paramLayer\">{{ '@pry.widget.map.wms.paramLayer' | i18n }}</label>\n <input\n id=\"map_wms_paramLayer\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeParamLayer($event, layer)\"\n [value]=\"layer.paramLayer\"\n />\n </div>\n\n <div class=\"m-form-label-field\" *ngIf=\"layer.type === 'wmts'\">\n <label class=\"a-label\" for=\"map_wms_matrixSet\">{{ '@pry.widget.map.wms.matrixSet' | i18n }}</label>\n <input\n id=\"map_wms_matrixSet\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeMatrixSet($event, layer)\"\n [value]=\"layer.matrixSet\"\n />\n </div>\n\n <div class=\"m-form-label-field\" *ngIf=\"layer.type === 'wmts'\">\n <label class=\"a-label\" for=\"map_wms_style\">{{ '@pry.widget.map.wms.style' | i18n }}</label>\n <input\n id=\"map_wms_style\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeParamStyle($event, layer)\"\n [value]=\"layer.style\"\n />\n </div>\n\n <div class=\"m-form-label-field\" *ngIf=\"layer.type === 'wms'\">\n <pry-checkbox (ngModelChange)=\"changeParamTiled($event, layer)\" [ngModel]=\"layer?.paramTiled ?? false\">\n {{ '@pry.widget.map.wms.paramTiled' | i18n }}\n </pry-checkbox>\n </div>\n </fieldset>\n\n <fieldset *ngIf=\"layer.type === 'marker'\">\n <legend class=\"u-visually-hidden\">{{ '@pry.widget.map.clustering' | i18n }}</legend>\n <div class=\"m-form-label-field\">\n <pry-checkbox (ngModelChange)=\"changeClustered(layer, $event)\" [ngModel]=\"layer.clustered\">\n {{ '@pry.widget.map.clustered' | i18n }}\n </pry-checkbox>\n </div>\n <div *ngIf=\"layer.clustered\">\n <pry-range\n [ngModel]=\"layer.clustered\"\n (ngModelChange)=\"changeClusterDistance(layer, $event)\"\n labelTranslate=\"@pry.widget.map.clusterDistance\"\n min=\"1\"\n max=\"500\"\n ></pry-range>\n </div>\n </fieldset>\n\n <div class=\"m-form-label-field\" *ngIf=\"optionsCopy.attributions\">\n <label class=\"a-label\" for=\"attribution\">{{ '@pry.widget.map.attribution' | i18n }}</label>\n <input\n id=\"attribution\"\n class=\"a-form-field\"\n type=\"text\"\n (input)=\"changeAttribution($event, layer)\"\n [value]=\"layer.attribution ? layer.attribution : ''\"\n />\n </div>\n\n <button\n type=\"button\"\n (click)=\"deleteLayer(i, layer)\"\n class=\"a-btn a-btn--icon-text -link-like\"\n *ngIf=\"layer.type !== 'geoserver'\"\n data-func=\"delete\"\n >\n <pry-icon iconSvg=\"delete\" [width]=\"19\" [height]=\"19\"></pry-icon>\n <span>{{ '@pry.widget.map.deleteLayer' | i18n }}</span>\n </button>\n </div>\n </pry-settings>\n </pry-widget-header>\n\n <div class=\"m-btn-group -selection-choice\" [style.transform]=\"bottomLeft$ | async\">\n <ng-container *ngFor=\"let action of basicActions$ | async\">\n <button\n type=\"button\"\n class=\"a-btn a-btn--icon-only\"\n (click)=\"interactionManager.selectionInteraction.changeSelection(action)\"\n [class.-selected]=\"interactionManager.selectionInteraction.selectionType === action\"\n [pryTooltip]=\"infoTooltipAction\"\n pryTooltipPosition=\"bottom\"\n aria-describedby=\"infoTooltipAction\"\n [pryTooltipContext]=\"{ action: action }\"\n >\n <pry-icon [iconSvg]=\"action\"></pry-icon>\n <span class=\"u-visually-hidden\">{{ '@pry.widget.map.' + action | i18n }}</span>\n </button>\n </ng-container>\n\n <button\n type=\"button\"\n class=\"a-btn a-btn--icon-only\"\n id=\"export_card\"\n aria-expanded=\"false\"\n aria-controls=\"export_type\"\n aria-haspopup=\"menu\"\n [pryTooltip]=\"infoTooltipDown\"\n pryTooltipPosition=\"bottom\"\n aria-describedby=\"infoTooltipDown_widgetMap\"\n *ngIf=\"(actions$ | async)?.includes('export')\"\n >\n <pry-icon iconSvg=\"file_download\" (click)=\"export()\"></pry-icon>\n <span class=\"u-visually-hidden\">{{ '@pry.widget.map.export' | i18n }}</span>\n </button>\n </div>\n\n <div\n class=\"ol-control m-layer-switcher\"\n *ngIf=\"((layers$ | async)?.length ?? 0) > 0\"\n [style.top.px]=\"layersTop$ | async\"\n >\n <button\n class=\"m-layer-switcher__toggle\"\n (click)=\"toggleLayersWindow()\"\n [title]=\"'@pry.widget.map.selectLayers' | i18n\"\n >\n <pry-icon iconSvg=\"layers\" [width]=\"22\" [height]=\"22\"></pry-icon>\n </button>\n <ng-container *ngFor=\"let layer of mapLayers; let index = index\">\n <div class=\"m-layer-switcher__title\" [class.-hidden]=\"!layersTabOpen\">\n {{ layer.get('title') }}\n <ng-container *ngIf=\"!(options$ | async)?.singleLayer; else singleLayer\">\n <pry-checkbox [ngModel]=\"layer.getVisible()\" (change)=\"changeVisibility(layer)\"></pry-checkbox>\n </ng-container>\n <ng-template #singleLayer>\n <input\n type=\"radio\"\n name=\"layer\"\n [id]=\"'radio-layer-' + layer.get('title').split(' ')[0]\"\n [ngModel]=\"layerVisibleIdx\"\n [value]=\"index\"\n (change)=\"changeVisibility(layer)\"\n />\n </ng-template>\n </div>\n </ng-container>\n </div>\n\n <div\n class=\"ol-control m-layer-legend\"\n *ngIf=\"((legendLayers$ | async)?.length ?? 0) > 0\"\n [style.top.px]=\"legendTop$ | async\"\n >\n <button class=\"m-layer-legend__toggle\" (click)=\"toggleLegendWindow()\" [title]=\"'@pry.widget.map.legends' | i18n\">\n <pry-icon iconSvg=\"legend\" [width]=\"22\" [height]=\"22\"></pry-icon>\n </button>\n <ng-container *ngFor=\"let geoLayer of legendLayers$ | async; let index = index\">\n <div class=\"m-layer-legend__title\" [class.-hidden]=\"!legendTabOpen\">\n {{ geoLayer.title }}\n <ng-container *ngIf=\"isLayerRendered(geoLayer)\">\n <button class=\"m-layer-legend__toggle\" (click)=\"toggleLegend(index)\">\n <pry-icon\n [iconSvg]=\"legendTab === index ? 'chevron_top' : 'chevron_bottom'\"\n [width]=\"22\"\n [height]=\"22\"\n ></pry-icon>\n </button>\n </ng-container>\n <ng-container *ngIf=\"!isLayerRendered(geoLayer)\">\n <pry-icon [iconSvg]=\"'close'\" [width]=\"22\" [height]=\"22\"></pry-icon>\n </ng-container>\n </div>\n <div\n class=\"m-layer-legend__image\"\n [class.-hidden]=\"!legendTabOpen || legendTab !== index || !isLayerRendered(geoLayer)\"\n [style.max-height.px]=\"legendHeight$ | async\"\n >\n <ng-container *ngIf=\"geoLayer | legendUrl : { capabilities: (wmsCapabilities$ | async) } as url\">\n <img\n [src]=\"url\"\n [alt]=\"'@pry.widget.map.legend' | i18n : { layer: geoLayer.title }\"\n (error)=\"imageNotProvided[index] = true\"\n />\n </ng-container>\n <ng-container *ngIf=\"!(geoLayer | legendUrl : { capabilities: (wmsCapabilities$ | async) })\">\n <p class=\"m-layer-legend__error\">{{ '@pry.widget.map.legendNotProvided' | i18n }}</p>\n </ng-container>\n </div>\n </ng-container>\n </div>\n\n <div [style.height.px]=\"height$ | async\" class=\"o-map-wrapper\">\n <div class=\"o-map\">\n <div #mapRef id=\"map\"></div>\n </div>\n </div>\n\n <ng-template #infoTooltipAction let-action=\"action\">\n <div class=\"m-tooltip\" role=\"tooltip\" id=\"infoTooltipAction\" aria-hidden=\"true\">\n <span class=\"m-tooltip__text\">{{ '@pry.widget.map.' + action | i18n }}</span>\n </div>\n </ng-template>\n\n <ng-template #infoTooltipDown>\n <div class=\"m-tooltip\" role=\"tooltip\" id=\"infoTooltipDown_widgetMap\" aria-hidden=\"true\">\n <span class=\"m-tooltip__text\">{{ '@pry.widget.map.export' | i18n }}</span>\n </div>\n </ng-template>\n\n <div #popup class=\"m-tooltip m-tooltip--popup\" [hidden]=\"true\" role=\"tooltip\">\n <div class=\"m-tooltip--popup__header\">\n <p>{{ this.tooltipIndex + 1 }} / {{ this.tooltipNumber }}</p>\n <button class=\"a-btn a-btn--primary a-btn--icon-only\" (click)=\"tooltipMove(-1)\" [disabled]=\"!tooltipCanMove(-1)\">\n <pry-icon iconSvg=\"arrow_back\"></pry-icon>\n </button>\n <button class=\"a-btn a-btn--primary a-btn--icon-only\" (click)=\"tooltipMove(1)\" [disabled]=\"!tooltipCanMove(1)\">\n <pry-icon iconSvg=\"arrow_right\"></pry-icon>\n </button>\n </div>\n <div class=\"m-tooltip--popup__container\">\n <ng-container #popupContent></ng-container>\n </div>\n </div>\n <div\n #address\n class=\"m-tooltip m-tooltip--address tooltip-address\"\n [style.display]=\"'none'\"\n (click)=\"hideAddress()\"\n ></div>\n</div>\n" }]
|
|
1740
1834
|
}], ctorParameters: function () { return [{ type: i1$1.Store }, { type: i2.PrySnackbarService }, { type: i2.PryI18nService }, { type: i2.TooltipFactoryService }, { type: i3.Overlay }, { type: i0.ViewContainerRef }, { type: i2.SymbolService }, { type: i0.Injector }, { type: WidgetMapLayerService }, { type: i0.ElementRef }, { type: WmsService }]; }, propDecorators: { mapRef: [{
|
|
1741
1835
|
type: ViewChild,
|
|
1742
1836
|
args: ['mapRef']
|
|
@@ -1829,7 +1923,8 @@ const enTranslations = {
|
|
|
1829
1923
|
legendNotProvided: 'Legend not provided by server',
|
|
1830
1924
|
selectLayers: 'Select layers',
|
|
1831
1925
|
legends: 'Display legend',
|
|
1832
|
-
singleLayer: 'Single layer mode'
|
|
1926
|
+
singleLayer: 'Single layer mode',
|
|
1927
|
+
autoLayer: 'Automatic datasource layers configuration'
|
|
1833
1928
|
}
|
|
1834
1929
|
}
|
|
1835
1930
|
}
|
|
@@ -1910,7 +2005,8 @@ const frTranslations = {
|
|
|
1910
2005
|
legendNotProvided: 'Légende non fournie par le serveur',
|
|
1911
2006
|
selectLayers: 'Sélectionner les couches',
|
|
1912
2007
|
legends: 'Afficher la légende',
|
|
1913
|
-
singleLayer: 'Mode mono-couche'
|
|
2008
|
+
singleLayer: 'Mode mono-couche',
|
|
2009
|
+
autoLayer: 'Configuration automatique des sources de données'
|
|
1914
2010
|
}
|
|
1915
2011
|
}
|
|
1916
2012
|
}
|
|
@@ -1979,5 +2075,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.6", ngImpor
|
|
|
1979
2075
|
* Generated bundle index. Do not edit.
|
|
1980
2076
|
*/
|
|
1981
2077
|
|
|
1982
|
-
export { CqlUtils, DEFAULT_HEATMAP_RADIUS, DEFAULT_MAP_CENTER, DEFAULT_RADIUS_INTENSITY_FACTOR, DEFAULT_ZOOM_MAX, DEFAULT_ZOOM_MIN, DEFAULT_ZOOM_START,
|
|
2078
|
+
export { CqlUtils, DEFAULT_HEATMAP_RADIUS, DEFAULT_MAP_CENTER, DEFAULT_RADIUS_INTENSITY_FACTOR, DEFAULT_ZOOM_MAX, DEFAULT_ZOOM_MIN, DEFAULT_ZOOM_START, GeometryFieldsForPipe, InteractionManager, PryWidgetMapCssComponent, SelectionInteraction, TOOLTIP_PADDING, WidgetMapComponent, WidgetMapLayerService, WidgetMapLegendUrlPipe, WidgetMapModule, WmsService, XMLUtils, exportMapAsImage, geometryForLayer, getCircleFeatureFromItem, getFeatureFromItem, getLinkFeature, getMapAsPng, populateIntensityAttribute, populateLocationAttribute };
|
|
1983
2079
|
//# sourceMappingURL=provoly-dashboard-widgets-widget-map.mjs.map
|