@angular-helpers/openlayers 0.4.0 → 0.5.1

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,9 +1,11 @@
1
1
  import * as _angular_core from '@angular/core';
2
2
  import { Layer, Extent, Feature, Style, OlFeature } from '@angular-helpers/openlayers/core';
3
+ import { FlatStyleLike } from 'ol/style/flat';
4
+ import { Style as Style$1 } from 'ol/layer/WebGLTile';
3
5
  import BaseLayer from 'ol/layer/Base';
4
6
 
5
7
  interface LayerConfig extends Layer {
6
- type: 'vector' | 'tile' | 'image';
8
+ type: 'vector' | 'tile' | 'image' | 'heatmap';
7
9
  extent?: Extent;
8
10
  minResolution?: number;
9
11
  maxResolution?: number;
@@ -19,13 +21,26 @@ interface ClusterConfig {
19
21
  showCount?: boolean;
20
22
  /** Style for individual features when clustering */
21
23
  featureStyle?: Style;
24
+ /** Automatically spiderfy overlapping points on click (default: false) */
25
+ spiderfyOnSelect?: boolean;
26
+ /** Callback when a spider leg feature is clicked */
27
+ onSpiderfyClick?: (feature: Feature) => void;
22
28
  }
23
29
  interface VectorLayerConfig extends LayerConfig {
24
30
  type: 'vector';
25
31
  features?: Feature[];
32
+ url?: string;
33
+ format?: 'geojson' | 'topojson' | 'kml';
26
34
  style?: Style | ((feature: Feature) => Style);
27
35
  cluster?: ClusterConfig;
28
36
  }
37
+ interface HeatmapLayerConfig extends LayerConfig {
38
+ type: 'heatmap';
39
+ features?: Feature[];
40
+ weight?: string | ((feature: Feature) => number);
41
+ blur?: number;
42
+ radius?: number;
43
+ }
29
44
  interface TileLayerConfig extends LayerConfig {
30
45
  type: 'tile';
31
46
  source: SourceConfig;
@@ -46,20 +61,35 @@ interface ImageSourceConfig {
46
61
  params?: Record<string, unknown>;
47
62
  imageExtent?: Extent;
48
63
  }
64
+ type AnyLayerConfig = VectorLayerConfig | TileLayerConfig | ImageLayerConfig | HeatmapLayerConfig;
65
+
66
+ declare class OlClusterComponent {
67
+ distance: _angular_core.InputSignal<number>;
68
+ minDistance: _angular_core.InputSignal<number>;
69
+ showCount: _angular_core.InputSignal<boolean>;
70
+ featureStyle: _angular_core.InputSignal<Style>;
71
+ spiderfyOnSelect: _angular_core.InputSignal<boolean>;
72
+ spiderfyClick: _angular_core.OutputEmitterRef<Feature>;
73
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlClusterComponent, never>;
74
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlClusterComponent, "ol-cluster", never, { "distance": { "alias": "distance"; "required": false; "isSignal": true; }; "minDistance": { "alias": "minDistance"; "required": false; "isSignal": true; }; "showCount": { "alias": "showCount"; "required": false; "isSignal": true; }; "featureStyle": { "alias": "featureStyle"; "required": false; "isSignal": true; }; "spiderfyOnSelect": { "alias": "spiderfyOnSelect"; "required": false; "isSignal": true; }; }, { "spiderfyClick": "spiderfyClick"; }, never, never, true, never>;
75
+ }
49
76
 
50
77
  declare class OlVectorLayerComponent {
51
78
  private layerService;
52
79
  private destroyRef;
53
80
  id: _angular_core.InputSignal<string>;
54
81
  features: _angular_core.InputSignal<Feature[]>;
82
+ url: _angular_core.InputSignal<string>;
83
+ format: _angular_core.InputSignal<"geojson" | "topojson" | "kml">;
55
84
  zIndex: _angular_core.InputSignal<number>;
56
85
  opacity: _angular_core.InputSignal<number>;
57
86
  visible: _angular_core.InputSignal<boolean>;
58
- style: _angular_core.InputSignal<Style | ((feature: Feature) => Style)>;
87
+ style: _angular_core.InputSignal<any>;
59
88
  cluster: _angular_core.InputSignal<ClusterConfig>;
89
+ clusterComponent: _angular_core.Signal<OlClusterComponent>;
60
90
  constructor();
61
91
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlVectorLayerComponent, never>;
62
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlVectorLayerComponent, "ol-vector-layer", never, { "id": { "alias": "id"; "required": true; "isSignal": true; }; "features": { "alias": "features"; "required": false; "isSignal": true; }; "zIndex": { "alias": "zIndex"; "required": false; "isSignal": true; }; "opacity": { "alias": "opacity"; "required": false; "isSignal": true; }; "visible": { "alias": "visible"; "required": false; "isSignal": true; }; "style": { "alias": "style"; "required": false; "isSignal": true; }; "cluster": { "alias": "cluster"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
92
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlVectorLayerComponent, "ol-vector-layer", never, { "id": { "alias": "id"; "required": true; "isSignal": true; }; "features": { "alias": "features"; "required": false; "isSignal": true; }; "url": { "alias": "url"; "required": false; "isSignal": true; }; "format": { "alias": "format"; "required": false; "isSignal": true; }; "zIndex": { "alias": "zIndex"; "required": false; "isSignal": true; }; "opacity": { "alias": "opacity"; "required": false; "isSignal": true; }; "visible": { "alias": "visible"; "required": false; "isSignal": true; }; "style": { "alias": "style"; "required": false; "isSignal": true; }; "cluster": { "alias": "cluster"; "required": false; "isSignal": true; }; }, {}, ["clusterComponent"], never, true, never>;
63
93
  }
64
94
 
65
95
  declare class OlTileLayerComponent {
@@ -94,9 +124,130 @@ declare class OlImageLayerComponent {
94
124
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlImageLayerComponent, "ol-image-layer", never, { "id": { "alias": "id"; "required": true; "isSignal": true; }; "sourceType": { "alias": "sourceType"; "required": true; "isSignal": true; }; "url": { "alias": "url"; "required": true; "isSignal": true; }; "params": { "alias": "params"; "required": false; "isSignal": true; }; "imageExtent": { "alias": "imageExtent"; "required": false; "isSignal": true; }; "zIndex": { "alias": "zIndex"; "required": false; "isSignal": true; }; "opacity": { "alias": "opacity"; "required": false; "isSignal": true; }; "visible": { "alias": "visible"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
95
125
  }
96
126
 
127
+ declare class OlHeatmapLayerComponent {
128
+ private layerService;
129
+ private mapService;
130
+ private destroyRef;
131
+ id: _angular_core.InputSignal<string>;
132
+ features: _angular_core.InputSignal<Feature[]>;
133
+ zIndex: _angular_core.InputSignal<number>;
134
+ opacity: _angular_core.InputSignal<number>;
135
+ visible: _angular_core.InputSignal<boolean>;
136
+ blur: _angular_core.InputSignal<number>;
137
+ radius: _angular_core.InputSignal<number>;
138
+ /** Unit for radius and blur: 'pixels' (default) or 'meters' */
139
+ radiusUnit: _angular_core.InputSignal<"pixels" | "meters">;
140
+ weight: _angular_core.InputSignal<string | ((feature: Feature) => number)>;
141
+ /** Computed radius in pixels based on current resolution if unit is 'meters' */
142
+ private scaledRadius;
143
+ /** Computed blur in pixels based on current resolution if unit is 'meters' */
144
+ private scaledBlur;
145
+ constructor();
146
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlHeatmapLayerComponent, never>;
147
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlHeatmapLayerComponent, "ol-heatmap-layer", never, { "id": { "alias": "id"; "required": true; "isSignal": true; }; "features": { "alias": "features"; "required": false; "isSignal": true; }; "zIndex": { "alias": "zIndex"; "required": false; "isSignal": true; }; "opacity": { "alias": "opacity"; "required": false; "isSignal": true; }; "visible": { "alias": "visible"; "required": false; "isSignal": true; }; "blur": { "alias": "blur"; "required": false; "isSignal": true; }; "radius": { "alias": "radius"; "required": false; "isSignal": true; }; "radiusUnit": { "alias": "radiusUnit"; "required": false; "isSignal": true; }; "weight": { "alias": "weight"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
148
+ }
149
+
150
+ /**
151
+ * GPU-accelerated vector layer for rendering large datasets.
152
+ *
153
+ * Important: Uses WebGL 2 for rendering. Styles must be provided as
154
+ * `FlatStyleLike` objects (not `ol/style/Style` instances).
155
+ * Hit detection is disabled by default for performance.
156
+ *
157
+ * @usageNotes
158
+ * ```html
159
+ * <ol-webgl-vector-layer
160
+ * id="big-dataset"
161
+ * [features]="largeDataset()"
162
+ * [flatStyle]="{
163
+ * 'circle-radius': 6,
164
+ * 'circle-fill-color': ['match', ['get', 'type'], 'alert', 'red', 'blue'],
165
+ * 'stroke-color': '#333',
166
+ * 'stroke-width': 1
167
+ * }"
168
+ * [disableHitDetection]="true">
169
+ * </ol-webgl-vector-layer>
170
+ * ```
171
+ */
172
+ declare class OlWebGLVectorLayerComponent {
173
+ private mapService;
174
+ private destroyRef;
175
+ /** Unique layer identifier */
176
+ id: _angular_core.InputSignal<string>;
177
+ /** Features to render */
178
+ features: _angular_core.InputSignal<Feature[]>;
179
+ /** WebGL flat style (required — no default provided) */
180
+ flatStyle: _angular_core.InputSignal<FlatStyleLike>;
181
+ /** Z-index for layer ordering */
182
+ zIndex: _angular_core.InputSignal<number>;
183
+ /** Opacity (0–1) */
184
+ opacity: _angular_core.InputSignal<number>;
185
+ /** Layer visibility */
186
+ visible: _angular_core.InputSignal<boolean>;
187
+ /** Disable hit detection for better performance (default: true) */
188
+ disableHitDetection: _angular_core.InputSignal<boolean>;
189
+ /** Style variables for dynamic expressions (e.g. `['var', 'threshold']`) */
190
+ variables: _angular_core.InputSignal<Record<string, string | number | boolean | number[]>>;
191
+ private layer;
192
+ private vectorSource;
193
+ constructor();
194
+ /**
195
+ * Imperatively update style variables without triggering Angular change detection.
196
+ * Ideal for 60FPS animations (e.g., linked to OlTimeService) where you don't want
197
+ * to use the declarative [variables] input.
198
+ */
199
+ updateVariables(vars: Record<string, string | number | boolean | number[]>): void;
200
+ private syncFeatures;
201
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlWebGLVectorLayerComponent, never>;
202
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlWebGLVectorLayerComponent, "ol-webgl-vector-layer", never, { "id": { "alias": "id"; "required": true; "isSignal": true; }; "features": { "alias": "features"; "required": false; "isSignal": true; }; "flatStyle": { "alias": "flatStyle"; "required": true; "isSignal": true; }; "zIndex": { "alias": "zIndex"; "required": false; "isSignal": true; }; "opacity": { "alias": "opacity"; "required": false; "isSignal": true; }; "visible": { "alias": "visible"; "required": false; "isSignal": true; }; "disableHitDetection": { "alias": "disableHitDetection"; "required": false; "isSignal": true; }; "variables": { "alias": "variables"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
203
+ }
204
+
205
+ /**
206
+ * GPU-accelerated tile layer with color/brightness/contrast expressions.
207
+ *
208
+ * Supports the same tile sources as `ol-tile-layer` but renders via WebGL,
209
+ * enabling GPU-powered color manipulation (brightness, contrast, saturation, gamma).
210
+ *
211
+ * @usageNotes
212
+ * ```html
213
+ * <ol-webgl-tile-layer
214
+ * id="satellite-webgl"
215
+ * source="xyz"
216
+ * [url]="'https://server.arcgisonline.com/.../{z}/{y}/{x}'"
217
+ * [tileStyle]="{ brightness: 0.1, contrast: 0.2 }">
218
+ * </ol-webgl-tile-layer>
219
+ * ```
220
+ */
221
+ declare class OlWebGLTileLayerComponent {
222
+ private mapService;
223
+ private destroyRef;
224
+ /** Unique layer identifier */
225
+ id: _angular_core.InputSignal<string>;
226
+ /** Tile source type */
227
+ source: _angular_core.InputSignal<"osm" | "xyz" | "mvt">;
228
+ /** Tile URL template (required for 'xyz' and 'mvt') */
229
+ url: _angular_core.InputSignal<string>;
230
+ /** Attribution text */
231
+ attributions: _angular_core.InputSignal<string | string[]>;
232
+ /** WebGL tile style (raster expressions) or flat style (MVT) */
233
+ tileStyle: _angular_core.InputSignal<FlatStyleLike | Style$1>;
234
+ /** Z-index for layer ordering */
235
+ zIndex: _angular_core.InputSignal<number>;
236
+ /** Opacity (0–1) */
237
+ opacity: _angular_core.InputSignal<number>;
238
+ /** Layer visibility */
239
+ visible: _angular_core.InputSignal<boolean>;
240
+ /** Preload low-res tiles up to this many zoom levels */
241
+ preload: _angular_core.InputSignal<number>;
242
+ private layer;
243
+ constructor();
244
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlWebGLTileLayerComponent, never>;
245
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlWebGLTileLayerComponent, "ol-webgl-tile-layer", never, { "id": { "alias": "id"; "required": true; "isSignal": true; }; "source": { "alias": "source"; "required": true; "isSignal": true; }; "url": { "alias": "url"; "required": false; "isSignal": true; }; "attributions": { "alias": "attributions"; "required": false; "isSignal": true; }; "tileStyle": { "alias": "tileStyle"; "required": false; "isSignal": true; }; "zIndex": { "alias": "zIndex"; "required": false; "isSignal": true; }; "opacity": { "alias": "opacity"; "required": false; "isSignal": true; }; "visible": { "alias": "visible"; "required": false; "isSignal": true; }; "preload": { "alias": "preload"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
246
+ }
247
+
97
248
  interface LayerInfo {
98
249
  id: string;
99
- type: 'vector' | 'tile' | 'image';
250
+ type: 'vector' | 'tile' | 'image' | 'heatmap';
100
251
  visible: boolean;
101
252
  opacity: number;
102
253
  zIndex: number;
@@ -106,11 +257,12 @@ declare class OlLayerService {
106
257
  private layerCache;
107
258
  private pendingConfigs;
108
259
  private layerState;
260
+ private spiderManager;
109
261
  readonly layers: _angular_core.Signal<LayerInfo[]>;
110
262
  readonly visibleLayers: _angular_core.Signal<LayerInfo[]>;
111
263
  readonly tileLayers: _angular_core.Signal<LayerInfo[]>;
112
264
  readonly vectorLayers: _angular_core.Signal<LayerInfo[]>;
113
- addLayer(config: LayerConfig): {
265
+ addLayer(config: AnyLayerConfig): {
114
266
  id: string;
115
267
  };
116
268
  private flushPending;
@@ -122,26 +274,19 @@ declare class OlLayerService {
122
274
  toggleVisibility(id: string): boolean;
123
275
  setOpacity(id: string, opacity: number): void;
124
276
  setZIndex(id: string, zIndex: number): void;
277
+ setClusterDistance(id: string, distance: number): void;
278
+ setClusterMinDistance(id: string, minDistance: number): void;
279
+ setHeatmapProperties(id: string, props: {
280
+ blur?: number;
281
+ radius?: number;
282
+ weight?: string | ((feature: any) => number);
283
+ }): void;
125
284
  isVisible(id: string): boolean;
126
285
  getOpacity(id: string): number;
127
286
  getZIndex(id: string): number;
128
- /**
129
- * Clears all features from a vector layer's source.
130
- * Does not remove the layer itself.
131
- * @param id - Layer identifier
132
- */
133
287
  clearFeatures(id: string): void;
134
- /**
135
- * Updates the features of a vector layer.
136
- * Syncs new features without clearing existing ones (preserves OL modifications).
137
- * @param id - Layer identifier
138
- * @param features - New features to sync
139
- */
140
288
  updateFeatures(id: string, features: VectorLayerConfig['features']): void;
141
289
  private updateLayerState;
142
- private createVectorLayer;
143
- private createTileLayer;
144
- private createImageLayer;
145
290
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlLayerService, never>;
146
291
  static ɵprov: _angular_core.ɵɵInjectableDeclaration<OlLayerService>;
147
292
  }
@@ -149,5 +294,5 @@ declare class OlLayerService {
149
294
  declare function withLayers(): OlFeature<'layers'>;
150
295
  declare function provideLayers(): OlFeature<'layers'>;
151
296
 
152
- export { OlImageLayerComponent, OlLayerService, OlTileLayerComponent, OlVectorLayerComponent, provideLayers, withLayers };
153
- export type { ImageLayerConfig, ImageSourceConfig, LayerConfig, LayerInfo, SourceConfig, TileLayerConfig, VectorLayerConfig };
297
+ export { OlClusterComponent, OlHeatmapLayerComponent, OlImageLayerComponent, OlLayerService, OlTileLayerComponent, OlVectorLayerComponent, OlWebGLTileLayerComponent, OlWebGLVectorLayerComponent, provideLayers, withLayers };
298
+ export type { HeatmapLayerConfig, ImageLayerConfig, ImageSourceConfig, LayerConfig, LayerInfo, SourceConfig, TileLayerConfig, VectorLayerConfig };
@@ -1,78 +1,8 @@
1
- import { Coordinate, Feature, OlFeature } from '@angular-helpers/openlayers/core';
2
1
  import * as i0 from '@angular/core';
2
+ import { Coordinate, EllipseConfig, Feature, SectorConfig, DonutConfig, OlFeature } from '@angular-helpers/openlayers/core';
3
+ import { Style } from 'ol/style';
4
+ import { Feature as Feature$1 } from 'ol';
3
5
 
4
- /**
5
- * Configuration for an ellipse polygon centered at `center`.
6
- * Coordinates are emitted in EPSG:4326 (lon/lat) using a local tangent-plane
7
- * approximation; accuracy degrades for radii > ~100 km or near the poles.
8
- */
9
- interface EllipseConfig {
10
- /** Ellipse center as `[lon, lat]` in EPSG:4326. */
11
- center: Coordinate;
12
- /** Semi-major axis in meters. Must be > 0. */
13
- semiMajor: number;
14
- /** Semi-minor axis in meters. Must be > 0. */
15
- semiMinor: number;
16
- /**
17
- * Rotation in radians, counter-clockwise from East. Default: 0
18
- * (semi-major axis points East).
19
- */
20
- rotation?: number;
21
- /**
22
- * Number of vertices used to approximate the ellipse. Default: 64.
23
- * Minimum: 8.
24
- */
25
- segments?: number;
26
- /** Custom feature properties to attach to the output feature. */
27
- properties?: Record<string, unknown>;
28
- }
29
- /**
30
- * Configuration for a circular sector (pie-slice) polygon.
31
- * Same projection caveats as `EllipseConfig`.
32
- */
33
- interface SectorConfig {
34
- /** Sector apex / center as `[lon, lat]` in EPSG:4326. */
35
- center: Coordinate;
36
- /** Sector radius in meters. Must be > 0. */
37
- radius: number;
38
- /** Start angle in radians (0 = East, CCW positive). */
39
- startAngle: number;
40
- /**
41
- * End angle in radians. Must satisfy `startAngle < endAngle <= startAngle + 2π`.
42
- */
43
- endAngle: number;
44
- /**
45
- * Number of vertices along the arc. Default: 32. Minimum: 4. The output
46
- * polygon has `segments + 3` vertices (apex + arc + apex closer).
47
- */
48
- segments?: number;
49
- /** Custom feature properties to attach to the output feature. */
50
- properties?: Record<string, unknown>;
51
- }
52
- /**
53
- * Configuration for a donut (annular ring) polygon — a disk with a
54
- * concentric circular hole. Useful for range rings, exclusion zones,
55
- * and similar GIS military primitives.
56
- *
57
- * The output `Feature<Polygon>` has TWO rings: an outer ring (CCW) and
58
- * an inner ring (CW per the GeoJSON right-hand rule), so renderers that
59
- * follow the spec fill only the band between the radii.
60
- */
61
- interface DonutConfig {
62
- /** Donut center as `[lon, lat]` in EPSG:4326. */
63
- center: Coordinate;
64
- /** Outer radius in meters. Must be > `innerRadius`. */
65
- outerRadius: number;
66
- /** Inner radius in meters. Must be > 0 and < `outerRadius`. */
67
- innerRadius: number;
68
- /**
69
- * Number of vertices per ring. Default: 64. Minimum: 8. Both rings use
70
- * the same segment count.
71
- */
72
- segments?: number;
73
- /** Custom feature properties to attach to the output feature. */
74
- properties?: Record<string, unknown>;
75
- }
76
6
  /**
77
7
  * Subset of `milsymbol`'s `SymbolOptions` exposed by this package.
78
8
  * `sidc` is the only required field; everything else is optional and
@@ -124,13 +54,20 @@ interface MilSymbolStyleResult {
124
54
  * Service exposing geometry helpers and MIL-STD-2525 symbology rendering.
125
55
  *
126
56
  * - `createEllipse`, `createSector`, `createDonut` are **pure math** and
127
- * have no runtime dependencies beyond the bundled types.
128
- * - `createMilSymbol` uses the milsymbol library via dynamic ESM import.
57
+ * delegate to {@link OlGeometryService} in core.
58
+ * - `createMilSymbol` uses the milsymbol library via Angular resource loading.
129
59
  */
130
60
  declare class OlMilitaryService {
131
61
  private idCounter;
132
- private mlLoader;
133
- private msModule;
62
+ private geometryService;
63
+ /**
64
+ * Resource managing the lazy-loading of the milsymbol library.
65
+ * Angular resource provides native signals for value, loading state, and errors.
66
+ */
67
+ private readonly msResource;
68
+ /** Signal indicating if the milsymbol library is currently being loaded. */
69
+ readonly isLoading: i0.Signal<boolean>;
70
+ constructor();
134
71
  /**
135
72
  * Build a `Feature<Polygon>` approximating an ellipse centered at
136
73
  * `config.center`. See {@link EllipseConfig} for parameter semantics.
@@ -142,46 +79,99 @@ declare class OlMilitaryService {
142
79
  */
143
80
  createSector(config: SectorConfig): Feature;
144
81
  /**
145
- * Build a `Feature<Polygon>` for a donut (annular ring). The output has
146
- * two rings: an outer ring wound counter-clockwise and an inner ring
147
- * wound clockwise so the GeoJSON right-hand rule renders the hole.
82
+ * Build a `Feature<Polygon>` for a donut (annular ring).
148
83
  */
149
84
  createDonut(config: DonutConfig): Feature;
150
85
  /**
151
- * Pre-load the optional `milsymbol` peer dependency so subsequent calls
152
- * to `createMilSymbol` / `createMilSymbolSync` resolve immediately.
153
- * Idempotent multiple calls share the same promise.
86
+ * Pre-load the optional `milsymbol` peer dependency.
87
+ * Since resource() starts loading immediately, this simply returns a promise
88
+ * that resolves when the resource is ready.
154
89
  */
155
90
  preloadMilsymbol(): Promise<void>;
156
91
  /**
157
92
  * Build a MIL-STD-2525 symbol feature asynchronously.
158
- * Lazy-loads `milsymbol` on the first call.
93
+ * Waits for the milsymbol resource to resolve.
159
94
  */
160
95
  createMilSymbol(config: MilSymbolConfig): Promise<Feature>;
161
96
  /**
162
97
  * Build a MIL-STD-2525 symbol feature synchronously.
163
- * Throws if `milsymbol` has not been preloaded via `preloadMilsymbol()`
164
- * or a previous `createMilSymbol()` call.
98
+ * Throws if `milsymbol` resource is not ready.
165
99
  */
166
100
  createMilSymbolSync(config: MilSymbolConfig): Feature;
167
- /**
168
- * Project an `(dx, dy)` meter offset from `center` to lon/lat using a
169
- * local tangent-plane (equirectangular) approximation. Acceptable for
170
- * the radii typical in military symbology (<100 km from center).
171
- */
172
- private offsetMetersToLonLat;
173
101
  private nextId;
174
102
  private buildSymbolFeature;
175
103
  private symbolToStyleResult;
176
104
  private encodeBase64Utf8;
105
+ /**
106
+ * Generates a canvas and anchor for a MIL-STD-2525 symbol.
107
+ * Requires milsymbol to be loaded (synchronous).
108
+ */
109
+ createUnitStyle(sidc: string, selected?: boolean, size?: number): {
110
+ image: {
111
+ img: HTMLCanvasElement;
112
+ size: [number, number];
113
+ anchor: [number, number];
114
+ };
115
+ zIndex: number;
116
+ } | null;
177
117
  private assertSidc;
178
118
  private assertBrowser;
179
119
  static ɵfac: i0.ɵɵFactoryDeclaration<OlMilitaryService, never>;
180
120
  static ɵprov: i0.ɵɵInjectableDeclaration<OlMilitaryService>;
181
121
  }
182
122
 
123
+ /**
124
+ * Service providing styles and geometry generators for military tactical graphics
125
+ * such as battle fronts, axes of attack, and boundaries.
126
+ *
127
+ * NOTE: For point symbols (units), it delegates to {@link OlMilitaryService}
128
+ * for lazy-loading `milsymbol`.
129
+ */
130
+ declare class OlTacticalGraphicsService {
131
+ private idCounter;
132
+ private militaryService;
133
+ /**
134
+ * Creates a LineString feature representing a battle front.
135
+ */
136
+ createFrontLine(coordinates: Coordinate[], direction?: 'friendly' | 'hostile'): Feature;
137
+ /**
138
+ * Creates a LineString feature representing an attack arrow.
139
+ */
140
+ createAttackArrow(coordinates: Coordinate[], direction?: 'friendly' | 'hostile'): Feature;
141
+ /**
142
+ * Creates a Polygon feature representing a control zone.
143
+ */
144
+ createControlZone(coordinates: Coordinate[][], direction?: 'friendly' | 'hostile'): Feature;
145
+ /**
146
+ * Creates a Point feature representing a military unit.
147
+ * @param sidc - Symbol Identification Code (MIL-STD-2525 / APP-6)
148
+ */
149
+ createUnit(coordinate: Coordinate, sidc: string, name: string): Feature;
150
+ private nextId;
151
+ /**
152
+ * Style for Troop Units using milsymbol.
153
+ * NOTE: Requires milsymbol to be pre-loaded via OlMilitaryService.
154
+ */
155
+ createUnitStyle(sidc: string, selected?: boolean): Style | null;
156
+ /**
157
+ * Style for Battle Fronts (Complex LineString with teeth).
158
+ */
159
+ createFrontLineStyle(color: string, direction?: 'friendly' | 'hostile'): (feature: Feature$1, resolution: number) => Style[];
160
+ /**
161
+ * Style for Troop Movements (Arrows).
162
+ */
163
+ createAttackArrowStyle(color: string): (feature: Feature$1) => Style[];
164
+ /**
165
+ * Style for Control Zones (Polygons).
166
+ */
167
+ createZoneStyle(color: string, opacity?: number): Style;
168
+ private hexToRgba;
169
+ static ɵfac: i0.ɵɵFactoryDeclaration<OlTacticalGraphicsService, never>;
170
+ static ɵprov: i0.ɵɵInjectableDeclaration<OlTacticalGraphicsService>;
171
+ }
172
+
183
173
  declare function withMilitary(): OlFeature<'military'>;
184
174
  declare function provideMilitary(): OlFeature<'military'>;
185
175
 
186
- export { OlMilitaryService, provideMilitary, withMilitary };
187
- export type { DonutConfig, EllipseConfig, MilSymbolConfig, MilSymbolStyleResult, SectorConfig };
176
+ export { OlMilitaryService, OlTacticalGraphicsService, provideMilitary, withMilitary };
177
+ export type { MilSymbolConfig, MilSymbolStyleResult };