@angular-helpers/openlayers 0.1.1 → 0.2.0

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,62 +1,196 @@
1
1
  import * as _angular_core from '@angular/core';
2
- import { OnInit, OnDestroy } from '@angular/core';
2
+ import { InjectionToken } from '@angular/core';
3
+ import OLMap from 'ol/Map';
3
4
  import { OlFeature } from '@angular-helpers/openlayers/core';
4
5
 
5
- declare class OlZoomControlComponent implements OnInit, OnDestroy {
6
+ declare class OlZoomControlComponent {
6
7
  private mapService;
7
- private ngZone;
8
+ private zoneHelper;
8
9
  delta: _angular_core.InputSignal<number>;
9
10
  duration: _angular_core.InputSignal<number>;
10
11
  private control?;
11
- ngOnInit(): void;
12
- private tryAddControl;
13
- ngOnDestroy(): void;
12
+ constructor();
14
13
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlZoomControlComponent, never>;
15
14
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlZoomControlComponent, "ol-zoom-control", never, { "delta": { "alias": "delta"; "required": false; "isSignal": true; }; "duration": { "alias": "duration"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
16
15
  }
17
16
 
18
- declare class OlAttributionControlComponent implements OnInit, OnDestroy {
17
+ declare class OlAttributionControlComponent {
19
18
  private mapService;
20
- private ngZone;
19
+ private zoneHelper;
21
20
  collapsible: _angular_core.InputSignal<boolean>;
22
21
  collapsed: _angular_core.InputSignal<boolean>;
23
22
  private control?;
24
- ngOnInit(): void;
25
- private tryAddControl;
26
- ngOnDestroy(): void;
23
+ constructor();
27
24
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlAttributionControlComponent, never>;
28
25
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlAttributionControlComponent, "ol-attribution-control", never, { "collapsible": { "alias": "collapsible"; "required": false; "isSignal": true; }; "collapsed": { "alias": "collapsed"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
29
26
  }
30
27
 
31
- declare class OlScaleLineControlComponent implements OnInit, OnDestroy {
28
+ declare class OlScaleLineControlComponent {
32
29
  private mapService;
33
- private ngZone;
30
+ private zoneHelper;
34
31
  units: _angular_core.InputSignal<"metric" | "imperial" | "nautical" | "us">;
35
32
  bar: _angular_core.InputSignal<boolean>;
36
33
  steps: _angular_core.InputSignal<number>;
37
34
  private control?;
38
- ngOnInit(): void;
39
- private tryAddControl;
40
- ngOnDestroy(): void;
35
+ constructor();
41
36
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlScaleLineControlComponent, never>;
42
37
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlScaleLineControlComponent, "ol-scale-line-control", never, { "units": { "alias": "units"; "required": false; "isSignal": true; }; "bar": { "alias": "bar"; "required": false; "isSignal": true; }; "steps": { "alias": "steps"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
43
38
  }
44
39
 
45
- declare class OlFullscreenControlComponent implements OnInit, OnDestroy {
40
+ declare class OlFullscreenControlComponent {
46
41
  private mapService;
47
- private ngZone;
42
+ private zoneHelper;
48
43
  source: _angular_core.InputSignal<HTMLElement>;
49
44
  label: _angular_core.InputSignal<string>;
50
45
  labelActive: _angular_core.InputSignal<string>;
51
46
  tipLabel: _angular_core.InputSignal<string>;
52
47
  private control?;
53
- ngOnInit(): void;
54
- private tryAddControl;
55
- ngOnDestroy(): void;
48
+ constructor();
56
49
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlFullscreenControlComponent, never>;
57
50
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlFullscreenControlComponent, "ol-fullscreen-control", never, { "source": { "alias": "source"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "labelActive": { "alias": "labelActive"; "required": false; "isSignal": true; }; "tipLabel": { "alias": "tipLabel"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
58
51
  }
59
52
 
53
+ /**
54
+ * Interface for map service that rotate control needs
55
+ * Implement this or provide your OlMapService using this token
56
+ */
57
+ interface RotateControlMapService {
58
+ getMap(): OLMap | null;
59
+ onReady(callback: (map: OLMap) => void): void;
60
+ }
61
+ /**
62
+ * Injection token for map service used by rotate control
63
+ * Consumers should provide their OlMapService using this token:
64
+ * ```ts
65
+ * { provide: ROTATE_CONTROL_MAP_SERVICE, useExisting: OlMapService }
66
+ * ```
67
+ */
68
+ declare const ROTATE_CONTROL_MAP_SERVICE: InjectionToken<RotateControlMapService>;
69
+ declare class OlRotateControlComponent {
70
+ private mapService;
71
+ private zoneHelper;
72
+ autoHide: _angular_core.InputSignal<boolean>;
73
+ duration: _angular_core.InputSignal<number>;
74
+ tipLabel: _angular_core.InputSignal<string>;
75
+ private control?;
76
+ constructor();
77
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlRotateControlComponent, never>;
78
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlRotateControlComponent, "ol-rotate-control", never, { "autoHide": { "alias": "autoHide"; "required": false; "isSignal": true; }; "duration": { "alias": "duration"; "required": false; "isSignal": true; }; "tipLabel": { "alias": "tipLabel"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
79
+ }
80
+
81
+ /**
82
+ * Item representing a layer in the layer switcher UI
83
+ */
84
+ interface LayerSwitcherItem {
85
+ /** Unique identifier for the layer */
86
+ id: string;
87
+ /** Display name for the layer */
88
+ name: string;
89
+ /** Type of the layer */
90
+ type: 'vector' | 'tile' | 'image';
91
+ /** Whether the layer is currently visible */
92
+ visible: boolean;
93
+ /** Opacity of the layer (0-1) */
94
+ opacity: number;
95
+ }
96
+ /**
97
+ * Position options for the layer switcher control
98
+ */
99
+ type LayerSwitcherPosition = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
100
+
101
+ /**
102
+ * A reusable layer switcher control that displays all layers
103
+ * and allows toggling their visibility.
104
+ *
105
+ * @usageNotes
106
+ * ```html
107
+ * <ol-layer-switcher
108
+ * position="top-right"
109
+ * [layers]="layerItems()"
110
+ * [collapsible]="true"
111
+ * [showOpacity]="true"
112
+ * (visibilityChange)="onVisibilityChange($event)"
113
+ * (opacityChange)="onOpacityChange($event)">
114
+ * </ol-layer-switcher>
115
+ * ```
116
+ */
117
+ declare class OlLayerSwitcherComponent {
118
+ position: _angular_core.InputSignal<"top-left" | "top-right" | "bottom-left" | "bottom-right">;
119
+ layers: _angular_core.InputSignal<LayerSwitcherItem[]>;
120
+ collapsible: _angular_core.InputSignal<boolean>;
121
+ showOpacity: _angular_core.InputSignal<boolean>;
122
+ startCollapsed: _angular_core.InputSignal<boolean>;
123
+ visibilityChange: _angular_core.OutputEmitterRef<{
124
+ id: string;
125
+ visible: boolean;
126
+ }>;
127
+ opacityChange: _angular_core.OutputEmitterRef<{
128
+ id: string;
129
+ opacity: number;
130
+ }>;
131
+ protected isCollapsed: _angular_core.WritableSignal<boolean>;
132
+ toggleCollapsed(): void;
133
+ toggleLayer(id: string): void;
134
+ setOpacity(id: string, event: Event): void;
135
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlLayerSwitcherComponent, never>;
136
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlLayerSwitcherComponent, "ol-layer-switcher", never, { "position": { "alias": "position"; "required": false; "isSignal": true; }; "layers": { "alias": "layers"; "required": false; "isSignal": true; }; "collapsible": { "alias": "collapsible"; "required": false; "isSignal": true; }; "showOpacity": { "alias": "showOpacity"; "required": false; "isSignal": true; }; "startCollapsed": { "alias": "startCollapsed"; "required": false; "isSignal": true; }; }, { "visibilityChange": "visibilityChange"; "opacityChange": "opacityChange"; }, never, never, true, never>;
137
+ }
138
+
139
+ /**
140
+ * Configuration for a basemap (background layer)
141
+ */
142
+ interface BasemapConfig {
143
+ /** Unique identifier for the basemap */
144
+ id: string;
145
+ /** Display name for the basemap */
146
+ name: string;
147
+ /** Type of tile source */
148
+ type: 'osm' | 'xyz' | 'wms';
149
+ /** URL template for XYZ/WMS sources */
150
+ url?: string;
151
+ /** Additional parameters for WMS requests */
152
+ params?: Record<string, unknown>;
153
+ /** Attribution text */
154
+ attributions?: string | string[];
155
+ /** Optional icon/emoji */
156
+ icon?: string;
157
+ }
158
+ /**
159
+ * Position options for the basemap switcher control
160
+ */
161
+ type BasemapSwitcherPosition = 'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right';
162
+
163
+ /**
164
+ * A basemap switcher control that allows switching between
165
+ * different tile providers without page refresh.
166
+ *
167
+ * @usageNotes
168
+ * ```html
169
+ * <ol-basemap-switcher
170
+ * position="bottom-left"
171
+ * [basemaps]="[
172
+ * { id: 'osm', name: 'OpenStreetMap', type: 'osm' },
173
+ * { id: 'satellite', name: 'Satellite', type: 'xyz', url: 'https://...' }
174
+ * ]"
175
+ * [activeBasemap]="'osm'"
176
+ * (basemapChange)="onBasemapChange($event)">
177
+ * </ol-basemap-switcher>
178
+ * ```
179
+ */
180
+ declare class OlBasemapSwitcherComponent {
181
+ basemaps: _angular_core.InputSignal<BasemapConfig[]>;
182
+ activeBasemap: _angular_core.InputSignal<string>;
183
+ position: _angular_core.InputSignal<BasemapSwitcherPosition>;
184
+ basemapChange: _angular_core.OutputEmitterRef<string>;
185
+ protected isExpanded: _angular_core.WritableSignal<boolean>;
186
+ toggleExpanded(): void;
187
+ switchBasemap(basemap: BasemapConfig): void;
188
+ getActiveBasemapName(): string;
189
+ getDefaultIcon(basemap: BasemapConfig): string;
190
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlBasemapSwitcherComponent, never>;
191
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlBasemapSwitcherComponent, "ol-basemap-switcher", never, { "basemaps": { "alias": "basemaps"; "required": false; "isSignal": true; }; "activeBasemap": { "alias": "activeBasemap"; "required": false; "isSignal": true; }; "position": { "alias": "position"; "required": false; "isSignal": true; }; }, { "basemapChange": "basemapChange"; }, never, never, true, never>;
192
+ }
193
+
60
194
  type ControlPosition = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'top-center' | 'bottom-center' | 'left-center' | 'right-center';
61
195
  interface ControlConfig {
62
196
  position?: ControlPosition;
@@ -70,8 +204,12 @@ declare class OlControlService {
70
204
  static ɵprov: _angular_core.ɵɵInjectableDeclaration<OlControlService>;
71
205
  }
72
206
 
207
+ /**
208
+ * Provides control services and configures the rotate control map service alias.
209
+ * Requires OlMapService to be provided at the application level.
210
+ */
73
211
  declare function withControls(): OlFeature<'controls'>;
74
212
  declare function provideControls(): OlFeature<'controls'>;
75
213
 
76
- export { OlAttributionControlComponent, OlControlService, OlFullscreenControlComponent, OlScaleLineControlComponent, OlZoomControlComponent, provideControls, withControls };
77
- export type { ControlConfig, ControlPosition };
214
+ export { OlAttributionControlComponent, OlBasemapSwitcherComponent, OlControlService, OlFullscreenControlComponent, OlLayerSwitcherComponent, OlRotateControlComponent, OlScaleLineControlComponent, OlZoomControlComponent, ROTATE_CONTROL_MAP_SERVICE, provideControls, withControls };
215
+ export type { BasemapConfig, BasemapSwitcherPosition, ControlConfig, ControlPosition, LayerSwitcherItem, LayerSwitcherPosition, RotateControlMapService };
@@ -1,5 +1,5 @@
1
1
  import * as _angular_core from '@angular/core';
2
- import { AfterViewInit, OnDestroy, ElementRef, Provider, EnvironmentProviders } from '@angular/core';
2
+ import { ElementRef, Provider, EnvironmentProviders } from '@angular/core';
3
3
  import OLMap from 'ol/Map';
4
4
  import { View } from 'ol';
5
5
 
@@ -70,9 +70,10 @@ interface MapClickEvent {
70
70
  coordinate: Coordinate;
71
71
  pixel: Pixel;
72
72
  }
73
- declare class OlMapComponent implements AfterViewInit, OnDestroy {
73
+ declare class OlMapComponent {
74
74
  private mapService;
75
- private ngZone;
75
+ private zoneHelper;
76
+ private destroyRef;
76
77
  center: _angular_core.InputSignal<Coordinate>;
77
78
  zoom: _angular_core.InputSignal<number>;
78
79
  rotation: _angular_core.InputSignal<number>;
@@ -83,8 +84,6 @@ declare class OlMapComponent implements AfterViewInit, OnDestroy {
83
84
  mapContainerRef: _angular_core.Signal<ElementRef<HTMLDivElement>>;
84
85
  private map?;
85
86
  constructor();
86
- ngAfterViewInit(): void;
87
- ngOnDestroy(): void;
88
87
  private initMap;
89
88
  private destroyMap;
90
89
  private updateCenter;
@@ -95,30 +94,55 @@ declare class OlMapComponent implements AfterViewInit, OnDestroy {
95
94
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlMapComponent, "ol-map", never, { "center": { "alias": "center"; "required": false; "isSignal": true; }; "zoom": { "alias": "zoom"; "required": false; "isSignal": true; }; "rotation": { "alias": "rotation"; "required": false; "isSignal": true; }; "projection": { "alias": "projection"; "required": false; "isSignal": true; }; }, { "viewChange": "viewChange"; "mapClick": "mapClick"; "mapDblClick": "mapDblClick"; }, never, ["*"], true, never>;
96
95
  }
97
96
 
97
+ /**
98
+ * Options for animating the map view.
99
+ */
98
100
  interface AnimationOptions {
101
+ /** Target center coordinate */
99
102
  center?: Coordinate;
103
+ /** Target zoom level */
100
104
  zoom?: number;
105
+ /** Target rotation in radians */
101
106
  rotation?: number;
107
+ /** Animation duration in milliseconds */
102
108
  duration?: number;
103
109
  }
110
+ /**
111
+ * Options for fitting the view to an extent.
112
+ */
104
113
  interface FitOptions {
114
+ /** Padding around the extent [top, right, bottom, left] */
105
115
  padding?: [number, number, number, number];
116
+ /** Maximum zoom level to use */
106
117
  maxZoom?: number;
118
+ /** Animation duration in milliseconds */
107
119
  duration?: number;
108
120
  }
121
+ /**
122
+ * Configuration options for the map view.
123
+ */
109
124
  interface MapViewOptions {
125
+ /** Initial center coordinate */
110
126
  center?: Coordinate;
127
+ /** Initial zoom level */
111
128
  zoom?: number;
129
+ /** Minimum allowed zoom */
112
130
  minZoom?: number;
131
+ /** Maximum allowed zoom */
113
132
  maxZoom?: number;
133
+ /** Initial rotation in radians */
114
134
  rotation?: number;
135
+ /** Map projection (e.g., 'EPSG:3857') */
115
136
  projection?: string;
116
137
  }
138
+
117
139
  declare class OlMapService {
118
- private ngZone;
140
+ private zoneHelper;
119
141
  private map;
142
+ private readyCallbacks;
120
143
  setMap(map: OLMap): void;
121
144
  getMap(): OLMap | null;
145
+ onReady(callback: (map: OLMap) => void): void;
122
146
  getView(): View | null;
123
147
  setCenter(coordinate: Coordinate): void;
124
148
  setZoom(level: number): void;
@@ -133,6 +157,47 @@ declare class OlMapService {
133
157
  static ɵprov: _angular_core.ɵɵInjectableDeclaration<OlMapService>;
134
158
  }
135
159
 
160
+ /**
161
+ * Helper service that abstracts NgZone operations for zoneless compatibility.
162
+ *
163
+ * When NgZone is available (classic Angular):
164
+ * - runOutsideAngular: executes outside Angular's zone for performance
165
+ * - runInsideAngular: executes inside Angular's zone to trigger change detection
166
+ *
167
+ * When zoneless (signals-only Angular):
168
+ * - Both methods execute directly since signals handle reactivity
169
+ *
170
+ * @usageNotes
171
+ * Inject this service instead of NgZone directly:
172
+ * ```ts
173
+ * private zoneHelper = inject(OlZoneHelper);
174
+ *
175
+ * this.zoneHelper.runOutsideAngular(() => {
176
+ * // OpenLayers operations that don't need CD
177
+ * });
178
+ * ```
179
+ */
180
+ declare class OlZoneHelper {
181
+ private ngZone;
182
+ /**
183
+ * Runs callback outside Angular zone if available (for performance with NgZone),
184
+ * or directly if zoneless.
185
+ *
186
+ * Use for: OpenLayers operations that don't need to trigger Angular change detection
187
+ * (map manipulation, event listeners, animations)
188
+ */
189
+ runOutsideAngular<T>(fn: () => T): T;
190
+ /**
191
+ * Runs callback inside Angular zone if available (for triggering CD),
192
+ * or directly if zoneless.
193
+ *
194
+ * Use for: Emitting outputs that should be handled by parent components
195
+ */
196
+ runInsideAngular<T>(fn: () => T): T;
197
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlZoneHelper, never>;
198
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<OlZoneHelper>;
199
+ }
200
+
136
201
  type OlFeatureKind = 'layers' | 'controls' | 'interactions' | 'overlays' | 'military';
137
202
  interface OlFeature<Kind extends OlFeatureKind> {
138
203
  kind: Kind;
@@ -140,5 +205,5 @@ interface OlFeature<Kind extends OlFeatureKind> {
140
205
  }
141
206
  declare function provideOpenLayers(...features: OlFeature<OlFeatureKind>[]): EnvironmentProviders;
142
207
 
143
- export { OlMapComponent, OlMapService, provideOpenLayers };
208
+ export { OlMapComponent, OlMapService, OlZoneHelper, provideOpenLayers };
144
209
  export type { AnimationOptions, Coordinate, Extent, Feature, FitOptions, Geometry, GeometryType, Layer, MapClickEvent, MapConfig, MapViewOptions, OlFeature, OlFeatureKind, Pixel, ProjectionCode, Style, ViewState };