@angular-helpers/openlayers 0.3.0 → 0.5.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.
package/README.md CHANGED
@@ -10,12 +10,14 @@ A modern Angular wrapper for OpenLayers with modular architecture, standalone co
10
10
  - **Dual API** - Template for UI, Inputs for data, Services for operations
11
11
  - **Tree-shaking** - Unused OpenLayers code is eliminated from your bundle
12
12
  - **TypeScript First** - Full type safety with strict mode support
13
- - **Military Features** - Ellipses, sectors, NATO symbology, and MGRS coordinates
13
+ - **Military Features** - True geodesic precision for ellipses and sectors, NATO symbology, and MGRS coordinates
14
+ - **Proj4 Integration** - Declarative registration of local coordinate systems (like UTM)
15
+ - **WebGL Accelerated** - Mapbox Vector Tiles (MVT) and GPU raster expressions
14
16
 
15
17
  ## Installation
16
18
 
17
19
  ```bash
18
- npm install @angular-helpers/openlayers ol
20
+ pnpm add @angular-helpers/openlayers ol
19
21
  ```
20
22
 
21
23
  ## Quick Start
@@ -30,7 +32,14 @@ import { withLayers } from '@angular-helpers/openlayers/layers';
30
32
  import { withControls } from '@angular-helpers/openlayers/controls';
31
33
 
32
34
  export const appConfig: ApplicationConfig = {
33
- providers: [provideOpenLayers(withLayers(), withControls())],
35
+ providers: [
36
+ provideOpenLayers(
37
+ withLayers(),
38
+ withControls(),
39
+ // Optional: Register custom coordinate systems with proj4
40
+ // withProjections(proj4, [{ code: 'EPSG:32630', proj4def: '...', extent: [...] }])
41
+ ),
42
+ ],
34
43
  };
35
44
  ```
36
45
 
@@ -49,7 +58,6 @@ import { OlMapService } from '@angular-helpers/openlayers/core';
49
58
 
50
59
  @Component({
51
60
  selector: 'app-map',
52
- standalone: true,
53
61
  imports: [
54
62
  OlMapComponent,
55
63
  OlTileLayerComponent,
@@ -176,6 +184,94 @@ const handle = popups.openComponent({
176
184
 
177
185
  `open` is idempotent by `id` and updates the existing overlay in place. `openComponent` always recreates the `ComponentRef` on a repeated id and disposes the previous one (`appRef.detachView` + `ref.destroy`) to avoid CD leaks. Calls made before the map is ready are queued and replayed on `OlMapService.onReady`.
178
186
 
187
+ ## Military symbology
188
+
189
+ Available since `0.4.0` from `@angular-helpers/openlayers/military`.
190
+
191
+ Three pure-math geometry helpers (no extra deps) plus a NATO MIL-STD-2525 symbol helper backed by the optional [`milsymbol`](https://github.com/spatialillusions/milsymbol) peer dependency.
192
+
193
+ ```typescript
194
+ import { inject, signal } from '@angular/core';
195
+ import { OlMilitaryService } from '@angular-helpers/openlayers/military';
196
+ import type { Feature } from '@angular-helpers/openlayers/core';
197
+
198
+ @Component({
199
+ // …
200
+ imports: [OlMapComponent, OlVectorLayerComponent],
201
+ template: `
202
+ <ol-map [center]="[2.17, 41.38]" [zoom]="8">
203
+ <ol-tile-layer id="osm" source="osm" />
204
+ <ol-vector-layer id="military" [features]="features()" [zIndex]="10" />
205
+ </ol-map>
206
+ `,
207
+ })
208
+ export class MilDemo {
209
+ private ml = inject(OlMilitaryService);
210
+ features = signal<Feature[]>([]);
211
+
212
+ async ngOnInit() {
213
+ const ellipse = this.ml.createEllipse({
214
+ center: [2.17, 41.38],
215
+ semiMajor: 6_000,
216
+ semiMinor: 3_000,
217
+ rotation: Math.PI / 6,
218
+ });
219
+ const sector = this.ml.createSector({
220
+ center: [-0.38, 39.47],
221
+ radius: 8_000,
222
+ startAngle: Math.PI / 6,
223
+ endAngle: Math.PI / 2,
224
+ });
225
+ const donut = this.ml.createDonut({
226
+ center: [-5.99, 37.39],
227
+ innerRadius: 5_000,
228
+ outerRadius: 10_000,
229
+ });
230
+ const symbol = await this.ml.createMilSymbol({
231
+ sidc: 'SFGPUCI-----',
232
+ position: [-3.7, 40.42],
233
+ size: 36,
234
+ });
235
+ this.features.set([ellipse, sector, donut, symbol]);
236
+ }
237
+ }
238
+ ```
239
+
240
+ ### Geometry helpers
241
+
242
+ | Method | Output | Notes |
243
+ | ----------------------- | ------------------ | ---------------------------------------------------------------------------------------------------------------------- |
244
+ | `createEllipse(config)` | `Feature<Polygon>` | Optional `rotation` in radians, configurable `segments` (default 64) |
245
+ | `createSector(config)` | `Feature<Polygon>` | Pie-slice (apex-arc-apex). `startAngle < endAngle ≤ start + 2π` |
246
+ | `createDonut(config)` | `Feature<Polygon>` | Two rings: outer CCW, inner CW (right-hand rule). Renders as an annular band with the basemap visible through the hole |
247
+
248
+ Coordinates are emitted in `EPSG:4326` (lon/lat) using true geodesic calculations (`Vincenty`'s formulae via `ol/sphere`). This means your shapes remain mathematically accurate and visually consistent (without scale distortion) across massive global distances, fulfilling military precision requirements.
249
+
250
+ ### MIL-STD-2525 symbols
251
+
252
+ `createMilSymbol` lazy-loads `milsymbol` on first use and returns a `Feature<Point>` with style metadata (`feature.style.icon`) so the vector layer renders it as an `ol/style/Icon`. The library is declared as an **optional peer dependency** — install it only if you use this helper:
253
+
254
+ ```bash
255
+ pnpm add milsymbol
256
+ ```
257
+
258
+ ```ts
259
+ const symbol = await ml.createMilSymbol({
260
+ sidc: 'SFGPUCI-----', // friendly infantry, ground unit
261
+ position: [-3.7, 40.42],
262
+ size: 36,
263
+ uniqueDesignation: 'A1',
264
+ });
265
+ ```
266
+
267
+ Three flavors:
268
+
269
+ - **`createMilSymbol(config)`** — async; lazy-loads on first call.
270
+ - **`createMilSymbolSync(config)`** — sync; throws if `milsymbol` is not loaded yet.
271
+ - **`preloadMilsymbol()`** — fire-and-forget on app init to make the first symbol render synchronous.
272
+
273
+ The service throws clearly on non-browser environments (`createMilSymbol` requires `window`).
274
+
179
275
  ## Architecture
180
276
 
181
277
  ### Data vs UI Separation
@@ -206,8 +302,8 @@ import {
206
302
  withInteractions,
207
303
  } from '@angular-helpers/openlayers/interactions';
208
304
 
209
- // Add military features (~10KB additional)
210
- import { OlEllipseFeatureComponent, withMilitary } from '@angular-helpers/openlayers/military';
305
+ // Add military features pure-math helpers + lazy-loaded milsymbol
306
+ import { OlMilitaryService, withMilitary } from '@angular-helpers/openlayers/military';
211
307
  ```
212
308
 
213
309
  ## API Reference