@provoly/dashboard 0.14.5 → 0.14.7
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/components/metadata-editor/metadata-editor.component.d.ts +3 -1
- 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/admin-select-dataset/admin-select-dataset.component.mjs +1 -1
- 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/components/admin-user/admin-user-select/admin-user-select.component.mjs +1 -1
- package/esm2022/admin/i18n/en.translations.mjs +17 -2
- package/esm2022/admin/i18n/fr.translations.mjs +19 -4
- package/esm2022/components/metadata-editor/metadata-editor.component.mjs +30 -9
- 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 +4 -2
- package/esm2022/lib/core/i18n/fr.translations.mjs +4 -2
- 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/lib/dashboard/public-api.mjs +2 -2
- package/esm2022/lib/dashboard/store/dashboard.actions.mjs +6 -2
- package/esm2022/lib/dashboard/store/dashboard.effects.mjs +20 -13
- package/esm2022/lib/dashboard/store/dashboard.reducers.mjs +11 -2
- package/esm2022/lib/dashboard/store/dashboard.selectors.mjs +4 -2
- package/esm2022/lib/dashboard/store/manifest.service.mjs +11 -1
- package/esm2022/lib/dashboard/store/wms.service.mjs +54 -0
- package/esm2022/pipeline/components/pipeline-list/pipeline-list.component.mjs +25 -13
- package/esm2022/pipeline/pipeline.module.mjs +8 -4
- package/esm2022/presentation/components/add-edit-presentation/add-edit-presentation.component.mjs +19 -3
- package/esm2022/presentation/presentation.module.mjs +8 -4
- package/esm2022/presentation/style/css.component.mjs +2 -2
- package/esm2022/supervision/store/supervision.reducer.mjs +2 -7
- package/esm2022/widgets/widget-map/component/widget-map-layer.service.mjs +35 -3
- package/esm2022/widgets/widget-map/component/widget-map.component.mjs +99 -39
- 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/pipe/widget-map-legend-url.pipe.mjs +3 -4
- package/esm2022/widgets/widget-map/public-api.mjs +1 -2
- package/esm2022/widgets/widget-map/utils/widget-map.utils.mjs +14 -8
- package/esm2022/widgets/widget-map/utils/xml-utils.class.mjs +20 -1
- package/fesm2022/provoly-dashboard-admin.mjs +81 -33
- package/fesm2022/provoly-dashboard-admin.mjs.map +1 -1
- package/fesm2022/provoly-dashboard-components-metadata-editor.mjs +29 -8
- package/fesm2022/provoly-dashboard-components-metadata-editor.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-presentation.mjs +26 -7
- package/fesm2022/provoly-dashboard-presentation.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 +380 -323
- package/fesm2022/provoly-dashboard-widgets-widget-map.mjs.map +1 -1
- package/fesm2022/provoly-dashboard.mjs +266 -133
- 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 +2 -0
- package/lib/core/i18n/fr.translations.d.ts +2 -0
- package/lib/core/model/admin-api.model.d.ts +1 -0
- package/lib/core/model/widget-map-manifest.interface.d.ts +12 -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/lib/dashboard/public-api.d.ts +1 -1
- package/lib/dashboard/store/dashboard.actions.d.ts +31 -0
- package/lib/dashboard/store/dashboard.effects.d.ts +9 -3
- package/lib/dashboard/store/dashboard.reducers.d.ts +4 -0
- package/lib/dashboard/store/dashboard.selectors.d.ts +5 -0
- package/lib/dashboard/store/manifest.service.d.ts +2 -0
- package/{widgets/widget-map/component → lib/dashboard/store}/wms.service.d.ts +4 -4
- package/package.json +30 -30
- package/pipeline/components/pipeline-list/pipeline-list.component.d.ts +1 -0
- package/pipeline/pipeline.module.d.ts +2 -1
- package/presentation/components/add-edit-presentation/add-edit-presentation.component.d.ts +3 -0
- package/presentation/presentation.module.d.ts +2 -1
- package/presentation/style/_o-pry-new-presentation.scss +18 -5
- 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 +51 -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 +14 -9
- 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/pipe/widget-map-legend-url.pipe.d.ts +4 -3
- package/widgets/widget-map/public-api.d.ts +0 -1
- package/widgets/widget-map/utils/widget-map.utils.d.ts +2 -5
- package/widgets/widget-map/utils/xml-utils.class.d.ts +1 -0
- package/esm2022/lib/dashboard/store/geocoding.service.mjs +0 -44
- package/esm2022/widgets/widget-map/component/wms.service.mjs +0 -67
- package/lib/dashboard/store/geocoding.service.d.ts +0 -56
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import * as i3 from '@angular/cdk/overlay';
|
|
2
2
|
import { OverlayModule } from '@angular/cdk/overlay';
|
|
3
|
-
import * as
|
|
3
|
+
import * as i5 from '@angular/common';
|
|
4
4
|
import { CommonModule } from '@angular/common';
|
|
5
5
|
import * as i0 from '@angular/core';
|
|
6
6
|
import { Injectable, Component, ViewEncapsulation, Pipe, ViewContainerRef, TemplateRef, ViewChild, NgModule } from '@angular/core';
|
|
7
|
-
import * as
|
|
7
|
+
import * as i6 from '@angular/forms';
|
|
8
8
|
import { FormsModule } from '@angular/forms';
|
|
9
9
|
import * as i2 from '@provoly/dashboard';
|
|
10
|
-
import { widgetMapConfig, DashboardActions, ContextMenuActions, TooltipMode,
|
|
11
|
-
import * as
|
|
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
|
+
import * as i7 from '@provoly/dashboard/components/checkbox';
|
|
12
12
|
import { PryCheckboxModule } from '@provoly/dashboard/components/checkbox';
|
|
13
13
|
import equal from 'fast-deep-equal/es6';
|
|
14
14
|
import { Feature, Overlay, Map, View } from 'ol';
|
|
@@ -20,22 +20,20 @@ import { toLonLat, fromLonLat, get, transform } from 'ol/proj';
|
|
|
20
20
|
import { register } from 'ol/proj/proj4';
|
|
21
21
|
import { Vector, TileWMS, WMTS, XYZ, Cluster } from 'ol/source';
|
|
22
22
|
import proj4 from 'proj4';
|
|
23
|
-
import { map,
|
|
23
|
+
import { map, combineLatest, filter, BehaviorSubject, startWith, distinctUntilChanged, debounceTime, delay, mergeMap, of, 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 '@ngrx/store';
|
|
39
37
|
|
|
40
38
|
class SelectionInteraction extends PointerInteraction {
|
|
41
39
|
constructor() {
|
|
@@ -352,281 +350,6 @@ class CqlUtils {
|
|
|
352
350
|
}
|
|
353
351
|
}
|
|
354
352
|
|
|
355
|
-
const populateLocationAttribute = (layer, resultSet, classesNotFiltered, fields) => {
|
|
356
|
-
if (['heatmap', 'marker', 'bubble', 'point', 'line', 'polygon', 'multi-line', 'multi-polygon'].includes(layer.type) &&
|
|
357
|
-
!!resultSet &&
|
|
358
|
-
!!classesNotFiltered &&
|
|
359
|
-
classesNotFiltered.length > 0) {
|
|
360
|
-
const specificLayer = layer;
|
|
361
|
-
const classes = classesNotFiltered.filter((cl) => specificLayer.classes?.includes(cl.id) || !specificLayer.classes || specificLayer.classes.length === 0);
|
|
362
|
-
if (!specificLayer.attribute) {
|
|
363
|
-
// No location attribute available, then try to guess one that will be ok
|
|
364
|
-
const geometry = geometryForLayer(layer);
|
|
365
|
-
let candidates = [];
|
|
366
|
-
if (Object.keys(resultSet.items).length > 0) {
|
|
367
|
-
// Based on items that we have to display
|
|
368
|
-
candidates = Object.keys(resultSet.items)
|
|
369
|
-
.map((key) => ({ items: resultSet.items[key], oClass: classes.find((cl) => cl.id === key) }))
|
|
370
|
-
.map(({ items, oClass }) => (oClass ?? { attributes: [] }).attributes
|
|
371
|
-
.map((attr) => ({ attr, field: fields.find((f) => f.id === attr.field) }))
|
|
372
|
-
.filter((attr) => attr.field?.type === geometry))
|
|
373
|
-
.reduce((p, c) => [...p, ...c], []);
|
|
374
|
-
}
|
|
375
|
-
else {
|
|
376
|
-
// We don't have any items to display, so allow all corresponding geometry fields
|
|
377
|
-
candidates = classesNotFiltered
|
|
378
|
-
.map((clazz) => clazz.attributes)
|
|
379
|
-
.reduce((p, c) => [...p, ...c], [])
|
|
380
|
-
.map((attr) => fields.filter((field) => field?.type === geometry).map((field) => ({ attr, field })))
|
|
381
|
-
.reduce((p, c) => [...p, ...c], []);
|
|
382
|
-
}
|
|
383
|
-
if (candidates.length > 0) {
|
|
384
|
-
specificLayer.attribute = candidates[0].attr.name;
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
};
|
|
389
|
-
const populateIntensityAttribute = (layer, resultSet, classesNotFiltered, fields) => {
|
|
390
|
-
if (['heatmap', 'bubble'].includes(layer.type) &&
|
|
391
|
-
!!resultSet &&
|
|
392
|
-
!!classesNotFiltered &&
|
|
393
|
-
classesNotFiltered.length > 0) {
|
|
394
|
-
const specificLayer = layer;
|
|
395
|
-
const classes = classesNotFiltered.filter((cl) => (specificLayer.classes?.includes(cl.id) || !specificLayer.classes || specificLayer.classes.length === 0) &&
|
|
396
|
-
cl.attributes.find((attr) => attr.name === (specificLayer?.attribute ?? [])));
|
|
397
|
-
if (!specificLayer.intensityAttribute) {
|
|
398
|
-
// No intensity attribute available, then take the maximum intensity matching attribute
|
|
399
|
-
const candidatesDry = Object.keys(resultSet.items)
|
|
400
|
-
.map((key) => ({ items: resultSet.items[key], oClass: classes.find((cl) => cl.id === key) }))
|
|
401
|
-
.map(({ items, oClass }) => {
|
|
402
|
-
return (oClass ?? { attributes: [] }).attributes
|
|
403
|
-
.map((attr) => ({ attr, field: fields.find((f) => f.id === attr.field) }))
|
|
404
|
-
.filter((attr) => attr.field?.type === FieldType.DECIMAL || attr.field?.type === FieldType.INTEGER)
|
|
405
|
-
.map((attr) => {
|
|
406
|
-
const attrValues = ItemUtils.pertinentValue(items, attr.attr);
|
|
407
|
-
return {
|
|
408
|
-
min: Math.min(...attrValues),
|
|
409
|
-
max: Math.max(...attrValues),
|
|
410
|
-
name: attr.attr.name
|
|
411
|
-
};
|
|
412
|
-
});
|
|
413
|
-
})
|
|
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
|
-
});
|
|
497
|
-
map.renderSync();
|
|
498
|
-
});
|
|
499
|
-
};
|
|
500
|
-
const exportMapAsImage = (map, filename) => {
|
|
501
|
-
getMapAsPng(map).then((data) => {
|
|
502
|
-
const link = document.createElement('a');
|
|
503
|
-
link.download = filename;
|
|
504
|
-
link.href = data;
|
|
505
|
-
link.click();
|
|
506
|
-
});
|
|
507
|
-
};
|
|
508
|
-
const geometryForLayer = (layer) => {
|
|
509
|
-
switch (layer.type) {
|
|
510
|
-
case 'marker':
|
|
511
|
-
case 'heatmap':
|
|
512
|
-
case 'bubble':
|
|
513
|
-
case 'point':
|
|
514
|
-
return FieldType.POINT;
|
|
515
|
-
case 'line':
|
|
516
|
-
return FieldType.LINE;
|
|
517
|
-
case 'polygon':
|
|
518
|
-
return FieldType.POLYGON;
|
|
519
|
-
case 'multi-line':
|
|
520
|
-
return FieldType.MULTILINE;
|
|
521
|
-
case 'multi-polygon':
|
|
522
|
-
return FieldType.MULTIPOLYGON;
|
|
523
|
-
default:
|
|
524
|
-
return FieldType.POINT;
|
|
525
|
-
}
|
|
526
|
-
};
|
|
527
|
-
const DEFAULT_HEATMAP_RADIUS = 25;
|
|
528
|
-
const DEFAULT_RADIUS_INTENSITY_FACTOR = 10000;
|
|
529
|
-
const DEFAULT_ZOOM_MIN = 3;
|
|
530
|
-
const DEFAULT_ZOOM_START = 10;
|
|
531
|
-
const DEFAULT_ZOOM_MAX = 18;
|
|
532
|
-
const DEFAULT_MAP_CENTER = [2.2827217347381525, 48.864706031557716];
|
|
533
|
-
const EMPTY_MAP_STYLE = { layers: [] };
|
|
534
|
-
|
|
535
|
-
class XMLUtils {
|
|
536
|
-
static find(childs, name) {
|
|
537
|
-
if (!!childs) {
|
|
538
|
-
for (let i = 0; i < childs.length; i++) {
|
|
539
|
-
const node = childs[i];
|
|
540
|
-
if (node.nodeName === name) {
|
|
541
|
-
return node;
|
|
542
|
-
}
|
|
543
|
-
}
|
|
544
|
-
}
|
|
545
|
-
return null;
|
|
546
|
-
}
|
|
547
|
-
static findAll(childs, name) {
|
|
548
|
-
const result = [];
|
|
549
|
-
for (let i = 0; i < childs.length; i++) {
|
|
550
|
-
const node = childs[i];
|
|
551
|
-
if (node.nodeName === name) {
|
|
552
|
-
result.push(node);
|
|
553
|
-
}
|
|
554
|
-
}
|
|
555
|
-
return result;
|
|
556
|
-
}
|
|
557
|
-
static findWith(childs, attribute, value) {
|
|
558
|
-
for (let i = 0; i < childs.length; i++) {
|
|
559
|
-
const node = childs[i];
|
|
560
|
-
const attrNode = XMLUtils.find(node.childNodes, attribute);
|
|
561
|
-
if (attrNode?.textContent === value) {
|
|
562
|
-
return node;
|
|
563
|
-
}
|
|
564
|
-
}
|
|
565
|
-
return null;
|
|
566
|
-
}
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
class WmsService {
|
|
570
|
-
constructor(httpClient) {
|
|
571
|
-
this.httpClient = httpClient;
|
|
572
|
-
this.parser = new DOMParser();
|
|
573
|
-
}
|
|
574
|
-
getCapabilities(wmsLayer) {
|
|
575
|
-
if (wmsLayer && wmsLayer.url) {
|
|
576
|
-
const layerUrlWithQmark = wmsLayer.url.indexOf('?') === -1 ? wmsLayer.url + '?' : wmsLayer.url;
|
|
577
|
-
const layerUrlWithService = layerUrlWithQmark.indexOf('&SERVICE=') === -1 ? layerUrlWithQmark + '&SERVICE=WMS' : layerUrlWithQmark;
|
|
578
|
-
const layerUrlWithVersion = layerUrlWithService.indexOf('&VERSION=') === -1 ? layerUrlWithService + '&VERSION=1.3.0' : layerUrlWithService;
|
|
579
|
-
return this.httpClient
|
|
580
|
-
.get(`${layerUrlWithVersion}&REQUEST=GetCapabilities`, {
|
|
581
|
-
headers: new HttpHeaders({
|
|
582
|
-
Accept: 'text/html, application/xhtml+xml, */*',
|
|
583
|
-
'Content-Type': 'application/x-www-form-urlencoded'
|
|
584
|
-
}),
|
|
585
|
-
responseType: 'text'
|
|
586
|
-
})
|
|
587
|
-
.pipe(map((response) => {
|
|
588
|
-
const doc = this.parser.parseFromString(response, 'application/xml');
|
|
589
|
-
const errorNode = doc.querySelector('parsererror');
|
|
590
|
-
if (errorNode) {
|
|
591
|
-
console.error(`Cannot getCapabilities for ${wmsLayer.url}[${wmsLayer.paramLayer}]`);
|
|
592
|
-
return null;
|
|
593
|
-
}
|
|
594
|
-
else {
|
|
595
|
-
return { url: wmsLayer.url, paramLayer: wmsLayer.paramLayer, doc };
|
|
596
|
-
}
|
|
597
|
-
}));
|
|
598
|
-
}
|
|
599
|
-
return of(null);
|
|
600
|
-
}
|
|
601
|
-
static getMatchingLayer(paramLayer, doc) {
|
|
602
|
-
const WMSCapability = XMLUtils.find(doc.childNodes, 'WMS_Capabilities');
|
|
603
|
-
if (WMSCapability) {
|
|
604
|
-
const Capabilities = XMLUtils.find(WMSCapability.childNodes, 'Capability');
|
|
605
|
-
if (Capabilities) {
|
|
606
|
-
const Layer = XMLUtils.find(Capabilities.childNodes, 'Layer');
|
|
607
|
-
if (Layer) {
|
|
608
|
-
let matchingLayer = XMLUtils.findWith(Layer.childNodes, 'Name', paramLayer);
|
|
609
|
-
const split = paramLayer.split(':');
|
|
610
|
-
if (!matchingLayer && split.length >= 2) {
|
|
611
|
-
// Try again, splitting on ":" in the name to ignore namespace if present
|
|
612
|
-
matchingLayer = XMLUtils.findWith(Layer.childNodes, 'Name', split[split.length - 1]);
|
|
613
|
-
}
|
|
614
|
-
return matchingLayer;
|
|
615
|
-
}
|
|
616
|
-
}
|
|
617
|
-
}
|
|
618
|
-
return null;
|
|
619
|
-
}
|
|
620
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.6", ngImport: i0, type: WmsService, deps: [{ token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
621
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.1.6", ngImport: i0, type: WmsService, providedIn: 'root' }); }
|
|
622
|
-
}
|
|
623
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.6", ngImport: i0, type: WmsService, decorators: [{
|
|
624
|
-
type: Injectable,
|
|
625
|
-
args: [{
|
|
626
|
-
providedIn: 'root'
|
|
627
|
-
}]
|
|
628
|
-
}], ctorParameters: function () { return [{ type: i1.HttpClient }]; } });
|
|
629
|
-
|
|
630
353
|
class WidgetMapLayerService {
|
|
631
354
|
constructor() {
|
|
632
355
|
this.styleCache = {};
|
|
@@ -649,22 +372,36 @@ class WidgetMapLayerService {
|
|
|
649
372
|
})
|
|
650
373
|
});
|
|
651
374
|
this.pointStyle = new Style({
|
|
652
|
-
image: new Circle
|
|
375
|
+
image: new Circle({
|
|
653
376
|
fill: new Fill({ color: 'rgba(37,89,163,0.24)' }),
|
|
654
377
|
stroke: new Stroke({ color: 'rgb(37,89,163)', width: 2 }),
|
|
655
378
|
radius: 10
|
|
656
379
|
})
|
|
657
380
|
});
|
|
658
381
|
this.selectedPointStyle = new Style({
|
|
659
|
-
image: new Circle
|
|
382
|
+
image: new Circle({
|
|
660
383
|
fill: new Fill({ color: 'rgba(37,163,58,0.24)' }),
|
|
661
384
|
stroke: new Stroke({ color: 'rgb(37,163,58)', width: 2 }),
|
|
662
385
|
radius: 10
|
|
663
386
|
})
|
|
664
387
|
});
|
|
665
388
|
this.dontNeedLocation = ['relation', 'wms', 'wmts', 'geoserver', 'featurelayer', 'vectortile', 'rastertile'];
|
|
666
|
-
this.dontNeedIntensity = [
|
|
389
|
+
this.dontNeedIntensity = [
|
|
390
|
+
...this.dontNeedLocation,
|
|
391
|
+
'marker',
|
|
392
|
+
'point',
|
|
393
|
+
'line',
|
|
394
|
+
'polygon',
|
|
395
|
+
'multi-line',
|
|
396
|
+
'multi-polygon',
|
|
397
|
+
'auto'
|
|
398
|
+
];
|
|
667
399
|
this.layersImplementation = {
|
|
400
|
+
auto: (layer, attributesForClass, layerClassesId, resultSet, range, itemStyles, map) => {
|
|
401
|
+
return this.layersImplementation[WidgetMapLayerService.translateFieldTypeToLayerType(layer.subType)](
|
|
402
|
+
// @ts-ignore
|
|
403
|
+
layer, attributesForClass, layerClassesId, resultSet, range, itemStyles, map);
|
|
404
|
+
},
|
|
668
405
|
heatmap: (layer, attributesForClass, layerClassesId, resultSet, range, itemStyles, map) => {
|
|
669
406
|
const heatmap = new Heatmap({
|
|
670
407
|
minZoom: layer.minZoom ?? DEFAULT_ZOOM_MIN,
|
|
@@ -773,6 +510,7 @@ class WidgetMapLayerService {
|
|
|
773
510
|
})
|
|
774
511
|
});
|
|
775
512
|
impl.set('oClass', layer.oClass);
|
|
513
|
+
impl.set('getFeatureInfoAdditionalParameters', layer.getFeatureInfoAdditionalParameters ?? {});
|
|
776
514
|
return impl;
|
|
777
515
|
},
|
|
778
516
|
wmts: (layer, attributesForClass, layerClassesId, resultSet, range, itemStyles, map) => {
|
|
@@ -918,6 +656,23 @@ class WidgetMapLayerService {
|
|
|
918
656
|
});
|
|
919
657
|
return layer;
|
|
920
658
|
}
|
|
659
|
+
static translateFieldTypeToLayerType(subType) {
|
|
660
|
+
switch (subType) {
|
|
661
|
+
case FieldType.POINT:
|
|
662
|
+
return 'marker';
|
|
663
|
+
case FieldType.LINE:
|
|
664
|
+
return 'line';
|
|
665
|
+
case FieldType.POLYGON:
|
|
666
|
+
return 'polygon';
|
|
667
|
+
case FieldType.MULTILINE:
|
|
668
|
+
return 'multi-line';
|
|
669
|
+
case FieldType.MULTIPOLYGON:
|
|
670
|
+
return 'multi-polygon';
|
|
671
|
+
default:
|
|
672
|
+
console.warn(`wrong type ${subType} for auto options`);
|
|
673
|
+
return 'marker';
|
|
674
|
+
}
|
|
675
|
+
}
|
|
921
676
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.6", ngImport: i0, type: WidgetMapLayerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
922
677
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.1.6", ngImport: i0, type: WidgetMapLayerService, providedIn: 'root' }); }
|
|
923
678
|
}
|
|
@@ -928,6 +683,244 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.6", ngImpor
|
|
|
928
683
|
}]
|
|
929
684
|
}] });
|
|
930
685
|
|
|
686
|
+
const populateLocationAttribute = (layer, resultSet, classesNotFiltered, fields) => {
|
|
687
|
+
if (['heatmap', 'marker', 'bubble', 'point', 'line', 'polygon', 'multi-line', 'multi-polygon', 'auto'].includes(layer.type) &&
|
|
688
|
+
!!resultSet &&
|
|
689
|
+
!!classesNotFiltered &&
|
|
690
|
+
classesNotFiltered.length > 0) {
|
|
691
|
+
const specificLayer = layer;
|
|
692
|
+
const classes = classesNotFiltered.filter((cl) => specificLayer.classes?.includes(cl.id) || !specificLayer.classes || specificLayer.classes.length === 0);
|
|
693
|
+
if (!specificLayer.attribute) {
|
|
694
|
+
// No location attribute available, then try to guess one that will be ok
|
|
695
|
+
const geometry = geometryForLayer(layer);
|
|
696
|
+
let candidates = [];
|
|
697
|
+
if (Object.keys(resultSet.items).length > 0) {
|
|
698
|
+
// Based on items that we have to display
|
|
699
|
+
candidates = Object.keys(resultSet.items)
|
|
700
|
+
.map((key) => ({ items: resultSet.items[key], oClass: classes.find((cl) => cl.id === key) }))
|
|
701
|
+
.map(({ items, oClass }) => (oClass ?? { attributes: [] }).attributes
|
|
702
|
+
.map((attr) => ({ attr, field: fields.find((f) => f.id === attr.field) }))
|
|
703
|
+
.filter((attr) => attr.field?.type === geometry))
|
|
704
|
+
.reduce((p, c) => [...p, ...c], []);
|
|
705
|
+
}
|
|
706
|
+
else {
|
|
707
|
+
// We don't have any items to display, so allow all corresponding geometry fields
|
|
708
|
+
candidates = classesNotFiltered
|
|
709
|
+
.map((clazz) => clazz.attributes)
|
|
710
|
+
.flat()
|
|
711
|
+
.map((attr) => ({ attr, field: fields.find((field) => field.id === attr.field) }))
|
|
712
|
+
.filter(({ attr, field }) => field?.type === geometry);
|
|
713
|
+
}
|
|
714
|
+
if (candidates.length > 0) {
|
|
715
|
+
specificLayer.attribute = candidates[0].attr.name;
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
};
|
|
720
|
+
const populateIntensityAttribute = (layer, resultSet, classesNotFiltered, fields) => {
|
|
721
|
+
if (['heatmap', 'bubble'].includes(layer.type) &&
|
|
722
|
+
!!resultSet &&
|
|
723
|
+
!!classesNotFiltered &&
|
|
724
|
+
classesNotFiltered.length > 0) {
|
|
725
|
+
const specificLayer = layer;
|
|
726
|
+
const classes = classesNotFiltered.filter((cl) => (specificLayer.classes?.includes(cl.id) || !specificLayer.classes || specificLayer.classes.length === 0) &&
|
|
727
|
+
cl.attributes.find((attr) => attr.name === (specificLayer?.attribute ?? [])));
|
|
728
|
+
if (!specificLayer.intensityAttribute) {
|
|
729
|
+
// No intensity attribute available, then take the maximum intensity matching attribute
|
|
730
|
+
const candidatesDry = Object.keys(resultSet.items)
|
|
731
|
+
.map((key) => ({ items: resultSet.items[key], oClass: classes.find((cl) => cl.id === key) }))
|
|
732
|
+
.map(({ items, oClass }) => {
|
|
733
|
+
return (oClass ?? { attributes: [] }).attributes
|
|
734
|
+
.map((attr) => ({ attr, field: fields.find((f) => f.id === attr.field) }))
|
|
735
|
+
.filter((attr) => attr.field?.type === FieldType.DECIMAL || attr.field?.type === FieldType.INTEGER)
|
|
736
|
+
.map((attr) => {
|
|
737
|
+
const attrValues = ItemUtils.pertinentValue(items, attr.attr);
|
|
738
|
+
return {
|
|
739
|
+
min: Math.min(...attrValues),
|
|
740
|
+
max: Math.max(...attrValues),
|
|
741
|
+
name: attr.attr.name
|
|
742
|
+
};
|
|
743
|
+
});
|
|
744
|
+
})
|
|
745
|
+
.reduce((p, c) => [...p, ...c], [])
|
|
746
|
+
.sort((a, b) => b.max - a.max);
|
|
747
|
+
if (candidatesDry.length > 0) {
|
|
748
|
+
specificLayer.intensityAttribute = candidatesDry[0].name;
|
|
749
|
+
specificLayer.intensityAsc = true;
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
};
|
|
754
|
+
const getFeatureFromItem = (item, type, locationAttribute, iconStyle, selectedIconStyle) => {
|
|
755
|
+
return new Feature({
|
|
756
|
+
...item,
|
|
757
|
+
type,
|
|
758
|
+
geometry: ItemUtils.readGeometry(item, 'point', locationAttribute),
|
|
759
|
+
classicStyle: iconStyle ?? null,
|
|
760
|
+
selectedStyle: selectedIconStyle ?? null
|
|
761
|
+
});
|
|
762
|
+
};
|
|
763
|
+
const getCircleFeatureFromItem = (item, locationAttribute, radius, iconStyle, selectedIconStyle) => {
|
|
764
|
+
return new Feature({
|
|
765
|
+
...item,
|
|
766
|
+
geometry: new Circle$1(ItemUtils.readGeometry(item, 'point', locationAttribute).getCoordinates(), radius),
|
|
767
|
+
classicStyle: iconStyle,
|
|
768
|
+
selectedStyle: selectedIconStyle,
|
|
769
|
+
type: 'bubble'
|
|
770
|
+
});
|
|
771
|
+
};
|
|
772
|
+
const getLinkFeature = (relation, featureSource, featureDestination) => {
|
|
773
|
+
return new Feature({
|
|
774
|
+
...relation,
|
|
775
|
+
geometry: new LineString([
|
|
776
|
+
// @ts-ignore
|
|
777
|
+
featureSource.getGeometry()?.getCoordinates() ?? featureSource.getGeometry()?.getCenter() ?? [0, 0],
|
|
778
|
+
// @ts-ignore
|
|
779
|
+
featureDestination.getGeometry()?.getCoordinates() ?? featureDestination.getGeometry()?.getCenter() ?? [0, 0]
|
|
780
|
+
]),
|
|
781
|
+
source: featureSource,
|
|
782
|
+
destination: featureDestination,
|
|
783
|
+
type: 'link'
|
|
784
|
+
});
|
|
785
|
+
};
|
|
786
|
+
const getMapAsPng = (map) => {
|
|
787
|
+
return new Promise((resolve, reject) => {
|
|
788
|
+
map.once('rendercomplete', function () {
|
|
789
|
+
const mapCanvas = document.createElement('canvas');
|
|
790
|
+
const size = map.getSize() || [100, 100];
|
|
791
|
+
mapCanvas.width = size[0];
|
|
792
|
+
mapCanvas.height = size[1];
|
|
793
|
+
const mapContext = mapCanvas.getContext('2d') || null;
|
|
794
|
+
Array.prototype.forEach.call(document.querySelectorAll('.ol-layer canvas, canvas.ol-layer'), (canvas) => {
|
|
795
|
+
if (canvas.width > 0) {
|
|
796
|
+
const opacity = canvas.parentNode.style.opacity || canvas.style.opacity;
|
|
797
|
+
mapContext.globalAlpha = opacity === '' ? 1 : Number(opacity);
|
|
798
|
+
const backgroundColor = canvas.parentNode.style.backgroundColor;
|
|
799
|
+
if (backgroundColor) {
|
|
800
|
+
mapContext.fillStyle = backgroundColor;
|
|
801
|
+
mapContext.fillRect(0, 0, canvas.width, canvas.height);
|
|
802
|
+
}
|
|
803
|
+
let matrix;
|
|
804
|
+
const transform = canvas.style.transform;
|
|
805
|
+
if (transform) {
|
|
806
|
+
// Get the transform parameters from the style's transform matrix
|
|
807
|
+
matrix = transform
|
|
808
|
+
.match(/^matrix\(([^(]*)\)$/)[1]
|
|
809
|
+
.split(',')
|
|
810
|
+
.map(Number);
|
|
811
|
+
}
|
|
812
|
+
else {
|
|
813
|
+
matrix = [
|
|
814
|
+
parseFloat(canvas.style.width) / canvas.width,
|
|
815
|
+
0,
|
|
816
|
+
0,
|
|
817
|
+
parseFloat(canvas.style.height) / canvas.height,
|
|
818
|
+
0,
|
|
819
|
+
0
|
|
820
|
+
];
|
|
821
|
+
}
|
|
822
|
+
// Apply the transform to the export map context
|
|
823
|
+
CanvasRenderingContext2D.prototype.setTransform.apply(mapContext, matrix);
|
|
824
|
+
mapContext.drawImage(canvas, 0, 0);
|
|
825
|
+
}
|
|
826
|
+
});
|
|
827
|
+
mapContext.globalAlpha = 1;
|
|
828
|
+
resolve(mapCanvas.toDataURL('image/png'));
|
|
829
|
+
});
|
|
830
|
+
map.renderSync();
|
|
831
|
+
});
|
|
832
|
+
};
|
|
833
|
+
const exportMapAsImage = (map, filename) => {
|
|
834
|
+
getMapAsPng(map).then((data) => {
|
|
835
|
+
const link = document.createElement('a');
|
|
836
|
+
link.download = filename;
|
|
837
|
+
link.href = data;
|
|
838
|
+
link.click();
|
|
839
|
+
});
|
|
840
|
+
};
|
|
841
|
+
const geometryForLayer = (layer) => {
|
|
842
|
+
switch (layer.type) {
|
|
843
|
+
case 'marker':
|
|
844
|
+
case 'heatmap':
|
|
845
|
+
case 'bubble':
|
|
846
|
+
case 'point':
|
|
847
|
+
return FieldType.POINT;
|
|
848
|
+
case 'line':
|
|
849
|
+
return FieldType.LINE;
|
|
850
|
+
case 'polygon':
|
|
851
|
+
return FieldType.POLYGON;
|
|
852
|
+
case 'multi-line':
|
|
853
|
+
return FieldType.MULTILINE;
|
|
854
|
+
case 'multi-polygon':
|
|
855
|
+
return FieldType.MULTIPOLYGON;
|
|
856
|
+
case 'auto':
|
|
857
|
+
return geometryForLayer({
|
|
858
|
+
type: WidgetMapLayerService.translateFieldTypeToLayerType(layer.subType)
|
|
859
|
+
});
|
|
860
|
+
default:
|
|
861
|
+
return FieldType.POINT;
|
|
862
|
+
}
|
|
863
|
+
};
|
|
864
|
+
const DEFAULT_HEATMAP_RADIUS = 25;
|
|
865
|
+
const DEFAULT_RADIUS_INTENSITY_FACTOR = 10000;
|
|
866
|
+
const DEFAULT_ZOOM_MIN = 3;
|
|
867
|
+
const DEFAULT_ZOOM_START = 10;
|
|
868
|
+
const DEFAULT_ZOOM_MAX = 18;
|
|
869
|
+
const DEFAULT_MAP_CENTER = [2.2827217347381525, 48.864706031557716];
|
|
870
|
+
|
|
871
|
+
class XMLUtils {
|
|
872
|
+
static find(childs, name) {
|
|
873
|
+
if (!!childs) {
|
|
874
|
+
for (let i = 0; i < childs.length; i++) {
|
|
875
|
+
const node = childs[i];
|
|
876
|
+
if (node.nodeName === name) {
|
|
877
|
+
return node;
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
return null;
|
|
882
|
+
}
|
|
883
|
+
static findAll(childs, name) {
|
|
884
|
+
const result = [];
|
|
885
|
+
for (let i = 0; i < childs.length; i++) {
|
|
886
|
+
const node = childs[i];
|
|
887
|
+
if (node.nodeName === name) {
|
|
888
|
+
result.push(node);
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
return result;
|
|
892
|
+
}
|
|
893
|
+
static findWith(childs, attribute, value) {
|
|
894
|
+
for (let i = 0; i < childs.length; i++) {
|
|
895
|
+
const node = childs[i];
|
|
896
|
+
const attrNode = XMLUtils.find(node.childNodes, attribute);
|
|
897
|
+
if (attrNode?.textContent === value) {
|
|
898
|
+
return node;
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
return null;
|
|
902
|
+
}
|
|
903
|
+
static getMatchingLayer(paramLayer, doc) {
|
|
904
|
+
const WMSCapability = XMLUtils.find(doc.childNodes, 'WMS_Capabilities');
|
|
905
|
+
if (WMSCapability) {
|
|
906
|
+
const Capabilities = XMLUtils.find(WMSCapability.childNodes, 'Capability');
|
|
907
|
+
if (Capabilities) {
|
|
908
|
+
const Layer = XMLUtils.find(Capabilities.childNodes, 'Layer');
|
|
909
|
+
if (Layer) {
|
|
910
|
+
let matchingLayer = XMLUtils.findWith(Layer.childNodes, 'Name', paramLayer);
|
|
911
|
+
const split = paramLayer.split(':');
|
|
912
|
+
if (!matchingLayer && split.length >= 2) {
|
|
913
|
+
// Try again, splitting on ":" in the name to ignore namespace if present
|
|
914
|
+
matchingLayer = XMLUtils.findWith(Layer.childNodes, 'Name', split[split.length - 1]);
|
|
915
|
+
}
|
|
916
|
+
return matchingLayer;
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
return null;
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
|
|
931
924
|
class PryWidgetMapCssComponent {
|
|
932
925
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.6", ngImport: i0, type: PryWidgetMapCssComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
933
926
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.6", type: PryWidgetMapCssComponent, selector: "pry-widget-map-css", ngImport: i0, template: '', isInline: true, styles: [":root,:host{--ol-background-color: white;--ol-accent-background-color: #F5F5F5;--ol-subtle-background-color: rgba(128, 128, 128, .25);--ol-partial-background-color: rgba(255, 255, 255, .75);--ol-foreground-color: #333333;--ol-subtle-foreground-color: #666666;--ol-brand-color: #00AAFF}.ol-box{box-sizing:border-box;border-radius:2px;border:1.5px solid var(--ol-background-color);background-color:var(--ol-partial-background-color)}.ol-mouse-position{top:8px;right:8px;position:absolute}.ol-scale-line{background:var(--ol-partial-background-color);border-radius:4px;bottom:8px;left:8px;padding:2px;position:absolute}.ol-scale-line-inner{border:1px solid var(--ol-subtle-foreground-color);border-top:none;color:var(--ol-foreground-color);font-size:10px;text-align:center;margin:1px;will-change:contents,width;transition:all .25s}.ol-scale-bar{position:absolute;bottom:8px;left:8px}.ol-scale-bar-inner{display:flex}.ol-scale-step-marker{width:1px;height:15px;background-color:var(--ol-foreground-color);float:right;z-index:10}.ol-scale-step-text{position:absolute;bottom:-5px;font-size:10px;z-index:11;color:var(--ol-foreground-color);text-shadow:-1.5px 0 var(--ol-partial-background-color),0 1.5px var(--ol-partial-background-color),1.5px 0 var(--ol-partial-background-color),0 -1.5px var(--ol-partial-background-color)}.ol-scale-text{position:absolute;font-size:12px;text-align:center;bottom:25px;color:var(--ol-foreground-color);text-shadow:-1.5px 0 var(--ol-partial-background-color),0 1.5px var(--ol-partial-background-color),1.5px 0 var(--ol-partial-background-color),0 -1.5px var(--ol-partial-background-color)}.ol-scale-singlebar{position:relative;height:10px;z-index:9;box-sizing:border-box;border:1px solid var(--ol-foreground-color)}.ol-scale-singlebar-even{background-color:var(--ol-subtle-foreground-color)}.ol-scale-singlebar-odd{background-color:var(--ol-background-color)}.ol-unsupported{display:none}.ol-viewport,.ol-unselectable{-webkit-touch-callout:none;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent}.ol-viewport canvas{all:unset}.ol-selectable{-webkit-touch-callout:default;-webkit-user-select:text;user-select:text}.ol-grabbing{cursor:grabbing}.ol-grab{cursor:move;cursor:grab}.ol-control{position:absolute;background-color:var(--ol-subtle-background-color);border-radius:4px}.ol-zoom{top:.5em;left:.5em}.ol-rotate{top:.5em;right:.5em;transition:opacity .25s linear,visibility 0s linear}.ol-rotate.ol-hidden{opacity:0;visibility:hidden;transition:opacity .25s linear,visibility 0s linear .25s}.ol-zoom-extent{top:4.643em;left:.5em}.ol-full-screen{right:.5em;top:.5em}.ol-control button{display:block;margin:1px;padding:0;color:var(--ol-subtle-foreground-color);font-weight:700;text-decoration:none;font-size:inherit;text-align:center;height:1.375em;width:1.375em;line-height:.4em;background-color:var(--ol-background-color);border:none;border-radius:2px}.ol-control button::-moz-focus-inner{border:none;padding:0}.ol-zoom-extent button{line-height:1.4em}.ol-compass{display:block;font-weight:400;will-change:transform}.ol-touch .ol-control button{font-size:1.5em}.ol-touch .ol-zoom-extent{top:5.5em}.ol-control button:hover,.ol-control button:focus{text-decoration:none;outline:1px solid var(--ol-subtle-foreground-color);color:var(--ol-foreground-color)}.ol-zoom .ol-zoom-in{border-radius:2px 2px 0 0}.ol-zoom .ol-zoom-out{border-radius:0 0 2px 2px}.ol-attribution{text-align:right;bottom:.5em;right:.5em;max-width:calc(100% - 1.3em);display:flex;flex-flow:row-reverse;align-items:center}.ol-attribution a{color:var(--ol-subtle-foreground-color);text-decoration:none}.ol-attribution ul{margin:0;padding:1px .5em;color:var(--ol-foreground-color);text-shadow:0 0 2px var(--ol-background-color);font-size:12px}.ol-attribution li{display:inline;list-style:none}.ol-attribution li:not(:last-child):after{content:\" \"}.ol-attribution img{max-height:2em;max-width:inherit;vertical-align:middle}.ol-attribution button{flex-shrink:0}.ol-attribution.ol-collapsed ul{display:none}.ol-attribution:not(.ol-collapsed){background:var(--ol-partial-background-color)}.ol-attribution.ol-uncollapsible{bottom:0;right:0;border-radius:4px 0 0}.ol-attribution.ol-uncollapsible img{margin-top:-.2em;max-height:1.6em}.ol-attribution.ol-uncollapsible button{display:none}.ol-zoomslider{top:4.5em;left:.5em;height:200px}.ol-zoomslider button{position:relative;height:10px}.ol-touch .ol-zoomslider{top:5.5em}.ol-overviewmap{left:.5em;bottom:.5em}.ol-overviewmap.ol-uncollapsible{bottom:0;left:0;border-radius:0 4px 0 0}.ol-overviewmap .ol-overviewmap-map,.ol-overviewmap button{display:block}.ol-overviewmap .ol-overviewmap-map{border:1px solid var(--ol-subtle-foreground-color);height:150px;width:150px}.ol-overviewmap:not(.ol-collapsed) button{bottom:0;left:0;position:absolute}.ol-overviewmap.ol-collapsed .ol-overviewmap-map,.ol-overviewmap.ol-uncollapsible button{display:none}.ol-overviewmap:not(.ol-collapsed){background:var(--ol-subtle-background-color)}.ol-overviewmap-box{border:1.5px dotted var(--ol-subtle-foreground-color)}.ol-overviewmap .ol-overviewmap-box:hover{cursor:move}.o-widget--map{display:flex;flex-direction:column}.o-widget--map div.ol-scale-bar{position:absolute;left:initial;right:8px;bottom:8px}.o-map-wrapper{display:flex;width:100%;flex:1 1}.o-map{width:100%;height:100%}#map,.map-frame{height:100%}.layer-switcher{top:5rem;left:.5rem;right:unset;border-width:.0625rem;border-style:solid;border-radius:.4375rem}.layer-switcher button{background-size:30px;background-position:unset;background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgd2lkdGg9IjMyIiBoZWlnaHQ9IjMyIj48cGF0aCBmaWxsPSJub25lIiBkPSJNMCAwaDI0djI0SDB6Ii8+PHBhdGggZD0iTTIwLjA4MyAxNS4ybDEuMjAyLjcyMWEuNS41IDAgMCAxIDAgLjg1OGwtOC43NyA1LjI2MmExIDEgMCAwIDEtMS4wMyAwbC04Ljc3LTUuMjYyYS41LjUgMCAwIDEgMC0uODU4bDEuMjAyLS43MjFMMTIgMjAuMDVsOC4wODMtNC44NXptMC00LjdsMS4yMDIuNzIxYS41LjUgMCAwIDEgMCAuODU4TDEyIDE3LjY1bC05LjI4NS01LjU3MWEuNS41IDAgMCAxIDAtLjg1OGwxLjIwMi0uNzIxTDEyIDE1LjM1bDguMDgzLTQuODV6bS03LjU2OS05LjE5MWw4Ljc3MSA1LjI2MmEuNS41IDAgMCAxIDAgLjg1OEwxMiAxMyAyLjcxNSA3LjQyOWEuNS41IDAgMCAxIDAtLjg1OGw4Ljc3LTUuMjYyYTEgMSAwIDAgMSAxLjAzIDB6TTEyIDMuMzMyTDUuODg3IDcgMTIgMTAuNjY4IDE4LjExMyA3IDEyIDMuMzMyeiIvPjwvc3ZnPg==)}.layer-switcher.shown.ol-control:hover{background-color:#fff9}.ol-attribution{top:.3125rem;bottom:unset}.a-form-field[type=radio]:read-only{pointer-events:auto}\n", ".m-layer-legend{z-index:2;left:.5rem;overflow:hidden}.m-layer-legend.ol-control{border:1px solid #bccad8}.m-layer-legend button{background-color:#fafafa!important;color:#000}.m-layer-legend .-hidden{display:none}.m-layer-legend__toggle{width:1.875rem;height:1.875rem}.m-layer-legend__title{display:flex;flex-direction:row;align-items:center;background-color:#fff;justify-content:space-between}.m-layer-legend__image{background:white;overflow:scroll}.m-layer-legend__error{font-style:italic;color:#c74646}.m-layer-switcher{z-index:2;left:.5rem;overflow:hidden}.m-layer-switcher.ol-control{border:1px solid #bccad8}.m-layer-switcher button{background-color:#fafafa!important;color:#000}.m-layer-switcher .-hidden{display:none}.m-layer-switcher__toggle{width:1.875rem;height:1.875rem}.m-layer-switcher__title{display:flex;flex-direction:row;background-color:#fff;justify-content:space-between;gap:.625rem;margin-left:2.1875rem;padding:5px}.m-layer-switcher__image{background:white;overflow:scroll}.m-layer-switcher__error{font-style:italic;color:#c74646}\n"], encapsulation: i0.ViewEncapsulation.None }); }
|
|
@@ -973,7 +966,7 @@ class GeometryFieldsForPipe {
|
|
|
973
966
|
return resArr;
|
|
974
967
|
}));
|
|
975
968
|
}
|
|
976
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.6", ngImport: i0, type: GeometryFieldsForPipe, deps: [{ token: i1
|
|
969
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.6", ngImport: i0, type: GeometryFieldsForPipe, deps: [{ token: i1.Store }], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
977
970
|
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "16.1.6", ngImport: i0, type: GeometryFieldsForPipe, name: "geometryFieldsFor" }); }
|
|
978
971
|
}
|
|
979
972
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.6", ngImport: i0, type: GeometryFieldsForPipe, decorators: [{
|
|
@@ -981,16 +974,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.6", ngImpor
|
|
|
981
974
|
args: [{
|
|
982
975
|
name: 'geometryFieldsFor'
|
|
983
976
|
}]
|
|
984
|
-
}], ctorParameters: function () { return [{ type: i1
|
|
977
|
+
}], ctorParameters: function () { return [{ type: i1.Store }]; } });
|
|
985
978
|
|
|
986
979
|
class WidgetMapLegendUrlPipe {
|
|
987
980
|
constructor() {
|
|
988
981
|
this.parser = new DOMParser();
|
|
989
982
|
}
|
|
990
983
|
transform(geoLayer, ...args) {
|
|
991
|
-
const capability = args[0].capabilities
|
|
984
|
+
const capability = (args[0].capabilities ?? {})[geoLayer.url];
|
|
992
985
|
if (capability) {
|
|
993
|
-
const matchingLayer =
|
|
986
|
+
const matchingLayer = XMLUtils.getMatchingLayer(geoLayer.paramLayer, capability.doc);
|
|
994
987
|
if (matchingLayer) {
|
|
995
988
|
const matchingStyle = XMLUtils.find(matchingLayer.childNodes, 'Style');
|
|
996
989
|
if (matchingStyle) {
|
|
@@ -1019,7 +1012,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.6", ngImpor
|
|
|
1019
1012
|
|
|
1020
1013
|
const TOOLTIP_PADDING = 15;
|
|
1021
1014
|
class WidgetMapComponent extends DataWidgetComponent {
|
|
1022
|
-
constructor(store, snackBar, translateService, tooltipFactoryService, overlay, viewContainerRef, symbolService, injector, widgetMapLayerService, el
|
|
1015
|
+
constructor(store, snackBar, translateService, tooltipFactoryService, overlay, viewContainerRef, symbolService, injector, widgetMapLayerService, el) {
|
|
1023
1016
|
super(store, el);
|
|
1024
1017
|
this.snackBar = snackBar;
|
|
1025
1018
|
this.translateService = translateService;
|
|
@@ -1029,8 +1022,9 @@ class WidgetMapComponent extends DataWidgetComponent {
|
|
|
1029
1022
|
this.symbolService = symbolService;
|
|
1030
1023
|
this.injector = injector;
|
|
1031
1024
|
this.widgetMapLayerService = widgetMapLayerService;
|
|
1032
|
-
this.
|
|
1033
|
-
|
|
1025
|
+
this.layerTypes = this.widgetMapLayerService.implementationList
|
|
1026
|
+
.filter((type) => type !== 'auto')
|
|
1027
|
+
.sort((a, b) => this.translateService
|
|
1034
1028
|
.instant('@pry.widget.map.layerType.' + a)
|
|
1035
1029
|
.localeCompare(this.translateService.instant('@pry.widget.map.layerType.' + b)));
|
|
1036
1030
|
this.optionsCopy = {};
|
|
@@ -1063,9 +1057,9 @@ class WidgetMapComponent extends DataWidgetComponent {
|
|
|
1063
1057
|
})));
|
|
1064
1058
|
this.selectedIds$ = this.store.select(DashboardSelectors.selectedItemIds);
|
|
1065
1059
|
this.geoServerLayerDescriptions$ = combineLatest([
|
|
1066
|
-
this.usedDatasources$.pipe(startWith([])),
|
|
1067
|
-
this.store.select(ConfigSelectors.geoServerUrl).pipe(
|
|
1068
|
-
]).pipe(map(([dataSources, geoServerUrl]) => {
|
|
1060
|
+
this.usedDatasources$.pipe(startWith([]), distinctUntilChanged((p, c) => equal(p, c))),
|
|
1061
|
+
this.store.select(ConfigSelectors.geoServerUrl).pipe(startWith(undefined))
|
|
1062
|
+
]).pipe(debounceTime(100), map(([dataSources, geoServerUrl]) => {
|
|
1069
1063
|
if (!geoServerUrl)
|
|
1070
1064
|
return [];
|
|
1071
1065
|
return dataSources
|
|
@@ -1088,13 +1082,33 @@ class WidgetMapComponent extends DataWidgetComponent {
|
|
|
1088
1082
|
};
|
|
1089
1083
|
})
|
|
1090
1084
|
.map((layer) => layer);
|
|
1091
|
-
}));
|
|
1092
|
-
this.
|
|
1093
|
-
this.
|
|
1094
|
-
this.
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1085
|
+
}), distinctUntilChanged((p, c) => equal(p, c)));
|
|
1086
|
+
this.autoDatasetLayers$ = combineLatest([
|
|
1087
|
+
this.classes$,
|
|
1088
|
+
this.fields$,
|
|
1089
|
+
this.usedDatasources$.pipe(startWith([]), map((datasources) => datasources.filter((ds) => ds.sourceType === 'dataset')))
|
|
1090
|
+
]).pipe(map(([classes, fields, dataSets]) => dataSets
|
|
1091
|
+
.map((ds) => {
|
|
1092
|
+
const model = classes.find((clazz) => clazz.id === ds.oClass);
|
|
1093
|
+
const geoAttributes = (model?.attributes.map((attr) => ({ attr, field: fields.find((f) => attr.field === f.id) })) ?? []).filter(({ attr, field }) => !!field && GeometricFieldTypes.includes(field.type));
|
|
1094
|
+
return geoAttributes.map((geo) => ({
|
|
1095
|
+
type: 'auto',
|
|
1096
|
+
title: `${ds.name} - ${geo.attr.name} (${geo.field.type})`,
|
|
1097
|
+
oClass: ds.oClass,
|
|
1098
|
+
key: ds.id,
|
|
1099
|
+
subType: geo.field.type,
|
|
1100
|
+
classes: [ds.oClass],
|
|
1101
|
+
attribute: geo.attr.name
|
|
1102
|
+
}));
|
|
1103
|
+
})
|
|
1104
|
+
.flat()));
|
|
1105
|
+
this.subscriptions.add(this.manifest$
|
|
1106
|
+
.pipe(map((manifest) => ((manifest.options ?? { layers: [] }).layers?.filter((layer) => ['wms'].includes(layer.type))).map((layer) => layer.url)))
|
|
1107
|
+
.subscribe((urls) => urls.forEach((url) => this.store.dispatch(DashboardActions.getCapability({ url })))));
|
|
1108
|
+
this.subscriptions.add(this.geoServerLayerDescriptions$
|
|
1109
|
+
.pipe(map((layers) => layers.map((layer) => layer.url)))
|
|
1110
|
+
.subscribe((urls) => urls.forEach((url) => this.store.dispatch(DashboardActions.getCapability({ url })))));
|
|
1111
|
+
this.wmsCapabilities$ = this.store.select(DashboardSelectors.capabilities);
|
|
1098
1112
|
this.options$ = combineLatest([
|
|
1099
1113
|
this.manifest$,
|
|
1100
1114
|
this.resultSet$,
|
|
@@ -1102,13 +1116,28 @@ class WidgetMapComponent extends DataWidgetComponent {
|
|
|
1102
1116
|
this.fields$,
|
|
1103
1117
|
this.styles$,
|
|
1104
1118
|
this.geoServerLayerDescriptions$,
|
|
1105
|
-
this.wmsCapabilities
|
|
1106
|
-
|
|
1119
|
+
this.wmsCapabilities$,
|
|
1120
|
+
this.autoDatasetLayers$
|
|
1121
|
+
]).pipe(map(([manifest, resultSet, classes, fields, mapStyles, geoLayers, capabilities, autoDatasetLayers]) => {
|
|
1107
1122
|
// auto determine layers parameters to provide a working view
|
|
1108
|
-
const autoOptions = JSON.parse(JSON.stringify(
|
|
1123
|
+
const autoOptions = JSON.parse(JSON.stringify(manifest.options));
|
|
1109
1124
|
if (!autoOptions.tooltipMode) {
|
|
1110
1125
|
autoOptions.tooltipMode = TooltipMode.CLICK;
|
|
1111
1126
|
}
|
|
1127
|
+
autoOptions.layers = [
|
|
1128
|
+
...(autoOptions.layers ?? []).filter((layer) => layer.type !== 'auto'),
|
|
1129
|
+
...(autoOptions.automaticLayers
|
|
1130
|
+
? autoDatasetLayers
|
|
1131
|
+
.filter((layer) => !autoOptions.ignoreAutoLayer ||
|
|
1132
|
+
!autoOptions.ignoreAutoLayer.includes(layer.key + '-' + layer.subType))
|
|
1133
|
+
.map((layer) => ({
|
|
1134
|
+
...layer,
|
|
1135
|
+
...((autoOptions.layers ?? []).find(
|
|
1136
|
+
// @ts-ignore
|
|
1137
|
+
(prevLayer) => prevLayer.key === layer.key && prevLayer.attribute === layer.attribute) ?? {})
|
|
1138
|
+
}))
|
|
1139
|
+
: [])
|
|
1140
|
+
];
|
|
1112
1141
|
autoOptions.layers?.forEach((layer, i) => {
|
|
1113
1142
|
populateLocationAttribute(layer, resultSet, classes, fields);
|
|
1114
1143
|
populateIntensityAttribute(layer, resultSet, classes, fields);
|
|
@@ -1122,7 +1151,8 @@ class WidgetMapComponent extends DataWidgetComponent {
|
|
|
1122
1151
|
// Get all previous layers, without geoserver layers that are not requested anymore, then add new geoserver layers (potentially with a preconfig from manifest).
|
|
1123
1152
|
autoOptions.layers = [
|
|
1124
1153
|
...(autoOptions.layers ?? []).map((layer) => {
|
|
1125
|
-
|
|
1154
|
+
// @ts-ignore
|
|
1155
|
+
const geoLayer = geoLayers.find((geoLayer) => layer.key === geoLayer.key) ?? null;
|
|
1126
1156
|
return layer.type === 'geoserver'
|
|
1127
1157
|
? geoLayer
|
|
1128
1158
|
? { ...geoLayer, ...layer }
|
|
@@ -1140,8 +1170,20 @@ class WidgetMapComponent extends DataWidgetComponent {
|
|
|
1140
1170
|
const lightStyles = mapStyles.filter((style) => !(style.identifier ?? '-').includes('dark'));
|
|
1141
1171
|
autoOptions.style = lightStyles.length > 0 ? lightStyles[0].identifier : mapStyles[0].identifier;
|
|
1142
1172
|
}
|
|
1173
|
+
if (autoOptions.ignoreAutoLayer) {
|
|
1174
|
+
const base = autoOptions.ignoreAutoLayer;
|
|
1175
|
+
// Remove from ignoreAutoLayers, values that are not necessary
|
|
1176
|
+
const possibleIgnoreAutoLayerKeys = autoDatasetLayers.map((layer) => layer.key + '-' + layer.subType);
|
|
1177
|
+
autoOptions.ignoreAutoLayer = (autoOptions.ignoreAutoLayer ?? []).filter((key) => possibleIgnoreAutoLayerKeys.includes(key));
|
|
1178
|
+
if (autoOptions.ignoreAutoLayer.length === 0) {
|
|
1179
|
+
delete autoOptions.ignoreAutoLayer;
|
|
1180
|
+
}
|
|
1181
|
+
if (!autoOptions.ignoreAutoLayer || base.length !== autoOptions.ignoreAutoLayer.length) {
|
|
1182
|
+
this.emitManifest();
|
|
1183
|
+
}
|
|
1184
|
+
}
|
|
1143
1185
|
return autoOptions;
|
|
1144
|
-
}));
|
|
1186
|
+
}), distinctUntilChanged((p, c) => equal(p, c)));
|
|
1145
1187
|
this.subscriptions.add(this.options$.pipe(filter((opt) => !!opt)).subscribe((options) => {
|
|
1146
1188
|
this.optionsCopy = JSON.parse(JSON.stringify(options));
|
|
1147
1189
|
}));
|
|
@@ -1422,13 +1464,16 @@ class WidgetMapComponent extends DataWidgetComponent {
|
|
|
1422
1464
|
if (!layer.title) {
|
|
1423
1465
|
if (['geoserver', 'wms'].includes(layer.type)) {
|
|
1424
1466
|
const geoLayer = layer;
|
|
1425
|
-
const layerCapabilities = capabilities
|
|
1467
|
+
const layerCapabilities = capabilities ? capabilities[geoLayer.url] : undefined;
|
|
1426
1468
|
if (layerCapabilities) {
|
|
1427
|
-
const matchingLayer =
|
|
1469
|
+
const matchingLayer = XMLUtils.getMatchingLayer(geoLayer.paramLayer, layerCapabilities.doc);
|
|
1428
1470
|
if (matchingLayer) {
|
|
1429
1471
|
const matchingTitle = XMLUtils.find(matchingLayer.childNodes, 'Title');
|
|
1430
1472
|
if (matchingTitle) {
|
|
1431
|
-
layer.title =
|
|
1473
|
+
layer.title =
|
|
1474
|
+
!!matchingTitle.textContent && matchingTitle.textContent.length > 0
|
|
1475
|
+
? matchingTitle.textContent
|
|
1476
|
+
: undefined;
|
|
1432
1477
|
}
|
|
1433
1478
|
}
|
|
1434
1479
|
}
|
|
@@ -1576,8 +1621,11 @@ class WidgetMapComponent extends DataWidgetComponent {
|
|
|
1576
1621
|
const specificLayer = layer;
|
|
1577
1622
|
specificLayer.classes = $event;
|
|
1578
1623
|
}
|
|
1579
|
-
deleteLayer(i) {
|
|
1624
|
+
deleteLayer(i, layer) {
|
|
1580
1625
|
this.optionsCopy?.layers?.splice(i, 1);
|
|
1626
|
+
if (layer.type === 'auto') {
|
|
1627
|
+
this.optionsCopy.ignoreAutoLayer = [...(this.optionsCopy.ignoreAutoLayer ?? []), layer.key + '-' + layer.subType];
|
|
1628
|
+
}
|
|
1581
1629
|
}
|
|
1582
1630
|
invertLayers(idx, idxWith) {
|
|
1583
1631
|
if (!!this.optionsCopy && !!this.optionsCopy.layers) {
|
|
@@ -1660,12 +1708,13 @@ class WidgetMapComponent extends DataWidgetComponent {
|
|
|
1660
1708
|
.getSource()
|
|
1661
1709
|
.getFeatureInfoUrl(transform(pixel, projGeo, projLambert), this.map.getView().getResolution(), 'EPSG:2154', {
|
|
1662
1710
|
INFO_FORMAT: 'application/json',
|
|
1663
|
-
FEATURE_COUNT: 10
|
|
1711
|
+
FEATURE_COUNT: 10,
|
|
1712
|
+
...layer.getProperties()['getFeatureInfoAdditionalParameters']
|
|
1664
1713
|
});
|
|
1665
1714
|
if (url) {
|
|
1666
1715
|
this.store.dispatch(DashboardActions.getWmsFeatures({
|
|
1667
1716
|
url,
|
|
1668
|
-
oClass: layer.getProperties()
|
|
1717
|
+
oClass: layer.getProperties()['oClass'] ?? '',
|
|
1669
1718
|
coordinates: pixel
|
|
1670
1719
|
}));
|
|
1671
1720
|
}
|
|
@@ -1724,6 +1773,12 @@ class WidgetMapComponent extends DataWidgetComponent {
|
|
|
1724
1773
|
changeSingleLayer($event) {
|
|
1725
1774
|
this.optionsCopy.singleLayer = $event;
|
|
1726
1775
|
}
|
|
1776
|
+
changeAutoLayer($event) {
|
|
1777
|
+
this.optionsCopy.automaticLayers = $event;
|
|
1778
|
+
if (!this.optionsCopy.automaticLayers) {
|
|
1779
|
+
delete this.optionsCopy.ignoreAutoLayer;
|
|
1780
|
+
}
|
|
1781
|
+
}
|
|
1727
1782
|
get layerVisibleIdx() {
|
|
1728
1783
|
return this.mapLayers.map((layer, idx) => (layer.getVisible() ? idx : 0)).reduce((a, b) => a + b);
|
|
1729
1784
|
}
|
|
@@ -1731,13 +1786,13 @@ class WidgetMapComponent extends DataWidgetComponent {
|
|
|
1731
1786
|
super.ngOnDestroy();
|
|
1732
1787
|
this.store.dispatch(DashboardActions.resetWmsFeatures());
|
|
1733
1788
|
}
|
|
1734
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.6", ngImport: i0, type: WidgetMapComponent, deps: [{ token: i1
|
|
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" }] }); }
|
|
1789
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.6", ngImport: i0, type: WidgetMapComponent, deps: [{ token: i1.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 }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1790
|
+
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: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i6.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: i6.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i6.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i6.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: i7.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: i5.AsyncPipe, name: "async" }, { kind: "pipe", type: i2.I18nPipe, name: "i18n" }, { kind: "pipe", type: GeometryFieldsForPipe, name: "geometryFieldsFor" }, { kind: "pipe", type: WidgetMapLegendUrlPipe, name: "legendUrl" }] }); }
|
|
1736
1791
|
}
|
|
1737
1792
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.6", ngImport: i0, type: WidgetMapComponent, decorators: [{
|
|
1738
1793
|
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" }]
|
|
1740
|
-
}], ctorParameters: function () { return [{ type: i1
|
|
1794
|
+
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" }]
|
|
1795
|
+
}], ctorParameters: function () { return [{ type: i1.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 }]; }, propDecorators: { mapRef: [{
|
|
1741
1796
|
type: ViewChild,
|
|
1742
1797
|
args: ['mapRef']
|
|
1743
1798
|
}], popup: [{
|
|
@@ -1829,7 +1884,8 @@ const enTranslations = {
|
|
|
1829
1884
|
legendNotProvided: 'Legend not provided by server',
|
|
1830
1885
|
selectLayers: 'Select layers',
|
|
1831
1886
|
legends: 'Display legend',
|
|
1832
|
-
singleLayer: 'Single layer mode'
|
|
1887
|
+
singleLayer: 'Single layer mode',
|
|
1888
|
+
autoLayer: 'Automatic datasource layers configuration'
|
|
1833
1889
|
}
|
|
1834
1890
|
}
|
|
1835
1891
|
}
|
|
@@ -1910,7 +1966,8 @@ const frTranslations = {
|
|
|
1910
1966
|
legendNotProvided: 'Légende non fournie par le serveur',
|
|
1911
1967
|
selectLayers: 'Sélectionner les couches',
|
|
1912
1968
|
legends: 'Afficher la légende',
|
|
1913
|
-
singleLayer: 'Mode mono-couche'
|
|
1969
|
+
singleLayer: 'Mode mono-couche',
|
|
1970
|
+
autoLayer: 'Configuration automatique des sources de données'
|
|
1914
1971
|
}
|
|
1915
1972
|
}
|
|
1916
1973
|
}
|
|
@@ -1979,5 +2036,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.6", ngImpor
|
|
|
1979
2036
|
* Generated bundle index. Do not edit.
|
|
1980
2037
|
*/
|
|
1981
2038
|
|
|
1982
|
-
export { CqlUtils, DEFAULT_HEATMAP_RADIUS, DEFAULT_MAP_CENTER, DEFAULT_RADIUS_INTENSITY_FACTOR, DEFAULT_ZOOM_MAX, DEFAULT_ZOOM_MIN, DEFAULT_ZOOM_START,
|
|
2039
|
+
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, XMLUtils, exportMapAsImage, geometryForLayer, getCircleFeatureFromItem, getFeatureFromItem, getLinkFeature, getMapAsPng, populateIntensityAttribute, populateLocationAttribute };
|
|
1983
2040
|
//# sourceMappingURL=provoly-dashboard-widgets-widget-map.mjs.map
|