@igo2/geo 21.0.0-next.20 → 21.0.0-next.21

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.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Injectable, inject, Optional, DOCUMENT, input, output, Component, ChangeDetectorRef, InjectionToken, makeEnvironmentProviders, computed, ChangeDetectionStrategy, HostBinding, viewChildren, signal, model, effect, DestroyRef, Directive, viewChild, contentChild, TemplateRef, HostListener, Input, ApplicationRef, NgModule, Pipe, ElementRef, Self, EventEmitter, Output, ViewEncapsulation, Inject, Injector, APP_INITIALIZER } from '@angular/core';
2
+ import { Injectable, inject, Optional, InjectionToken, makeEnvironmentProviders, DOCUMENT, input, output, Component, ChangeDetectorRef, Injector, runInInjectionContext, computed, ChangeDetectionStrategy, HostBinding, viewChildren, signal, model, effect, DestroyRef, Directive, viewChild, contentChild, TemplateRef, HostListener, Input, ApplicationRef, NgModule, Pipe, ElementRef, Self, EventEmitter, Output, ViewEncapsulation, Inject } from '@angular/core';
3
3
  import { Clipboard } from '@angular/cdk/clipboard';
4
4
  import * as i1 from '@angular/material/button';
5
5
  import { MatButtonModule } from '@angular/material/button';
@@ -10,7 +10,7 @@ import { MatTooltipModule } from '@angular/material/tooltip';
10
10
  import { LanguageService, IgoLanguageModule } from '@igo2/core/language';
11
11
  import { MessageService } from '@igo2/core/message';
12
12
  import { RouteService } from '@igo2/core/route';
13
- import { NumberUtils, TimeFrame, uuid, ObjectUtils, isTimeFrame, resolveDate, Watcher, SubjectStatus, Compression, strEnum, Tree, TREE_SEPERATOR, ChangeUtils, downloadContent, createExcelWorkBook, addExcelSheetToWorkBook, writeExcelFile, isIsoDate, downloadBlob, customCacheHasher, removeQueryParameters } from '@igo2/utils';
13
+ import { NumberUtils, TimeFrame, uuid, ObjectUtils, isTimeFrame, resolveDate, Watcher, SubjectStatus, strEnum, Tree, TREE_SEPERATOR, ChangeUtils, downloadContent, createExcelWorkBook, addExcelSheetToWorkBook, writeExcelFile, isIsoDate, downloadBlob, customCacheHasher, removeQueryParameters } from '@igo2/utils';
14
14
  import { MAC } from 'ol/has';
15
15
  import * as olproj from 'ol/proj';
16
16
  import { transform } from 'ol/proj';
@@ -20,12 +20,12 @@ import html2canvas from 'html2canvas';
20
20
  import jsPDF, { jsPDF as jsPDF$1 } from 'jspdf';
21
21
  import { autoTable } from 'jspdf-autotable';
22
22
  import moment from 'moment';
23
- import { Observable, of, combineLatest, BehaviorSubject, interval, tap, merge, fromEvent, from, switchMap, first, concatMap as concatMap$1, map as map$1, mergeMap, zip, firstValueFrom, Subject, forkJoin, catchError as catchError$1, debounceTime as debounceTime$1, EMPTY, timer, filter as filter$1, pairwise, Subscription, lastValueFrom, throwError } from 'rxjs';
23
+ import { Observable, of, combineLatest, BehaviorSubject, interval, tap, merge, fromEvent, firstValueFrom, Subject, forkJoin, map as map$1, catchError as catchError$1, debounceTime as debounceTime$1, switchMap, EMPTY, timer, filter as filter$1, from, pairwise, Subscription, lastValueFrom, throwError, first as first$1, zip } from 'rxjs';
24
24
  import { HttpClient, HttpParams, HttpHeaders } from '@angular/common/http';
25
25
  import { fetchImageFromDepotUrl, ImageErrorDirective, SecureImagePipe } from '@igo2/common/image';
26
26
  import { saveAs } from 'file-saver';
27
27
  import JSZip from 'jszip';
28
- import { concatMap, distinctUntilChanged, map, switchMap as switchMap$1, first as first$1, mergeMap as mergeMap$1, tap as tap$1, debounceTime, catchError, delay, timeout, skip, filter, debounce, skipWhile, takeUntil, take, finalize, startWith } from 'rxjs/operators';
28
+ import { concatMap, distinctUntilChanged, map, timeout, first, catchError, debounceTime, skip, filter, switchMap as switchMap$1, debounce, mergeMap, skipWhile, takeUntil, take, finalize, startWith } from 'rxjs/operators';
29
29
  import { getUid } from 'ol/util';
30
30
  import { __decorate, __param, __metadata } from 'tslib';
31
31
  import olSourceImageWMS from 'ol/source/ImageWMS';
@@ -41,28 +41,39 @@ import olFormatGML3 from 'ol/format/GML3';
41
41
  import olFormatGML32 from 'ol/format/GML32';
42
42
  import olFormatOSMXML from 'ol/format/OSMXML';
43
43
  import LayerGroup$1 from 'ol/layer/Group';
44
- import { AuthInterceptor, AuthService } from '@igo2/auth';
44
+ import { XHR_INTERCEPTOR } from '@igo2/core/auth';
45
+ import Style from 'ol/style/Style';
46
+ import OlFeature from 'ol/Feature';
47
+ import { toString, asArray } from 'ol/color';
48
+ import * as olextent from 'ol/extent';
49
+ import { getCenter, equals } from 'ol/extent';
50
+ import OlPoint from 'ol/geom/Point';
51
+ import Circle from 'ol/style/Circle';
52
+ import Fill from 'ol/style/Fill';
53
+ import Icon from 'ol/style/Icon';
54
+ import Stroke from 'ol/style/Stroke';
55
+ import Text from 'ol/style/Text';
56
+ import { getEntityId, getEntityTitle, getEntityProperty, getEntityRevision, getEntityIcon, EntityStoreStrategy, EntityStore, EntityStoreWatcher, EntityTableColumnRenderer, EntityTableComponent, EntityStoreFilterSelectionStrategy, EntityService, isChoiceField, getColumnKeyWithoutPropertiesTag as getColumnKeyWithoutPropertiesTag$1, getEntityTitleHtml, EntityStoreFilterCustomFuncStrategy, isChoiceFieldWithLabelField } from '@igo2/common/entity';
57
+ import OlGeoJSON from 'ol/format/GeoJSON';
58
+ import OlLineString from 'ol/geom/LineString';
59
+ import OlPolygon, { fromCircle, circular } from 'ol/geom/Polygon';
60
+ import * as olstyle from 'ol/style';
45
61
  import olLayerImage from 'ol/layer/Image';
46
62
  import olLayerTile from 'ol/layer/Tile';
47
63
  import * as olObservable from 'ol/Observable';
48
64
  import { unByKey } from 'ol/Observable';
49
- import { asArray, toString } from 'ol/color';
65
+ import OlVectorLayer from 'ol/layer/Vector';
66
+ import olSourceCluster from 'ol/source/Cluster';
67
+ import OlVectorSource from 'ol/source/Vector';
50
68
  import * as oleasing from 'ol/easing';
51
69
  import { easeOut } from 'ol/easing';
52
- import OlVectorLayer from 'ol/layer/Vector';
53
70
  import { getVectorContext, getRenderPixel } from 'ol/render';
54
- import OlVectorSource from 'ol/source/Vector';
55
- import { openDB } from 'idb';
56
- import Style from 'ol/style/Style';
57
- import olSourceCluster from 'ol/source/Cluster';
71
+ import RegularShape from 'ol/style/RegularShape';
58
72
  import olLayerVectorTile from 'ol/layer/VectorTile';
59
73
  import { BehaviorSubject as BehaviorSubject$1 } from 'rxjs/internal/BehaviorSubject';
60
74
  import { Group } from 'ol/layer.js';
61
- import OlFeature from 'ol/Feature';
62
- import OlGeoJSON from 'ol/format/GeoJSON';
63
75
  import * as olgeom from 'ol/geom';
64
76
  import { Point } from 'ol/geom';
65
- import * as olstyle from 'ol/style';
66
77
  import olSourceOSM from 'ol/source/OSM';
67
78
  import olSourceXYZ from 'ol/source/XYZ';
68
79
  import * as OlLoadingStrategy from 'ol/loadingstrategy';
@@ -77,18 +88,7 @@ import TileDebug from 'ol/source/TileDebug';
77
88
  import TileGrid from 'ol/tilegrid/TileGrid';
78
89
  import olFormatMVT from 'ol/format/MVT';
79
90
  import olSourceVectorTile from 'ol/source/VectorTile';
80
- import { EntityStoreStrategy, getEntityId, getEntityTitle, getEntityProperty, getEntityRevision, getEntityIcon, EntityStore, EntityStoreWatcher, EntityTableColumnRenderer, EntityTableComponent, EntityStoreFilterSelectionStrategy, EntityService, isChoiceField, getColumnKeyWithoutPropertiesTag as getColumnKeyWithoutPropertiesTag$1, getEntityTitleHtml, EntityStoreFilterCustomFuncStrategy, isChoiceFieldWithLabelField } from '@igo2/common/entity';
81
91
  import OlDragBoxInteraction from 'ol/interaction/DragBox';
82
- import * as olextent from 'ol/extent';
83
- import { getCenter } from 'ol/extent';
84
- import OlLineString from 'ol/geom/LineString';
85
- import OlPoint from 'ol/geom/Point';
86
- import OlPolygon, { fromCircle, circular } from 'ol/geom/Polygon';
87
- import Circle from 'ol/style/Circle';
88
- import Fill from 'ol/style/Fill';
89
- import Icon from 'ol/style/Icon';
90
- import Stroke from 'ol/style/Stroke';
91
- import Text from 'ol/style/Text';
92
92
  import * as i4 from '@ngx-translate/core';
93
93
  import { moveItemInArray, CdkDropList, CdkDrag, CdkDragHandle } from '@angular/cdk/drag-drop';
94
94
  import { AsyncPipe, NgTemplateOutlet, NgClass, KeyValuePipe, JsonPipe, CommonModule, DOCUMENT as DOCUMENT$1 } from '@angular/common';
@@ -112,9 +112,12 @@ import { MatSlideToggleModule } from '@angular/material/slide-toggle';
112
112
  import * as olCondition from 'ol/events/condition';
113
113
  import { doubleClick } from 'ol/events/condition';
114
114
  import * as olInteraction from 'ol/interaction';
115
+ import olAttribution from 'ol/control/Attribution';
116
+ import { optionsFromCapabilities } from 'ol/source/WMTS.js';
117
+ import { Cacheable } from 'ts-cacheable';
118
+ import { SelectionModel } from '@angular/cdk/collections';
115
119
  import olMap from 'ol/Map';
116
120
  import olView from 'ol/View';
117
- import olAttribution from 'ol/control/Attribution';
118
121
  import olControlScaleLine from 'ol/control/ScaleLine';
119
122
  import * as olproj4 from 'ol/proj/proj4';
120
123
  import proj4 from 'proj4';
@@ -126,10 +129,7 @@ import { MatBadgeModule } from '@angular/material/badge';
126
129
  import { DomSanitizer } from '@angular/platform-browser';
127
130
  import { IgoBadgeIconDirective } from '@igo2/common/badge';
128
131
  import { IgoIconComponent, VECTOR_SQUARE_ICON, KEYBOARD_ESC_ICON } from '@igo2/common/icon';
129
- import { optionsFromCapabilities } from 'ol/source/WMTS.js';
130
- import { Cacheable } from 'ts-cacheable';
131
132
  import { NetworkService } from '@igo2/core/network';
132
- import { SelectionModel } from '@angular/cdk/collections';
133
133
  import { CollapseDirective, CollapsibleComponent } from '@igo2/common/collapsible';
134
134
  import { SanitizeHtmlPipe, CustomHtmlComponent } from '@igo2/common/custom-html';
135
135
  import { ListComponent, ListItemDirective } from '@igo2/common/list';
@@ -647,6 +647,80 @@ function mtmZoneFromLonLat(lonLat) {
647
647
  return mtmZone;
648
648
  }
649
649
 
650
+ class LayerExtensionManager {
651
+ _instances = [];
652
+ _instancesByExtension = new Map();
653
+ _attached = false;
654
+ attach(extensions, options, context) {
655
+ if (this._attached) {
656
+ throw new Error('Layer extensions are already attached');
657
+ }
658
+ const sorted = extensions
659
+ .map((extension, registrationIndex) => ({ extension, registrationIndex }))
660
+ .filter(({ extension }) => extension.supports(options))
661
+ .sort((left, right) => {
662
+ const leftPriority = left.extension.priority ?? 0;
663
+ const rightPriority = right.extension.priority ?? 0;
664
+ if (leftPriority !== rightPriority) {
665
+ return rightPriority - leftPriority;
666
+ }
667
+ return left.registrationIndex - right.registrationIndex;
668
+ })
669
+ .map(({ extension }) => extension);
670
+ const instances = [];
671
+ const instancesByExtension = new Map();
672
+ try {
673
+ for (const extension of sorted) {
674
+ const instance = extension.attach(context);
675
+ instances.push(instance);
676
+ instancesByExtension.set(extension, instance);
677
+ }
678
+ }
679
+ catch (error) {
680
+ try {
681
+ destroyInReverse(instances);
682
+ }
683
+ catch {
684
+ // Preserve the attachment error.
685
+ }
686
+ throw error;
687
+ }
688
+ this._instances = instances;
689
+ this._instancesByExtension = instancesByExtension;
690
+ this._attached = true;
691
+ }
692
+ getInstances() {
693
+ return this._instances;
694
+ }
695
+ getInstance(extension) {
696
+ return this._instancesByExtension.get(extension);
697
+ }
698
+ destroy() {
699
+ if (!this._attached) {
700
+ return;
701
+ }
702
+ const instances = this._instances;
703
+ this._instances = [];
704
+ this._instancesByExtension.clear();
705
+ this._attached = false;
706
+ destroyInReverse(instances);
707
+ }
708
+ }
709
+ function destroyInReverse(instances) {
710
+ let firstError;
711
+ for (let i = instances.length - 1; i >= 0; i--) {
712
+ try {
713
+ instances[i].destroy();
714
+ }
715
+ catch (error) {
716
+ firstError ??= error;
717
+ }
718
+ }
719
+ if (firstError) {
720
+ throw firstError;
721
+ }
722
+ }
723
+
650
724
  /**
651
725
  * @param date: string
652
726
  * @example date = <[2014-08-25, 2018-08-25]>
@@ -1810,6 +1884,7 @@ class DataSource {
1810
1884
  id;
1811
1885
  ol;
1812
1886
  legend = [];
1887
+ destroyed = false;
1813
1888
  get saveableOptions() {
1814
1889
  return {
1815
1890
  id: this.id,
@@ -1866,9 +1941,12 @@ class DataSource {
1866
1941
  this.events.set(name, obs.subscribe());
1867
1942
  }
1868
1943
  destroy() {
1869
- this.events.forEach((listener) => {
1870
- listener.unsubscribe();
1871
- });
1944
+ if (this.destroyed) {
1945
+ return;
1946
+ }
1947
+ this.destroyed = true;
1948
+ this.removeEvents();
1949
+ this.onUnwatch();
1872
1950
  }
1873
1951
  }
1874
1952
  class DatasourceProperties {
@@ -2009,8 +2087,9 @@ function formatWFSQueryString(dataSourceOptions, count, epsg, properties, startI
2009
2087
  const getCapabilities = `${url}${separator}service=WFS&request=GetCapabilities&${version}`;
2010
2088
  let getFeature = `${url}${separator}service=WFS&request=GetFeature&${version}&${featureTypes}&`;
2011
2089
  getFeature += `${outputFormat}&${srs}&${cnt}&${propertyName}&${effectiveStartIndex}`;
2012
- if (dataSourceOptions[EventRefresh]) {
2013
- getFeature += `&${EventRefresh}=${dataSourceOptions[EventRefresh]}`;
2090
+ const refreshValue = dataSourceOptions[EventRefresh];
2091
+ if (refreshValue !== undefined) {
2092
+ getFeature += `&${EventRefresh}=${String(refreshValue)}`;
2014
2093
  }
2015
2094
  let getpropertyvalue = `${url}?service=WFS&request=GetPropertyValue&version=${versionWfs200}&${featureTypes}&`;
2016
2095
  getpropertyvalue += `&${cnt}&${valueReference}`;
@@ -3431,6 +3510,629 @@ function _isLinkedMaster(layer, layerToCheck) {
3431
3510
  return false;
3432
3511
  }
3433
3512
 
3513
+ const FLAT_STYLE_KEYS = [
3514
+ 'fill-color',
3515
+ 'fill-opacity',
3516
+ 'stroke-color',
3517
+ 'stroke-width',
3518
+ 'stroke-opacity',
3519
+ 'circle-radius',
3520
+ 'circle-fill-color',
3521
+ 'icon-src',
3522
+ 'icon-scale',
3523
+ 'text-field',
3524
+ 'text-font',
3525
+ 'text-size'
3526
+ ];
3527
+ function isEngineLayerStyle(value) {
3528
+ return isRecord(value) && typeof value['type'] === 'string';
3529
+ }
3530
+ function isOlFlatStyleLike(value) {
3531
+ if (!value)
3532
+ return false;
3533
+ if (isOlRuleArray(value))
3534
+ return true;
3535
+ if (Array.isArray(value)) {
3536
+ return value.length > 0 && value.every(isOlFlatStyleLike);
3537
+ }
3538
+ return isRecord(value) && hasAnyFlatStyleKey(value);
3539
+ }
3540
+ function isAnyOlStyle(value) {
3541
+ return (!isEngineLayerStyle(value) &&
3542
+ (isOlStyleLike(value) || isOlFlatStyleLike(value)));
3543
+ }
3544
+ // Analyser les méthodes exporter ou non, enlever les export si elles sont utilisé localement.
3545
+ function isRecord(value) {
3546
+ return typeof value === 'object' && value !== null;
3547
+ }
3548
+ function isOlStyleInstance(value) {
3549
+ return value instanceof Style;
3550
+ }
3551
+ function isOlStyleInstanceArray(value) {
3552
+ return Array.isArray(value) && value.every(isOlStyleInstance);
3553
+ }
3554
+ function isOlStyleFunction(value) {
3555
+ return typeof value === 'function';
3556
+ }
3557
+ function isOlRule(value) {
3558
+ if (!isRecord(value) || !('style' in value))
3559
+ return false;
3560
+ const styleValue = value.style;
3561
+ return (isOlFlatStyleLike(styleValue) ||
3562
+ (Array.isArray(styleValue) && styleValue.every(isOlFlatStyleLike)));
3563
+ }
3564
+ function isOlRuleArray(value) {
3565
+ return Array.isArray(value) && value.every(isOlRule);
3566
+ }
3567
+ function hasAnyFlatStyleKey(value) {
3568
+ return FLAT_STYLE_KEYS.some((key) => Object.prototype.hasOwnProperty.call(value, key));
3569
+ }
3570
+ function isOlStyleLike(value) {
3571
+ return (!!value &&
3572
+ (isOlStyleInstance(value) ||
3573
+ isOlStyleInstanceArray(value) ||
3574
+ isOlStyleFunction(value)));
3575
+ }
3576
+
3577
+ const FEATURE = 'Feature';
3578
+ var FeatureMotion;
3579
+ (function (FeatureMotion) {
3580
+ FeatureMotion[FeatureMotion["None"] = 0] = "None";
3581
+ FeatureMotion[FeatureMotion["Move"] = 1] = "Move";
3582
+ FeatureMotion[FeatureMotion["Zoom"] = 2] = "Zoom";
3583
+ FeatureMotion[FeatureMotion["Default"] = 3] = "Default";
3584
+ })(FeatureMotion || (FeatureMotion = {}));
3585
+
3586
+ /**
3587
+ * Create an Openlayers feature object out of a feature definition.
3588
+ * The output object has a reference to the feature id.
3589
+ * @param feature Feature definition
3590
+ * @param projectionOut Feature object projection
3591
+ * @returns OpenLayers feature object
3592
+ */
3593
+ function featureToOl(feature, projectionOut, getId) {
3594
+ getId = getId ? getId : getEntityId;
3595
+ const olFormat = new OlGeoJSON();
3596
+ const olFeature = olFormat.readFeature(feature, {
3597
+ dataProjection: feature.projection,
3598
+ featureProjection: projectionOut
3599
+ });
3600
+ olFeature.setId(getId(feature));
3601
+ const title = getEntityTitle(feature);
3602
+ if (title !== undefined) {
3603
+ olFeature.set('_title', title, true);
3604
+ }
3605
+ if (feature.extent !== undefined) {
3606
+ olFeature.set('_extent', feature.extent, true);
3607
+ }
3608
+ if (feature.projection !== undefined) {
3609
+ olFeature.set('_projection', feature.projection, true);
3610
+ }
3611
+ const mapTitle = getEntityProperty(feature, 'meta.mapTitle');
3612
+ if (mapTitle !== undefined) {
3613
+ olFeature.set('_mapTitle', mapTitle, true);
3614
+ }
3615
+ olFeature.set('_entityRevision', getEntityRevision(feature), true);
3616
+ const icon = getEntityIcon(feature);
3617
+ if (icon !== undefined) {
3618
+ olFeature.set('_icon', icon, true);
3619
+ }
3620
+ if (feature.meta && feature.meta.style) {
3621
+ olFeature.set('_style', feature.meta.style, true);
3622
+ }
3623
+ if (feature.sourceId) {
3624
+ olFeature.set('_sourceId', feature.sourceId, true);
3625
+ }
3626
+ return olFeature;
3627
+ }
3628
+ function renderFeatureFromOl(olRenderFeature, projectionIn, olLayer, projectionOut = 'EPSG:4326') {
3629
+ let geom;
3630
+ let title;
3631
+ let exclude;
3632
+ let excludeOffline;
3633
+ if (olLayer) {
3634
+ title = olLayer.get('title');
3635
+ if (olLayer.get('sourceOptions')) {
3636
+ exclude = olLayer.get('sourceOptions').excludeAttribute;
3637
+ excludeOffline = olLayer.get('sourceOptions').excludeAttributeOffline;
3638
+ }
3639
+ }
3640
+ else {
3641
+ title = olRenderFeature.get('_title');
3642
+ }
3643
+ const olFormat = new OlGeoJSON();
3644
+ const properties = olRenderFeature.getProperties();
3645
+ const geometryType = olRenderFeature.getType();
3646
+ if (geometryType === 'Polygon') {
3647
+ const ends = olRenderFeature.getEnds();
3648
+ geom = new OlPolygon(olRenderFeature.getFlatCoordinates(), 'XY', ends);
3649
+ }
3650
+ else if (geometryType === 'Point') {
3651
+ geom = new OlPoint(olRenderFeature.getFlatCoordinates(), 'XY');
3652
+ }
3653
+ else if (geometryType === 'LineString') {
3654
+ geom = new OlLineString(olRenderFeature.getFlatCoordinates(), 'XY');
3655
+ }
3656
+ const geometry = olFormat.writeGeometryObject(geom, {
3657
+ dataProjection: projectionOut,
3658
+ featureProjection: projectionIn
3659
+ });
3660
+ const id = (olRenderFeature.getId() ?? uuid());
3661
+ const mapTitle = olRenderFeature.get('_mapTitle');
3662
+ const extent = olproj.transformExtent(olRenderFeature.getExtent(), projectionIn, projectionOut);
3663
+ return {
3664
+ type: FEATURE,
3665
+ projection: projectionOut,
3666
+ extent,
3667
+ meta: {
3668
+ id,
3669
+ title: title ? title : mapTitle ? mapTitle : id,
3670
+ mapTitle,
3671
+ excludeAttribute: exclude,
3672
+ excludeAttributeOffline: excludeOffline
3673
+ },
3674
+ properties,
3675
+ geometry,
3676
+ ol: olRenderFeature
3677
+ };
3678
+ }
3679
+ /**
3680
+ * Create a feature object out of an OL feature
3681
+ * The output object has a reference to the feature id.
3682
+ * @param olFeature OL Feature
3683
+ * @param projectionIn OL feature projection
3684
+ * @param olLayer OL Layer
3685
+ * @param projectionOut Feature projection
3686
+ * @returns Feature
3687
+ */
3688
+ function featureFromOl(olFeature, projectionIn, olLayer, projectionOut = 'EPSG:4326') {
3689
+ let title;
3690
+ let exclude;
3691
+ let excludeOffline;
3692
+ let idColumn; // for arcgisrest and tilearcgisrest source
3693
+ const olFormat = new OlGeoJSON();
3694
+ const keys = olFeature.getKeys().filter((key) => {
3695
+ return !key.startsWith('_') && key !== 'geometry';
3696
+ });
3697
+ const properties = keys.reduce((acc, key) => {
3698
+ acc[key] = olFeature.get(key);
3699
+ return acc;
3700
+ }, {});
3701
+ const geometry = olFormat.writeGeometryObject(olFeature.getGeometry(), {
3702
+ dataProjection: projectionOut,
3703
+ featureProjection: projectionIn
3704
+ });
3705
+ if (olLayer) {
3706
+ title = olLayer.get('title');
3707
+ const sourceOptions = olLayer.get('sourceOptions');
3708
+ if (sourceOptions) {
3709
+ exclude = sourceOptions.excludeAttribute;
3710
+ excludeOffline = sourceOptions.excludeAttributeOffline;
3711
+ idColumn =
3712
+ sourceOptions.idColumn ||
3713
+ (sourceOptions.type === 'arcgisrest' ||
3714
+ sourceOptions.type === 'tilearcgisrest'
3715
+ ? 'OBJECTID'
3716
+ : undefined);
3717
+ }
3718
+ }
3719
+ else {
3720
+ title = olFeature.get('_title');
3721
+ }
3722
+ const mapTitle = olFeature.get('_mapTitle');
3723
+ const id = olFeature.getId()
3724
+ ? olFeature.getId()
3725
+ : olFeature.get(idColumn)
3726
+ ? olFeature.get(idColumn)
3727
+ : uuid();
3728
+ return {
3729
+ type: FEATURE,
3730
+ projection: projectionOut,
3731
+ extent: olFeature.get('_extent'),
3732
+ meta: {
3733
+ id,
3734
+ title: title ? title : mapTitle ? mapTitle : id,
3735
+ mapTitle,
3736
+ revision: olFeature.getRevision(),
3737
+ style: olFeature.get('_style'),
3738
+ excludeAttribute: exclude,
3739
+ excludeAttributeOffline: excludeOffline
3740
+ },
3741
+ properties,
3742
+ geometry,
3743
+ ol: olFeature
3744
+ };
3745
+ }
3746
+ /**
3747
+ * Compute an OL feature extent in it's map projection
3748
+ * @param map Map
3749
+ * @param olFeature OL feature
3750
+ * @returns Extent in the map projection
3751
+ */
3752
+ function computeOlFeatureExtent(olFeature, projection) {
3753
+ let olExtent = olextent.createEmpty();
3754
+ const olFeatureExtent = olFeature.get('_extent');
3755
+ const olFeatureProjection = olFeature.get('_projection');
3756
+ if (olFeatureExtent !== undefined && olFeatureProjection !== undefined) {
3757
+ olExtent = olproj.transformExtent(olFeatureExtent, olFeatureProjection, projection);
3758
+ }
3759
+ else {
3760
+ const olGeometry = olFeature.getGeometry();
3761
+ if (olGeometry !== null && olGeometry !== undefined) {
3762
+ olExtent = olGeometry.getExtent();
3763
+ }
3764
+ }
3765
+ return olExtent;
3766
+ }
3767
+ /**
3768
+ * Compute a multiple OL features extent in their map projection
3769
+ * @param map Map
3770
+ * @param olFeatures OL features
3771
+ * @returns Extent in the map projection
3772
+ */
3773
+ function computeOlFeaturesExtent(olFeatures, projection) {
3774
+ const extent = olextent.createEmpty();
3775
+ olFeatures.forEach((olFeature) => {
3776
+ const featureExtent = computeOlFeatureExtent(olFeature, projection);
3777
+ olextent.extend(extent, featureExtent);
3778
+ });
3779
+ return extent;
3780
+ }
3781
+ /**
3782
+ * Scale an extent.
3783
+ * @param extent Extent
3784
+ * @param Scaling factors for top, right, bottom and left directions, in that order
3785
+ * @returns Scaled extent
3786
+ */
3787
+ function scaleExtent(extent, scale) {
3788
+ const [width, height] = olextent.getSize(extent);
3789
+ return [
3790
+ scale[3] ? extent[0] - width * scale[3] : extent[0],
3791
+ scale[2] ? extent[1] - height * scale[2] : extent[1],
3792
+ scale[1] ? extent[2] + width * scale[1] : extent[2],
3793
+ scale[0] ? extent[3] + height * scale[0] : extent[3]
3794
+ ];
3795
+ }
3796
+ /**
3797
+ * Return true if features are out of view.
3798
+ * If features are too close to the edge, they are considered out of view.
3799
+ * By default, we define the edge as 5% (0.05) of the extent size.
3800
+ * @param map Map
3801
+ * @param featuresExtent The features's extent
3802
+ * @param edgeRatio Number or Number[] Single value OR an array =>
3803
+ * [top,right,bottom,left] directions, in that order
3804
+ * @returns Return true if features are out of view
3805
+ */
3806
+ function featuresAreOutOfView(extent, featuresExtent, edgeRatio = 0.05) {
3807
+ const edgesRatio = Array.isArray(edgeRatio)
3808
+ ? edgeRatio
3809
+ : [edgeRatio, edgeRatio, edgeRatio, edgeRatio];
3810
+ const scale = [-1, -1, -1, -1].map((x, i) => x * edgesRatio[i]);
3811
+ const viewExtent = scaleExtent(extent, scale);
3812
+ return !olextent.containsExtent(viewExtent, featuresExtent);
3813
+ }
3814
+ /**
3815
+ * Return true if features are too deep into the view. This results
3816
+ * in features being too small.
3817
+ * Features are considered too small if their extent occupies less than
3818
+ * 1% of the map extent.
3819
+ * @param map Map
3820
+ * @param featuresExtent The features's extent
3821
+ * @param areaRatio The features extent to view extent acceptable ratio
3822
+ * @returns Return true if features are too deep in the view
3823
+ */
3824
+ function featuresAreTooDeepInView(viewController, featuresExtent, areaRatio) {
3825
+ // An area ratio of 0.004 means that the feature extent's width and height
3826
+ // should be about 1/16 of the map extent's width and height
3827
+ areaRatio = areaRatio ? areaRatio : 0.004;
3828
+ const mapExtent = viewController.getExtent();
3829
+ const mapExtentArea = olextent.getArea(mapExtent);
3830
+ const featuresExtentArea = olextent.getArea(featuresExtent);
3831
+ if (featuresExtentArea === 0 && viewController.getZoom() > 13) {
3832
+ // In case it's a point
3833
+ return false;
3834
+ }
3835
+ return featuresExtentArea / mapExtentArea < areaRatio;
3836
+ }
3837
+ /**
3838
+ * Fit view to include the features extent.
3839
+ * By default, this method will let the features occupy about 50% of the viewport.
3840
+ * @param map Map
3841
+ * @param olFeatures OL features
3842
+ * @param motion To motion to the new map view
3843
+ * @param scale If this is defined, the original view will be scaled
3844
+ * by that factor before any logic is applied.
3845
+ */
3846
+ function moveToOlFeatures(viewController, olFeatures, motion = FeatureMotion.Default, scale, areaRatio) {
3847
+ const extent = viewController.getExtent();
3848
+ const projection = viewController.getOlProjection();
3849
+ const featuresExtent = computeOlFeaturesExtent(Array.isArray(olFeatures) ? olFeatures : [olFeatures], projection);
3850
+ let viewExtent = featuresExtent;
3851
+ if (scale !== undefined) {
3852
+ viewExtent = scaleExtent(viewExtent, scale);
3853
+ }
3854
+ if (motion === FeatureMotion.Zoom) {
3855
+ viewController.zoomToExtent(viewExtent);
3856
+ }
3857
+ else if (motion === FeatureMotion.Move) {
3858
+ viewController.moveToExtent(viewExtent);
3859
+ }
3860
+ else if (motion === FeatureMotion.Default) {
3861
+ if (featuresAreOutOfView(extent, featuresExtent) ||
3862
+ featuresAreTooDeepInView(viewController, featuresExtent, areaRatio)) {
3863
+ viewController.zoomToExtent(viewExtent);
3864
+ }
3865
+ }
3866
+ }
3867
+ /**
3868
+ * Hide an OL feature
3869
+ * @param olFeature OL feature
3870
+ */
3871
+ function hideOlFeature(olFeature) {
3872
+ olFeature.setStyle(new olstyle.Style({}));
3873
+ }
3874
+ /**
3875
+ * Compute a diff between a source array of Ol features and a target array
3876
+ * @param source Source array of OL features
3877
+ * @param starget Target array of OL features
3878
+ * @returns Features to add and remove
3879
+ */
3880
+ function computeOlFeaturesDiff(source, target) {
3881
+ const olFeaturesMap = new Map();
3882
+ target.forEach((olFeature) => {
3883
+ olFeaturesMap.set(olFeature.getId(), olFeature);
3884
+ });
3885
+ const olFeaturesToRemove = [];
3886
+ source.forEach((olFeature) => {
3887
+ const newOlFeature = olFeaturesMap.get(olFeature.getId());
3888
+ if (newOlFeature === undefined) {
3889
+ olFeaturesToRemove.push(olFeature);
3890
+ }
3891
+ else if (newOlFeature.get('_entityRevision') !== olFeature.get('_entityRevision')) {
3892
+ olFeaturesToRemove.push(olFeature);
3893
+ }
3894
+ else {
3895
+ olFeaturesMap.delete(newOlFeature.getId());
3896
+ }
3897
+ });
3898
+ const olFeaturesToAddIds = Array.from(olFeaturesMap.keys());
3899
+ const olFeaturesToAdd = target.filter((olFeature) => {
3900
+ return olFeaturesToAddIds.indexOf(olFeature.getId()) >= 0;
3901
+ });
3902
+ return {
3903
+ add: olFeaturesToAdd,
3904
+ remove: olFeaturesToRemove
3905
+ };
3906
+ }
3907
+
3908
+ const STYLES_VARIANT = {
3909
+ base: {
3910
+ fill: 'rgba(0, 161, 222, 0.15)',
3911
+ stroke: 'rgba(0, 161, 222, 0.5)',
3912
+ strokeWidth: 2,
3913
+ markerColor: 'rgba(0, 161, 222, 0.5)',
3914
+ markerOutlineColor: 'rgba(255, 255, 255, 1)'
3915
+ },
3916
+ focus: {
3917
+ fill: 'rgba(207, 222, 0, 0.15)',
3918
+ stroke: 'rgba(11, 220, 228, 0.5)',
3919
+ strokeWidth: 4,
3920
+ markerColor: 'rgba(207, 222, 0, 1)',
3921
+ markerOutlineColor: 'rgba(11, 220, 228, 1)'
3922
+ },
3923
+ selection: {
3924
+ fill: 'rgba(0, 161, 222, 0.15)',
3925
+ stroke: 'rgba(0, 255, 255, 0.5)',
3926
+ strokeWidth: 4,
3927
+ markerColor: 'rgba(0, 161, 222, 1)',
3928
+ markerOutlineColor: 'rgba(0, 255, 255, 1)'
3929
+ }
3930
+ };
3931
+ const NEAR_TRANSPARENT_COLOR = 'rgba(255, 255, 255, 0.01)';
3932
+ const DEFAULT_MARKER_COLOR = 'rgba(0, 161, 222, 1)';
3933
+ const DEFAULT_MARKER_OUTLINE_COLOR = 'rgba(255, 255, 255, 1)';
3934
+ const DEFAULT_CLUSTER_COLOR = 'rgba(24, 134, 45)';
3935
+ const DEFAULT_CLUSTER_FILL_COLOR = 'rgba(24, 134, 45, 0.5)';
3936
+ const DEFAULT_TEXT_COLOR = '#000';
3937
+ const DEFAULT_TEXT_OUTLINE_COLOR = '#fff';
3938
+ const DEFAULT_TEXT_FONT = '12px Calibri,sans-serif';
3939
+ const DEFAULT_TEXT_STROKE_WIDTH = 3;
3940
+ const DEFAULT_MARKER_ANCHOR = [0.5, 0.92];
3941
+ const GEOMETRY_THRESHOLD = 0.0025;
3942
+ const RANDOM_STYLE_MAX_CHANNEL = 255;
3943
+ const CLUSTER_MIN_RADIUS = 6;
3944
+ const CLUSTER_RADIUS_FACTOR = 5;
3945
+ function styleVariant(viewController, type = 'base') {
3946
+ return (featureLike) => {
3947
+ const { _mapTitle: mapTitle } = featureLike.getProperties();
3948
+ const imposedGeometry = featureLike instanceof OlFeature
3949
+ ? createStyleGeometry(viewController, featureLike)
3950
+ : undefined;
3951
+ return createStyleVariant(type, mapTitle, imposedGeometry);
3952
+ };
3953
+ }
3954
+ function baseOlStyle(text, imposedGeometry) {
3955
+ return createStyleVariant('base', text, imposedGeometry);
3956
+ }
3957
+ function selectionOlStyle(text, imposedGeometry) {
3958
+ return createStyleVariant('selection', text, imposedGeometry);
3959
+ }
3960
+ /**
3961
+ * Invisible-but-interactive style (hit detection, event capture).
3962
+ */
3963
+ function nearTransparentOlStyle() {
3964
+ return new Style({
3965
+ fill: new Fill({ color: NEAR_TRANSPARENT_COLOR }),
3966
+ stroke: new Stroke({ width: 10, color: NEAR_TRANSPARENT_COLOR }),
3967
+ image: new Circle({
3968
+ stroke: new Stroke({ width: 10, color: NEAR_TRANSPARENT_COLOR }),
3969
+ fill: new Fill({ color: NEAR_TRANSPARENT_COLOR }),
3970
+ radius: 5
3971
+ })
3972
+ });
3973
+ }
3974
+ function markerOlStyle({ text, markerColor = DEFAULT_MARKER_COLOR, markerOutlineColor = DEFAULT_MARKER_OUTLINE_COLOR, imposedGeometry }) {
3975
+ const svg = createMarkerSvg(markerColor, markerOutlineColor);
3976
+ const style = new Style({
3977
+ image: new Icon({
3978
+ src: `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}`,
3979
+ opacity: 1,
3980
+ anchor: DEFAULT_MARKER_ANCHOR
3981
+ })
3982
+ });
3983
+ if (text) {
3984
+ style.setText(new Text({
3985
+ text,
3986
+ font: DEFAULT_TEXT_FONT,
3987
+ fill: new Fill({ color: DEFAULT_TEXT_COLOR }),
3988
+ stroke: new Stroke({
3989
+ color: DEFAULT_TEXT_OUTLINE_COLOR,
3990
+ width: DEFAULT_TEXT_STROKE_WIDTH
3991
+ }),
3992
+ overflow: true
3993
+ }));
3994
+ }
3995
+ return setGeometryIfNeeded(style, imposedGeometry);
3996
+ }
3997
+ function randomOlFlatStyle() {
3998
+ const red = randomChannel();
3999
+ const green = randomChannel();
4000
+ const blue = randomChannel();
4001
+ return {
4002
+ 'stroke-color': [red, green, blue, 1],
4003
+ 'stroke-width': 2,
4004
+ 'fill-color': [red, green, blue, 0.4],
4005
+ 'circle-radius': 5,
4006
+ 'circle-stroke-color': [red, green, blue, 1],
4007
+ 'circle-stroke-width': 2,
4008
+ 'circle-fill-color': [red, green, blue, 0.4],
4009
+ 'text-value': ['case', ['has', '_mapTitle'], ['get', '_mapTitle'], ''],
4010
+ 'text-offset-x': 5,
4011
+ 'text-offset-y': -5,
4012
+ 'text-font': DEFAULT_TEXT_FONT,
4013
+ 'text-fill-color': DEFAULT_TEXT_COLOR,
4014
+ 'text-stroke-color': DEFAULT_TEXT_OUTLINE_COLOR,
4015
+ 'text-stroke-width': DEFAULT_TEXT_STROKE_WIDTH,
4016
+ 'text-overflow': true
4017
+ };
4018
+ }
4019
+ function clusterOlStyleFunction(clusterParam = {}) {
4020
+ return (feature) => {
4021
+ const size = feature.get('features')
4022
+ ?.length ?? 0;
4023
+ if (size <= 1) {
4024
+ return markerOlStyle({ markerColor: DEFAULT_CLUSTER_COLOR });
4025
+ }
4026
+ const clusterRadius = clusterParam.radiusCalc?.(size) ??
4027
+ Math.max(CLUSTER_MIN_RADIUS, CLUSTER_RADIUS_FACTOR * Math.log(size));
4028
+ return [
4029
+ new Style({
4030
+ image: new Circle({
4031
+ radius: clusterRadius,
4032
+ stroke: new Stroke({ color: DEFAULT_CLUSTER_COLOR }),
4033
+ fill: new Fill({ color: DEFAULT_CLUSTER_FILL_COLOR })
4034
+ }),
4035
+ text: new Text({
4036
+ text: String(size),
4037
+ fill: new Fill({ color: DEFAULT_TEXT_OUTLINE_COLOR })
4038
+ })
4039
+ })
4040
+ ];
4041
+ };
4042
+ }
4043
+ function createMarkerSvg(markerColor, markerOutlineColor) {
4044
+ return `<svg version="1.1" xmlns="http://www.w3.org/2000/svg" height="36" width="36" viewBox="0 0 36 36">
4045
+ <path fill="${toString(asArray(markerColor))}" stroke="${toString(asArray(markerOutlineColor))}" stroke-width="2"
4046
+ d="M 17.692635,32.565644 C 15.71852,30.330584 13.290925,27.058065 11.6766,24.455732 9.3398623,20.688851 7.8905694,17.205334 7.6297492,14.728733 7.5616025,14.081649 7.5739557,12.528552 7.6513363,12.014724 8.1013861,9.0262716 9.8047068,6.3655569 12.310675,4.7364878 c 1.113691,-0.7239832 2.508083,-1.2834131 3.776687,-1.5152052 0.242945,-0.044389 0.451656,-0.09393 0.463804,-0.1100911 0.01215,-0.016161 0.638282,-0.025502 1.391411,-0.02076 1.088235,0.00685 1.450932,0.024316 1.766871,0.085071 2.650763,0.5097353 4.947142,1.8701891 6.498786,3.8501033 0.628018,0.8013587 1.297046,2.0200608 1.640967,2.9891872 0.191065,0.538399 0.427644,1.447408 0.477391,1.834287 0.0164,0.127546 0.0434,0.231902 0.06,0.231902 0.0166,0 0.03122,0.626135 0.03249,1.391411 0.0013,0.765276 -0.011,1.391411 -0.02726,1.391411 -0.01626,0 -0.05449,0.154049 -0.08495,0.342331 -0.08815,0.544879 -0.387235,1.721449 -0.604837,2.379406 -1.209421,3.656888 -4.014463,8.349762 -7.849521,13.132357 -0.790496,0.985807 -1.795217,2.167992 -1.842543,2.167992 -0.01896,0 -0.161766,-0.144111 -0.317336,-0.320246 z m 1.066937,-15.36525 c 0.133519,-0.02121 0.248766,-0.05657 0.256105,-0.07859 0.0073,-0.02202 0.04918,-0.03066 0.09298,-0.0192 0.0438,0.01145 0.107628,-0.0072 0.141834,-0.04137 0.03421,-0.03421 0.08456,-0.05474 0.111888,-0.04563 0.02733,0.0091 0.07703,-0.01077 0.110429,-0.04417 0.03341,-0.03341 0.08416,-0.05293 0.112796,-0.04338 0.02863,0.0095 0.08974,-0.01867 0.135802,-0.06271 0.04606,-0.04403 0.111902,-0.08625 0.146319,-0.09381 0.204084,-0.04483 0.762371,-0.519108 1.079463,-0.917027 0.26749,-0.335672 0.570987,-0.878795 0.529019,-0.946701 -0.01496,-0.0242 -0.0067,-0.044 0.01835,-0.044 0.05645,0 0.196809,-0.467982 0.158801,-0.529481 -0.01521,-0.02461 -0.0043,-0.04475 0.02427,-0.04475 0.03157,0 0.04365,-0.04329 0.03082,-0.11043 -0.01161,-0.06074 -0.0066,-0.110429 0.01124,-0.110429 0.01779,0 0.03235,-0.258405 0.03235,-0.574233 0,-0.315829 -0.01545,-0.574234 -0.03434,-0.574234 -0.01889,0 -0.02437,-0.03811 -0.01219,-0.08469 0.04412,-0.168712 -0.336329,-1.152668 -0.481536,-1.245401 -0.02327,-0.01486 -0.04022,-0.03992 -0.03765,-0.05568 0.01222,-0.07498 -0.156557,-0.318365 -0.406379,-0.586027 -0.295921,-0.317054 -0.773059,-0.690104 -0.83427,-0.652274 -0.0206,0.01273 -0.03745,0.0024 -0.03745,-0.02289 0,-0.06107 -0.433076,-0.2789369 -0.487546,-0.245273 -0.02338,0.01445 -0.04251,0.0068 -0.04251,-0.01695 0,-0.056281 -0.393995,-0.1865457 -0.613804,-0.2029397 -0.0943,-0.00703 -0.188579,-0.023183 -0.209503,-0.035888 -0.02092,-0.012705 -0.276571,-0.023337 -0.568105,-0.023627 -0.534044,-5.301e-4 -1.12638,0.091025 -1.12638,0.1741017 0,0.023781 -0.01713,0.032648 -0.03808,0.019705 -0.05054,-0.031232 -0.403641,0.1088602 -0.403641,0.1601422 0,0.02204 -0.01988,0.02779 -0.04417,0.01278 -0.0243,-0.01501 -0.04417,-0.0051 -0.04417,0.02209 0,0.02716 -0.01988,0.0371 -0.04417,0.02209 -0.0243,-0.01501 -0.04417,-0.0051 -0.04417,0.02209 0,0.02716 -0.01915,0.03755 -0.04256,0.02308 -0.02341,-0.01447 -0.08138,0.01252 -0.128834,0.05997 -0.04745,0.04745 -0.0974,0.07515 -0.111001,0.06155 -0.0136,-0.0136 -0.03722,0.0078 -0.05248,0.0476 -0.01526,0.03978 -0.0411,0.06408 -0.0574,0.054 -0.03277,-0.02025 -0.462299,0.323995 -0.491977,0.394291 -0.01026,0.02429 -0.07454,0.0912 -0.142856,0.148686 -0.248033,0.208705 -0.730279,0.974169 -0.672565,1.067553 0.0145,0.02346 0.0059,0.04266 -0.01914,0.04266 -0.05907,0 -0.241471,0.599428 -0.208527,0.685278 0.01385,0.0361 0.0044,0.06564 -0.02098,0.06564 -0.02539,0 -0.04169,0.0646 -0.03622,0.143558 0.0055,0.07896 -0.0042,0.213129 -0.02144,0.29816 -0.04741,0.233576 0.0511,1.055502 0.167516,1.397721 0.126048,0.370516 0.310099,0.740163 0.426484,0.856548 0.04776,0.04776 0.07554,0.08684 0.06174,0.08684 -0.0138,0 0.01516,0.05653 0.06436,0.125632 0.131301,0.184396 0.499365,0.587266 0.518785,0.567846 0.0092,-0.0092 0.09821,0.06081 0.197812,0.155562 0.09961,0.09475 0.190589,0.162786 0.202187,0.151188 0.0116,-0.0116 0.05991,0.01774 0.107361,0.06519 0.04745,0.04745 0.105426,0.07444 0.128834,0.05997 0.02341,-0.01447 0.04256,-0.0057 0.04256,0.01958 0,0.06106 0.344664,0.23496 0.399061,0.201341 0.02346,-0.0145 0.04266,-0.0059 0.04266,0.01914 0,0.05907 0.599429,0.241471 0.685279,0.208527 0.0361,-0.01385 0.06564,-0.0065 0.06564,0.01645 0,0.05196 1.079115,0.04833 1.413314,-0.0048 z"></path>
4047
+ </svg>`;
4048
+ }
4049
+ function randomChannel() {
4050
+ return Math.floor(Math.random() * RANDOM_STYLE_MAX_CHANNEL);
4051
+ }
4052
+ function setGeometryIfNeeded(style, geometry) {
4053
+ if (geometry)
4054
+ style.setGeometry(geometry);
4055
+ return style;
4056
+ }
4057
+ function createStyleGeometry(viewController, feature) {
4058
+ if (!viewController || !feature)
4059
+ return undefined;
4060
+ const geometry = feature.getGeometry();
4061
+ const extent = geometry?.getExtent();
4062
+ if (!extent)
4063
+ return undefined;
4064
+ if (!featuresAreTooDeepInView(viewController, extent, GEOMETRY_THRESHOLD)) {
4065
+ return undefined;
4066
+ }
4067
+ return new OlPoint(getCenter(extent));
4068
+ }
4069
+ function createStyleVariant(variant, text, imposedGeometry) {
4070
+ const config = STYLES_VARIANT[variant];
4071
+ return [
4072
+ markerOlStyle({
4073
+ text,
4074
+ markerColor: config.markerColor,
4075
+ markerOutlineColor: config.markerOutlineColor,
4076
+ imposedGeometry
4077
+ }),
4078
+ setGeometryIfNeeded(new Style({
4079
+ fill: new Fill({ color: config.fill }),
4080
+ stroke: new Stroke({ width: config.strokeWidth, color: config.stroke })
4081
+ }), imposedGeometry)
4082
+ ];
4083
+ }
4084
+
4085
+ const STYLE_ENGINES = new InjectionToken('STYLE_ENGINES');
4086
+ function provideStyle(...features) {
4087
+ const providers = [];
4088
+ for (const feature of features) {
4089
+ providers.push(...feature.providers);
4090
+ }
4091
+ return makeEnvironmentProviders(providers);
4092
+ }
4093
+
4094
+ const ENGINE_PROVIDER_HINT = {
4095
+ Geostyler: 'withGeostyler()',
4096
+ Mapbox: 'withMapbox()'
4097
+ };
4098
+ class StyleService {
4099
+ engines = inject(STYLE_ENGINES, { optional: true }) ?? [];
4100
+ async getStyle(options, ol) {
4101
+ if (isAnyOlStyle(options)) {
4102
+ return options;
4103
+ }
4104
+ const engine = this.findEngine(options);
4105
+ return engine?.getStyle(options, ol) ?? randomOlFlatStyle();
4106
+ }
4107
+ async getLegend(options) {
4108
+ if (isAnyOlStyle(options)) {
4109
+ return undefined;
4110
+ }
4111
+ const engine = this.findEngine(options);
4112
+ if (!engine?.getLegend) {
4113
+ return undefined;
4114
+ }
4115
+ return engine.getLegend(options);
4116
+ }
4117
+ findEngine(options) {
4118
+ const engine = this.engines.find((e) => e.supports(options));
4119
+ if (!engine) {
4120
+ const hint = ENGINE_PROVIDER_HINT[options.type];
4121
+ const hintMsg = hint
4122
+ ? ` Did you forget to add ${hint} to provideStyle(...)?`
4123
+ : ` No registered provider handles type "${options.type}".`;
4124
+ console.warn(`[StyleService]${hintMsg}`);
4125
+ }
4126
+ return engine;
4127
+ }
4128
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: StyleService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
4129
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: StyleService, providedIn: 'root' });
4130
+ }
4131
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: StyleService, decorators: [{
4132
+ type: Injectable,
4133
+ args: [{ providedIn: 'root' }]
4134
+ }] });
4135
+
3434
4136
  class LayerBase {
3435
4137
  options;
3436
4138
  collapsed;
@@ -3644,9 +4346,6 @@ class LayerGroupBase extends LayerBase {
3644
4346
 
3645
4347
  class Layer extends LayerBase {
3646
4348
  options;
3647
- messageService;
3648
- authInterceptor;
3649
- styleService;
3650
4349
  ol;
3651
4350
  hasBeenVisible$ = new BehaviorSubject(false);
3652
4351
  legend;
@@ -3654,6 +4353,10 @@ class Layer extends LayerBase {
3654
4353
  link;
3655
4354
  linkMaster;
3656
4355
  resolution$$;
4356
+ /** Do not remove those injections, they are needed in the other layer class. Without that they are not injected. */
4357
+ messageService = inject(MessageService, { optional: true });
4358
+ xhrInterceptor = inject(XHR_INTERCEPTOR, { optional: true });
4359
+ styleService = inject(StyleService, { optional: true });
3657
4360
  get visible() {
3658
4361
  return super.visible;
3659
4362
  }
@@ -3695,12 +4398,9 @@ class Layer extends LayerBase {
3695
4398
  sourceOptions: this.dataSource.saveableOptions
3696
4399
  };
3697
4400
  }
3698
- constructor(options, messageService, authInterceptor, styleService) {
4401
+ constructor(options) {
3699
4402
  super(options);
3700
4403
  this.options = options;
3701
- this.messageService = messageService;
3702
- this.authInterceptor = authInterceptor;
3703
- this.styleService = styleService;
3704
4404
  if (!options.id) {
3705
4405
  options.id = uuid();
3706
4406
  }
@@ -3721,6 +4421,9 @@ class Layer extends LayerBase {
3721
4421
  this.ol.set('_layer', this, true);
3722
4422
  super.afterCreated();
3723
4423
  }
4424
+ refresh() {
4425
+ this.dataSource.refresh();
4426
+ }
3724
4427
  init(map) {
3725
4428
  super.init(map);
3726
4429
  map.layerWatcher.watchLayer(this);
@@ -3894,16 +4597,12 @@ ImageWatcher = __decorate([
3894
4597
  __metadata("design:paramtypes", [Function, MessageService])
3895
4598
  ], ImageWatcher);
3896
4599
 
3897
- let ImageLayer = class ImageLayer extends Layer {
3898
- messageService;
3899
- authInterceptor;
4600
+ class ImageLayer extends Layer {
3900
4601
  type = 'raster';
3901
4602
  watcher;
3902
- constructor(options, messageService, authInterceptor) {
3903
- super(options, messageService, authInterceptor);
3904
- this.messageService = messageService;
3905
- this.authInterceptor = authInterceptor;
3906
- this.watcher = new ImageWatcher(this, this.messageService);
4603
+ constructor(options) {
4604
+ super(options);
4605
+ this.watcher = new ImageWatcher(this, this.messageService ?? undefined);
3907
4606
  this.status$ = this.watcher.status$;
3908
4607
  this.status$.subscribe((valStatus) => {
3909
4608
  if (valStatus === 0) {
@@ -3916,9 +4615,9 @@ let ImageLayer = class ImageLayer extends Layer {
3916
4615
  source: this.options.source.ol
3917
4616
  });
3918
4617
  const image = new olLayerImage(olOptions);
3919
- if (this.authInterceptor) {
4618
+ if (this.xhrInterceptor) {
3920
4619
  image.getSource().setImageLoadFunction((tile, src) => {
3921
- this.customLoader(tile, src, this.authInterceptor, this.messageService);
4620
+ this.customLoader(tile, src, this.xhrInterceptor, this.messageService ?? undefined);
3922
4621
  });
3923
4622
  }
3924
4623
  return image;
@@ -3966,13 +4665,7 @@ let ImageLayer = class ImageLayer extends Layer {
3966
4665
  };
3967
4666
  xhr.send();
3968
4667
  }
3969
- };
3970
- ImageLayer = __decorate([
3971
- __param(1, Optional()),
3972
- __param(2, Optional()),
3973
- __metadata("design:paramtypes", [Object, MessageService,
3974
- AuthInterceptor])
3975
- ], ImageLayer);
4668
+ }
3976
4669
 
3977
4670
  class TileWatcher extends Watcher {
3978
4671
  id;
@@ -4026,14 +4719,10 @@ class TileWatcher extends Watcher {
4026
4719
  }
4027
4720
 
4028
4721
  class TileLayer extends Layer {
4029
- messageService;
4030
- authInterceptor;
4031
4722
  type = 'raster';
4032
4723
  watcher;
4033
- constructor(options, messageService, authInterceptor) {
4034
- super(options, messageService);
4035
- this.messageService = messageService;
4036
- this.authInterceptor = authInterceptor;
4724
+ constructor(options) {
4725
+ super(options);
4037
4726
  this.watcher = new TileWatcher(this);
4038
4727
  this.status$ = this.watcher.status$;
4039
4728
  }
@@ -4045,7 +4734,7 @@ class TileLayer extends Layer {
4045
4734
  const tileSource = tileLayer.getSource();
4046
4735
  if (tileSource !== null && 'setTileLoadFunction' in tileSource) {
4047
4736
  tileSource.setTileLoadFunction((tile, url) => {
4048
- this.customLoader(tile, url, this.authInterceptor);
4737
+ this.customLoader(tile, url, this.xhrInterceptor);
4049
4738
  });
4050
4739
  }
4051
4740
  return tileLayer;
@@ -4058,7 +4747,7 @@ class TileLayer extends Layer {
4058
4747
  */
4059
4748
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
4060
4749
  customLoader(tile, url, interceptor) {
4061
- const alteredUrlWithKeyAuth = interceptor.alterUrlWithKeyAuth(url);
4750
+ const alteredUrlWithKeyAuth = interceptor?.alterUrlWithKeyAuth(url);
4062
4751
  let modifiedUrl = url;
4063
4752
  if (alteredUrlWithKeyAuth) {
4064
4753
  modifiedUrl = alteredUrlWithKeyAuth;
@@ -4081,6 +4770,13 @@ class TileLayer extends Layer {
4081
4770
  }
4082
4771
  }
4083
4772
 
4773
+ function hasVectorSourceLoader(dataSource) {
4774
+ return (typeof dataSource === 'object' &&
4775
+ dataSource !== null &&
4776
+ 'createVectorSourceLoader' in dataSource &&
4777
+ typeof dataSource.createVectorSourceLoader === 'function');
4778
+ }
4779
+
4084
4780
  class FeatureDataSource extends DataSource {
4085
4781
  get saveableOptions() {
4086
4782
  const baseOptions = super.saveableOptions;
@@ -4130,291 +4826,6 @@ class FeatureDataSource extends DataSource {
4130
4826
  }
4131
4827
  }
4132
4828
 
4133
- function createIndexedDb() {
4134
- return from(openDB('igo2DB', undefined, {
4135
- upgrade(db) {
4136
- const geoDataStore = db.createObjectStore('geoData', {
4137
- keyPath: 'url',
4138
- autoIncrement: false
4139
- });
4140
- geoDataStore.createIndex('regionID-idx', 'regionID', {
4141
- unique: false
4142
- });
4143
- db.createObjectStore('layerData', {
4144
- keyPath: 'layerId',
4145
- autoIncrement: false
4146
- });
4147
- }
4148
- }));
4149
- }
4150
-
4151
- class GeoDB {
4152
- db$;
4153
- compression = new Compression();
4154
- collisionsMap = new Map();
4155
- _newData = 0;
4156
- revertObservablesSubscription;
4157
- constructor() {
4158
- this.db$ = createIndexedDb();
4159
- }
4160
- /**
4161
- * Only blob can be compressed
4162
- * @param url
4163
- * @param regionID
4164
- * @param object object to handle
4165
- * @param insertSource type of event user or system
4166
- * @param insertEvent Name of the event where the insert has been triggered
4167
- * @returns
4168
- */
4169
- update(url, regionID, object, insertSource, insertEvent) {
4170
- const object$ = (object instanceof Blob
4171
- ? this.compression.compressBlob(object)
4172
- : of(object));
4173
- const compress = object instanceof Blob ? true : false;
4174
- let geoDBData;
4175
- const a = this.db$.pipe(switchMap((db) => {
4176
- return object$.pipe(first(), switchMap((object) => {
4177
- geoDBData = {
4178
- url,
4179
- regionID,
4180
- object: object,
4181
- compressed: compress,
4182
- insertSource,
4183
- insertEvent
4184
- };
4185
- return this.getGeoDBData(url);
4186
- }), concatMap$1((res) => {
4187
- const dbObject = res;
4188
- if (!dbObject) {
4189
- this._newData++;
4190
- return from(db.add('geoData', geoDBData)).pipe(map$1(() => geoDBData));
4191
- }
4192
- else {
4193
- const currentRegionID = dbObject.regionID;
4194
- if (currentRegionID !== regionID) {
4195
- const collisions = this.collisionsMap.get(currentRegionID);
4196
- if (collisions !== undefined) {
4197
- collisions.push(dbObject.url);
4198
- this.collisionsMap.set(currentRegionID, collisions);
4199
- }
4200
- else {
4201
- this.collisionsMap.set(currentRegionID, [dbObject.url]);
4202
- }
4203
- }
4204
- return this.customUpdate(geoDBData);
4205
- }
4206
- }));
4207
- }));
4208
- return a;
4209
- }
4210
- customUpdate(geoDBData) {
4211
- const b = this.delete(geoDBData.url).pipe(mergeMap(() => this.add(geoDBData)));
4212
- return b;
4213
- }
4214
- add(geoDBData) {
4215
- return this.db$.pipe(switchMap((db) => from(db?.add('geoData', geoDBData)).pipe(map$1(() => geoDBData))));
4216
- }
4217
- put(geoDBData) {
4218
- return this.db$.pipe(switchMap((db) => from(db?.put('geoData', geoDBData)).pipe(map$1(() => geoDBData))));
4219
- }
4220
- getGeoDBData(url) {
4221
- return this.db$.pipe(switchMap((db) => from(db?.get('geoData', url))));
4222
- }
4223
- get(url) {
4224
- return this.getGeoDBData(url).pipe(mergeMap((data) => {
4225
- const rObj = !data?.compressed
4226
- ? data?.object
4227
- : this.compression.decompressBlob(data?.object);
4228
- return of(rObj);
4229
- }));
4230
- }
4231
- delete(key) {
4232
- return this.db$.pipe(switchMap((db) => from(db?.delete('geoData', key))), map$1(() => {
4233
- {
4234
- return { key };
4235
- }
4236
- }));
4237
- }
4238
- getRegionCountByID(id) {
4239
- return this.getRegionByID(id).pipe(switchMap((datas) => {
4240
- return of(datas.length);
4241
- }));
4242
- }
4243
- getRegionByID(id) {
4244
- if (!id) {
4245
- return of([]);
4246
- }
4247
- const IDBKey = IDBKeyRange.only(id);
4248
- return this.db$.pipe(switchMap((db) => from(db?.getAllFromIndex('geoData', 'regionID-idx', IDBKey))));
4249
- }
4250
- deleteByRegionID(id) {
4251
- if (!id) {
4252
- return of([]);
4253
- }
4254
- return this.db$.pipe(switchMap((db) => {
4255
- const tx = db.transaction('geoData', 'readwrite');
4256
- return of(tx);
4257
- }), mergeMap((tx) => this.getRegionByID(id).pipe(concatMap$1((datas) => {
4258
- const promises = datas.map((data) => tx.store.delete(data.url));
4259
- promises.push(tx.done);
4260
- return from(Promise.all(promises));
4261
- }))));
4262
- }
4263
- resetCounters() {
4264
- this.resetCollisionsMap();
4265
- this._newData = 0;
4266
- }
4267
- resetCollisionsMap() {
4268
- this.collisionsMap = new Map();
4269
- }
4270
- revertCollisions() {
4271
- if (this.revertObservablesSubscription) {
4272
- this.revertObservablesSubscription.unsubscribe();
4273
- }
4274
- const revertObservables = [];
4275
- for (const [regionID, collisions] of this.collisionsMap) {
4276
- for (const url of collisions) {
4277
- revertObservables.push(this.getGeoDBData(url).pipe(first(), concatMap$1((dbObject) => {
4278
- const updatedObject = dbObject;
4279
- updatedObject.regionID = regionID;
4280
- return this.customUpdate(updatedObject);
4281
- })));
4282
- }
4283
- }
4284
- this.revertObservablesSubscription = zip(...revertObservables).subscribe();
4285
- }
4286
- get newData() {
4287
- return this._newData;
4288
- }
4289
- }
4290
-
4291
- var InsertSourceInsertDBEnum;
4292
- (function (InsertSourceInsertDBEnum) {
4293
- InsertSourceInsertDBEnum["System"] = "system";
4294
- InsertSourceInsertDBEnum["User"] = "user";
4295
- })(InsertSourceInsertDBEnum || (InsertSourceInsertDBEnum = {}));
4296
-
4297
- class LayerDB {
4298
- db$;
4299
- constructor() {
4300
- this.db$ = createIndexedDb();
4301
- }
4302
- /**
4303
- * This method allow to update the stored layer into the indexeddb (layerData)
4304
- * @param layerDBData
4305
- * @returns
4306
- */
4307
- update(layerDBData) {
4308
- return this.db$.pipe(switchMap$1((db) => this.getByID(layerDBData.layerId).pipe(first$1(), concatMap((dbObject) => {
4309
- if (!dbObject) {
4310
- return from(db.add('layerData', layerDBData)).pipe(map(() => layerDBData));
4311
- }
4312
- else {
4313
- return this.customUpdate(layerDBData);
4314
- }
4315
- }))));
4316
- }
4317
- customUpdate(layerDBData) {
4318
- const b = this.delete(layerDBData.layerId).pipe(mergeMap$1(() => this.add(layerDBData)));
4319
- return b;
4320
- }
4321
- add(layerDBData) {
4322
- return this.db$.pipe(switchMap$1((db) => from(db?.add('layerData', layerDBData)).pipe(map(() => layerDBData))));
4323
- }
4324
- /**
4325
- * This method retrieve an idb layer definition
4326
- * @param layerId
4327
- * @returns
4328
- */
4329
- getByID(layerId) {
4330
- return this.db$.pipe(switchMap$1((db) => from(db?.get('layerData', layerId))));
4331
- }
4332
- /**
4333
- * This method delete an idb layer definition
4334
- * @param key
4335
- * @returns
4336
- */
4337
- delete(key) {
4338
- return this.db$.pipe(switchMap$1((db) => from(db?.delete('layerData', key))), map(() => {
4339
- {
4340
- return { key };
4341
- }
4342
- }));
4343
- }
4344
- /**
4345
- * This method retrive all idb layer definition
4346
- * @param layerId
4347
- * @returns
4348
- */
4349
- getAll() {
4350
- return this.db$.pipe(switchMap$1((db) => from(db?.getAll('layerData'))));
4351
- }
4352
- }
4353
-
4354
- const FLAT_STYLE_KEYS = [
4355
- 'fill-color',
4356
- 'fill-opacity',
4357
- 'stroke-color',
4358
- 'stroke-width',
4359
- 'stroke-opacity',
4360
- 'circle-radius',
4361
- 'circle-fill-color',
4362
- 'icon-src',
4363
- 'icon-scale',
4364
- 'text-field',
4365
- 'text-font',
4366
- 'text-size'
4367
- ];
4368
- function isEngineLayerStyle(value) {
4369
- return isRecord(value) && typeof value['type'] === 'string';
4370
- }
4371
- function isOlFlatStyleLike(value) {
4372
- if (!value)
4373
- return false;
4374
- if (isOlRuleArray(value))
4375
- return true;
4376
- if (Array.isArray(value)) {
4377
- return value.length > 0 && value.every(isOlFlatStyleLike);
4378
- }
4379
- return isRecord(value) && hasAnyFlatStyleKey(value);
4380
- }
4381
- function isAnyOlStyle(value) {
4382
- return (!isEngineLayerStyle(value) &&
4383
- (isOlStyleLike(value) || isOlFlatStyleLike(value)));
4384
- }
4385
- // Analyser les méthodes exporter ou non, enlever les export si elles sont utilisé localement.
4386
- function isRecord(value) {
4387
- return typeof value === 'object' && value !== null;
4388
- }
4389
- function isOlStyleInstance(value) {
4390
- return value instanceof Style;
4391
- }
4392
- function isOlStyleInstanceArray(value) {
4393
- return Array.isArray(value) && value.every(isOlStyleInstance);
4394
- }
4395
- function isOlStyleFunction(value) {
4396
- return typeof value === 'function';
4397
- }
4398
- function isOlRule(value) {
4399
- if (!isRecord(value) || !('style' in value))
4400
- return false;
4401
- const styleValue = value.style;
4402
- return (isOlFlatStyleLike(styleValue) ||
4403
- (Array.isArray(styleValue) && styleValue.every(isOlFlatStyleLike)));
4404
- }
4405
- function isOlRuleArray(value) {
4406
- return Array.isArray(value) && value.every(isOlRule);
4407
- }
4408
- function hasAnyFlatStyleKey(value) {
4409
- return FLAT_STYLE_KEYS.some((key) => Object.prototype.hasOwnProperty.call(value, key));
4410
- }
4411
- function isOlStyleLike(value) {
4412
- return (!!value &&
4413
- (isOlStyleInstance(value) ||
4414
- isOlStyleInstanceArray(value) ||
4415
- isOlStyleFunction(value)));
4416
- }
4417
-
4418
4829
  class ClusterDataSource extends FeatureDataSource {
4419
4830
  get saveableOptions() {
4420
4831
  const baseOptions = super.saveableOptions;
@@ -4440,6 +4851,8 @@ class VectorWatcher extends Watcher {
4440
4851
  id;
4441
4852
  loaded = 0;
4442
4853
  loading = 0;
4854
+ onFeatureLoadStart = () => this.handleLoadStart();
4855
+ onFeatureLoadEnd = () => this.handleLoadEnd();
4443
4856
  layer;
4444
4857
  constructor(layer) {
4445
4858
  super();
@@ -4447,27 +4860,29 @@ class VectorWatcher extends Watcher {
4447
4860
  this.id = uuid();
4448
4861
  }
4449
4862
  watch() {
4450
- let olSource = this.layer.options.source.ol;
4451
- if (this.layer.dataSource instanceof ClusterDataSource) {
4452
- olSource = this.layer.options.source.options.source;
4453
- }
4863
+ const olSource = this.getWatchableSource();
4454
4864
  if (olSource.getUrl()) {
4455
- olSource.on(`featuresloadstart`, () => this.handleLoadStart());
4456
- olSource.on(`featuresloadend`, () => this.handleLoadEnd());
4457
- olSource.on(`featuresloaderror`, () => this.handleLoadEnd());
4865
+ olSource.on('featuresloadstart', this.onFeatureLoadStart);
4866
+ olSource.on('featuresloadend', this.onFeatureLoadEnd);
4867
+ olSource.on('featuresloaderror', this.onFeatureLoadEnd);
4458
4868
  }
4459
4869
  }
4460
4870
  unwatch() {
4461
- let olSource = this.layer.options.source.ol;
4462
- if (this.layer.dataSource instanceof ClusterDataSource) {
4463
- olSource = this.layer.options.source.options.source;
4464
- }
4871
+ const olSource = this.getWatchableSource();
4465
4872
  if (olSource.getUrl()) {
4466
- olSource.un(`featuresloadstart`, () => this.handleLoadStart());
4467
- olSource.un(`featuresloadend`, () => this.handleLoadEnd());
4468
- olSource.un(`featuresloaderror`, () => this.handleLoadEnd());
4873
+ olSource.un('featuresloadstart', this.onFeatureLoadStart);
4874
+ olSource.un('featuresloadend', this.onFeatureLoadEnd);
4875
+ olSource.un('featuresloaderror', this.onFeatureLoadEnd);
4469
4876
  }
4470
4877
  }
4878
+ getWatchableSource() {
4879
+ const source = this.layer.options.source;
4880
+ if (this.layer.dataSource instanceof ClusterDataSource) {
4881
+ const clusterOptions = source.options;
4882
+ return clusterOptions.source ?? source.ol;
4883
+ }
4884
+ return source.ol;
4885
+ }
4471
4886
  handleLoadStart() {
4472
4887
  this.loading += 1;
4473
4888
  this.status = SubjectStatus.Working;
@@ -4484,23 +4899,342 @@ class VectorWatcher extends Watcher {
4484
4899
  }
4485
4900
  }
4486
4901
 
4902
+ class VectorLayerFlashAnimator {
4903
+ layer;
4904
+ render;
4905
+ listenerKeys = new Set();
4906
+ constructor(layer, render) {
4907
+ this.layer = layer;
4908
+ this.render = render;
4909
+ }
4910
+ flash(feature, options) {
4911
+ const start = Date.now();
4912
+ const duration = options.duration ?? 1000;
4913
+ const animate = (event) => {
4914
+ if (!event.frameState) {
4915
+ return;
4916
+ }
4917
+ const elapsed = event.frameState.time - start;
4918
+ const elapsedRatio = elapsed / duration;
4919
+ const style = this.resolveRenderableStyle(feature, event.frameState.viewState.resolution);
4920
+ if (style) {
4921
+ const styleClone = style.clone();
4922
+ this.updateStyle(styleClone, feature.getGeometry()?.getType(), elapsedRatio, options);
4923
+ const geometry = feature.getGeometry()?.clone();
4924
+ if (geometry) {
4925
+ const vectorContext = getVectorContext(event);
4926
+ vectorContext.setStyle(styleClone);
4927
+ vectorContext.drawGeometry(geometry);
4928
+ }
4929
+ }
4930
+ if (elapsed > duration) {
4931
+ this.removeListener(listenerKey);
4932
+ }
4933
+ this.render();
4934
+ };
4935
+ const listenerKey = this.layer.on('postrender', animate);
4936
+ this.listenerKeys.add(listenerKey);
4937
+ }
4938
+ destroy() {
4939
+ unByKey([...this.listenerKeys]);
4940
+ this.listenerKeys.clear();
4941
+ }
4942
+ updateStyle(style, geometryType, elapsedRatio, options) {
4943
+ const opacity = easeOut(1 - elapsedRatio);
4944
+ const color = [...asArray(options.color ?? [255, 0, 0, 1])];
4945
+ color[3] = opacity;
4946
+ const image = style.getImage();
4947
+ if (geometryType === 'Point' && image instanceof RegularShape) {
4948
+ image.setRadius(easeOut(elapsedRatio) * image.getRadius() * 3);
4949
+ image.setOpacity(opacity);
4950
+ return;
4951
+ }
4952
+ if (geometryType === 'LineString') {
4953
+ if (image instanceof RegularShape) {
4954
+ const imageStroke = image.getStroke();
4955
+ if (imageStroke) {
4956
+ imageStroke.setColor(color);
4957
+ imageStroke.setWidth(easeOut(elapsedRatio) * (imageStroke.getWidth() ?? 1) * 3);
4958
+ }
4959
+ }
4960
+ const stroke = style.getStroke();
4961
+ if (stroke) {
4962
+ stroke.setColor(color);
4963
+ stroke.setWidth(easeOut(elapsedRatio) * (stroke.getWidth() ?? 1) * 3);
4964
+ }
4965
+ return;
4966
+ }
4967
+ if (geometryType === 'Polygon') {
4968
+ if (image instanceof RegularShape) {
4969
+ image.getFill()?.setColor(color);
4970
+ }
4971
+ style.getFill()?.setColor(color);
4972
+ }
4973
+ }
4974
+ resolveRenderableStyle(feature, resolution) {
4975
+ const styleResult = this.layer.getStyleFunction()?.(feature, resolution);
4976
+ if (!styleResult) {
4977
+ return undefined;
4978
+ }
4979
+ const styles = Array.isArray(styleResult) ? styleResult : [styleResult];
4980
+ return styles.find((style) => !!style.getImage()) ?? styles[0];
4981
+ }
4982
+ removeListener(listenerKey) {
4983
+ unByKey(listenerKey);
4984
+ this.listenerKeys.delete(listenerKey);
4985
+ }
4986
+ }
4987
+
4988
+ const vectorLayerAnimationExtension = {
4989
+ id: 'vector-animation',
4990
+ supports: (options) => options.animation !== undefined,
4991
+ attach: (context) => {
4992
+ const animator = new VectorLayerFlashAnimator(context.layer, context.requestRender);
4993
+ let listenerKey = context.source.on('addfeature', (event) => {
4994
+ if (event.feature && context.options.animation) {
4995
+ animator.flash(event.feature, context.options.animation);
4996
+ }
4997
+ });
4998
+ const stopAnimation = () => {
4999
+ if (listenerKey) {
5000
+ unByKey(listenerKey);
5001
+ listenerKey = undefined;
5002
+ }
5003
+ };
5004
+ return {
5005
+ stopAnimation,
5006
+ destroy: () => {
5007
+ stopAnimation();
5008
+ animator.destroy();
5009
+ }
5010
+ };
5011
+ }
5012
+ };
5013
+
5014
+ const VECTOR_LAYER_EXTENSIONS = new InjectionToken('VECTOR_LAYER_EXTENSIONS');
5015
+
5016
+ class VectorSourceLoader {
5017
+ dependencies;
5018
+ ongoingRequests = [];
5019
+ requestGroups = new WeakMap();
5020
+ constructor(dependencies) {
5021
+ this.dependencies = dependencies;
5022
+ }
5023
+ execute(request) {
5024
+ this.dependencies.executeLoadExtensions(request, (nextRequest) => {
5025
+ if (this.shouldAbortRequests(nextRequest.extent, nextRequest.resolution)) {
5026
+ this.abortRequests();
5027
+ }
5028
+ const resolvedUrl = typeof nextRequest.url === 'function'
5029
+ ? nextRequest.url(nextRequest.extent, nextRequest.resolution, nextRequest.projection)
5030
+ : nextRequest.url;
5031
+ const urls = request.resolveUrls?.(resolvedUrl) ?? [resolvedUrl];
5032
+ const readOptions = {
5033
+ ...request.readOptions,
5034
+ extent: nextRequest.extent,
5035
+ featureProjection: nextRequest.projection
5036
+ };
5037
+ this.loadFeatures(urls, nextRequest.source, nextRequest.extent, nextRequest.resolution, readOptions, nextRequest.success, nextRequest.failure);
5038
+ });
5039
+ }
5040
+ loadFeatures(urls, vectorSource, extent, resolution, readOptions, success, failure) {
5041
+ if (!urls.length) {
5042
+ success([]);
5043
+ return;
5044
+ }
5045
+ if (urls.length === 1) {
5046
+ this.loadUrl(urls[0], vectorSource, extent, resolution, readOptions, success, failure);
5047
+ return;
5048
+ }
5049
+ this.loadFeatureBatches(urls, vectorSource, extent, resolution, readOptions, success, failure);
5050
+ }
5051
+ loadFeatureBatches(urls, vectorSource, extent, resolution, readOptions, success, failure) {
5052
+ const loadedFeatures = [];
5053
+ const requestGroup = {};
5054
+ let completedBatches = 0;
5055
+ let hasFailed = false;
5056
+ const rollback = () => {
5057
+ loadedFeatures
5058
+ .flat()
5059
+ .forEach((feature) => vectorSource.removeFeature(feature));
5060
+ };
5061
+ urls.forEach((url, index) => {
5062
+ if (hasFailed) {
5063
+ return;
5064
+ }
5065
+ this.loadUrl(url, vectorSource, extent, resolution, readOptions, (features) => {
5066
+ if (hasFailed) {
5067
+ features.forEach((feature) => vectorSource.removeFeature(feature));
5068
+ return;
5069
+ }
5070
+ loadedFeatures[index] = features;
5071
+ completedBatches++;
5072
+ if (completedBatches === urls.length) {
5073
+ success(loadedFeatures.flat());
5074
+ }
5075
+ }, () => {
5076
+ if (hasFailed) {
5077
+ return;
5078
+ }
5079
+ hasFailed = true;
5080
+ rollback();
5081
+ this.abortRequestGroup(requestGroup);
5082
+ failure();
5083
+ }, requestGroup);
5084
+ });
5085
+ }
5086
+ abortRequests() {
5087
+ this.abortMatchingRequests(() => true);
5088
+ }
5089
+ abortRequestGroup(requestGroup) {
5090
+ this.abortMatchingRequests((request) => this.requestGroups.get(request) === requestGroup);
5091
+ }
5092
+ abortMatchingRequests(predicate) {
5093
+ const requests = this.ongoingRequests.filter(predicate);
5094
+ for (const request of requests) {
5095
+ request.source.removeLoadedExtent(request.extent);
5096
+ request.xhr?.abort();
5097
+ this.removeRequest(request);
5098
+ }
5099
+ }
5100
+ shouldAbortRequests(currentExtent, resolution) {
5101
+ return this.ongoingRequests.some((request) => !equals(request.extent, currentExtent) ||
5102
+ request.resolution !== resolution);
5103
+ }
5104
+ loadUrl(url, vectorSource, extent, resolution, readOptions, success, failure, requestGroup) {
5105
+ const request = this.createVectorRequest(vectorSource, extent, resolution);
5106
+ if (requestGroup) {
5107
+ this.requestGroups.set(request, requestGroup);
5108
+ }
5109
+ const responseType = vectorSource.getFormat()?.getType() === 'arraybuffer'
5110
+ ? 'arraybuffer'
5111
+ : undefined;
5112
+ this.executeXhrRequest({
5113
+ request,
5114
+ url,
5115
+ readOptions,
5116
+ success,
5117
+ failure,
5118
+ responseType
5119
+ });
5120
+ }
5121
+ executeXhrRequest(options) {
5122
+ const { xhr, resolvedUrl } = this.createConfiguredXhr(options.url, options.responseType);
5123
+ const onError = () => this.handleRequestError(options);
5124
+ xhr.onerror = onError;
5125
+ xhr.onload = () => this.handleRequestLoadEvent(options, xhr, onError);
5126
+ this.trackRequest(options.request, xhr);
5127
+ try {
5128
+ this.dependencies.xhrInterceptor?.interceptXhr(xhr, resolvedUrl);
5129
+ xhr.send();
5130
+ }
5131
+ catch {
5132
+ onError();
5133
+ }
5134
+ }
5135
+ createConfiguredXhr(url, responseType) {
5136
+ const xhr = new XMLHttpRequest();
5137
+ const resolvedUrl = this.dependencies.xhrInterceptor?.alterUrlWithKeyAuth(url) ?? url;
5138
+ xhr.open('GET', resolvedUrl);
5139
+ if (responseType) {
5140
+ xhr.responseType = responseType;
5141
+ }
5142
+ return { xhr, resolvedUrl };
5143
+ }
5144
+ handleRequestError(options) {
5145
+ options.request.source.removeLoadedExtent(options.request.extent);
5146
+ this.removeRequest(options.request);
5147
+ options.failure();
5148
+ }
5149
+ handleRequestLoadEvent(options, xhr, onError) {
5150
+ if (xhr.status && (xhr.status < 200 || xhr.status >= 300)) {
5151
+ onError();
5152
+ return;
5153
+ }
5154
+ let content;
5155
+ try {
5156
+ content = this.getResponseContent(xhr, options.responseType);
5157
+ }
5158
+ catch {
5159
+ onError();
5160
+ return;
5161
+ }
5162
+ this.handleResponse(options, content, onError);
5163
+ }
5164
+ handleResponse(options, content, onError) {
5165
+ if (!content) {
5166
+ this.removeRequest(options.request);
5167
+ options.success([]);
5168
+ return;
5169
+ }
5170
+ try {
5171
+ const format = options.request.source.getFormat();
5172
+ if (!format) {
5173
+ onError();
5174
+ return;
5175
+ }
5176
+ const source = format.getType() === 'xml'
5177
+ ? new DOMParser().parseFromString(content.toString(), 'application/xml')
5178
+ : content;
5179
+ const features = format.readFeatures(source, options.readOptions);
5180
+ options.request.source.addFeatures(features);
5181
+ this.removeRequest(options.request);
5182
+ options.success(features);
5183
+ }
5184
+ catch {
5185
+ onError();
5186
+ }
5187
+ }
5188
+ getResponseContent(xhr, responseType) {
5189
+ if (responseType !== 'arraybuffer') {
5190
+ return xhr.responseText;
5191
+ }
5192
+ if (xhr.response instanceof ArrayBuffer) {
5193
+ return xhr.response;
5194
+ }
5195
+ throw new TypeError('Expected an ArrayBuffer response');
5196
+ }
5197
+ createVectorRequest(source, extent, resolution) {
5198
+ return {
5199
+ xhr: undefined,
5200
+ extent,
5201
+ resolution,
5202
+ source
5203
+ };
5204
+ }
5205
+ trackRequest(request, xhr) {
5206
+ request.xhr = xhr;
5207
+ this.ongoingRequests.push(request);
5208
+ }
5209
+ removeRequest(request) {
5210
+ const index = this.ongoingRequests.indexOf(request);
5211
+ if (index > -1) {
5212
+ this.ongoingRequests.splice(index, 1);
5213
+ }
5214
+ }
5215
+ }
5216
+
4487
5217
  class VectorLayer extends Layer {
4488
- messageService;
4489
- authInterceptor;
4490
- geoNetworkService;
4491
- styleService;
4492
5218
  type = 'vector';
4493
- lastRequest;
4494
- ongoingRequests = [];
4495
5219
  watcher;
4496
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
4497
- trackFeatureListenerId;
5220
+ styleRevision = 0;
5221
+ preloadState;
5222
+ preloadListenerKey;
4498
5223
  get browsable() {
4499
5224
  return this.options.browsable !== false;
4500
5225
  }
4501
5226
  get exportable() {
4502
5227
  return this.options.exportable !== false;
4503
5228
  }
5229
+ get saveableOptions() {
5230
+ const baseOptions = super.saveableOptions;
5231
+ return {
5232
+ ...baseOptions,
5233
+ visible: this.preloadState?.visible ?? baseOptions.visible,
5234
+ opacity: this.preloadState?.opacity ?? baseOptions.opacity,
5235
+ preload: this.options.preload
5236
+ };
5237
+ }
4504
5238
  get style() {
4505
5239
  return this._style$.getValue();
4506
5240
  }
@@ -4510,12 +5244,12 @@ class VectorLayer extends Layer {
4510
5244
  }
4511
5245
  _style$ = new BehaviorSubject(undefined);
4512
5246
  style$ = this._style$.asObservable();
4513
- constructor(options, messageService, authInterceptor, geoNetworkService, styleService) {
4514
- super(options, messageService, authInterceptor, styleService);
4515
- this.messageService = messageService;
4516
- this.authInterceptor = authInterceptor;
4517
- this.geoNetworkService = geoNetworkService;
4518
- this.styleService = styleService;
5247
+ constructor(options) {
5248
+ super(options);
5249
+ const preloadOptions = this.options.preload;
5250
+ if (preloadOptions) {
5251
+ this.configurePreload(preloadOptions);
5252
+ }
4519
5253
  this.watcher = new VectorWatcher(this);
4520
5254
  this.status$ = this.watcher.status$;
4521
5255
  this.style = this.options.style;
@@ -4536,16 +5270,6 @@ class VectorLayer extends Layer {
4536
5270
  source: this.options.source?.ol,
4537
5271
  sourceOptions: this.options.sourceOptions || this.options.source?.options
4538
5272
  });
4539
- if (this.options.sourceOptions?.preload?.bypassResolution ||
4540
- this.options.sourceOptions?.preload?.bypassVisible) {
4541
- this.handlePreload();
4542
- }
4543
- if (this.options.animation) {
4544
- this.dataSource.ol.on('addfeature', (e) => {
4545
- if (e.feature)
4546
- this.flash(e.feature);
4547
- });
4548
- }
4549
5273
  if (this.options.trackFeature) {
4550
5274
  this.enableTrackFeature(this.options.trackFeature);
4551
5275
  }
@@ -4556,227 +5280,118 @@ class VectorLayer extends Layer {
4556
5280
  style: isOlStyle ? layerStyle : undefined
4557
5281
  });
4558
5282
  const vectorSource = vector.getSource();
4559
- let url = vectorSource.getUrl();
4560
- if (typeof url === 'function') {
4561
- return vector;
4562
- }
4563
- let loader;
4564
- const wfsOptions = olOptions.sourceOptions;
4565
- if (wfsOptions?.type === 'wfs' &&
4566
- (wfsOptions.params || wfsOptions.paramsWFS)) {
4567
- loader = (extent, resolution, proj, success, failure) => {
4568
- this.customWFSLoader(vectorSource, wfsOptions, extent, resolution, proj, success, failure);
4569
- };
4570
- }
4571
- else {
4572
- if (!url &&
4573
- this.options.idbInfo?.storeToIdb &&
4574
- this.options.idbInfo?._firstLoad === false) {
4575
- url = this.id.toString();
4576
- }
4577
- if (url) {
4578
- const loaderUrl = url;
4579
- loader = (extent, resolution, proj, success, failure) => {
4580
- this.customLoader(vectorSource, loaderUrl, extent, resolution, proj, success, failure);
4581
- };
4582
- }
5283
+ this.configureVectorSourceLoader(vectorSource);
5284
+ this.attachExtensions(vector, vectorSource);
5285
+ return vector;
5286
+ }
5287
+ configureVectorSourceLoader(vectorSource) {
5288
+ const loader = this.createSourceLoader(vectorSource);
5289
+ if (!loader) {
5290
+ return;
4583
5291
  }
4584
- if (loader) {
4585
- vectorSource.setLoader(loader);
5292
+ const layerLoader = this.createCompletionSafeLoader(loader);
5293
+ vectorSource.setLoader(layerLoader);
5294
+ }
5295
+ createSourceLoader(vectorSource) {
5296
+ if (hasVectorSourceLoader(this.dataSource)) {
5297
+ return this.dataSource.createVectorSourceLoader(this.getSourceLoader());
4586
5298
  }
4587
- if (this.options.idbInfo?.storeToIdb) {
4588
- this.handleIdbStorage(vector);
5299
+ const sourceUrl = vectorSource.getUrl();
5300
+ if (!sourceUrl) {
5301
+ return undefined;
4589
5302
  }
4590
- return vector;
5303
+ return this.createGenericSourceLoader(vectorSource, sourceUrl);
5304
+ }
5305
+ createGenericSourceLoader(vectorSource, url) {
5306
+ return (extent, resolution, projection, success, failure) => {
5307
+ this.getSourceLoader().execute({
5308
+ source: vectorSource,
5309
+ url,
5310
+ extent,
5311
+ resolution,
5312
+ projection,
5313
+ readOptions: {
5314
+ extent,
5315
+ featureProjection: projection
5316
+ },
5317
+ success: success ?? (() => void 0),
5318
+ failure: failure ?? (() => void 0)
5319
+ });
5320
+ };
4591
5321
  }
4592
5322
  async setStyle(value) {
5323
+ const revision = ++this.styleRevision;
4593
5324
  if (!value) {
4594
5325
  this.ol.setStyle(undefined);
4595
5326
  }
4596
5327
  else if (this.styleService) {
4597
5328
  const olStyle = await this.styleService.getStyle(value, this.ol);
4598
- this.ol.setStyle(olStyle);
5329
+ if (revision === this.styleRevision) {
5330
+ this.ol.setStyle(olStyle);
5331
+ }
4599
5332
  }
4600
5333
  else if (isAnyOlStyle(value)) {
4601
5334
  this.ol.setStyle(value);
4602
5335
  }
4603
5336
  // else: no service and non-OL style — silently ignore
4604
5337
  }
4605
- handleIdbStorage(vector) {
4606
- fromEvent(vector, 'sourceready')
4607
- .pipe(tap$1(() => {
4608
- if (this.options.idbInfo?._firstLoad !== false) {
4609
- this.maintainFeaturesInIdb();
4610
- this.maintainOptionsInIdb();
4611
- }
4612
- }), switchMap$1(() => merge(fromEvent(vector.getSource(), 'featuresloadend'), fromEvent(vector.getSource(), 'addfeature'), fromEvent(vector.getSource(), 'changefeature'), fromEvent(vector.getSource(), 'clear'), fromEvent(vector.getSource(), 'removefeature'))))
4613
- .pipe(debounceTime(750))
4614
- .subscribe(() => this.maintainFeaturesInIdb());
4615
- fromEvent(vector, 'sourceready')
4616
- .pipe(switchMap$1(() => merge(fromEvent(vector, 'change'), fromEvent(vector, 'change:visible'), fromEvent(vector, 'change:opacity'), fromEvent(vector, 'change:zIndex'))))
4617
- .pipe(debounceTime(750))
4618
- .subscribe(() => {
4619
- this.maintainOptionsInIdb();
4620
- });
4621
- }
4622
- handlePreload() {
4623
- const preloadOptions = this.options.sourceOptions?.preload;
4624
- if (this.dataSource instanceof FeatureDataSource) {
4625
- const initialOpacityValue = this.options.opacity || 1;
4626
- const initialVisibleValue = this.options.visible !== false;
4627
- const initialMinResValue = this.options.minResolution ||
4628
- getResolutionFromScale(Number(this.options.minScaleDenom));
4629
- const initialMaxResValue = this.options.maxResolution ||
4630
- getResolutionFromScale(Number(this.options.maxScaleDenom));
4631
- this.options.opacity = 0;
4632
- if (preloadOptions?.bypassResolution &&
4633
- (this.options.minResolution || this.options.maxResolution)) {
4634
- this.options.minResolution = 0;
4635
- this.options.maxResolution = Infinity;
5338
+ configurePreload(preloadOptions) {
5339
+ this.preloadState = {
5340
+ opacity: this.opacity,
5341
+ visible: this.visible,
5342
+ minResolution: this.minResolution,
5343
+ maxResolution: this.maxResolution
5344
+ };
5345
+ this.opacity = 0;
5346
+ if (preloadOptions.bypass === 'resolution' ||
5347
+ preloadOptions.bypass === 'all') {
5348
+ this.minResolution = 0;
5349
+ this.maxResolution = Infinity;
5350
+ }
5351
+ if (preloadOptions.bypass === 'visibility' ||
5352
+ preloadOptions.bypass === 'all') {
5353
+ this.visible = true;
5354
+ }
5355
+ const restoreLayerState = () => {
5356
+ const state = this.preloadState;
5357
+ if (!state) {
5358
+ return;
4636
5359
  }
4637
- if (preloadOptions?.bypassVisible && !initialVisibleValue) {
4638
- this.options.visible = true;
5360
+ this.preloadState = undefined;
5361
+ if (this.preloadListenerKey) {
5362
+ unByKey(this.preloadListenerKey);
5363
+ this.preloadListenerKey = undefined;
4639
5364
  }
4640
- this.dataSource.ol.once('featuresloadend', () => {
4641
- if (initialOpacityValue) {
4642
- this.opacity = initialOpacityValue;
4643
- }
4644
- if (preloadOptions?.bypassResolution) {
4645
- this.minResolution = initialMinResValue;
4646
- this.maxResolution = initialMaxResValue;
4647
- }
4648
- if (preloadOptions?.bypassVisible) {
4649
- this.visible = initialVisibleValue;
4650
- }
4651
- });
4652
- }
5365
+ this.opacity = state.opacity;
5366
+ if (preloadOptions.bypass === 'resolution' ||
5367
+ preloadOptions.bypass === 'all') {
5368
+ this.minResolution = state.minResolution;
5369
+ this.maxResolution = state.maxResolution;
5370
+ }
5371
+ if (preloadOptions.bypass === 'visibility' ||
5372
+ preloadOptions.bypass === 'all') {
5373
+ this.visible = state.visible;
5374
+ }
5375
+ };
5376
+ this.preloadListenerKey = this.dataSource.ol.on(['featuresloadend', 'featuresloaderror'], restoreLayerState);
4653
5377
  }
4654
5378
  remove() {
4655
- this.watcher.unsubscribe();
4656
- if (this.options.idbInfo?.storeToIdb &&
4657
- this.options.idbInfo?._deleteFromIdb) {
4658
- this.removeLayerFromIDB();
5379
+ try {
5380
+ this.cleanupVectorLifecycle();
5381
+ }
5382
+ finally {
5383
+ super.remove();
4659
5384
  }
4660
- super.remove();
4661
- }
4662
- removeLayerFromIDB() {
4663
- const geoDB = new GeoDB();
4664
- const layerDB = new LayerDB();
4665
- merge(geoDB.delete(this.id.toString()), layerDB.delete(this.id.toString())).subscribe();
4666
- }
4667
- maintainOptionsInIdb() {
4668
- const layerData = ObjectUtils.removeUndefined({
4669
- layerId: this.id,
4670
- detailedContextUri: this.options.idbInfo?.contextUri,
4671
- sourceOptions: {
4672
- id: this.id,
4673
- type: 'vector',
4674
- queryable: true,
4675
- url: this.options.sourceOptions?.url
4676
- },
4677
- layerOptions: {
4678
- workspace: this.options.workspace,
4679
- zIndex: this.ol ? this.zIndex : 1000000,
4680
- id: this.id,
4681
- isIgoInternalLayer: this.isIgoInternalLayer,
4682
- title: this.title,
4683
- visible: this.visible,
4684
- opacity: this.opacity,
4685
- style: isOlFlatStyleLike(this.style) ? this.style : undefined,
4686
- idbInfo: Object.assign({ contextUri: '*' }, this.options.idbInfo, {
4687
- _firstLoad: false
4688
- })
4689
- },
4690
- insertEvent: `${this.title}-${this.id}-${new Date()}`
4691
- });
4692
- const layerDB = new LayerDB();
4693
- layerDB.update(layerData).pipe(first$1()).subscribe();
4694
5385
  }
4695
- maintainFeaturesInIdb() {
4696
- const dsFeatures = this.dataSource.ol.getFeatures();
4697
- dsFeatures.forEach((f) => f.unset('_featureStore', true));
4698
- const geojsonObject = JSON.parse(new olformat.GeoJSON().writeFeatures(dsFeatures, {
4699
- dataProjection: 'EPSG:4326',
4700
- featureProjection: this.dataSource.ol.getProjection() || 'EPSG:3857'
4701
- }));
4702
- const geoDB = new GeoDB();
4703
- geoDB
4704
- .update(this.options.sourceOptions?.url || this.id.toString(), this.id, geojsonObject, InsertSourceInsertDBEnum.User, `${this.title}-${this.id}-${new Date()}`)
4705
- .pipe(first$1())
4706
- .subscribe();
4707
- }
4708
- flash(feature) {
4709
- const start = new Date().getTime();
4710
- const listenerKey = this.ol.on('postrender', animate.bind(this));
4711
- function animate(event) {
4712
- const vectorContext = getVectorContext(event);
4713
- const frameState = event.frameState;
4714
- const flashGeom = feature?.getGeometry()?.clone();
4715
- const elapsed = frameState.time - start;
4716
- const elapsedRatio = elapsed / (this.options.animation.duration ?? 1000);
4717
- const opacity = easeOut(1 - elapsedRatio);
4718
- const newColor = asArray(this.options.animation?.color || 'red');
4719
- newColor[3] = opacity;
4720
- let style = this.ol.getStyleFunction()
4721
- ?.call(this, feature)
4722
- ?.find((style2) => {
4723
- return style2.getImage();
4724
- });
4725
- if (!style) {
4726
- style = this.ol.getStyleFunction()?.call(this, feature)?.[0];
4727
- }
4728
- const styleClone = style.clone();
4729
- switch (feature?.getGeometry()?.getType()) {
4730
- case 'Point':
4731
- if (styleClone.getImage() !== null &&
4732
- typeof styleClone.getImage().getRadius === 'function') {
4733
- const radius = easeOut(elapsedRatio) * (styleClone.getImage().getRadius() * 3);
4734
- styleClone.getImage().setRadius(radius);
4735
- styleClone.getImage().setOpacity(opacity);
4736
- }
4737
- break;
4738
- case 'LineString':
4739
- // TODO
4740
- if (styleClone.getImage()) {
4741
- styleClone.getImage().getStroke().setColor(newColor);
4742
- styleClone
4743
- .getImage()
4744
- .getStroke()
4745
- .setWidth(easeOut(elapsedRatio) *
4746
- (styleClone.getImage().getStroke().getWidth() * 3));
4747
- }
4748
- if (styleClone.getStroke()) {
4749
- styleClone.getStroke().setColor(newColor);
4750
- styleClone
4751
- .getStroke()
4752
- .setWidth(easeOut(elapsedRatio) * (styleClone.getStroke().getWidth() * 3));
4753
- }
4754
- break;
4755
- case 'Polygon':
4756
- // TODO
4757
- if (styleClone.getImage()) {
4758
- styleClone.getImage().getFill().setColor(newColor);
4759
- }
4760
- if (styleClone.getFill()) {
4761
- styleClone.getFill().setColor(newColor);
4762
- }
4763
- break;
4764
- }
4765
- styleClone.setText('');
4766
- vectorContext.setStyle(styleClone);
4767
- if (flashGeom) {
4768
- vectorContext.drawGeometry(flashGeom);
4769
- }
4770
- if (elapsed > (this.options.animation?.duration ?? 1000)) {
4771
- unByKey(listenerKey);
4772
- // remove last geometry
4773
- // there is a little flash before feature disappear, better solution ?
4774
- this.map?.ol.render();
4775
- return;
4776
- }
4777
- // tell OpenLayers to continue postcompose animation
4778
- this.map?.ol.render();
5386
+ cleanupVectorLifecycle() {
5387
+ this.watcher.unsubscribe();
5388
+ this.disableTrackFeature();
5389
+ if (this.preloadListenerKey) {
5390
+ unByKey(this.preloadListenerKey);
5391
+ this.preloadListenerKey = undefined;
4779
5392
  }
5393
+ this.sourceLoader?.abortRequests();
5394
+ this.extensionManager.destroy();
4780
5395
  }
4781
5396
  init(map) {
4782
5397
  if (map === undefined) {
@@ -4796,253 +5411,98 @@ class VectorLayer extends Layer {
4796
5411
  this.stopAnimation();
4797
5412
  }
4798
5413
  stopAnimation() {
4799
- this.dataSource.ol.un('addfeature', (e) => {
4800
- if (this.visible && e.feature) {
4801
- this.flash(e.feature);
4802
- }
4803
- });
5414
+ this.extensionManager
5415
+ .getInstance(vectorLayerAnimationExtension)
5416
+ ?.stopAnimation();
4804
5417
  }
4805
5418
  enableTrackFeature(id) {
4806
- this.trackFeatureListenerId = this.dataSource.ol.on('addfeature', this.trackFeature.bind(this, id));
5419
+ this.disableTrackFeature();
5420
+ this.trackFeatureListenerKey = this.dataSource.ol.on('addfeature', (event) => this.trackFeature(id, event));
4807
5421
  }
4808
5422
  centerMapOnFeature(id) {
4809
5423
  const feat = this.dataSource.ol.getFeatureById(id);
4810
5424
  if (feat) {
4811
- this.map.ol.getView().setCenter(feat.getGeometry()?.getCoordinates());
5425
+ const geometry = feat.getGeometry();
5426
+ if (!geometry) {
5427
+ return;
5428
+ }
5429
+ const center = geometry instanceof OlPoint
5430
+ ? geometry.getCoordinates()
5431
+ : getCenter(geometry.getExtent());
5432
+ this.map.ol.getView().setCenter(center);
4812
5433
  }
4813
5434
  }
4814
- trackFeature(id, feat) {
4815
- if (feat.feature.getId() === id && this.visible) {
5435
+ trackFeature(id, event) {
5436
+ if (event.feature?.getId() === id && this.visible) {
4816
5437
  this.centerMapOnFeature(id);
4817
5438
  }
4818
5439
  }
4819
5440
  disableTrackFeature() {
4820
- unByKey(this.trackFeatureListenerId);
4821
- }
4822
- /**
4823
- * Custom loader for a WFS datasource
4824
- * @internal
4825
- * @param vectorSource the vector source to be created
4826
- * @param options olOptions from source
4827
- * @param extent the extent of the requested data
4828
- * @param resolution the current resolution
4829
- * @param proj the projection to retrieve the data
4830
- * @param success success callback
4831
- * @param failure failure callback
4832
- * @param randomParam random parameter to ensure cache is not causing problems in retrieving new data
4833
- */
4834
- customWFSLoader(vectorSource, options, extent, resolution, proj, success, failure, randomParam) {
4835
- const paramsWFS = options.paramsWFS;
4836
- const wfsProj = this.getProjection(proj, paramsWFS);
4837
- const currentExtent = olproj.transformExtent(extent, proj, wfsProj);
4838
- if (this.lastRequest &&
4839
- (this.lastRequest.extent !== currentExtent ||
4840
- this.lastRequest.resolution !== resolution)) {
4841
- this.abortRequests(vectorSource);
4842
- }
4843
- const properties = this.dataSource.properties.getAll();
4844
- const url = buildUrl({ ...options, ...properties }, currentExtent, wfsProj, randomParam);
4845
- const request = {
4846
- xhr: undefined,
4847
- extent,
4848
- resolution
4849
- };
4850
- const readOptions = {
4851
- dataProjection: wfsProj,
4852
- featureProjection: proj
4853
- };
4854
- if (paramsWFS.version === '2.0.0' &&
4855
- (paramsWFS.maxFeatures ?? 0) > defaultMaxFeatures) {
4856
- this.batchGetFeatures(url, request, vectorSource, paramsWFS, readOptions, success, failure);
4857
- }
4858
- else {
4859
- this.getFeatures(url, request, vectorSource, readOptions, success, failure);
4860
- }
4861
- }
4862
- abortRequests(vectorSource) {
4863
- if (this.lastRequest) {
4864
- vectorSource.removeLoadedExtent(this.lastRequest.extent);
4865
- }
4866
- for (const request of this.ongoingRequests) {
4867
- request.xhr?.abort();
4868
- this.removeRequest(request);
4869
- }
4870
- }
4871
- getProjection(proj, params) {
4872
- const newProj = params.srsName
4873
- ? new olProjection({ code: params.srsName })
4874
- : proj;
4875
- params.srsName = newProj.getCode();
4876
- return newProj;
4877
- }
4878
- batchGetFeatures(url, request, vectorSource, paramsWFS, readOptions, success, failure) {
4879
- const nbOfFeature = 1000;
4880
- let startIndex = 0;
4881
- while (startIndex < (paramsWFS.maxFeatures ?? 0)) {
4882
- let alteredUrl = url.replace('count=' + paramsWFS.maxFeatures, 'count=' + nbOfFeature);
4883
- alteredUrl = alteredUrl.replace('startIndex=0', '0');
4884
- alteredUrl += '&startIndex=' + startIndex;
4885
- alteredUrl.replace(/&&/g, '&');
4886
- this.getFeatures(alteredUrl, request, vectorSource, readOptions, success, failure);
4887
- startIndex += nbOfFeature;
4888
- }
4889
- }
4890
- /**
4891
- * Custom loader to get feature from a WFS datasource
4892
- * @internal
4893
- * @param vectorSource the vector source to be created
4894
- * @param extent the extent of the requested data
4895
- * @param dataProjection the projection of the retrieved data
4896
- * @param featureProjection the projection of the created features
4897
- * @param url the url string to retrieve the data
4898
- * @param success success callback
4899
- * @param failure failure callback
4900
- */
4901
- getFeatures(url, request, vectorSource, readOptions, success, failure) {
4902
- const xhr = new XMLHttpRequest();
4903
- const alteredUrlWithKeyAuth = this.authInterceptor?.alterUrlWithKeyAuth(url);
4904
- let modifiedUrl = url;
4905
- if (alteredUrlWithKeyAuth) {
4906
- modifiedUrl = alteredUrlWithKeyAuth;
4907
- }
4908
- xhr.open('GET', modifiedUrl);
4909
- if (this.authInterceptor) {
4910
- this.authInterceptor.interceptXhr(xhr, modifiedUrl);
4911
- }
4912
- const onError = () => {
4913
- vectorSource.removeLoadedExtent(request.extent);
4914
- this.removeRequest(request);
4915
- failure();
4916
- };
4917
- xhr.onerror = onError;
4918
- xhr.onload = () => {
4919
- if (xhr.status === 200 && xhr.responseText.length > 0) {
4920
- this.handleOnLoad(vectorSource, xhr.responseText, request, readOptions, success, onError);
4921
- }
4922
- else {
4923
- onError();
4924
- }
4925
- };
4926
- request.xhr = xhr;
4927
- this.lastRequest = request;
4928
- this.ongoingRequests.push(request);
4929
- xhr.send();
4930
- }
4931
- removeRequest(request) {
4932
- if (request === this.lastRequest) {
4933
- this.lastRequest = undefined;
4934
- }
4935
- const index = this.ongoingRequests.indexOf(request);
4936
- if (index > -1) {
4937
- this.ongoingRequests.splice(index, 1);
4938
- }
4939
- }
4940
- handleOnLoad(vectorSource, content, request, readOptions, success, onError) {
4941
- const format = vectorSource.getFormat();
4942
- const type = format.getType();
4943
- if (content) {
4944
- let source;
4945
- switch (type) {
4946
- case 'xml':
4947
- source = new DOMParser().parseFromString(content.toString(), 'application/xml');
4948
- break;
4949
- case 'json':
4950
- case 'text':
4951
- case 'arraybuffer':
4952
- default:
4953
- source = content;
4954
- break;
4955
- }
4956
- if (source) {
4957
- const features = format.readFeatures(source, readOptions);
4958
- if (features) {
4959
- vectorSource.addFeatures(features);
4960
- success(features);
4961
- }
4962
- else {
4963
- success([]);
4964
- }
4965
- this.removeRequest(request);
4966
- }
4967
- else {
4968
- onError();
4969
- }
5441
+ if (this.trackFeatureListenerKey) {
5442
+ unByKey(this.trackFeatureListenerKey);
5443
+ this.trackFeatureListenerKey = undefined;
4970
5444
  }
4971
5445
  }
4972
- /**
4973
- * Custom loader for vector layer.
4974
- * @internal
4975
- * @param vectorSource the vector source to be created
4976
- * @param url the url string or function to retrieve the data
4977
- * @param extent the extent of the requested data
4978
- * @param projection the projection to retrieve the data
4979
- */
4980
- customLoader(vectorSource, url, extent, resolution, projection, success, failure) {
4981
- const onError = () => {
4982
- vectorSource.removeLoadedExtent(extent);
4983
- failure();
4984
- };
4985
- const xhr = new XMLHttpRequest();
4986
- const request = {
4987
- xhr,
4988
- extent,
4989
- resolution
4990
- };
4991
- const readOptions = {
4992
- extent,
4993
- featureProjection: projection
5446
+ attachExtensions(layer, source) {
5447
+ this.extensionManager = new LayerExtensionManager();
5448
+ const context = {
5449
+ id: this.id,
5450
+ options: this.options,
5451
+ layer,
5452
+ source,
5453
+ requestRender: () => this.map?.ol.render(),
5454
+ getStateSnapshot: () => ({
5455
+ mapAttached: this.map !== undefined,
5456
+ visible: this.visible
5457
+ })
4994
5458
  };
4995
- let modifiedUrl = url;
4996
- if (typeof url !== 'function') {
4997
- const alteredUrlWithKeyAuth = this.authInterceptor?.alterUrlWithKeyAuth(url);
4998
- if (alteredUrlWithKeyAuth) {
4999
- modifiedUrl = alteredUrlWithKeyAuth;
5000
- }
5001
- }
5002
- const format = vectorSource.getFormat();
5003
- const type = format.getType();
5004
- if (this.geoNetworkService && typeof url !== 'function') {
5005
- const options = { responseType: type };
5006
- const getVectorObs$ = this.geoNetworkService
5007
- .get(modifiedUrl, options)
5008
- .pipe(first$1(), catchError((res) => {
5009
- onError();
5010
- throw res;
5011
- }));
5012
- const geoDB = new GeoDB();
5013
- const idbGetVectorObsObs$ = geoDB.get(url).pipe(delay(750), concatMap((r) => (r ? of(r) : getVectorObs$)));
5014
- (this.options.idbInfo?.storeToIdb
5015
- ? idbGetVectorObsObs$
5016
- : getVectorObs$).subscribe((content) => {
5017
- this.handleOnLoad(vectorSource, content, request, readOptions, success, onError);
5018
- });
5019
- }
5020
- else {
5021
- xhr.open('GET', modifiedUrl);
5022
- if (type === 'arraybuffer') {
5023
- xhr.responseType = 'arraybuffer';
5024
- }
5025
- if (this.authInterceptor) {
5026
- this.authInterceptor.interceptXhr(xhr, modifiedUrl);
5027
- }
5028
- xhr.onerror = onError;
5029
- xhr.onload = () => {
5030
- if (!xhr.status || (xhr.status >= 200 && xhr.status < 300)) {
5031
- this.handleOnLoad(vectorSource, xhr.responseText, request, readOptions, success, onError);
5459
+ this.extensionManager.attach([vectorLayerAnimationExtension, ...this.getRegisteredExtensions()], this.options, context);
5460
+ }
5461
+ getRegisteredExtensions() {
5462
+ return inject(VECTOR_LAYER_EXTENSIONS, { optional: true }) ?? [];
5463
+ }
5464
+ createCompletionSafeLoader(loader) {
5465
+ return (extent, resolution, projection, success, failure) => {
5466
+ const onSuccess = success ?? (() => void 0);
5467
+ const onFailure = failure ?? (() => void 0);
5468
+ let completed = false;
5469
+ const successOnce = (features) => {
5470
+ if (completed) {
5471
+ return;
5032
5472
  }
5033
- else {
5034
- onError();
5473
+ completed = true;
5474
+ onSuccess(features);
5475
+ };
5476
+ const failureOnce = () => {
5477
+ if (completed) {
5478
+ return;
5035
5479
  }
5480
+ completed = true;
5481
+ onFailure();
5036
5482
  };
5037
- xhr.send();
5038
- }
5483
+ loader(extent, resolution, projection, successOnce, failureOnce);
5484
+ };
5485
+ }
5486
+ executeLoadExtensions(request, baseLoader) {
5487
+ const interceptors = this.extensionManager
5488
+ .getInstances()
5489
+ .filter((instance) => !!instance.interceptLoad)
5490
+ .map((instance) => (nextRequest, next) => instance.interceptLoad(nextRequest, next));
5491
+ const chain = interceptors.reduceRight((next, intercept) => {
5492
+ return (nextRequest) => intercept(nextRequest, next);
5493
+ }, baseLoader);
5494
+ chain(request);
5495
+ }
5496
+ getSourceLoader() {
5497
+ this.sourceLoader ??= new VectorSourceLoader({
5498
+ executeLoadExtensions: (request, baseLoader) => this.executeLoadExtensions(request, baseLoader),
5499
+ xhrInterceptor: this.xhrInterceptor
5500
+ });
5501
+ return this.sourceLoader;
5039
5502
  }
5040
5503
  }
5041
5504
 
5042
5505
  class VectorTileLayer extends Layer {
5043
- messageService;
5044
- authInterceptor;
5045
- styleService;
5046
5506
  type = 'vector';
5047
5507
  watcher;
5048
5508
  get style() {
@@ -5054,11 +5514,8 @@ class VectorTileLayer extends Layer {
5054
5514
  }
5055
5515
  _style$ = new BehaviorSubject$1(undefined);
5056
5516
  style$ = this._style$.asObservable();
5057
- constructor(options, messageService, authInterceptor, styleService) {
5058
- super(options, messageService, authInterceptor, styleService);
5059
- this.messageService = messageService;
5060
- this.authInterceptor = authInterceptor;
5061
- this.styleService = styleService;
5517
+ constructor(options) {
5518
+ super(options);
5062
5519
  this.watcher = new TileWatcher(this);
5063
5520
  this.status$ = this.watcher.status$;
5064
5521
  this.style = this.options.style;
@@ -5086,7 +5543,7 @@ class VectorTileLayer extends Layer {
5086
5543
  });
5087
5544
  const vectorTileSource = vectorTile.getSource();
5088
5545
  vectorTileSource.setTileLoadFunction(((tile, url) => {
5089
- const loader = this.customLoader(url, tile.getFormat(), this.authInterceptor, tile.onLoad.bind(tile));
5546
+ const loader = this.customLoader(url, tile.getFormat(), this.xhrInterceptor, tile.onLoad.bind(tile));
5090
5547
  if (loader) {
5091
5548
  tile.setLoader(loader);
5092
5549
  }
@@ -5117,12 +5574,12 @@ class VectorTileLayer extends Layer {
5117
5574
  * @param failure On failure event action to trigger TODO
5118
5575
  */
5119
5576
  customLoader(url, format, interceptor, success, failure) {
5120
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
5121
5577
  return (extent, resolution, projection) => {
5122
5578
  const xhr = new XMLHttpRequest();
5123
- let modifiedUrl = url;
5579
+ let modifiedUrl;
5124
5580
  if (typeof url !== 'function') {
5125
- const alteredUrlWithKeyAuth = interceptor.alterUrlWithKeyAuth(url);
5581
+ modifiedUrl = url;
5582
+ const alteredUrlWithKeyAuth = interceptor?.alterUrlWithKeyAuth(url);
5126
5583
  if (alteredUrlWithKeyAuth) {
5127
5584
  modifiedUrl = alteredUrlWithKeyAuth;
5128
5585
  }
@@ -5131,9 +5588,7 @@ class VectorTileLayer extends Layer {
5131
5588
  modifiedUrl = url(extent, resolution, projection);
5132
5589
  }
5133
5590
  xhr.open('GET', modifiedUrl);
5134
- if (interceptor) {
5135
- interceptor.interceptXhr(xhr, modifiedUrl);
5136
- }
5591
+ interceptor?.interceptXhr(xhr, modifiedUrl);
5137
5592
  if (format.getType() === 'arraybuffer') {
5138
5593
  xhr.responseType = 'arraybuffer';
5139
5594
  }
@@ -6561,7 +7016,7 @@ class PrintService {
6561
7016
  return n * k;
6562
7017
  }
6563
7018
  mapRenderCompleteEvent$(map, mapSize, viewResolution, status$) {
6564
- return fromEvent(map.ol, 'rendercomplete').pipe(timeout(PRINT_TIMEOUT), first$1(), catchError((error) => {
7019
+ return fromEvent(map.ol, 'rendercomplete').pipe(timeout(PRINT_TIMEOUT), first(), catchError((error) => {
6565
7020
  const translate = this.languageService.translate;
6566
7021
  const message = translate.instant('igo.geo.printForm.timeout', {
6567
7022
  value: PRINT_TIMEOUT / 1000
@@ -6644,7 +7099,6 @@ class WFSDataSource extends DataSource {
6644
7099
  options;
6645
7100
  wfsService;
6646
7101
  ogcFilterService;
6647
- authInterceptor;
6648
7102
  set ogcFilters(value) {
6649
7103
  this.options.ogcFilters = value;
6650
7104
  }
@@ -6661,12 +7115,11 @@ class WFSDataSource extends DataSource {
6661
7115
  })
6662
7116
  };
6663
7117
  }
6664
- constructor(options, wfsService, ogcFilterService, authInterceptor) {
7118
+ constructor(options, wfsService, ogcFilterService) {
6665
7119
  super(checkWfsParams(options, 'wfs'));
6666
7120
  this.options = options;
6667
7121
  this.wfsService = wfsService;
6668
7122
  this.ogcFilterService = ogcFilterService;
6669
- this.authInterceptor = authInterceptor;
6670
7123
  const ogcFilters = this.options
6671
7124
  .ogcFilters;
6672
7125
  const fieldNameGeometry = this.options.paramsWFS?.fieldNameGeometry || defaultFieldNameGeometry;
@@ -6719,47 +7172,76 @@ class WFSDataSource extends DataSource {
6719
7172
  super.refresh();
6720
7173
  }
6721
7174
  fetchFeatures({ extent, projection, httpClient }) {
6722
- const paramsWFS = this.options.paramsWFS;
6723
- const wfsProj = paramsWFS.srsName
7175
+ const requestContext = this.createRequestContext({
7176
+ extent,
7177
+ projection,
7178
+ omitBboxWhenNoExtent: true
7179
+ });
7180
+ const urls = this.buildRequestUrls(requestContext.baseUrl, requestContext.paramsWFS);
7181
+ return forkJoin(urls.map((batchUrl) => this._fetchFeatures(requestContext.wfsProjection, batchUrl, {
7182
+ extent: requestContext.transformedExtent,
7183
+ projection,
7184
+ httpClient
7185
+ }))).pipe(map$1((featureBatches) => featureBatches.flat()));
7186
+ }
7187
+ createRequestContext({ extent, projection, options, randomParam, omitBboxWhenNoExtent = false }) {
7188
+ const effectiveOptions = options ?? this.options;
7189
+ const paramsWFS = effectiveOptions.paramsWFS;
7190
+ const wfsProjection = paramsWFS.srsName
6724
7191
  ? new olProjection({ code: paramsWFS.srsName })
6725
7192
  : projection;
6726
- const currentExtent = extent
6727
- ? olproj.transformExtent(extent, projection, wfsProj)
7193
+ const transformedExtent = extent
7194
+ ? olproj.transformExtent(extent, projection, wfsProjection)
6728
7195
  : undefined;
6729
7196
  paramsWFS.srsName = paramsWFS.srsName || projection.getCode();
6730
- let url = buildUrl(this.options, currentExtent, wfsProj);
6731
- // Exportation want to fetch without extent/bbox restrictions
6732
- if (!extent && url.includes('bbox')) {
6733
- const [baseUrl, params] = url.split('?');
7197
+ let baseUrl = buildUrl(effectiveOptions, transformedExtent, wfsProjection, randomParam);
7198
+ // Exportation wants to fetch without extent/bbox restrictions.
7199
+ if (omitBboxWhenNoExtent && !extent && baseUrl.includes('bbox')) {
7200
+ const [urlBase, params] = baseUrl.split('?');
6734
7201
  const paramSegments = params.split('&');
6735
7202
  const paramsWithoutBbox = paramSegments.filter((segment) => !segment.includes('bbox'));
6736
- url = `${baseUrl}?${paramsWithoutBbox.join('&')}`;
6737
- }
6738
- let startIndex = 0;
6739
- if (paramsWFS.version === '2.0.0' &&
6740
- paramsWFS.maxFeatures !== undefined &&
6741
- paramsWFS.maxFeatures > defaultMaxFeatures) {
6742
- const nbOfFeature = 1000;
6743
- while (startIndex < paramsWFS.maxFeatures) {
6744
- let alteredUrl = url.replace('count=' + paramsWFS.maxFeatures, 'count=' + nbOfFeature);
6745
- alteredUrl = alteredUrl.replace('startIndex=0', '0');
6746
- alteredUrl += '&startIndex=' + startIndex;
6747
- alteredUrl.replace(/&&/g, '&');
6748
- return this._fetchFeatures(wfsProj, alteredUrl, {
6749
- extent: currentExtent,
6750
- projection,
6751
- httpClient
6752
- }).pipe(map$1((res) => {
6753
- startIndex += nbOfFeature;
6754
- return res;
6755
- }));
6756
- }
7203
+ baseUrl = `${urlBase}?${paramsWithoutBbox.join('&')}`;
6757
7204
  }
6758
- return this._fetchFeatures(wfsProj, url, {
6759
- extent: currentExtent,
6760
- projection,
6761
- httpClient
6762
- });
7205
+ return {
7206
+ baseUrl,
7207
+ paramsWFS,
7208
+ wfsProjection,
7209
+ transformedExtent
7210
+ };
7211
+ }
7212
+ buildRequestUrls(url, paramsWFS) {
7213
+ if (!this.shouldBatchWfsRequest(paramsWFS)) {
7214
+ return [url];
7215
+ }
7216
+ return buildWfsBatchUrls(url, paramsWFS.maxFeatures ?? 0);
7217
+ }
7218
+ shouldBatchWfsRequest(paramsWFS) {
7219
+ return (paramsWFS.version === '2.0.0' &&
7220
+ (paramsWFS.maxFeatures ?? 0) > defaultMaxFeatures);
7221
+ }
7222
+ createVectorSourceLoader(host, options = this.options, randomParam = false) {
7223
+ return (extent, resolution, projection, success, failure) => {
7224
+ const requestContext = this.createRequestContext({
7225
+ extent,
7226
+ projection,
7227
+ options: { ...options, ...this.properties.getAll() },
7228
+ randomParam
7229
+ });
7230
+ host.execute({
7231
+ source: this.ol,
7232
+ url: requestContext.baseUrl,
7233
+ extent,
7234
+ resolution,
7235
+ projection,
7236
+ readOptions: {
7237
+ dataProjection: requestContext.wfsProjection,
7238
+ featureProjection: projection
7239
+ },
7240
+ resolveUrls: (url) => this.buildRequestUrls(url, requestContext.paramsWFS),
7241
+ success: success ?? (() => void 0),
7242
+ failure: failure ?? (() => void 0)
7243
+ });
7244
+ };
6763
7245
  }
6764
7246
  _fetchFeatures(featureProjection, url, { extent, projection, httpClient }) {
6765
7247
  return httpClient.get(url, { responseType: 'text' }).pipe(map$1((response) => {
@@ -6778,6 +7260,32 @@ class WFSDataSource extends DataSource {
6778
7260
  return features;
6779
7261
  }
6780
7262
  }
7263
+ function buildWfsBatchUrls(url, maxFeatures, batchSize = 1000) {
7264
+ if (maxFeatures <= batchSize) {
7265
+ return [url];
7266
+ }
7267
+ // Dummy base only to satisfy URL() when `url` is relative; discarded below if so.
7268
+ const isProtocolRelativeUrl = url.startsWith('//');
7269
+ const parsedUrl = new URL(isProtocolRelativeUrl ? `http:${url}` : url, 'http://igo.local');
7270
+ const isAbsoluteUrl = /^[a-zA-Z][a-zA-Z\d+.-]*:/.test(url);
7271
+ const pathEnd = [url.indexOf('?'), url.indexOf('#')]
7272
+ .filter((index) => index >= 0)
7273
+ .reduce((lowest, index) => Math.min(lowest, index), url.length);
7274
+ const originalPath = url.slice(0, pathEnd);
7275
+ const urls = [];
7276
+ for (let startIndex = 0; startIndex < maxFeatures; startIndex += batchSize) {
7277
+ const batchCount = Math.min(batchSize, maxFeatures - startIndex);
7278
+ parsedUrl.searchParams.set('count', batchCount.toString());
7279
+ parsedUrl.searchParams.set('startIndex', startIndex.toString());
7280
+ parsedUrl.searchParams.delete('maxFeatures');
7281
+ urls.push(isAbsoluteUrl
7282
+ ? parsedUrl.toString()
7283
+ : isProtocolRelativeUrl
7284
+ ? `//${parsedUrl.host}${parsedUrl.pathname}${parsedUrl.search}${parsedUrl.hash}`
7285
+ : `${originalPath}${parsedUrl.search}${parsedUrl.hash}`);
7286
+ }
7287
+ return urls;
7288
+ }
6781
7289
 
6782
7290
  function createDefaultTileGrid(epsg) {
6783
7291
  const projection = epsg ? olproj.get(epsg) : olproj.get('EPSG:3857');
@@ -7363,18 +7871,21 @@ class MVTDataSource extends DataSource {
7363
7871
  * @param store The store to bind the layer
7364
7872
  * @param layer An optional VectorLayer
7365
7873
  */
7366
- function tryBindStoreLayer(store, layer) {
7874
+ function tryBindStoreLayer(store, layer, layerService) {
7367
7875
  if (store.layer !== undefined) {
7368
7876
  if (!store.map.layerController.getById(store.layer.id)) {
7369
7877
  store.map.layerController.add(store.layer);
7370
7878
  }
7371
7879
  return store.layer;
7372
7880
  }
7373
- layer = layer
7374
- ? layer
7375
- : new VectorLayer({
7881
+ if (!layer) {
7882
+ if (!layerService) {
7883
+ throw new Error('LayerService is required to create a store layer.');
7884
+ }
7885
+ layer = layerService.createLayer({
7376
7886
  source: new FeatureDataSource()
7377
7887
  });
7888
+ }
7378
7889
  store.bindLayer(layer);
7379
7890
  if (!store.map.layerController.getById(layer.id)) {
7380
7891
  store.map.layerController.add(store.layer);
@@ -7382,15 +7893,6 @@ function tryBindStoreLayer(store, layer) {
7382
7893
  return layer;
7383
7894
  }
7384
7895
 
7385
- const FEATURE = 'Feature';
7386
- var FeatureMotion;
7387
- (function (FeatureMotion) {
7388
- FeatureMotion[FeatureMotion["None"] = 0] = "None";
7389
- FeatureMotion[FeatureMotion["Move"] = 1] = "Move";
7390
- FeatureMotion[FeatureMotion["Zoom"] = 2] = "Zoom";
7391
- FeatureMotion[FeatureMotion["Default"] = 3] = "Default";
7392
- })(FeatureMotion || (FeatureMotion = {}));
7393
-
7394
7896
  /**
7395
7897
  * This strategy loads a store's features into it's layer counterpart.
7396
7898
  * The store -> layer binding is a one-way binding. That means any entity
@@ -7527,328 +8029,6 @@ class FeatureStoreLoadingStrategy extends EntityStoreStrategy {
7527
8029
  }
7528
8030
  }
7529
8031
 
7530
- /**
7531
- * Create an Openlayers feature object out of a feature definition.
7532
- * The output object has a reference to the feature id.
7533
- * @param feature Feature definition
7534
- * @param projectionOut Feature object projection
7535
- * @returns OpenLayers feature object
7536
- */
7537
- function featureToOl(feature, projectionOut, getId) {
7538
- getId = getId ? getId : getEntityId;
7539
- const olFormat = new OlGeoJSON();
7540
- const olFeature = olFormat.readFeature(feature, {
7541
- dataProjection: feature.projection,
7542
- featureProjection: projectionOut
7543
- });
7544
- olFeature.setId(getId(feature));
7545
- const title = getEntityTitle(feature);
7546
- if (title !== undefined) {
7547
- olFeature.set('_title', title, true);
7548
- }
7549
- if (feature.extent !== undefined) {
7550
- olFeature.set('_extent', feature.extent, true);
7551
- }
7552
- if (feature.projection !== undefined) {
7553
- olFeature.set('_projection', feature.projection, true);
7554
- }
7555
- const mapTitle = getEntityProperty(feature, 'meta.mapTitle');
7556
- if (mapTitle !== undefined) {
7557
- olFeature.set('_mapTitle', mapTitle, true);
7558
- }
7559
- olFeature.set('_entityRevision', getEntityRevision(feature), true);
7560
- const icon = getEntityIcon(feature);
7561
- if (icon !== undefined) {
7562
- olFeature.set('_icon', icon, true);
7563
- }
7564
- if (feature.meta && feature.meta.style) {
7565
- olFeature.set('_style', feature.meta.style, true);
7566
- }
7567
- if (feature.sourceId) {
7568
- olFeature.set('_sourceId', feature.sourceId, true);
7569
- }
7570
- return olFeature;
7571
- }
7572
- function renderFeatureFromOl(olRenderFeature, projectionIn, olLayer, projectionOut = 'EPSG:4326') {
7573
- let geom;
7574
- let title;
7575
- let exclude;
7576
- let excludeOffline;
7577
- if (olLayer) {
7578
- title = olLayer.get('title');
7579
- if (olLayer.get('sourceOptions')) {
7580
- exclude = olLayer.get('sourceOptions').excludeAttribute;
7581
- excludeOffline = olLayer.get('sourceOptions').excludeAttributeOffline;
7582
- }
7583
- }
7584
- else {
7585
- title = olRenderFeature.get('_title');
7586
- }
7587
- const olFormat = new OlGeoJSON();
7588
- const properties = olRenderFeature.getProperties();
7589
- const geometryType = olRenderFeature.getType();
7590
- if (geometryType === 'Polygon') {
7591
- const ends = olRenderFeature.getEnds();
7592
- geom = new OlPolygon(olRenderFeature.getFlatCoordinates(), 'XY', ends);
7593
- }
7594
- else if (geometryType === 'Point') {
7595
- geom = new OlPoint(olRenderFeature.getFlatCoordinates(), 'XY');
7596
- }
7597
- else if (geometryType === 'LineString') {
7598
- geom = new OlLineString(olRenderFeature.getFlatCoordinates(), 'XY');
7599
- }
7600
- const geometry = olFormat.writeGeometryObject(geom, {
7601
- dataProjection: projectionOut,
7602
- featureProjection: projectionIn
7603
- });
7604
- const id = (olRenderFeature.getId() ?? uuid());
7605
- const mapTitle = olRenderFeature.get('_mapTitle');
7606
- const extent = olproj.transformExtent(olRenderFeature.getExtent(), projectionIn, projectionOut);
7607
- return {
7608
- type: FEATURE,
7609
- projection: projectionOut,
7610
- extent,
7611
- meta: {
7612
- id,
7613
- title: title ? title : mapTitle ? mapTitle : id,
7614
- mapTitle,
7615
- excludeAttribute: exclude,
7616
- excludeAttributeOffline: excludeOffline
7617
- },
7618
- properties,
7619
- geometry,
7620
- ol: olRenderFeature
7621
- };
7622
- }
7623
- /**
7624
- * Create a feature object out of an OL feature
7625
- * The output object has a reference to the feature id.
7626
- * @param olFeature OL Feature
7627
- * @param projectionIn OL feature projection
7628
- * @param olLayer OL Layer
7629
- * @param projectionOut Feature projection
7630
- * @returns Feature
7631
- */
7632
- function featureFromOl(olFeature, projectionIn, olLayer, projectionOut = 'EPSG:4326') {
7633
- let title;
7634
- let exclude;
7635
- let excludeOffline;
7636
- let idColumn; // for arcgisrest and tilearcgisrest source
7637
- const olFormat = new OlGeoJSON();
7638
- const keys = olFeature.getKeys().filter((key) => {
7639
- return !key.startsWith('_') && key !== 'geometry';
7640
- });
7641
- const properties = keys.reduce((acc, key) => {
7642
- acc[key] = olFeature.get(key);
7643
- return acc;
7644
- }, {});
7645
- const geometry = olFormat.writeGeometryObject(olFeature.getGeometry(), {
7646
- dataProjection: projectionOut,
7647
- featureProjection: projectionIn
7648
- });
7649
- if (olLayer) {
7650
- title = olLayer.get('title');
7651
- const sourceOptions = olLayer.get('sourceOptions');
7652
- if (sourceOptions) {
7653
- exclude = sourceOptions.excludeAttribute;
7654
- excludeOffline = sourceOptions.excludeAttributeOffline;
7655
- idColumn =
7656
- sourceOptions.idColumn ||
7657
- (sourceOptions.type === 'arcgisrest' ||
7658
- sourceOptions.type === 'tilearcgisrest'
7659
- ? 'OBJECTID'
7660
- : undefined);
7661
- }
7662
- }
7663
- else {
7664
- title = olFeature.get('_title');
7665
- }
7666
- const mapTitle = olFeature.get('_mapTitle');
7667
- const id = olFeature.getId()
7668
- ? olFeature.getId()
7669
- : olFeature.get(idColumn)
7670
- ? olFeature.get(idColumn)
7671
- : uuid();
7672
- return {
7673
- type: FEATURE,
7674
- projection: projectionOut,
7675
- extent: olFeature.get('_extent'),
7676
- meta: {
7677
- id,
7678
- title: title ? title : mapTitle ? mapTitle : id,
7679
- mapTitle,
7680
- revision: olFeature.getRevision(),
7681
- style: olFeature.get('_style'),
7682
- excludeAttribute: exclude,
7683
- excludeAttributeOffline: excludeOffline
7684
- },
7685
- properties,
7686
- geometry,
7687
- ol: olFeature
7688
- };
7689
- }
7690
- /**
7691
- * Compute an OL feature extent in it's map projection
7692
- * @param map Map
7693
- * @param olFeature OL feature
7694
- * @returns Extent in the map projection
7695
- */
7696
- function computeOlFeatureExtent(olFeature, projection) {
7697
- let olExtent = olextent.createEmpty();
7698
- const olFeatureExtent = olFeature.get('_extent');
7699
- const olFeatureProjection = olFeature.get('_projection');
7700
- if (olFeatureExtent !== undefined && olFeatureProjection !== undefined) {
7701
- olExtent = olproj.transformExtent(olFeatureExtent, olFeatureProjection, projection);
7702
- }
7703
- else {
7704
- const olGeometry = olFeature.getGeometry();
7705
- if (olGeometry !== null && olGeometry !== undefined) {
7706
- olExtent = olGeometry.getExtent();
7707
- }
7708
- }
7709
- return olExtent;
7710
- }
7711
- /**
7712
- * Compute a multiple OL features extent in their map projection
7713
- * @param map Map
7714
- * @param olFeatures OL features
7715
- * @returns Extent in the map projection
7716
- */
7717
- function computeOlFeaturesExtent(olFeatures, projection) {
7718
- const extent = olextent.createEmpty();
7719
- olFeatures.forEach((olFeature) => {
7720
- const featureExtent = computeOlFeatureExtent(olFeature, projection);
7721
- olextent.extend(extent, featureExtent);
7722
- });
7723
- return extent;
7724
- }
7725
- /**
7726
- * Scale an extent.
7727
- * @param extent Extent
7728
- * @param Scaling factors for top, right, bottom and left directions, in that order
7729
- * @returns Scaled extent
7730
- */
7731
- function scaleExtent(extent, scale) {
7732
- const [width, height] = olextent.getSize(extent);
7733
- return [
7734
- scale[3] ? extent[0] - width * scale[3] : extent[0],
7735
- scale[2] ? extent[1] - height * scale[2] : extent[1],
7736
- scale[1] ? extent[2] + width * scale[1] : extent[2],
7737
- scale[0] ? extent[3] + height * scale[0] : extent[3]
7738
- ];
7739
- }
7740
- /**
7741
- * Return true if features are out of view.
7742
- * If features are too close to the edge, they are considered out of view.
7743
- * By default, we define the edge as 5% (0.05) of the extent size.
7744
- * @param map Map
7745
- * @param featuresExtent The features's extent
7746
- * @param edgeRatio Number or Number[] Single value OR an array =>
7747
- * [top,right,bottom,left] directions, in that order
7748
- * @returns Return true if features are out of view
7749
- */
7750
- function featuresAreOutOfView(extent, featuresExtent, edgeRatio = 0.05) {
7751
- const edgesRatio = Array.isArray(edgeRatio)
7752
- ? edgeRatio
7753
- : [edgeRatio, edgeRatio, edgeRatio, edgeRatio];
7754
- const scale = [-1, -1, -1, -1].map((x, i) => x * edgesRatio[i]);
7755
- const viewExtent = scaleExtent(extent, scale);
7756
- return !olextent.containsExtent(viewExtent, featuresExtent);
7757
- }
7758
- /**
7759
- * Return true if features are too deep into the view. This results
7760
- * in features being too small.
7761
- * Features are considered too small if their extent occupies less than
7762
- * 1% of the map extent.
7763
- * @param map Map
7764
- * @param featuresExtent The features's extent
7765
- * @param areaRatio The features extent to view extent acceptable ratio
7766
- * @returns Return true if features are too deep in the view
7767
- */
7768
- function featuresAreTooDeepInView(viewController, featuresExtent, areaRatio) {
7769
- // An area ratio of 0.004 means that the feature extent's width and height
7770
- // should be about 1/16 of the map extent's width and height
7771
- areaRatio = areaRatio ? areaRatio : 0.004;
7772
- const mapExtent = viewController.getExtent();
7773
- const mapExtentArea = olextent.getArea(mapExtent);
7774
- const featuresExtentArea = olextent.getArea(featuresExtent);
7775
- if (featuresExtentArea === 0 && viewController.getZoom() > 13) {
7776
- // In case it's a point
7777
- return false;
7778
- }
7779
- return featuresExtentArea / mapExtentArea < areaRatio;
7780
- }
7781
- /**
7782
- * Fit view to include the features extent.
7783
- * By default, this method will let the features occupy about 50% of the viewport.
7784
- * @param map Map
7785
- * @param olFeatures OL features
7786
- * @param motion To motion to the new map view
7787
- * @param scale If this is defined, the original view will be scaled
7788
- * by that factor before any logic is applied.
7789
- */
7790
- function moveToOlFeatures(viewController, olFeatures, motion = FeatureMotion.Default, scale, areaRatio) {
7791
- const extent = viewController.getExtent();
7792
- const projection = viewController.getOlProjection();
7793
- const featuresExtent = computeOlFeaturesExtent(Array.isArray(olFeatures) ? olFeatures : [olFeatures], projection);
7794
- let viewExtent = featuresExtent;
7795
- if (scale !== undefined) {
7796
- viewExtent = scaleExtent(viewExtent, scale);
7797
- }
7798
- if (motion === FeatureMotion.Zoom) {
7799
- viewController.zoomToExtent(viewExtent);
7800
- }
7801
- else if (motion === FeatureMotion.Move) {
7802
- viewController.moveToExtent(viewExtent);
7803
- }
7804
- else if (motion === FeatureMotion.Default) {
7805
- if (featuresAreOutOfView(extent, featuresExtent) ||
7806
- featuresAreTooDeepInView(viewController, featuresExtent, areaRatio)) {
7807
- viewController.zoomToExtent(viewExtent);
7808
- }
7809
- }
7810
- }
7811
- /**
7812
- * Hide an OL feature
7813
- * @param olFeature OL feature
7814
- */
7815
- function hideOlFeature(olFeature) {
7816
- olFeature.setStyle(new olstyle.Style({}));
7817
- }
7818
- /**
7819
- * Compute a diff between a source array of Ol features and a target array
7820
- * @param source Source array of OL features
7821
- * @param starget Target array of OL features
7822
- * @returns Features to add and remove
7823
- */
7824
- function computeOlFeaturesDiff(source, target) {
7825
- const olFeaturesMap = new Map();
7826
- target.forEach((olFeature) => {
7827
- olFeaturesMap.set(olFeature.getId(), olFeature);
7828
- });
7829
- const olFeaturesToRemove = [];
7830
- source.forEach((olFeature) => {
7831
- const newOlFeature = olFeaturesMap.get(olFeature.getId());
7832
- if (newOlFeature === undefined) {
7833
- olFeaturesToRemove.push(olFeature);
7834
- }
7835
- else if (newOlFeature.get('_entityRevision') !== olFeature.get('_entityRevision')) {
7836
- olFeaturesToRemove.push(olFeature);
7837
- }
7838
- else {
7839
- olFeaturesMap.delete(newOlFeature.getId());
7840
- }
7841
- });
7842
- const olFeaturesToAddIds = Array.from(olFeaturesMap.keys());
7843
- const olFeaturesToAdd = target.filter((olFeature) => {
7844
- return olFeaturesToAddIds.indexOf(olFeature.getId()) >= 0;
7845
- });
7846
- return {
7847
- add: olFeaturesToAdd,
7848
- remove: olFeaturesToRemove
7849
- };
7850
- }
7851
-
7852
8032
  /**
7853
8033
  * The class is a specialized version of an EntityStore that stores
7854
8034
  * features and the map layer to display them on. Synchronization
@@ -8344,7 +8524,10 @@ class FeatureStoreSelectionStrategy extends EntityStoreStrategy {
8344
8524
  * @returns Overlay layer
8345
8525
  */
8346
8526
  createOverlayLayer() {
8347
- return new VectorLayer({
8527
+ if (!this.options.layerService) {
8528
+ throw new Error('LayerService is required when no selection layer is provided.');
8529
+ }
8530
+ return this.options.layerService.createLayer({
8348
8531
  zIndex: 300,
8349
8532
  source: new FeatureDataSource(),
8350
8533
  style: undefined,
@@ -8398,192 +8581,10 @@ function tryAddSelectionStrategy(store, strategy) {
8398
8581
  store.activateStrategyOfType(FeatureStoreSelectionStrategy);
8399
8582
  return;
8400
8583
  }
8401
- strategy = strategy
8402
- ? strategy
8403
- : new FeatureStoreSelectionStrategy({
8404
- map: store.map
8405
- });
8406
8584
  store.addStrategy(strategy);
8407
8585
  strategy.activate();
8408
8586
  }
8409
8587
 
8410
- const STYLES_VARIANT = {
8411
- base: {
8412
- fill: 'rgba(0, 161, 222, 0.15)',
8413
- stroke: 'rgba(0, 161, 222, 0.5)',
8414
- strokeWidth: 2,
8415
- markerColor: 'rgba(0, 161, 222, 0.5)',
8416
- markerOutlineColor: 'rgba(255, 255, 255, 1)'
8417
- },
8418
- focus: {
8419
- fill: 'rgba(207, 222, 0, 0.15)',
8420
- stroke: 'rgba(11, 220, 228, 0.5)',
8421
- strokeWidth: 4,
8422
- markerColor: 'rgba(207, 222, 0, 1)',
8423
- markerOutlineColor: 'rgba(11, 220, 228, 1)'
8424
- },
8425
- selection: {
8426
- fill: 'rgba(0, 161, 222, 0.15)',
8427
- stroke: 'rgba(0, 255, 255, 0.5)',
8428
- strokeWidth: 4,
8429
- markerColor: 'rgba(0, 161, 222, 1)',
8430
- markerOutlineColor: 'rgba(0, 255, 255, 1)'
8431
- }
8432
- };
8433
- const NEAR_TRANSPARENT_COLOR = 'rgba(255, 255, 255, 0.01)';
8434
- const DEFAULT_MARKER_COLOR = 'rgba(0, 161, 222, 1)';
8435
- const DEFAULT_MARKER_OUTLINE_COLOR = 'rgba(255, 255, 255, 1)';
8436
- const DEFAULT_CLUSTER_COLOR = 'rgba(24, 134, 45)';
8437
- const DEFAULT_CLUSTER_FILL_COLOR = 'rgba(24, 134, 45, 0.5)';
8438
- const DEFAULT_TEXT_COLOR = '#000';
8439
- const DEFAULT_TEXT_OUTLINE_COLOR = '#fff';
8440
- const DEFAULT_TEXT_FONT = '12px Calibri,sans-serif';
8441
- const DEFAULT_TEXT_STROKE_WIDTH = 3;
8442
- const DEFAULT_MARKER_ANCHOR = [0.5, 0.92];
8443
- const GEOMETRY_THRESHOLD = 0.0025;
8444
- const RANDOM_STYLE_MAX_CHANNEL = 255;
8445
- const CLUSTER_MIN_RADIUS = 6;
8446
- const CLUSTER_RADIUS_FACTOR = 5;
8447
- function styleVariant(viewController, type = 'base') {
8448
- return (featureLike) => {
8449
- const { _mapTitle: mapTitle } = featureLike.getProperties();
8450
- const imposedGeometry = featureLike instanceof OlFeature
8451
- ? createStyleGeometry(viewController, featureLike)
8452
- : undefined;
8453
- return createStyleVariant(type, mapTitle, imposedGeometry);
8454
- };
8455
- }
8456
- function baseOlStyle(text, imposedGeometry) {
8457
- return createStyleVariant('base', text, imposedGeometry);
8458
- }
8459
- function selectionOlStyle(text, imposedGeometry) {
8460
- return createStyleVariant('selection', text, imposedGeometry);
8461
- }
8462
- /**
8463
- * Invisible-but-interactive style (hit detection, event capture).
8464
- */
8465
- function nearTransparentOlStyle() {
8466
- return new Style({
8467
- fill: new Fill({ color: NEAR_TRANSPARENT_COLOR }),
8468
- stroke: new Stroke({ width: 10, color: NEAR_TRANSPARENT_COLOR }),
8469
- image: new Circle({
8470
- stroke: new Stroke({ width: 10, color: NEAR_TRANSPARENT_COLOR }),
8471
- fill: new Fill({ color: NEAR_TRANSPARENT_COLOR }),
8472
- radius: 5
8473
- })
8474
- });
8475
- }
8476
- function markerOlStyle({ text, markerColor = DEFAULT_MARKER_COLOR, markerOutlineColor = DEFAULT_MARKER_OUTLINE_COLOR, imposedGeometry }) {
8477
- const svg = createMarkerSvg(markerColor, markerOutlineColor);
8478
- const style = new Style({
8479
- image: new Icon({
8480
- src: `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}`,
8481
- opacity: 1,
8482
- anchor: DEFAULT_MARKER_ANCHOR
8483
- })
8484
- });
8485
- if (text) {
8486
- style.setText(new Text({
8487
- text,
8488
- font: DEFAULT_TEXT_FONT,
8489
- fill: new Fill({ color: DEFAULT_TEXT_COLOR }),
8490
- stroke: new Stroke({
8491
- color: DEFAULT_TEXT_OUTLINE_COLOR,
8492
- width: DEFAULT_TEXT_STROKE_WIDTH
8493
- }),
8494
- overflow: true
8495
- }));
8496
- }
8497
- return setGeometryIfNeeded(style, imposedGeometry);
8498
- }
8499
- function randomOlFlatStyle() {
8500
- const red = randomChannel();
8501
- const green = randomChannel();
8502
- const blue = randomChannel();
8503
- return {
8504
- 'stroke-color': [red, green, blue, 1],
8505
- 'stroke-width': 2,
8506
- 'fill-color': [red, green, blue, 0.4],
8507
- 'circle-radius': 5,
8508
- 'circle-stroke-color': [red, green, blue, 1],
8509
- 'circle-stroke-width': 2,
8510
- 'circle-fill-color': [red, green, blue, 0.4],
8511
- 'text-value': ['case', ['has', '_mapTitle'], ['get', '_mapTitle'], ''],
8512
- 'text-offset-x': 5,
8513
- 'text-offset-y': -5,
8514
- 'text-font': DEFAULT_TEXT_FONT,
8515
- 'text-fill-color': DEFAULT_TEXT_COLOR,
8516
- 'text-stroke-color': DEFAULT_TEXT_OUTLINE_COLOR,
8517
- 'text-stroke-width': DEFAULT_TEXT_STROKE_WIDTH,
8518
- 'text-overflow': true
8519
- };
8520
- }
8521
- function clusterOlStyleFunction(clusterParam = {}) {
8522
- return (feature) => {
8523
- const size = feature.get('features')
8524
- ?.length ?? 0;
8525
- if (size <= 1) {
8526
- return markerOlStyle({ markerColor: DEFAULT_CLUSTER_COLOR });
8527
- }
8528
- const clusterRadius = clusterParam.radiusCalc?.(size) ??
8529
- Math.max(CLUSTER_MIN_RADIUS, CLUSTER_RADIUS_FACTOR * Math.log(size));
8530
- return [
8531
- new Style({
8532
- image: new Circle({
8533
- radius: clusterRadius,
8534
- stroke: new Stroke({ color: DEFAULT_CLUSTER_COLOR }),
8535
- fill: new Fill({ color: DEFAULT_CLUSTER_FILL_COLOR })
8536
- }),
8537
- text: new Text({
8538
- text: String(size),
8539
- fill: new Fill({ color: DEFAULT_TEXT_OUTLINE_COLOR })
8540
- })
8541
- })
8542
- ];
8543
- };
8544
- }
8545
- function createMarkerSvg(markerColor, markerOutlineColor) {
8546
- return `<svg version="1.1" xmlns="http://www.w3.org/2000/svg" height="36" width="36" viewBox="0 0 36 36">
8547
- <path fill="${toString(asArray(markerColor))}" stroke="${toString(asArray(markerOutlineColor))}" stroke-width="2"
8548
- d="M 17.692635,32.565644 C 15.71852,30.330584 13.290925,27.058065 11.6766,24.455732 9.3398623,20.688851 7.8905694,17.205334 7.6297492,14.728733 7.5616025,14.081649 7.5739557,12.528552 7.6513363,12.014724 8.1013861,9.0262716 9.8047068,6.3655569 12.310675,4.7364878 c 1.113691,-0.7239832 2.508083,-1.2834131 3.776687,-1.5152052 0.242945,-0.044389 0.451656,-0.09393 0.463804,-0.1100911 0.01215,-0.016161 0.638282,-0.025502 1.391411,-0.02076 1.088235,0.00685 1.450932,0.024316 1.766871,0.085071 2.650763,0.5097353 4.947142,1.8701891 6.498786,3.8501033 0.628018,0.8013587 1.297046,2.0200608 1.640967,2.9891872 0.191065,0.538399 0.427644,1.447408 0.477391,1.834287 0.0164,0.127546 0.0434,0.231902 0.06,0.231902 0.0166,0 0.03122,0.626135 0.03249,1.391411 0.0013,0.765276 -0.011,1.391411 -0.02726,1.391411 -0.01626,0 -0.05449,0.154049 -0.08495,0.342331 -0.08815,0.544879 -0.387235,1.721449 -0.604837,2.379406 -1.209421,3.656888 -4.014463,8.349762 -7.849521,13.132357 -0.790496,0.985807 -1.795217,2.167992 -1.842543,2.167992 -0.01896,0 -0.161766,-0.144111 -0.317336,-0.320246 z m 1.066937,-15.36525 c 0.133519,-0.02121 0.248766,-0.05657 0.256105,-0.07859 0.0073,-0.02202 0.04918,-0.03066 0.09298,-0.0192 0.0438,0.01145 0.107628,-0.0072 0.141834,-0.04137 0.03421,-0.03421 0.08456,-0.05474 0.111888,-0.04563 0.02733,0.0091 0.07703,-0.01077 0.110429,-0.04417 0.03341,-0.03341 0.08416,-0.05293 0.112796,-0.04338 0.02863,0.0095 0.08974,-0.01867 0.135802,-0.06271 0.04606,-0.04403 0.111902,-0.08625 0.146319,-0.09381 0.204084,-0.04483 0.762371,-0.519108 1.079463,-0.917027 0.26749,-0.335672 0.570987,-0.878795 0.529019,-0.946701 -0.01496,-0.0242 -0.0067,-0.044 0.01835,-0.044 0.05645,0 0.196809,-0.467982 0.158801,-0.529481 -0.01521,-0.02461 -0.0043,-0.04475 0.02427,-0.04475 0.03157,0 0.04365,-0.04329 0.03082,-0.11043 -0.01161,-0.06074 -0.0066,-0.110429 0.01124,-0.110429 0.01779,0 0.03235,-0.258405 0.03235,-0.574233 0,-0.315829 -0.01545,-0.574234 -0.03434,-0.574234 -0.01889,0 -0.02437,-0.03811 -0.01219,-0.08469 0.04412,-0.168712 -0.336329,-1.152668 -0.481536,-1.245401 -0.02327,-0.01486 -0.04022,-0.03992 -0.03765,-0.05568 0.01222,-0.07498 -0.156557,-0.318365 -0.406379,-0.586027 -0.295921,-0.317054 -0.773059,-0.690104 -0.83427,-0.652274 -0.0206,0.01273 -0.03745,0.0024 -0.03745,-0.02289 0,-0.06107 -0.433076,-0.2789369 -0.487546,-0.245273 -0.02338,0.01445 -0.04251,0.0068 -0.04251,-0.01695 0,-0.056281 -0.393995,-0.1865457 -0.613804,-0.2029397 -0.0943,-0.00703 -0.188579,-0.023183 -0.209503,-0.035888 -0.02092,-0.012705 -0.276571,-0.023337 -0.568105,-0.023627 -0.534044,-5.301e-4 -1.12638,0.091025 -1.12638,0.1741017 0,0.023781 -0.01713,0.032648 -0.03808,0.019705 -0.05054,-0.031232 -0.403641,0.1088602 -0.403641,0.1601422 0,0.02204 -0.01988,0.02779 -0.04417,0.01278 -0.0243,-0.01501 -0.04417,-0.0051 -0.04417,0.02209 0,0.02716 -0.01988,0.0371 -0.04417,0.02209 -0.0243,-0.01501 -0.04417,-0.0051 -0.04417,0.02209 0,0.02716 -0.01915,0.03755 -0.04256,0.02308 -0.02341,-0.01447 -0.08138,0.01252 -0.128834,0.05997 -0.04745,0.04745 -0.0974,0.07515 -0.111001,0.06155 -0.0136,-0.0136 -0.03722,0.0078 -0.05248,0.0476 -0.01526,0.03978 -0.0411,0.06408 -0.0574,0.054 -0.03277,-0.02025 -0.462299,0.323995 -0.491977,0.394291 -0.01026,0.02429 -0.07454,0.0912 -0.142856,0.148686 -0.248033,0.208705 -0.730279,0.974169 -0.672565,1.067553 0.0145,0.02346 0.0059,0.04266 -0.01914,0.04266 -0.05907,0 -0.241471,0.599428 -0.208527,0.685278 0.01385,0.0361 0.0044,0.06564 -0.02098,0.06564 -0.02539,0 -0.04169,0.0646 -0.03622,0.143558 0.0055,0.07896 -0.0042,0.213129 -0.02144,0.29816 -0.04741,0.233576 0.0511,1.055502 0.167516,1.397721 0.126048,0.370516 0.310099,0.740163 0.426484,0.856548 0.04776,0.04776 0.07554,0.08684 0.06174,0.08684 -0.0138,0 0.01516,0.05653 0.06436,0.125632 0.131301,0.184396 0.499365,0.587266 0.518785,0.567846 0.0092,-0.0092 0.09821,0.06081 0.197812,0.155562 0.09961,0.09475 0.190589,0.162786 0.202187,0.151188 0.0116,-0.0116 0.05991,0.01774 0.107361,0.06519 0.04745,0.04745 0.105426,0.07444 0.128834,0.05997 0.02341,-0.01447 0.04256,-0.0057 0.04256,0.01958 0,0.06106 0.344664,0.23496 0.399061,0.201341 0.02346,-0.0145 0.04266,-0.0059 0.04266,0.01914 0,0.05907 0.599429,0.241471 0.685279,0.208527 0.0361,-0.01385 0.06564,-0.0065 0.06564,0.01645 0,0.05196 1.079115,0.04833 1.413314,-0.0048 z"></path>
8549
- </svg>`;
8550
- }
8551
- function randomChannel() {
8552
- return Math.floor(Math.random() * RANDOM_STYLE_MAX_CHANNEL);
8553
- }
8554
- function setGeometryIfNeeded(style, geometry) {
8555
- if (geometry)
8556
- style.setGeometry(geometry);
8557
- return style;
8558
- }
8559
- function createStyleGeometry(viewController, feature) {
8560
- if (!viewController || !feature)
8561
- return undefined;
8562
- const geometry = feature.getGeometry();
8563
- const extent = geometry?.getExtent();
8564
- if (!extent)
8565
- return undefined;
8566
- if (!featuresAreTooDeepInView(viewController, extent, GEOMETRY_THRESHOLD)) {
8567
- return undefined;
8568
- }
8569
- return new OlPoint(getCenter(extent));
8570
- }
8571
- function createStyleVariant(variant, text, imposedGeometry) {
8572
- const config = STYLES_VARIANT[variant];
8573
- return [
8574
- markerOlStyle({
8575
- text,
8576
- markerColor: config.markerColor,
8577
- markerOutlineColor: config.markerOutlineColor,
8578
- imposedGeometry
8579
- }),
8580
- setGeometryIfNeeded(new Style({
8581
- fill: new Fill({ color: config.fill }),
8582
- stroke: new Stroke({ width: config.strokeWidth, color: config.stroke })
8583
- }), imposedGeometry)
8584
- ];
8585
- }
8586
-
8587
8588
  var DirectionsFormat;
8588
8589
  (function (DirectionsFormat) {
8589
8590
  DirectionsFormat[DirectionsFormat["GeoJSON"] = 0] = "GeoJSON";
@@ -8779,11 +8780,11 @@ function directionsStyle(feature) {
8779
8780
  * @param {StopsFeatureStore} stopsFeatureStore - The stops feature store to initialize.
8780
8781
  * @param {LanguageService} languageService - The language service used for translations.
8781
8782
  */
8782
- function initStopsFeatureStore(stopsFeatureStore, languageService) {
8783
+ function initStopsFeatureStore(stopsFeatureStore, languageService, layerService) {
8783
8784
  const loadingStrategy = new FeatureStoreLoadingStrategy({
8784
8785
  motion: FeatureMotion.None
8785
8786
  });
8786
- const stopsLayer = new VectorLayer({
8787
+ const stopsLayer = layerService.createLayer({
8787
8788
  isIgoInternalLayer: true,
8788
8789
  id: 'igo-direction-stops-layer',
8789
8790
  title: languageService.translate.instant('igo.geo.directions.layer.stops'),
@@ -8817,11 +8818,11 @@ function initStopsFeatureStore(stopsFeatureStore, languageService) {
8817
8818
  * @param {StopsFeatureStore} routesFeatureStore - The routes feature store to initialize.
8818
8819
  * @param {LanguageService} languageService - The language service used for translations.
8819
8820
  */
8820
- function initRoutesFeatureStore(routesFeatureStore, languageService) {
8821
+ function initRoutesFeatureStore(routesFeatureStore, languageService, layerService) {
8821
8822
  const loadingStrategy = new FeatureStoreLoadingStrategy({
8822
8823
  motion: FeatureMotion.None
8823
8824
  });
8824
- const routeLayer = new VectorLayer({
8825
+ const routeLayer = layerService.createLayer({
8825
8826
  isIgoInternalLayer: true,
8826
8827
  id: 'igo-direction-route-layer',
8827
8828
  title: languageService.translate.instant('igo.geo.directions.layer.route'),
@@ -8847,11 +8848,11 @@ function initRoutesFeatureStore(routesFeatureStore, languageService) {
8847
8848
  *
8848
8849
  * @param {StopsFeatureStore} stepsFeatureStore - The steps feature store to initialize.
8849
8850
  */
8850
- function initStepsFeatureStore(stepsFeatureStore) {
8851
+ function initStepsFeatureStore(stepsFeatureStore, layerService) {
8851
8852
  const loadingStrategy = new FeatureStoreLoadingStrategy({
8852
8853
  motion: FeatureMotion.None
8853
8854
  });
8854
- const stepLayer = new VectorLayer({
8855
+ const stepLayer = layerService.createLayer({
8855
8856
  isIgoInternalLayer: true,
8856
8857
  id: 'igo-direction-step-layer',
8857
8858
  title: '',
@@ -10884,7 +10885,7 @@ class DataSourceService {
10884
10885
  ogcFilterService = inject(OGCFilterService);
10885
10886
  languageService = inject(LanguageService);
10886
10887
  messageService = inject(MessageService);
10887
- authInterceptor = inject(AuthInterceptor);
10888
+ xhrInterceptor = inject(XHR_INTERCEPTOR, { optional: true });
10888
10889
  createAsyncDataSource(options, detailedContextUri) {
10889
10890
  if (!options.type) {
10890
10891
  console.error(options);
@@ -10953,7 +10954,7 @@ class DataSourceService {
10953
10954
  return new Observable((d) => d.next(new WebSocketDataSource(options)));
10954
10955
  }
10955
10956
  createWFSDataSource(options) {
10956
- return new Observable((d) => d.next(new WFSDataSource(options, this.wfsDataSourceService, this.ogcFilterService, this.authInterceptor)));
10957
+ return new Observable((d) => d.next(new WFSDataSource(options, this.wfsDataSourceService, this.ogcFilterService)));
10957
10958
  }
10958
10959
  createWMSDataSource(options, detailedContextUri) {
10959
10960
  const observables = [];
@@ -11116,236 +11117,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
11116
11117
  }]
11117
11118
  }] });
11118
11119
 
11119
- class ConfigFileToGeoDBService {
11120
- http = inject(HttpClient);
11121
- messageService = inject(MessageService);
11122
- load(urlFile) {
11123
- const geoDB = new GeoDB();
11124
- let downloadMessage;
11125
- this.http
11126
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
11127
- .get(urlFile)
11128
- .pipe(catchError((error) => {
11129
- this.messageService.error(`GeoData file ${urlFile} could not be read`);
11130
- error.error.caught = true;
11131
- throw error;
11132
- }), concatMap((datasToIDB) => {
11133
- const datas$ = [];
11134
- let firstDownload = true;
11135
- if (datasToIDB?.geoDatas) {
11136
- const currentDate = new Date();
11137
- datasToIDB?.geoDatas.forEach((geoData) => {
11138
- if (typeof geoData.triggerDate === 'string') {
11139
- geoData.triggerDate = new Date(Date.parse(geoData.triggerDate));
11140
- }
11141
- if (currentDate >= geoData.triggerDate) {
11142
- if (geoData.action === 'update') {
11143
- const insertEvent = `${geoData.source || InsertSourceInsertDBEnum.System} (${geoData.triggerDate})`;
11144
- geoData.urls.forEach((url) => {
11145
- datas$.push(geoDB.getGeoDBData(url).pipe(concatMap((res) => {
11146
- if (res?.insertEvent !== insertEvent) {
11147
- if (firstDownload) {
11148
- downloadMessage = this.messageService.info('igo.geo.indexedDb.data-download-start', undefined, {
11149
- disableTimeOut: true,
11150
- progressBar: false,
11151
- closeButton: true,
11152
- tapToDismiss: false
11153
- });
11154
- firstDownload = false;
11155
- }
11156
- let responseType = 'json';
11157
- const isZip = this.isZip(url);
11158
- if (isZip) {
11159
- responseType = 'arraybuffer';
11160
- }
11161
- return this.http.get(url, { responseType }).pipe(catchError((error) => {
11162
- this.messageService.remove(downloadMessage.toastId);
11163
- this.messageService.error('igo.geo.indexedDb.data-download-failed', undefined, { timeOut: 40000 });
11164
- error.error.caught = true;
11165
- throw error;
11166
- }), concatMap((r) => {
11167
- if (isZip) {
11168
- const observables$ = [
11169
- geoDB.update(url, url, {}, InsertSourceInsertDBEnum.System, insertEvent)
11170
- ];
11171
- JSZip.loadAsync(r).then((zipped) => {
11172
- zipped.forEach((relativePath) => {
11173
- if (relativePath
11174
- .toLocaleLowerCase()
11175
- .endsWith('.geojson')) {
11176
- zipped
11177
- .file(relativePath)
11178
- .async('text')
11179
- .then((r) => {
11180
- const geojson = JSON.parse(r);
11181
- const subUrl = geoData.zippedBaseUrl || '';
11182
- const zippedUrl = subUrl +
11183
- (subUrl.endsWith('/')
11184
- ? ''
11185
- : '/') +
11186
- relativePath;
11187
- observables$.push(geoDB.update(zippedUrl, url, geojson, InsertSourceInsertDBEnum.System, insertEvent));
11188
- });
11189
- }
11190
- });
11191
- });
11192
- return zip(observables$);
11193
- }
11194
- return geoDB.update(url, url, r, InsertSourceInsertDBEnum.System, insertEvent);
11195
- }));
11196
- }
11197
- else {
11198
- return of(false);
11199
- }
11200
- })));
11201
- });
11202
- }
11203
- else if (geoData.action === 'delete') {
11204
- geoData.urls.forEach((url) => {
11205
- datas$.push(geoDB.delete(url));
11206
- });
11207
- }
11208
- }
11209
- });
11210
- }
11211
- return zip(...datas$);
11212
- }))
11213
- .subscribe(() => {
11214
- if (downloadMessage) {
11215
- setTimeout(() => {
11216
- this.messageService.remove(downloadMessage.toastId);
11217
- this.messageService.success('igo.geo.indexedDb.data-download-completed', undefined, { timeOut: 40000 });
11218
- }, 2500);
11219
- }
11220
- });
11221
- }
11222
- isZip(value) {
11223
- const regex = /(zip)$/;
11224
- return typeof value === 'string' && regex.test(value.toLowerCase());
11225
- }
11226
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: ConfigFileToGeoDBService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
11227
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: ConfigFileToGeoDBService });
11228
- }
11229
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: ConfigFileToGeoDBService, decorators: [{
11230
- type: Injectable
11231
- }] });
11232
-
11233
- class GeoNetworkService {
11234
- http = inject(HttpClient);
11235
- networkService = inject(NetworkService);
11236
- networkOnline = true;
11237
- constructor() {
11238
- this.networkService.currentState().subscribe((state) => {
11239
- this.networkOnline = state.connection;
11240
- });
11241
- }
11242
- get(url, simpleGetOptions) {
11243
- if (window.navigator.onLine && this.networkOnline) {
11244
- return this.getOnline(url, simpleGetOptions);
11245
- }
11246
- return this.getOffline(url);
11247
- }
11248
- getOnline(url, simpleGetOptions) {
11249
- let request;
11250
- switch (simpleGetOptions.responseType) {
11251
- case 'arraybuffer':
11252
- request = this.http.get(url, {
11253
- responseType: 'arraybuffer',
11254
- withCredentials: simpleGetOptions.withCredentials
11255
- });
11256
- break;
11257
- case 'text':
11258
- request = this.http.get(url, {
11259
- responseType: 'text',
11260
- withCredentials: simpleGetOptions.withCredentials
11261
- });
11262
- break;
11263
- case 'json':
11264
- request = this.http.get(url, {
11265
- responseType: 'json',
11266
- withCredentials: simpleGetOptions.withCredentials
11267
- });
11268
- break;
11269
- default:
11270
- request = this.http.get(url, {
11271
- responseType: 'blob',
11272
- withCredentials: simpleGetOptions.withCredentials
11273
- });
11274
- break;
11275
- }
11276
- return request;
11277
- }
11278
- getOffline(url) {
11279
- const geoDB = new GeoDB();
11280
- return geoDB?.get(url);
11281
- }
11282
- isOnline() {
11283
- return this.networkOnline && window.navigator.onLine;
11284
- }
11285
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: GeoNetworkService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
11286
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: GeoNetworkService });
11287
- }
11288
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: GeoNetworkService, decorators: [{
11289
- type: Injectable
11290
- }], ctorParameters: () => [] });
11291
-
11292
- const STYLE_ENGINES = new InjectionToken('STYLE_ENGINES');
11293
- function provideStyle(...features) {
11294
- const providers = [];
11295
- for (const feature of features) {
11296
- providers.push(...feature.providers);
11297
- }
11298
- return makeEnvironmentProviders(providers);
11299
- }
11300
-
11301
- const ENGINE_PROVIDER_HINT = {
11302
- Geostyler: 'withGeostyler()',
11303
- Mapbox: 'withMapbox()'
11304
- };
11305
- class StyleService {
11306
- engines = inject(STYLE_ENGINES, { optional: true }) ?? [];
11307
- async getStyle(options, ol) {
11308
- if (isAnyOlStyle(options)) {
11309
- return options;
11310
- }
11311
- const engine = this.findEngine(options);
11312
- return engine?.getStyle(options, ol) ?? randomOlFlatStyle();
11313
- }
11314
- async getLegend(options) {
11315
- if (isAnyOlStyle(options)) {
11316
- return undefined;
11317
- }
11318
- const engine = this.findEngine(options);
11319
- if (!engine?.getLegend) {
11320
- return undefined;
11321
- }
11322
- return engine.getLegend(options);
11323
- }
11324
- findEngine(options) {
11325
- const engine = this.engines.find((e) => e.supports(options));
11326
- if (!engine) {
11327
- const hint = ENGINE_PROVIDER_HINT[options.type];
11328
- const hintMsg = hint
11329
- ? ` Did you forget to add ${hint} to provideStyle(...)?`
11330
- : ` No registered provider handles type "${options.type}".`;
11331
- console.warn(`[StyleService]${hintMsg}`);
11332
- }
11333
- return engine;
11334
- }
11335
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: StyleService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
11336
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: StyleService, providedIn: 'root' });
11337
- }
11338
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: StyleService, decorators: [{
11339
- type: Injectable,
11340
- args: [{ providedIn: 'root' }]
11341
- }] });
11120
+ const OFFLINE_LAYER_RESTORE = new InjectionToken('OFFLINE_LAYER_RESTORE');
11342
11121
 
11343
11122
  class LayerService {
11344
11123
  dataSourceService = inject(DataSourceService);
11345
- messageService = inject(MessageService);
11346
- geoNetworkService = inject(GeoNetworkService, { optional: true });
11347
- authInterceptor = inject(AuthInterceptor, { optional: true });
11348
- styleService = inject(StyleService, { optional: true });
11124
+ injector = inject(Injector);
11125
+ offlineLayerRestore = inject(OFFLINE_LAYER_RESTORE, {
11126
+ optional: true
11127
+ });
11349
11128
  unavailableLayers = [];
11350
11129
  createLayers(layersOption, contextUri) {
11351
11130
  const arrayObsLayers = layersOption.map((option) => {
@@ -11418,10 +11197,10 @@ class LayerService {
11418
11197
  return group;
11419
11198
  }
11420
11199
  createImageLayer(layerOptions) {
11421
- return new ImageLayer(layerOptions, this.messageService, this.authInterceptor ?? undefined);
11200
+ return runInInjectionContext(this.injector, () => new ImageLayer(layerOptions));
11422
11201
  }
11423
11202
  createTileLayer(layerOptions) {
11424
- return new TileLayer(layerOptions, this.messageService, this.authInterceptor ?? undefined);
11203
+ return runInInjectionContext(this.injector, () => new TileLayer(layerOptions));
11425
11204
  }
11426
11205
  createVectorLayer(layerOptions) {
11427
11206
  if (layerOptions.source instanceof ArcGISRestDataSource) {
@@ -11432,23 +11211,16 @@ class LayerService {
11432
11211
  layerOptions.style =
11433
11212
  layerOptions.style ?? clusterOlStyleFunction();
11434
11213
  }
11435
- const vectorLayer = new VectorLayer(layerOptions, this.messageService, this.authInterceptor ?? undefined, this.geoNetworkService ?? undefined, this.styleService ?? undefined);
11436
- return vectorLayer;
11214
+ return runInInjectionContext(this.injector, () => new VectorLayer(layerOptions));
11437
11215
  }
11438
11216
  createVectorTileLayer(layerOptions) {
11439
- return new VectorTileLayer(layerOptions, this.messageService, this.authInterceptor ?? undefined, this.styleService ?? undefined);
11440
- }
11441
- createAsyncIdbLayers(contextUri = '*') {
11442
- const layerDB = new LayerDB();
11443
- return layerDB.getAll().pipe(concatMap((res) => {
11444
- const idbLayers = contextUri !== '*'
11445
- ? res.filter((l) => l.detailedContextUri === contextUri)
11446
- : res;
11447
- const layersOptions = idbLayers.map((idbl) => Object.assign({}, idbl.layerOptions, {
11448
- sourceOptions: idbl.sourceOptions
11449
- }));
11450
- return combineLatest(layersOptions.map((layerOptions) => this.createAsyncLayer(layerOptions))).pipe(map((ls) => ls.filter(Boolean)));
11451
- }));
11217
+ return runInInjectionContext(this.injector, () => new VectorTileLayer(layerOptions));
11218
+ }
11219
+ createAsyncOfflineLayers(contextUri = '*') {
11220
+ if (!this.offlineLayerRestore) {
11221
+ return of([]);
11222
+ }
11223
+ return this.offlineLayerRestore.createAsyncLayers(contextUri);
11452
11224
  }
11453
11225
  deleteUnavailableLayers(anyLayerOptions) {
11454
11226
  const anyLayerSourceOptions = anyLayerOptions.sourceOptions;
@@ -11485,6 +11257,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
11485
11257
 
11486
11258
  const LAYER = 'Layer';
11487
11259
 
11260
+ const LAYER_PERSISTENCE = new InjectionToken('LAYER_PERSISTENCE');
11261
+
11488
11262
  class LayerSelectionModel {
11489
11263
  selection = new SelectionModel(true);
11490
11264
  descendantSelection = new SelectionModel(true);
@@ -13128,14 +12902,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
13128
12902
  args: [{ selector: 'igo-layer-unavailable-list', changeDetection: ChangeDetectionStrategy.OnPush, imports: [ListComponent, ListItemDirective, LayerUnavailableComponent], template: "<igo-list [navigation]=\"false\" [selection]=\"false\">\n @for (layer of layersOptions(); track layer) {\n <igo-layer-unavailable\n igoListItem\n [layerOptions]=\"layer\"\n (remove)=\"deleteUnavailableLayer($event)\"\n />\n }\n</igo-list>\n", styles: ["igo-list{height:auto}igo-list ::ng-deep mat-list{padding-bottom:0}\n"] }]
13129
12903
  }], propDecorators: { layersOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "layersOptions", required: false }] }] } });
13130
12904
 
13131
- function isIdbLayer(layer) {
13132
- return (isLayerItem(layer) &&
13133
- layer.type === 'vector' &&
13134
- layer.options.idbInfo?.storeToIdb === true);
13135
- }
13136
-
13137
12905
  class LayerViewerBottomActionsComponent {
13138
12906
  layerListToolService = inject(LayerListToolService);
12907
+ layerPersistence = inject(LAYER_PERSISTENCE, { optional: true });
13139
12908
  orderable = true;
13140
12909
  map = input.required(...(ngDevMode ? [{ debugName: "map" }] : /* istanbul ignore next */ []));
13141
12910
  controller = input.required(...(ngDevMode ? [{ debugName: "controller" }] : /* istanbul ignore next */ []));
@@ -13192,11 +12961,12 @@ class LayerViewerBottomActionsComponent {
13192
12961
  return layers?.every((l) => this.isLayerRemovable(l));
13193
12962
  }
13194
12963
  removeLayers() {
13195
- this.selected
13196
- .filter((layer) => isIdbLayer(layer))
13197
- .forEach((layer) => {
13198
- layer.options.idbInfo._deleteFromIdb = true;
13199
- });
12964
+ const layerPersistence = this.layerPersistence;
12965
+ if (layerPersistence) {
12966
+ this.selected
12967
+ .filter((layer) => layerPersistence.isPersistent(layer))
12968
+ .forEach((layer) => layerPersistence.removePersistedData(layer));
12969
+ }
13200
12970
  this.controller().remove(...this.selected);
13201
12971
  this.controller().clearSelection();
13202
12972
  }
@@ -13526,148 +13296,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
13526
13296
  args: [{ selector: 'igo-track-feature-button', changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatButtonModule, MatTooltipModule, MatIconModule, IgoLanguageModule], template: "@if (layer().options.trackFeature) {\n <button\n mat-icon-button\n collapsibleButton\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n [matTooltip]=\"'igo.geo.layer.trackFeature' | translate\"\n [color]=\"color\"\n (click)=\"toggleTrackFeature()\"\n >\n <mat-icon>my_location</mat-icon>\n </button>\n}\n" }]
13527
13297
  }], propDecorators: { layer: [{ type: i0.Input, args: [{ isSignal: true, alias: "layer", required: true }] }], trackFeature: [{ type: i0.Input, args: [{ isSignal: true, alias: "trackFeature", required: false }] }, { type: i0.Output, args: ["trackFeatureChange"] }] } });
13528
13298
 
13529
- /**
13530
- * This class is simply a shortcut for adding features to a map.
13531
- * It does nothing more than a standard layer but it's shipped with
13532
- * a defautl style based on the geometry type of the features it contains.
13533
- * @todo Enhance that by using a FeatureStore and strategies.
13534
- */
13535
- class Overlay {
13536
- /**
13537
- * The map to add the layer to
13538
- */
13539
- map;
13540
- /**
13541
- * Overlay layer
13542
- */
13543
- layer;
13544
- /**
13545
- * Overlay layer's data source
13546
- */
13547
- get dataSource() {
13548
- return this.layer.dataSource;
13549
- }
13550
- constructor(map, style) {
13551
- this.layer = new VectorLayer({
13552
- title: 'Overlay',
13553
- zIndex: 300,
13554
- source: new FeatureDataSource(),
13555
- style: style ?? baseOlStyle()
13556
- });
13557
- this.setMap(map);
13558
- }
13559
- /**
13560
- * Bind this to a map and add the overlay layer to that map
13561
- * @param map Map
13562
- */
13563
- setMap(map) {
13564
- if (map === undefined) {
13565
- if (this.map !== undefined) {
13566
- this.map.ol.removeLayer(this.layer.ol);
13567
- }
13568
- }
13569
- else {
13570
- map.ol.addLayer(this.layer.ol);
13571
- }
13572
- this.map = map;
13573
- }
13574
- /**
13575
- * Set the overlay features and, optionally, move to them
13576
- * @param features Features
13577
- * @param motion Optional: Apply this motion to the map view
13578
- * @param sourceId Optional: Remove features of certain sourceId (ex: 'Map' for query features)
13579
- */
13580
- setFeatures(features, motion = FeatureMotion.Default, sourceId) {
13581
- if (sourceId) {
13582
- for (const olFeature of this.dataSource.ol.getFeatures()) {
13583
- if (olFeature.get('_sourceId') === sourceId) {
13584
- this.removeOlFeature(olFeature);
13585
- }
13586
- }
13587
- }
13588
- else {
13589
- this.clear();
13590
- }
13591
- this.addFeatures(features, motion);
13592
- }
13593
- /**
13594
- * Add a feature to the overlay and, optionally, move to it
13595
- * @param feature Feature
13596
- * @param motion Optional: Apply this motion to the map view (default on FeatureMotion.Default)
13597
- */
13598
- addFeature(feature, motion = FeatureMotion.Default) {
13599
- this.addFeatures([feature], motion);
13600
- }
13601
- /**
13602
- * Add features to the overlay and, optionally, move to them
13603
- * @param features Features
13604
- * @param motion Optional: Apply this motion to the map view
13605
- */
13606
- addFeatures(features, motion = FeatureMotion.Default) {
13607
- const olFeatures = [];
13608
- features.forEach((feature) => {
13609
- const olFeature = featureToOl(feature, this.map.projectionCode);
13610
- const olGeometry = olFeature.getGeometry();
13611
- if (olGeometry === null) {
13612
- return;
13613
- }
13614
- olFeatures.push(olFeature);
13615
- });
13616
- this.addOlFeatures(olFeatures, motion);
13617
- }
13618
- /**
13619
- * Add a OpenLayers feature to the overlay and, optionally, move to it
13620
- * @param olFeature OpenLayers Feature
13621
- * @param motion Optional: Apply this motion to the map view
13622
- */
13623
- addOlFeature(olFeature, motion = FeatureMotion.Default) {
13624
- this.addOlFeatures([olFeature], motion);
13625
- }
13626
- /**
13627
- * Add OpenLayers features to the overlay and, optionally, move to them
13628
- * @param olFeatures OpenLayers Features
13629
- * @param motion Optional: Apply this motion to the map view
13630
- */
13631
- addOlFeatures(olFeatures, motion = FeatureMotion.Default) {
13632
- this.dataSource.ol.addFeatures(olFeatures);
13633
- moveToOlFeatures(this.map.viewController, olFeatures, motion);
13634
- }
13635
- /**
13636
- * Remove a feature from the overlay
13637
- * @param feature Feature
13638
- */
13639
- removeFeature(feature) {
13640
- this.removeFeatures([feature]);
13641
- }
13642
- /**
13643
- * Remove features from the overlay
13644
- * @param features Features
13645
- */
13646
- removeFeatures(features) {
13647
- features.forEach((feature) => {
13648
- if (feature.meta) {
13649
- const olFeature = this.dataSource.ol.getFeatureById(feature.meta.id);
13650
- if (olFeature) {
13651
- this.removeOlFeature(olFeature);
13652
- }
13653
- }
13654
- });
13655
- }
13656
- /**
13657
- * Remove an OpenLayers feature from the overlay
13658
- * @param olFeature OpenLayers Feature
13659
- */
13660
- removeOlFeature(olFeature) {
13661
- this.dataSource.ol.removeFeature(olFeature);
13662
- }
13663
- /**
13664
- * Clear the overlay
13665
- */
13666
- clear() {
13667
- this.dataSource.ol.clear();
13668
- }
13669
- }
13670
-
13671
13299
  /**
13672
13300
  * Base map controller
13673
13301
  */
@@ -13864,13 +13492,13 @@ class MapGeolocationController extends MapController {
13864
13492
  return this._followPosition;
13865
13493
  }
13866
13494
  _followPosition;
13867
- constructor(map, options, storageService, configService) {
13495
+ constructor(map, overlayService, options, storageService, configService) {
13868
13496
  super();
13869
13497
  this.map = map;
13870
13498
  this.options = options;
13871
13499
  this.storageService = storageService;
13872
13500
  this.configService = configService;
13873
- this.geolocationOverlay = new Overlay(this.map);
13501
+ this.geolocationOverlay = overlayService.create(this.map);
13874
13502
  this._followPosition =
13875
13503
  this.options && this.options.followPosition
13876
13504
  ? this.options.followPosition
@@ -14511,6 +14139,7 @@ class IgoMap {
14511
14139
  layerWatcher;
14512
14140
  options;
14513
14141
  mapViewOptions;
14142
+ overlayService;
14514
14143
  defaultOptions = {
14515
14144
  controls: { attribution: false }
14516
14145
  };
@@ -14569,9 +14198,11 @@ class IgoMap {
14569
14198
  stateHistory: true
14570
14199
  });
14571
14200
  this.viewController.setOlMap(this.ol);
14572
- this.overlay = new Overlay(this);
14573
14201
  this.ol.once('rendercomplete', () => {
14574
- this.geolocationController = new MapGeolocationController(this, {
14202
+ if (!this.overlayService) {
14203
+ return;
14204
+ }
14205
+ this.geolocationController = new MapGeolocationController(this, this.overlayService, {
14575
14206
  projection: this.viewController.getOlProjection()
14576
14207
  }, this.storageService, this.configService);
14577
14208
  this.geolocationController.setOlMap(this.ol);
@@ -14581,6 +14212,13 @@ class IgoMap {
14581
14212
  this.viewController.monitorRotation();
14582
14213
  });
14583
14214
  }
14215
+ initializeOverlays(overlayService) {
14216
+ if (this.overlayService) {
14217
+ return;
14218
+ }
14219
+ this.overlayService = overlayService;
14220
+ this.overlay = overlayService.create(this);
14221
+ }
14584
14222
  setTarget(id) {
14585
14223
  this.ol.setTarget(id);
14586
14224
  if (id !== undefined) {
@@ -14670,8 +14308,165 @@ class MapBase {
14670
14308
  viewProjection;
14671
14309
  }
14672
14310
 
14311
+ /**
14312
+ * This class is simply a shortcut for adding features to a map.
14313
+ * It does nothing more than a standard layer but it's shipped with
14314
+ * a defautl style based on the geometry type of the features it contains.
14315
+ * @todo Enhance that by using a FeatureStore and strategies.
14316
+ */
14317
+ class Overlay {
14318
+ /**
14319
+ * The map to add the layer to
14320
+ */
14321
+ map;
14322
+ /**
14323
+ * Overlay layer
14324
+ */
14325
+ layer;
14326
+ /**
14327
+ * Overlay layer's data source
14328
+ */
14329
+ get dataSource() {
14330
+ return this.layer.dataSource;
14331
+ }
14332
+ constructor(map, layer) {
14333
+ this.layer = layer;
14334
+ this.setMap(map);
14335
+ }
14336
+ /**
14337
+ * Bind this to a map and add the overlay layer to that map
14338
+ * @param map Map
14339
+ */
14340
+ setMap(map) {
14341
+ if (map === undefined) {
14342
+ if (this.map !== undefined) {
14343
+ this.map.ol.removeLayer(this.layer.ol);
14344
+ }
14345
+ }
14346
+ else {
14347
+ map.ol.addLayer(this.layer.ol);
14348
+ }
14349
+ this.map = map;
14350
+ }
14351
+ /**
14352
+ * Set the overlay features and, optionally, move to them
14353
+ * @param features Features
14354
+ * @param motion Optional: Apply this motion to the map view
14355
+ * @param sourceId Optional: Remove features of certain sourceId (ex: 'Map' for query features)
14356
+ */
14357
+ setFeatures(features, motion = FeatureMotion.Default, sourceId) {
14358
+ if (sourceId) {
14359
+ for (const olFeature of this.dataSource.ol.getFeatures()) {
14360
+ if (olFeature.get('_sourceId') === sourceId) {
14361
+ this.removeOlFeature(olFeature);
14362
+ }
14363
+ }
14364
+ }
14365
+ else {
14366
+ this.clear();
14367
+ }
14368
+ this.addFeatures(features, motion);
14369
+ }
14370
+ /**
14371
+ * Add a feature to the overlay and, optionally, move to it
14372
+ * @param feature Feature
14373
+ * @param motion Optional: Apply this motion to the map view (default on FeatureMotion.Default)
14374
+ */
14375
+ addFeature(feature, motion = FeatureMotion.Default) {
14376
+ this.addFeatures([feature], motion);
14377
+ }
14378
+ /**
14379
+ * Add features to the overlay and, optionally, move to them
14380
+ * @param features Features
14381
+ * @param motion Optional: Apply this motion to the map view
14382
+ */
14383
+ addFeatures(features, motion = FeatureMotion.Default) {
14384
+ const olFeatures = [];
14385
+ features.forEach((feature) => {
14386
+ const olFeature = featureToOl(feature, this.map.projectionCode);
14387
+ const olGeometry = olFeature.getGeometry();
14388
+ if (olGeometry === null) {
14389
+ return;
14390
+ }
14391
+ olFeatures.push(olFeature);
14392
+ });
14393
+ this.addOlFeatures(olFeatures, motion);
14394
+ }
14395
+ /**
14396
+ * Add a OpenLayers feature to the overlay and, optionally, move to it
14397
+ * @param olFeature OpenLayers Feature
14398
+ * @param motion Optional: Apply this motion to the map view
14399
+ */
14400
+ addOlFeature(olFeature, motion = FeatureMotion.Default) {
14401
+ this.addOlFeatures([olFeature], motion);
14402
+ }
14403
+ /**
14404
+ * Add OpenLayers features to the overlay and, optionally, move to them
14405
+ * @param olFeatures OpenLayers Features
14406
+ * @param motion Optional: Apply this motion to the map view
14407
+ */
14408
+ addOlFeatures(olFeatures, motion = FeatureMotion.Default) {
14409
+ this.dataSource.ol.addFeatures(olFeatures);
14410
+ moveToOlFeatures(this.map.viewController, olFeatures, motion);
14411
+ }
14412
+ /**
14413
+ * Remove a feature from the overlay
14414
+ * @param feature Feature
14415
+ */
14416
+ removeFeature(feature) {
14417
+ this.removeFeatures([feature]);
14418
+ }
14419
+ /**
14420
+ * Remove features from the overlay
14421
+ * @param features Features
14422
+ */
14423
+ removeFeatures(features) {
14424
+ features.forEach((feature) => {
14425
+ if (feature.meta) {
14426
+ const olFeature = this.dataSource.ol.getFeatureById(feature.meta.id);
14427
+ if (olFeature) {
14428
+ this.removeOlFeature(olFeature);
14429
+ }
14430
+ }
14431
+ });
14432
+ }
14433
+ /**
14434
+ * Remove an OpenLayers feature from the overlay
14435
+ * @param olFeature OpenLayers Feature
14436
+ */
14437
+ removeOlFeature(olFeature) {
14438
+ this.dataSource.ol.removeFeature(olFeature);
14439
+ }
14440
+ /**
14441
+ * Clear the overlay
14442
+ */
14443
+ clear() {
14444
+ this.dataSource.ol.clear();
14445
+ }
14446
+ }
14447
+
14448
+ class OverlayService {
14449
+ layerService = inject(LayerService);
14450
+ create(map, style) {
14451
+ const layer = this.layerService.createLayer({
14452
+ title: 'Overlay',
14453
+ zIndex: 300,
14454
+ source: new FeatureDataSource(),
14455
+ style: style ?? baseOlStyle()
14456
+ });
14457
+ return new Overlay(map, layer);
14458
+ }
14459
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: OverlayService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
14460
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: OverlayService, providedIn: 'root' });
14461
+ }
14462
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: OverlayService, decorators: [{
14463
+ type: Injectable,
14464
+ args: [{ providedIn: 'root' }]
14465
+ }] });
14466
+
14673
14467
  class MapBrowserComponent {
14674
14468
  activityService = inject(ActivityService);
14469
+ overlayService = inject(OverlayService);
14675
14470
  activityId;
14676
14471
  status$$;
14677
14472
  map = input.required(...(ngDevMode ? [{ debugName: "map" }] : /* istanbul ignore next */ []));
@@ -14698,6 +14493,7 @@ class MapBrowserComponent {
14698
14493
  });
14699
14494
  }
14700
14495
  ngOnInit() {
14496
+ this.map().initializeOverlays?.(this.overlayService);
14701
14497
  this.status$$ = this.map().status$.subscribe((status) => this.handleStatusChange(status));
14702
14498
  }
14703
14499
  ngAfterViewInit() {
@@ -14975,7 +14771,7 @@ class HoverFeatureDirective {
14975
14771
  }
14976
14772
  ngOnInit() {
14977
14773
  this.map.status$
14978
- .pipe(first$1((status) => status === SubjectStatus.Done))
14774
+ .pipe(first((status) => status === SubjectStatus.Done))
14979
14775
  .subscribe(() => {
14980
14776
  this.initStore();
14981
14777
  this.listenToMapPointerMove();
@@ -16076,7 +15872,7 @@ class QueryService {
16076
15872
  QueryFormat.HTMLGML2) {
16077
15873
  if (typeof url === 'string') {
16078
15874
  const urlGml = this.getQueryUrl(layer.dataSource, options, true);
16079
- return this.http.get(urlGml, { responseType: 'text' }).pipe(mergeMap$1((gmlRes) => {
15875
+ return this.http.get(urlGml, { responseType: 'text' }).pipe(mergeMap((gmlRes) => {
16080
15876
  const mergedGML = this.mergeGML(gmlRes, url, layer);
16081
15877
  const imposedGeom = mergedGML[0];
16082
15878
  const imposedProperties = mergedGML[1];
@@ -16112,7 +15908,7 @@ class QueryService {
16112
15908
  }
16113
15909
  }
16114
15910
  requestDataForHTMLGML2(urlGml, url, layer, options) {
16115
- return this.http.get(urlGml, { responseType: 'text' }).pipe(mergeMap$1((gmlRes) => {
15911
+ return this.http.get(urlGml, { responseType: 'text' }).pipe(mergeMap((gmlRes) => {
16116
15912
  const mergedGML = this.mergeGML(gmlRes, url, layer);
16117
15913
  const imposedGeom = mergedGML[0];
16118
15914
  const imposedProperties = mergedGML[1];
@@ -17067,6 +16863,7 @@ class DirectionsComponent {
17067
16863
  directionsSourceService = inject(DirectionsSourceService);
17068
16864
  searchService = inject(SearchService);
17069
16865
  queryService = inject(QueryService);
16866
+ layerService = inject(LayerService);
17070
16867
  projection = 'EPSG:4326';
17071
16868
  storeEmpty$$;
17072
16869
  storeChange$$;
@@ -17119,9 +16916,9 @@ class DirectionsComponent {
17119
16916
  this.queryService.queryEnabled = false;
17120
16917
  this.initEntityStores();
17121
16918
  setTimeout(() => {
17122
- initStopsFeatureStore(this.stopsFeatureStore(), this.languageService);
17123
- initRoutesFeatureStore(this.routesFeatureStore(), this.languageService);
17124
- initStepsFeatureStore(this.stepsFeatureStore());
16919
+ initStopsFeatureStore(this.stopsFeatureStore(), this.languageService, this.layerService);
16920
+ initRoutesFeatureStore(this.routesFeatureStore(), this.languageService, this.layerService);
16921
+ initStepsFeatureStore(this.stepsFeatureStore(), this.layerService);
17125
16922
  this.initOlInteraction();
17126
16923
  }, 1);
17127
16924
  }
@@ -23682,6 +23479,7 @@ class DrawComponent {
23682
23479
  drawStyleService = inject(DrawStyleService);
23683
23480
  dialog = inject(MatDialog);
23684
23481
  drawIconService = inject(DrawIconService);
23482
+ layerService = inject(LayerService);
23685
23483
  /**
23686
23484
  * Table template
23687
23485
  * @internal
@@ -23817,7 +23615,7 @@ class DrawComponent {
23817
23615
  .manyBy$((record) => {
23818
23616
  return record.state.selected === true;
23819
23617
  })
23820
- .pipe(first$1())
23618
+ .pipe(first())
23821
23619
  .subscribe((records) => {
23822
23620
  records.forEach((record) => {
23823
23621
  record.state.selected = false;
@@ -24299,7 +24097,7 @@ class DrawComponent {
24299
24097
  const numberId = Number(layer.id.toString().replace('igo-draw-layer', ''));
24300
24098
  this.layerCounterID = Math.max(numberId, this.layerCounterID);
24301
24099
  }
24302
- this.activeDrawingLayer.set(new VectorLayer({
24100
+ this.activeDrawingLayer.set(this.layerService.createLayer({
24303
24101
  isIgoInternalLayer: true,
24304
24102
  id: 'igo-draw-layer' + ++this.layerCounterID,
24305
24103
  title: isNewLayer
@@ -24322,6 +24120,7 @@ class DrawComponent {
24322
24120
  motion: FeatureMotion.None
24323
24121
  }));
24324
24122
  tryAddSelectionStrategy(this.activeStore, new FeatureStoreSelectionStrategy({
24123
+ layerService: this.layerService,
24325
24124
  map: this.map(),
24326
24125
  motion: FeatureMotion.None,
24327
24126
  many: true
@@ -25566,10 +25365,6 @@ class MeasurerItemComponent {
25566
25365
  * Placeholder
25567
25366
  */
25568
25367
  placeholder = input(...(ngDevMode ? [undefined, { debugName: "placeholder" }] : /* istanbul ignore next */ []));
25569
- /**
25570
- * Event emitted when the measure unit changes
25571
- */
25572
- measureUnitChange = output();
25573
25368
  /**
25574
25369
  * Available measure units for the measure type given
25575
25370
  * @internal
@@ -25593,7 +25388,6 @@ class MeasurerItemComponent {
25593
25388
  */
25594
25389
  onMeasureUnitChange(unit) {
25595
25390
  this.measureUnit.set(unit);
25596
- this.measureUnitChange.emit(unit);
25597
25391
  }
25598
25392
  toggleAutoUnit(toggle) {
25599
25393
  if (this.measure$$ !== undefined) {
@@ -25620,7 +25414,7 @@ class MeasurerItemComponent {
25620
25414
  }
25621
25415
  }
25622
25416
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: MeasurerItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
25623
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.19", type: MeasurerItemComponent, isStandalone: true, selector: "igo-measurer-item", inputs: { measureType: { classPropertyName: "measureType", publicName: "measureType", isSignal: true, isRequired: true, transformFunction: null }, measureUnit: { classPropertyName: "measureUnit", publicName: "measureUnit", isSignal: true, isRequired: true, transformFunction: null }, measure: { classPropertyName: "measure", publicName: "measure", isSignal: false, isRequired: false, transformFunction: null }, auto: { classPropertyName: "auto", publicName: "auto", isSignal: false, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { measureUnit: "measureUnitChange", measureUnitChange: "measureUnitChange" }, ngImport: i0, template: "<mat-form-field class=\"measure-field\" floatLabel=\"always\">\n <mat-label>{{ placeholder() }}</mat-label>\n <input\n matInput\n [disabled]=\"true\"\n [readonly]=\"true\"\n [value]=\"(measure$ | async) || 0 | measureFormat: measureUnit()\"\n />\n</mat-form-field>\n<mat-form-field class=\"unit-field\">\n <mat-select\n [value]=\"measureUnit()\"\n [disabled]=\"auto\"\n (selectionChange)=\"onMeasureUnitChange($event.value)\"\n >\n @for (measureUnit of measureUnits; track measureUnit) {\n <mat-option [value]=\"measureUnit\">\n {{ 'igo.geo.measure.' + measureUnit | translate }}\n </mat-option>\n }\n </mat-select>\n</mat-form-field>\n", styles: [":host{display:flex;width:100%;padding:5px 10px}:host .measure-field{pointer-events:none;flex:2}:host .unit-field{margin-left:8px;flex:1}:host ::ng-deep mat-form-field .mat-mdc-form-field-subscript-wrapper{display:none}\n"], dependencies: [{ kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3$1.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i4$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i4$3.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i4$3.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatOptionModule }, { kind: "ngmodule", type: IgoLanguageModule }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }, { kind: "pipe", type: MeasureFormatPipe, name: "measureFormat" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
25417
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.19", type: MeasurerItemComponent, isStandalone: true, selector: "igo-measurer-item", inputs: { measureType: { classPropertyName: "measureType", publicName: "measureType", isSignal: true, isRequired: true, transformFunction: null }, measureUnit: { classPropertyName: "measureUnit", publicName: "measureUnit", isSignal: true, isRequired: true, transformFunction: null }, measure: { classPropertyName: "measure", publicName: "measure", isSignal: false, isRequired: false, transformFunction: null }, auto: { classPropertyName: "auto", publicName: "auto", isSignal: false, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { measureUnit: "measureUnitChange" }, ngImport: i0, template: "<mat-form-field class=\"measure-field\" floatLabel=\"always\">\n <mat-label>{{ placeholder() }}</mat-label>\n <input\n matInput\n [disabled]=\"true\"\n [readonly]=\"true\"\n [value]=\"(measure$ | async) || 0 | measureFormat: measureUnit()\"\n />\n</mat-form-field>\n<mat-form-field class=\"unit-field\">\n <mat-select\n [value]=\"measureUnit()\"\n [disabled]=\"auto\"\n (selectionChange)=\"onMeasureUnitChange($event.value)\"\n >\n @for (measureUnit of measureUnits; track measureUnit) {\n <mat-option [value]=\"measureUnit\">\n {{ 'igo.geo.measure.' + measureUnit | translate }}\n </mat-option>\n }\n </mat-select>\n</mat-form-field>\n", styles: [":host{display:flex;width:100%;padding:5px 10px}:host .measure-field{pointer-events:none;flex:2}:host .unit-field{margin-left:8px;flex:1}:host ::ng-deep mat-form-field .mat-mdc-form-field-subscript-wrapper{display:none}\n"], dependencies: [{ kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3$1.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i4$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i4$3.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i4$3.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatOptionModule }, { kind: "ngmodule", type: IgoLanguageModule }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }, { kind: "pipe", type: MeasureFormatPipe, name: "measureFormat" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
25624
25418
  }
25625
25419
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: MeasurerItemComponent, decorators: [{
25626
25420
  type: Component,
@@ -25637,7 +25431,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
25637
25431
  type: Input
25638
25432
  }], auto: [{
25639
25433
  type: Input
25640
- }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], measureUnitChange: [{ type: i0.Output, args: ["measureUnitChange"] }] } });
25434
+ }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }] } });
25641
25435
 
25642
25436
  /**
25643
25437
  * Tool to measure lengths and areas
@@ -25647,6 +25441,7 @@ class MeasurerComponent {
25647
25441
  dialog = inject(MatDialog);
25648
25442
  storageService = inject(StorageService);
25649
25443
  document = inject(DOCUMENT);
25444
+ layerService = inject(LayerService);
25650
25445
  /**
25651
25446
  * Table template
25652
25447
  * @internal
@@ -26095,7 +25890,7 @@ class MeasurerComponent {
26095
25890
  */
26096
25891
  initStore() {
26097
25892
  const store = this.store();
26098
- let layer = new VectorLayer({
25893
+ let layer = this.layerService.createLayer({
26099
25894
  title: this.languageService.translate.instant('igo.geo.measure.layerTitle'),
26100
25895
  isIgoInternalLayer: true,
26101
25896
  id: `igo-measures-${uuid()}`,
@@ -26123,6 +25918,7 @@ class MeasurerComponent {
26123
25918
  tryAddSelectionStrategy(
26124
25919
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
26125
25920
  store, new FeatureStoreSelectionStrategy({
25921
+ layerService: this.layerService,
26126
25922
  map: this.map(),
26127
25923
  many: true
26128
25924
  }));
@@ -27090,6 +26886,7 @@ class SpatialFilterItemComponent {
27090
26886
  spatialFilterService = inject(SpatialFilterService);
27091
26887
  messageService = inject(MessageService);
27092
26888
  languageService = inject(LanguageService);
26889
+ layerService = inject(LayerService);
27093
26890
  map = input.required(...(ngDevMode ? [{ debugName: "map" }] : /* istanbul ignore next */ []));
27094
26891
  get type() {
27095
26892
  return this._type;
@@ -27420,7 +27217,7 @@ class SpatialFilterItemComponent {
27420
27217
  });
27421
27218
  const selectedRecordStrategy = new EntityStoreFilterSelectionStrategy({});
27422
27219
  const selectionStrategy = new FeatureStoreSelectionStrategy({
27423
- layer: new VectorLayer({
27220
+ layer: this.layerService.createLayer({
27424
27221
  zIndex: 300,
27425
27222
  source: new FeatureDataSource(),
27426
27223
  style: undefined,
@@ -29716,7 +29513,7 @@ function addLayerAndFeaturesToMap(features, map, contextUri, layerTitle, layerSe
29716
29513
  isIgoInternalLayer: true,
29717
29514
  source,
29718
29515
  style: randomOlFlatStyle(),
29719
- idbInfo: { storeToIdb, contextUri: contextUri }
29516
+ offline: { enabled: storeToIdb, contextUri }
29720
29517
  });
29721
29518
  layer.setExtent(computeOlFeaturesExtent(olFeatures, map.viewProjection));
29722
29519
  map.layerController.add(layer);
@@ -29735,7 +29532,7 @@ function handleFileImportSuccess(file, features, map, contextUri, messageService
29735
29532
  const obs$ = confirmDialogService
29736
29533
  ? confirmDialogService.open('igo.geo.import.promptStoreToIdb')
29737
29534
  : of(false);
29738
- obs$.pipe(first()).subscribe((confirm) => {
29535
+ obs$.pipe(first$1()).subscribe((confirm) => {
29739
29536
  const d = new Date();
29740
29537
  const dformat = [
29741
29538
  d.getFullYear(),
@@ -30837,7 +30634,7 @@ class DropGeoFileDirective extends DragAndDropDirective {
30837
30634
  onFilesDropped(files) {
30838
30635
  for (const file of files) {
30839
30636
  this.epsgCode$$.push(detectFileEPSG({ file })
30840
- .pipe(skipWhile((code) => !code), first$1(), concatMap((epsgCode) => {
30637
+ .pipe(skipWhile((code) => !code), first(), concatMap((epsgCode) => {
30841
30638
  if (!epsgCode || epsgCode === 'epsgNotDefined') {
30842
30639
  return this.openEPSGModal(file).pipe(filter((selectedCode) => !!selectedCode), // user must select
30843
30640
  concatMap((selectedCode) => this.importService.import(file, selectedCode)));
@@ -32588,7 +32385,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
32588
32385
  class SearchResultAddButtonComponent {
32589
32386
  layerService = inject(LayerService);
32590
32387
  dialog = inject(MatDialog);
32591
- dataSourceService = inject(DataSourceService);
32592
32388
  mediaService = inject(MediaService);
32593
32389
  tooltip$ = new BehaviorSubject('igo.geo.catalog.layer.addToMap');
32594
32390
  addFeatureToLayerTooltip$ = new BehaviorSubject('igo.geo.search.addToLayer');
@@ -32891,6 +32687,7 @@ class SearchResultAddButtonComponent {
32891
32687
  motion: FeatureMotion.None
32892
32688
  }));
32893
32689
  tryAddSelectionStrategy(activeStore, new FeatureStoreSelectionStrategy({
32690
+ layerService: this.layerService,
32894
32691
  map: this.map(),
32895
32692
  motion: FeatureMotion.None,
32896
32693
  many: true
@@ -33302,7 +33099,7 @@ class SearchPointerSummaryDirective {
33302
33099
  ngOnInit() {
33303
33100
  this.listenToMapPointerMove();
33304
33101
  this.map.status$
33305
- .pipe(first((status) => status === SubjectStatus.Done))
33102
+ .pipe(first$1((status) => status === SubjectStatus.Done))
33306
33103
  .subscribe(() => {
33307
33104
  this.store = new FeatureStore([], { map: this.map });
33308
33105
  this.initStore();
@@ -33954,16 +33751,8 @@ class IChercheSearchSource extends SearchSource {
33954
33751
  const config = inject(ConfigService, { optional: true });
33955
33752
  const options = ObjectUtils.mergeDeep(config?.getConfig(`searchSources.${IChercheSearchSource.id}`) ?? {}, directOptions ?? {});
33956
33753
  super(options, storageService);
33957
- const authService = inject(AuthService);
33958
33754
  if (this.settings.length) {
33959
- if (!authService) {
33960
- this.getAllowedTypes();
33961
- }
33962
- else {
33963
- authService.authenticate$.subscribe(() => {
33964
- this.getAllowedTypes();
33965
- });
33966
- }
33755
+ this.getAllowedTypes();
33967
33756
  }
33968
33757
  this.languageService.language$.subscribe(() => {
33969
33758
  this.title$.next(this.languageService.translate.instant(this.options.title ?? ''));
@@ -34494,21 +34283,12 @@ class IChercheReverseSearchSource extends SearchSource {
34494
34283
  });
34495
34284
  const config = inject(ConfigService, { optional: true });
34496
34285
  const options = ObjectUtils.mergeDeep(config?.getConfig(`searchSources.${IChercheReverseSearchSource.id}`) ?? {}, directOptions ?? {});
34497
- const injector = inject(Injector);
34498
34286
  super(options, storageService);
34499
34287
  this.languageService.language$.subscribe(() => {
34500
34288
  this.title$.next(this.languageService.translate.instant(this.options.title ?? ''));
34501
34289
  });
34502
- const authService = injector.get(AuthService);
34503
34290
  if (this.settings.length) {
34504
- if (!authService) {
34505
- this.getAllowedTypes();
34506
- }
34507
- else {
34508
- authService.authenticate$.subscribe(() => {
34509
- this.getAllowedTypes();
34510
- });
34511
- }
34291
+ this.getAllowedTypes();
34512
34292
  }
34513
34293
  }
34514
34294
  getId() {
@@ -35996,6 +35776,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
35996
35776
  class EditionWorkspace extends Workspace {
35997
35777
  configService;
35998
35778
  adding$;
35779
+ layerService;
35999
35780
  options;
36000
35781
  inResolutionRange$ = new BehaviorSubject(true);
36001
35782
  get layer() {
@@ -36043,10 +35824,11 @@ class EditionWorkspace extends Workspace {
36043
35824
  fillColor;
36044
35825
  strokeColor;
36045
35826
  strokeWidth;
36046
- constructor(configService, adding$, options) {
35827
+ constructor(configService, adding$, layerService, options) {
36047
35828
  super(options);
36048
35829
  this.configService = configService;
36049
35830
  this.adding$ = adding$;
35831
+ this.layerService = layerService;
36050
35832
  this.options = options;
36051
35833
  this.map.viewController.resolution$.subscribe((mapResolution) => {
36052
35834
  if ((mapResolution ?? 0) > this.layer.minResolution &&
@@ -36059,7 +35841,7 @@ class EditionWorkspace extends Workspace {
36059
35841
  });
36060
35842
  this.drawControl = this.createDrawControl();
36061
35843
  this.drawControl.setGeometryType(this.geometryType.Point);
36062
- this.olDrawingLayer = new VectorLayer({
35844
+ this.olDrawingLayer = this.layerService.createLayer({
36063
35845
  id: 'igo-draw-layer',
36064
35846
  title: 'edition',
36065
35847
  zIndex: 300,
@@ -36454,7 +36236,6 @@ class EditionWorkspaceService {
36454
36236
  messageService = inject(MessageService);
36455
36237
  http = inject(HttpClient);
36456
36238
  dialog = inject(MatDialog);
36457
- authInterceptor = inject(AuthInterceptor);
36458
36239
  ws$ = new BehaviorSubject(undefined);
36459
36240
  adding$ = new BehaviorSubject(false);
36460
36241
  relationLayers$ = new BehaviorSubject(undefined);
@@ -36571,7 +36352,7 @@ class EditionWorkspaceService {
36571
36352
  }
36572
36353
  }, false);
36573
36354
  workspaceLayer.dataSource.ol.refresh();
36574
- wks = new EditionWorkspace(this.configService, this.adding$, {
36355
+ wks = new EditionWorkspace(this.configService, this.adding$, this.layerService, {
36575
36356
  id: layer.id,
36576
36357
  title: layer.title,
36577
36358
  layer: workspaceLayer,
@@ -37007,14 +36788,7 @@ class EditionWorkspaceService {
37007
36788
  * WMS params are updated to ensure layer is correctly refreshed
37008
36789
  */
37009
36790
  refreshMap(layer, map) {
37010
- const wfsOlLayer = layer.dataSource.ol;
37011
- const loader = (extent, resolution, proj, success, failure) => {
37012
- layer.customWFSLoader(layer.ol.getSource(), layer.options.sourceOptions, extent, resolution, proj,
37013
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
37014
- success, failure, true);
37015
- };
37016
- wfsOlLayer.setLoader(loader);
37017
- wfsOlLayer.refresh();
36791
+ layer.refresh();
37018
36792
  const id = String(layer.id);
37019
36793
  for (const lay of map.layerController.all) {
37020
36794
  const layId = String(lay.id);
@@ -38881,7 +38655,7 @@ class CatalogBrowserLayerComponent {
38881
38655
  this.layerLegendShown$.next(!this.layerLegendShown$.value);
38882
38656
  this.layerService
38883
38657
  .createAsyncLayer(this.layer().options)
38884
- .pipe(first$1())
38658
+ .pipe(first())
38885
38659
  .subscribe((layer) => this.igoLayer$.next(layer));
38886
38660
  }
38887
38661
  /**
@@ -39353,7 +39127,7 @@ class CatalogBrowserComponent {
39353
39127
  removeLayersFromMap(layers) {
39354
39128
  if (this.isAddingLayers.value) {
39355
39129
  this.isAddingLayers
39356
- .pipe(first((value) => value === false))
39130
+ .pipe(first$1((value) => value === false))
39357
39131
  .subscribe((_isReady) => {
39358
39132
  this._removeLayersFromMap(layers);
39359
39133
  });
@@ -40682,28 +40456,6 @@ function withOsrmSource() {
40682
40456
  };
40683
40457
  }
40684
40458
 
40685
- /** Ensure to create the indexDB on app initialisation and provide
40686
- * GeoNetworkService, ConfigFileToGeoDBService */
40687
- function provideOffline(options) {
40688
- return makeEnvironmentProviders(options?.enable
40689
- ? [
40690
- {
40691
- provide: APP_INITIALIZER,
40692
- useFactory: idbFactory,
40693
- multi: true,
40694
- deps: [GeoDB, LayerDB]
40695
- },
40696
- GeoDB,
40697
- LayerDB,
40698
- GeoNetworkService,
40699
- ConfigFileToGeoDBService
40700
- ]
40701
- : []);
40702
- }
40703
- function idbFactory() {
40704
- return () => createIndexedDb();
40705
- }
40706
-
40707
40459
  var OverlayAction;
40708
40460
  (function (OverlayAction) {
40709
40461
  OverlayAction[OverlayAction["None"] = 0] = "None";
@@ -42243,5 +41995,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
42243
41995
  * Generated bundle index. Do not edit.
42244
41996
  */
42245
41997
 
42246
- export { AddCatalogDialogComponent, ArcGISRestCapabilitiesLayerTypes, ArcGISRestDataSource, BaseLayersSwitcherComponent, CADASTRE_SEARCH_SOURCE_OPTIONS, CATALOG_DIRECTIVES, CATALOG_LIBRARY_DIRECTIVES, COORDINATES_REVERSE_SEARCH_SOURCE_OPTIONS, COORDINATES_REVERSE_SEARCH_SOURCE_PROJECTIONS, CadastreSearchSource, CapabilitiesService, CartoDataSource, Catalog, CatalogBrowserComponent, CatalogItemType, CatalogLibraryComponent, CatalogService, ClusterDataSource, ConfigFileToGeoDBService, ConfirmationPopupComponent, CoordinatesReverseSearchSource, CoordinatesReverseSearchSourceFactory, CoordinatesSearchResultFormatter, CoordinatesUnit, CsvSeparator, DDtoDMS, DataService, DataSource, DataSourceService, DirectionRelativePositionType, DirectionSourceKind, DirectionsButtonsComponent, DirectionsComponent, DirectionsFormat, DirectionsInputsComponent, DirectionsResultsComponent, DirectionsService, DirectionsSource, DirectionsType, DownloadButtonComponent, DownloadService, DrawComponent, DrawControl, DrawIconService, DrawStyleService, DropGeoFileDirective, EditionWorkspace, EditionWorkspaceService, EpsgSelectorModalComponent, EsriStyleGenerator, EventRefresh, ExportButtonComponent, ExportError, ExportFormat, ExportFormatLegacy, ExportInvalidFileError, ExportNothingToExportError, ExportService, FEATURE, FEATURE_DETAILS_DIRECTIVES, FEATURE_DIRECTIVES, FILTER_DIRECTIVES, FeatureDataSource, FeatureDetailsComponent, FeatureDetailsDirective, FeatureDetailsPanelComponent, FeatureFormComponent, FeatureMotion, FeatureStore, FeatureStoreInMapExtentStrategy, FeatureStoreInMapResolutionStrategy, FeatureStoreLoadingLayerStrategy, FeatureStoreLoadingStrategy, FeatureStoreSearchIndexStrategy, FeatureStoreSelectionStrategy, FeatureWorkspace, FeatureWorkspaceService, FilterableDataSourcePipe, FontType, GEOMETRY_FORM_FIELD_DIRECTIVES, GeoDB, GeoNetworkService, GeoPropertiesStrategy, GeolocateButtonComponent, GeolocationOverlayType, GeometryFormFieldComponent, GeometryFormFieldInputComponent, GeometrySliceError, GeometrySliceLineStringError, GeometrySliceMultiPolygonError, GeometrySliceTooManyIntersectionError, GeometryType, GeostylerService, GetCapabilitiesParams, GoogleLinks, HomeExtentButtonComponent, HoverFeatureDirective, ICHERCHE_REVERSE_SEARCH_SOURCE_OPTIONS, ICHERCHE_SEARCH_SOURCE_OPTIONS, IChercheReverseSearchSource, IChercheSearchResultFormatter, IChercheSearchSource, ID_GROUP_PREFIX, ILAYER_SEARCH_SOURCE_OPTIONS, ILayerSearchResultFormatter, ILayerSearchSource, IMPORT_EXPORT_DIRECTIVES, IgoCatalogBrowserModule, IgoCatalogLibraryModule, IgoCatalogModule, IgoConfirmationPopupModule, IgoDirectionsModule, IgoDownloadModule, IgoDrawModule, IgoDrawingToolModule, IgoFeatureDetailsModule, IgoFeatureFormModule, IgoFeatureModule, IgoFilterModule, IgoGeoModule, IgoGeoWorkspaceModule, IgoGeometryFormFieldModule, IgoGeometryModule, IgoHttpParameterCodec, IgoImportExportModule, IgoLayerModule, IgoMap, IgoMapModule, IgoMeasureModule, IgoMeasurerModule, IgoMetadataModule, IgoOgcFilterModule, IgoPrintModule, IgoQueryModule, IgoSearchBarModule, IgoSearchModule, IgoSearchResultsModule, IgoSearchSelectorModule, IgoSearchSettingsModule, IgoStyleModule, IgoToastModule, IgoWktModule, IgoWorkspaceSelectorModule, IgoWorkspaceUpdatorModule, ImageArcGISRestDataSource, ImageLayer, ImageWatcher, ImportError, ImportExportComponent, ImportInvalidFileError, ImportNothingToImportError, ImportOgreServerError, ImportSRSError, ImportService, ImportSizeError, ImportUnreadableFileError, InfoSectionComponent, InsertSourceInsertDBEnum, InteractiveSelectionFormWidget, LAYER, LAYER_DIRECTIVES, LabelType, LaneType, Layer, LayerBase, LayerController, LayerDB, LayerGroup, LayerGroupBase, LayerGroupComponent, LayerItemComponent, LayerLegendComponent, LayerLegendItemComponent, LayerLegendListBindingDirective, LayerLegendListComponent, LayerListComponent, LayerListControlsEnum, LayerListToolComponent, LayerListToolService, LayerSearchComponent, LayerService, LayerUnavailableComponent, LayerUnavailableListComponent, LayerViewerBottomActionsComponent, LayerViewerComponent, LayerVisibilityButtonComponent, Linked, LinkedProperties, MAP_DIRECTIVES, MEASURER_DIRECTIVES, MEASURE_UNIT_AUTO, METADATA_DIRECTIVES, MVTDataSource, ManeuverModifier, ManeuverType, MapBase, MapBrowserComponent, MapCenterComponent, MapController, MapGeolocationController, MapOfflineDirective, MapService, MapViewAction, MapViewController, MapboxService, MeasureAreaUnit, MeasureAreaUnitAbbreviation, MeasureFormatPipe, MeasureLengthUnit, MeasureLengthUnitAbbreviation, MeasureType, MeasurerComponent, MenuButtonComponent, MetadataAbstractComponent, MetadataButtonComponent, MetadataService, MiniBaseMapComponent, ModifyControl, NOMINATIM_SEARCH_SOURCE_OPTIONS, NominatimSearchSource, OGCFilterService, OSMDataSource, OfflineButtonComponent, OgcFilterButtonComponent, OgcFilterComponent, OgcFilterFormComponent, OgcFilterOperator, OgcFilterOperatorType, OgcFilterSelectionComponent, OgcFilterTimeComponent, OgcFilterTimeSliderComponent, OgcFilterWidget, OgcFilterWriter, OgcFilterableFormComponent, OgcFilterableItemComponent, OgcFilterableListBindingDirective, OgcFilterableListComponent, OgcSelectorFields, OlDragSelectInteraction, OptionsApiService, OptionsService, OsmLinks, OsrmDirectionsSource, Overlay, OverlayAction, PointerPositionDirective, PrintComponent, PrintFormComponent, PrintLegendPosition, PrintOrientation, PrintOutputFormat, PrintPaperFormat, PrintResolution, PrintSaveImageFormat, PrintService, ProjectionService, PropertyTypeDetectorService, ProposalType, QueryDirective, QueryFormat, QueryFormatMimeType, QueryHtmlTarget, QuerySearchSource, QueryService, RADIUS_NAME, RotationButtonComponent, RoutesFeatureStore, SEARCH_DIRECTIVES, SEARCH_RESULTS_DIRECTIVES, SEARCH_TYPES, STORED_QUERIES_REVERSE_SEARCH_SOURCE_OPTIONS, STORED_QUERIES_SEARCH_SOURCE_OPTIONS, STYLE_ENGINES, SearchBarComponent, SearchPointerSummaryDirective, SearchResultAddButtonComponent, SearchResultMode, SearchResultsComponent, SearchSelectorComponent, SearchService, SearchSettingsComponent, SearchSource, SearchSourceKind, SearchSourceService, SliceControl, SourceDirectionsType, SpatialFilterItemComponent, SpatialFilterItemType, SpatialFilterListComponent, SpatialFilterQueryType, SpatialFilterService, SpatialFilterType, SpatialFilterTypeComponent, StepsFeatureStore, StopsFeatureStore, StopsStore, StoredQueriesReverseSearchSource, StoredQueriesSearchSource, StyleEngineKind, StyleModalDrawingComponent, StyleModalLayerButtonComponent, StyleModalLayerComponent, StyleService, SwipeControlComponent, TileArcGISRestDataSource, TileDebugDataSource, TileLayer, TileWatcher, TimeFilterButtonComponent, TimeFilterFormComponent, TimeFilterItemComponent, TimeFilterListBindingDirective, TimeFilterListComponent, TimeFilterService, TimeFilterStyle, TimeFilterType, TooltipType, TrackFeatureButtonComponent, TypeCapabilities, TypeCatalog, VectorLayer, VectorTileLayer, VectorWatcher, WFSDataSource, WFSService, WMSDataSource, WMTSDataSource, WORKSPACE_SEARCH_SOURCE_OPTIONS, WakeLockButtonComponent, WebSocketDataSource, WfsWorkspace, WfsWorkspaceService, WktService, WorkspaceSearchSource, WorkspaceSelectorDirective, WorkspaceUpdatorDirective, XYZDataSource, ZoomButtonComponent, addLayerAndFeaturesToMap, addLinearRingToOlPolygon, addOrRemoveLayer, addRouteToRoutesFeatureStore, addStopToStopsFeatureStore, addStopToStore, baseOlStyle, bufferOlGeometry, buildUrl, cadastreSearchSourceFactory, checkWfsParams, clearOlGeometryMidpoints, clusterOlStyleFunction, computeBestAreaUnit, computeBestLengthUnit, computeLayerTitleFromFile, computeOlFeatureExtent, computeOlFeaturesDiff, computeOlFeaturesExtent, computeProjectionsConstraints, computeRelativePosition, computeStopsPosition, computeTermSimilarity, convertDDToDMS, createDefaultTileGrid, createDrawHoleInteractionStyle, createDrawInteractionStyle, createFilterInMapExtentOrResolutionStrategy, createInteractionStyle, createMeasureInteractionStyle, createMeasureLayerStyle, createOlTooltipAtPoint, createOlTooltipDrawAtPoint, createTableTemplate, ctrlKeyDown, defaultCoordinatesSearchResultFormatterFactory, defaultEpsg, defaultFieldNameGeometry, defaultIChercheSearchResultFormatterFactory, defaultMaxFeatures, defaultWfsVersion, detectFileEPSG, directionsStyle, doesOlGeometryIntersects, entitiesToRowData, exportToCSV, featureFromOl, featureToOl, featureToSearchResult, featuresAreOutOfView, featuresAreTooDeepInView, findDiff, findLayerByLinkId, findParentId, formatDistance, formatDuration, formatMeasure, formatScale, formatStep, formatWFSQueryString, generateArcgisRestIdFromSourceOptions, generateFeatureIdFromSourceOptions, generateId, generateIdFromSourceOptions, generateWMSIdFromSourceOptions, generateWMTSIdFromSourceOptions, generateWfsIdFromSourceOptions, generateXYZIdFromSourceOptions, getAllChildLayersByDeletion, getAllChildLayersByProperty, getFileExtension, getFilterBadge, getFormatFromOptions, getGeoServiceAction, getLayerOptionIdentifier, getLayersByDeletion, getLayersLegends, getLinkedLayersOptions, getMousePositionFromOlGeometryEvent, getOlTooltipAtCenter, getOlTooltipsAtMidpoints, getResolutionFromScale, getRootParentByDeletion, getRootParentByProperty, getRowsInMapExtent, getSaveableOgcParams, getScaleFromResolution, getSelectedOnly, getTooltipsOfOlGeometry, gmlRegex, handleFileExportError, handleFileExportSuccess, handleFileImportError, handleFileImportSuccess, handleInvalidFileImportError, handleLayerPropertyChange, handleNothingToExportError, handleNothingToImportError, handleOgreServerImportError, handleSRSImportError, handleSizeFileImportError, handleUnreadbleFileImportError, hideOlFeature, ichercheReverseSearchSourceFactory, ichercheSearchSourceFactory, ilayerSearchResultFormatterFactory, ilayerSearchSourceFactory, initRoutesFeatureStore, initStepsFeatureStore, initStopsFeatureStore, interactiveSelectionFormWidgetFactory, isAnyOlStyle, isBaseLayer, isBaseLayerLinked, isCsvExport, isEngineLayerStyle, isLayerGroup, isLayerGroupOptions, isLayerItem, isLayerItemOptions, isLayerLinked, isLayerLinkedOptions, isLayerLinkedTogether, isLinkMaster, isOlFlatStyleLike, isSaveableLayer, jsonRegex, layerFeatureIsQueryable, layerIsQueryable, lonLatConversion, mapExtentStrategyActiveToolTip, markerOlStyle, measureOlGeometry, measureOlGeometryArea, measureOlGeometryLength, mergeLayersOptions, metersToFeet, metersToKilometers, metersToMiles, metersToUnit, moveToOlFeatures, mtmZoneFromLonLat, nearTransparentOlStyle, noElementSelected, nominatimSearchSourceFactory, ogcFilterWidgetFactory, olLayerFeatureIsQueryable, olLayerIsQueryable, optionsApiFactory, osrmDirectionsSourcesFactory, provideCadastreSearchSource, provideCoordinatesReverseSearchSource, provideDefaultCoordinatesSearchResultFormatter, provideDefaultIChercheSearchResultFormatter, provideDirection, provideIChercheReverseSearchSource, provideIChercheSearchSource, provideILayerSearchResultFormatter, provideILayerSearchSource, provideInteractiveSelectionFormWidget, provideNominatimSearchSource, provideOffline, provideOgcFilterWidget, provideOptionsApi, provideOsrmDirectionsSource, provideQuerySearchSource, provideSearch, provideSearchSourceService, provideStoredQueriesReverseSearchSource, provideStoredQueriesSearchSource, provideStyle, provideWorkspaceSearchSource, querySearchSourceFactory, randomOlFlatStyle, removeStopFromStore, renderFeatureFromOl, roundCoordTo, roundCoordToString, scaleExtent, searchSourceServiceFactory, selectionOlStyle, setRowsInMapExtent, setSelectedOnly, sliceOlGeometry, sliceOlPolygon, sortLayersByZindex, sourceCanReverseSearch, sourceCanReverseSearchAsSummary, sourceCanSearch, squareMetersToAcres, squareMetersToHectares, squareMetersToSquareFeet, squareMetersToSquareKilometers, squareMetersToSquareMiles, squareMetersToUnit, standardizeUrl, storedqueriesReverseSearchSourceFactory, storedqueriesSearchSourceFactory, stringToLonLat, styleVariant, translateManeuverBearing, translateManeuverModifier, tryAddLoadingStrategy, tryAddSelectionStrategy, tryBindStoreLayer, updateOlGeometryCenter, updateOlGeometryMidpoints, updateOlTooltipAtCenter, updateOlTooltipDrawAtCenter, updateOlTooltipsAtMidpoints, updateOlTooltipsDrawAtMidpoints, updateStoreSorting, utmZoneFromLonLat, viewStatesAreEqual, withCadastreSource, withCoordinatesReverseSource, withGeostyler, withIChercheReverseSource, withIChercheSource, withILayerSource, withMapbox, withNominatimSource, withOsrmSource, withStoredQueriesReverseSource, withStoredQueriesSource, withWorkspaceSource, workspaceSearchSourceFactory, zoneMtm, zoneUtm };
41998
+ export { AddCatalogDialogComponent, ArcGISRestCapabilitiesLayerTypes, ArcGISRestDataSource, BaseLayersSwitcherComponent, CADASTRE_SEARCH_SOURCE_OPTIONS, CATALOG_DIRECTIVES, CATALOG_LIBRARY_DIRECTIVES, COORDINATES_REVERSE_SEARCH_SOURCE_OPTIONS, COORDINATES_REVERSE_SEARCH_SOURCE_PROJECTIONS, CadastreSearchSource, CapabilitiesService, CartoDataSource, Catalog, CatalogBrowserComponent, CatalogItemType, CatalogLibraryComponent, CatalogService, ClusterDataSource, ConfirmationPopupComponent, CoordinatesReverseSearchSource, CoordinatesReverseSearchSourceFactory, CoordinatesSearchResultFormatter, CoordinatesUnit, CsvSeparator, DDtoDMS, DataService, DataSource, DataSourceService, DirectionRelativePositionType, DirectionSourceKind, DirectionsButtonsComponent, DirectionsComponent, DirectionsFormat, DirectionsInputsComponent, DirectionsResultsComponent, DirectionsService, DirectionsSource, DirectionsType, DownloadButtonComponent, DownloadService, DrawComponent, DrawControl, DrawIconService, DrawStyleService, DropGeoFileDirective, EditionWorkspace, EditionWorkspaceService, EpsgSelectorModalComponent, EsriStyleGenerator, EventRefresh, ExportButtonComponent, ExportError, ExportFormat, ExportFormatLegacy, ExportInvalidFileError, ExportNothingToExportError, ExportService, FEATURE, FEATURE_DETAILS_DIRECTIVES, FEATURE_DIRECTIVES, FILTER_DIRECTIVES, FeatureDataSource, FeatureDetailsComponent, FeatureDetailsDirective, FeatureDetailsPanelComponent, FeatureFormComponent, FeatureMotion, FeatureStore, FeatureStoreInMapExtentStrategy, FeatureStoreInMapResolutionStrategy, FeatureStoreLoadingLayerStrategy, FeatureStoreLoadingStrategy, FeatureStoreSearchIndexStrategy, FeatureStoreSelectionStrategy, FeatureWorkspace, FeatureWorkspaceService, FilterableDataSourcePipe, FontType, GEOMETRY_FORM_FIELD_DIRECTIVES, GeoPropertiesStrategy, GeolocateButtonComponent, GeolocationOverlayType, GeometryFormFieldComponent, GeometryFormFieldInputComponent, GeometrySliceError, GeometrySliceLineStringError, GeometrySliceMultiPolygonError, GeometrySliceTooManyIntersectionError, GeometryType, GeostylerService, GetCapabilitiesParams, GoogleLinks, HomeExtentButtonComponent, HoverFeatureDirective, ICHERCHE_REVERSE_SEARCH_SOURCE_OPTIONS, ICHERCHE_SEARCH_SOURCE_OPTIONS, IChercheReverseSearchSource, IChercheSearchResultFormatter, IChercheSearchSource, ID_GROUP_PREFIX, ILAYER_SEARCH_SOURCE_OPTIONS, ILayerSearchResultFormatter, ILayerSearchSource, IMPORT_EXPORT_DIRECTIVES, IgoCatalogBrowserModule, IgoCatalogLibraryModule, IgoCatalogModule, IgoConfirmationPopupModule, IgoDirectionsModule, IgoDownloadModule, IgoDrawModule, IgoDrawingToolModule, IgoFeatureDetailsModule, IgoFeatureFormModule, IgoFeatureModule, IgoFilterModule, IgoGeoModule, IgoGeoWorkspaceModule, IgoGeometryFormFieldModule, IgoGeometryModule, IgoHttpParameterCodec, IgoImportExportModule, IgoLayerModule, IgoMap, IgoMapModule, IgoMeasureModule, IgoMeasurerModule, IgoMetadataModule, IgoOgcFilterModule, IgoPrintModule, IgoQueryModule, IgoSearchBarModule, IgoSearchModule, IgoSearchResultsModule, IgoSearchSelectorModule, IgoSearchSettingsModule, IgoStyleModule, IgoToastModule, IgoWktModule, IgoWorkspaceSelectorModule, IgoWorkspaceUpdatorModule, ImageArcGISRestDataSource, ImageLayer, ImageWatcher, ImportError, ImportExportComponent, ImportInvalidFileError, ImportNothingToImportError, ImportOgreServerError, ImportSRSError, ImportService, ImportSizeError, ImportUnreadableFileError, InfoSectionComponent, InteractiveSelectionFormWidget, LAYER, LAYER_DIRECTIVES, LAYER_PERSISTENCE, LabelType, LaneType, Layer, LayerBase, LayerController, LayerExtensionManager, LayerGroup, LayerGroupBase, LayerGroupComponent, LayerItemComponent, LayerLegendComponent, LayerLegendItemComponent, LayerLegendListBindingDirective, LayerLegendListComponent, LayerListComponent, LayerListControlsEnum, LayerListToolComponent, LayerListToolService, LayerSearchComponent, LayerService, LayerUnavailableComponent, LayerUnavailableListComponent, LayerViewerBottomActionsComponent, LayerViewerComponent, LayerVisibilityButtonComponent, Linked, LinkedProperties, MAP_DIRECTIVES, MEASURER_DIRECTIVES, MEASURE_UNIT_AUTO, METADATA_DIRECTIVES, MVTDataSource, ManeuverModifier, ManeuverType, MapBase, MapBrowserComponent, MapCenterComponent, MapController, MapGeolocationController, MapOfflineDirective, MapService, MapViewAction, MapViewController, MapboxService, MeasureAreaUnit, MeasureAreaUnitAbbreviation, MeasureFormatPipe, MeasureLengthUnit, MeasureLengthUnitAbbreviation, MeasureType, MeasurerComponent, MenuButtonComponent, MetadataAbstractComponent, MetadataButtonComponent, MetadataService, MiniBaseMapComponent, ModifyControl, NOMINATIM_SEARCH_SOURCE_OPTIONS, NominatimSearchSource, OFFLINE_LAYER_RESTORE, OGCFilterService, OSMDataSource, OfflineButtonComponent, OgcFilterButtonComponent, OgcFilterComponent, OgcFilterFormComponent, OgcFilterOperator, OgcFilterOperatorType, OgcFilterSelectionComponent, OgcFilterTimeComponent, OgcFilterTimeSliderComponent, OgcFilterWidget, OgcFilterWriter, OgcFilterableFormComponent, OgcFilterableItemComponent, OgcFilterableListBindingDirective, OgcFilterableListComponent, OgcSelectorFields, OlDragSelectInteraction, OptionsApiService, OptionsService, OsmLinks, OsrmDirectionsSource, Overlay, OverlayAction, OverlayService, PointerPositionDirective, PrintComponent, PrintFormComponent, PrintLegendPosition, PrintOrientation, PrintOutputFormat, PrintPaperFormat, PrintResolution, PrintSaveImageFormat, PrintService, ProjectionService, PropertyTypeDetectorService, ProposalType, QueryDirective, QueryFormat, QueryFormatMimeType, QueryHtmlTarget, QuerySearchSource, QueryService, RADIUS_NAME, RotationButtonComponent, RoutesFeatureStore, SEARCH_DIRECTIVES, SEARCH_RESULTS_DIRECTIVES, SEARCH_TYPES, STORED_QUERIES_REVERSE_SEARCH_SOURCE_OPTIONS, STORED_QUERIES_SEARCH_SOURCE_OPTIONS, STYLE_ENGINES, SearchBarComponent, SearchPointerSummaryDirective, SearchResultAddButtonComponent, SearchResultMode, SearchResultsComponent, SearchSelectorComponent, SearchService, SearchSettingsComponent, SearchSource, SearchSourceKind, SearchSourceService, SliceControl, SourceDirectionsType, SpatialFilterItemComponent, SpatialFilterItemType, SpatialFilterListComponent, SpatialFilterQueryType, SpatialFilterService, SpatialFilterType, SpatialFilterTypeComponent, StepsFeatureStore, StopsFeatureStore, StopsStore, StoredQueriesReverseSearchSource, StoredQueriesSearchSource, StyleEngineKind, StyleModalDrawingComponent, StyleModalLayerButtonComponent, StyleModalLayerComponent, StyleService, SwipeControlComponent, TileArcGISRestDataSource, TileDebugDataSource, TileLayer, TileWatcher, TimeFilterButtonComponent, TimeFilterFormComponent, TimeFilterItemComponent, TimeFilterListBindingDirective, TimeFilterListComponent, TimeFilterService, TimeFilterStyle, TimeFilterType, TooltipType, TrackFeatureButtonComponent, TypeCapabilities, TypeCatalog, VECTOR_LAYER_EXTENSIONS, VectorLayer, VectorTileLayer, VectorWatcher, WFSDataSource, WFSService, WMSDataSource, WMTSDataSource, WORKSPACE_SEARCH_SOURCE_OPTIONS, WakeLockButtonComponent, WebSocketDataSource, WfsWorkspace, WfsWorkspaceService, WktService, WorkspaceSearchSource, WorkspaceSelectorDirective, WorkspaceUpdatorDirective, XYZDataSource, ZoomButtonComponent, addLinearRingToOlPolygon, addOrRemoveLayer, addRouteToRoutesFeatureStore, addStopToStopsFeatureStore, addStopToStore, baseOlStyle, bufferOlGeometry, buildUrl, buildWfsBatchUrls, cadastreSearchSourceFactory, checkWfsParams, clearOlGeometryMidpoints, clusterOlStyleFunction, computeBestAreaUnit, computeBestLengthUnit, computeLayerTitleFromFile, computeOlFeatureExtent, computeOlFeaturesDiff, computeOlFeaturesExtent, computeProjectionsConstraints, computeRelativePosition, computeStopsPosition, computeTermSimilarity, convertDDToDMS, createDefaultTileGrid, createDrawHoleInteractionStyle, createDrawInteractionStyle, createFilterInMapExtentOrResolutionStrategy, createInteractionStyle, createMeasureInteractionStyle, createMeasureLayerStyle, createOlTooltipAtPoint, createOlTooltipDrawAtPoint, createTableTemplate, ctrlKeyDown, defaultCoordinatesSearchResultFormatterFactory, defaultEpsg, defaultFieldNameGeometry, defaultIChercheSearchResultFormatterFactory, defaultMaxFeatures, defaultWfsVersion, detectFileEPSG, directionsStyle, doesOlGeometryIntersects, entitiesToRowData, exportToCSV, featureFromOl, featureToOl, featureToSearchResult, featuresAreOutOfView, featuresAreTooDeepInView, findDiff, findLayerByLinkId, findParentId, formatDistance, formatDuration, formatMeasure, formatScale, formatStep, formatWFSQueryString, generateArcgisRestIdFromSourceOptions, generateFeatureIdFromSourceOptions, generateId, generateIdFromSourceOptions, generateWMSIdFromSourceOptions, generateWMTSIdFromSourceOptions, generateWfsIdFromSourceOptions, generateXYZIdFromSourceOptions, getAllChildLayersByDeletion, getAllChildLayersByProperty, getFileExtension, getFilterBadge, getFormatFromOptions, getGeoServiceAction, getLayerOptionIdentifier, getLayersByDeletion, getLayersLegends, getLinkedLayersOptions, getMousePositionFromOlGeometryEvent, getOlTooltipAtCenter, getOlTooltipsAtMidpoints, getResolutionFromScale, getRootParentByDeletion, getRootParentByProperty, getRowsInMapExtent, getSaveableOgcParams, getScaleFromResolution, getSelectedOnly, getTooltipsOfOlGeometry, gmlRegex, handleFileExportError, handleFileExportSuccess, handleFileImportError, handleFileImportSuccess, handleInvalidFileImportError, handleLayerPropertyChange, handleNothingToExportError, handleNothingToImportError, handleOgreServerImportError, handleSRSImportError, handleSizeFileImportError, handleUnreadbleFileImportError, hideOlFeature, ichercheReverseSearchSourceFactory, ichercheSearchSourceFactory, ilayerSearchResultFormatterFactory, ilayerSearchSourceFactory, initRoutesFeatureStore, initStepsFeatureStore, initStopsFeatureStore, interactiveSelectionFormWidgetFactory, isAnyOlStyle, isBaseLayer, isBaseLayerLinked, isCsvExport, isEngineLayerStyle, isLayerGroup, isLayerGroupOptions, isLayerItem, isLayerItemOptions, isLayerLinked, isLayerLinkedOptions, isLayerLinkedTogether, isLinkMaster, isOlFlatStyleLike, isSaveableLayer, jsonRegex, layerFeatureIsQueryable, layerIsQueryable, lonLatConversion, mapExtentStrategyActiveToolTip, markerOlStyle, measureOlGeometry, measureOlGeometryArea, measureOlGeometryLength, mergeLayersOptions, metersToFeet, metersToKilometers, metersToMiles, metersToUnit, moveToOlFeatures, mtmZoneFromLonLat, nearTransparentOlStyle, noElementSelected, nominatimSearchSourceFactory, ogcFilterWidgetFactory, olLayerFeatureIsQueryable, olLayerIsQueryable, optionsApiFactory, osrmDirectionsSourcesFactory, provideCadastreSearchSource, provideCoordinatesReverseSearchSource, provideDefaultCoordinatesSearchResultFormatter, provideDefaultIChercheSearchResultFormatter, provideDirection, provideIChercheReverseSearchSource, provideIChercheSearchSource, provideILayerSearchResultFormatter, provideILayerSearchSource, provideInteractiveSelectionFormWidget, provideNominatimSearchSource, provideOgcFilterWidget, provideOptionsApi, provideOsrmDirectionsSource, provideQuerySearchSource, provideSearch, provideSearchSourceService, provideStoredQueriesReverseSearchSource, provideStoredQueriesSearchSource, provideStyle, provideWorkspaceSearchSource, querySearchSourceFactory, randomOlFlatStyle, removeStopFromStore, renderFeatureFromOl, roundCoordTo, roundCoordToString, scaleExtent, searchSourceServiceFactory, selectionOlStyle, setRowsInMapExtent, setSelectedOnly, sliceOlGeometry, sliceOlPolygon, sortLayersByZindex, sourceCanReverseSearch, sourceCanReverseSearchAsSummary, sourceCanSearch, squareMetersToAcres, squareMetersToHectares, squareMetersToSquareFeet, squareMetersToSquareKilometers, squareMetersToSquareMiles, squareMetersToUnit, standardizeUrl, storedqueriesReverseSearchSourceFactory, storedqueriesSearchSourceFactory, stringToLonLat, styleVariant, translateManeuverBearing, translateManeuverModifier, tryAddLoadingStrategy, tryAddSelectionStrategy, tryBindStoreLayer, updateOlGeometryCenter, updateOlGeometryMidpoints, updateOlTooltipAtCenter, updateOlTooltipDrawAtCenter, updateOlTooltipsAtMidpoints, updateOlTooltipsDrawAtMidpoints, updateStoreSorting, utmZoneFromLonLat, viewStatesAreEqual, withCadastreSource, withCoordinatesReverseSource, withGeostyler, withIChercheReverseSource, withIChercheSource, withILayerSource, withMapbox, withNominatimSource, withOsrmSource, withStoredQueriesReverseSource, withStoredQueriesSource, withWorkspaceSource, workspaceSearchSourceFactory, zoneMtm, zoneUtm };
42247
41999
  //# sourceMappingURL=igo2-geo.mjs.map