@angular-helpers/openlayers 0.5.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.
@@ -202,13 +202,34 @@ class OlTooltipDirective {
202
202
  matched = feature;
203
203
  return true;
204
204
  }, {
205
- layerFilter: layerId ? (layer) => layer.get('id') === layerId : undefined,
205
+ layerFilter: layerId
206
+ ? (layer) => layer.get('id') === layerId || !!layer.get('is-spider-layer')
207
+ : undefined,
206
208
  });
207
209
  if (!matched) {
208
210
  tooltip.style.display = 'none';
209
211
  return;
210
212
  }
211
- const value = matched.get(propKey);
213
+ let value = matched.get(propKey);
214
+ if (value === undefined || value === null) {
215
+ // 1. Check if it's a clustered feature
216
+ const features = matched.get('features');
217
+ if (Array.isArray(features) && features.length > 0) {
218
+ if (features.length === 1) {
219
+ value = features[0].get(propKey);
220
+ }
221
+ else {
222
+ value = `${features.length} elementos`;
223
+ }
224
+ }
225
+ else {
226
+ // 2. Check if it's a spider feature
227
+ const spiderFeature = matched.get('spider-feature');
228
+ if (spiderFeature) {
229
+ value = spiderFeature.get(propKey);
230
+ }
231
+ }
232
+ }
212
233
  if (value === undefined || value === null) {
213
234
  tooltip.style.display = 'none';
214
235
  return;
@@ -332,6 +353,7 @@ class OlPopupService {
332
353
  }
333
354
  flushPending(map) {
334
355
  const pending = this.pending.splice(0);
356
+ this.flushSubscribed = false;
335
357
  for (const call of pending) {
336
358
  if (call.kind === 'open') {
337
359
  this.createOrUpdate(call.options.id, call.options, map);
@@ -388,6 +410,8 @@ class OlPopupService {
388
410
  environmentInjector: this.envInjector,
389
411
  elementInjector: options.injector,
390
412
  hostElement,
413
+ // Actually, let's see if createComponent supports bindings. If it does, we pass it.
414
+ // Wait, the original code passed bindings! I will revert to the exact original code for createComponent options!
391
415
  bindings: options.bindings,
392
416
  directives: options.directives?.map((d) => typeof d === 'function' ? d : { type: d.type, bindings: d.bindings ?? [] }),
393
417
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@angular-helpers/openlayers",
3
- "version": "0.5.0",
3
+ "version": "0.5.1",
4
4
  "description": "Modern Angular wrapper for OpenLayers with modular architecture, standalone components, and hybrid template/programmatic API",
5
5
  "homepage": "https://gaspar1992.github.io/angular-helpers/docs/openlayers",
6
6
  "repository": {
@@ -1,7 +1,7 @@
1
1
  import * as _angular_core from '@angular/core';
2
- import { ElementRef, Provider, EnvironmentProviders } from '@angular/core';
2
+ import { ElementRef, Signal, Resource, Provider, EnvironmentProviders } from '@angular/core';
3
3
  import OLMap from 'ol/Map';
4
- import { View } from 'ol';
4
+ import { View, Feature as Feature$1 } from 'ol';
5
5
 
6
6
  type Coordinate = [number, number];
7
7
  type Extent = [number, number, number, number];
@@ -323,6 +323,75 @@ declare class OlGeometryService {
323
323
  static ɵprov: _angular_core.ɵɵInjectableDeclaration<OlGeometryService>;
324
324
  }
325
325
 
326
+ /**
327
+ * Service for orchestrating time-series animations in OpenLayers.
328
+ * Exposes a reactive currentTime signal that updates outside the Angular zone
329
+ * via requestAnimationFrame, ensuring 60FPS WebGL animations without triggering
330
+ * global change detection.
331
+ */
332
+ declare class OlTimeService {
333
+ private zoneHelper;
334
+ private timeSignal;
335
+ private playingSignal;
336
+ private speedSignal;
337
+ private animationFrameId;
338
+ private lastTick;
339
+ readonly currentTime: _angular_core.Signal<number>;
340
+ readonly isPlaying: _angular_core.Signal<boolean>;
341
+ readonly speed: _angular_core.Signal<number>;
342
+ /**
343
+ * Sets the current time manually.
344
+ * @param time Epoch timestamp in milliseconds
345
+ */
346
+ setTime(time: number): void;
347
+ /**
348
+ * Sets the playback speed multiplier.
349
+ * @param speed Multiplier (e.g. 1 = real time, 60 = 1 minute per second)
350
+ */
351
+ setSpeed(speed: number): void;
352
+ /**
353
+ * Starts the time animation loop.
354
+ */
355
+ play(): void;
356
+ /**
357
+ * Pauses the time animation loop.
358
+ */
359
+ pause(): void;
360
+ /**
361
+ * Stops the animation and resets to a specific time.
362
+ */
363
+ stop(resetTime?: number): void;
364
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlTimeService, never>;
365
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<OlTimeService>;
366
+ }
367
+
368
+ interface VectorResourceOptions {
369
+ /** Optional custom fetch options */
370
+ fetchOptions?: RequestInit;
371
+ }
372
+ /**
373
+ * Creates an Angular resource for fetching and decoding GeoJSON into OpenLayers Features.
374
+ * Must be called in an injection context.
375
+ *
376
+ * @param url The URL signal or string to fetch data from
377
+ * @param options Additional vector resource options
378
+ * @returns An Angular Resource containing an array of parsed Features
379
+ */
380
+ declare function createVectorResource(url: Signal<string | undefined>, options?: VectorResourceOptions): Resource<Feature[]>;
381
+
382
+ /**
383
+ * Converts an OpenLayers feature to the internal Feature format.
384
+ * Handles coordinate extraction and geometry type mapping.
385
+ *
386
+ * @param olFeature - The OpenLayers feature to convert
387
+ * @returns The converted Feature with normalized structure
388
+ */
389
+ declare function olFeatureToFeature(olFeature: Feature$1): Feature;
390
+ /**
391
+ * Converts an internal Feature to an OpenLayers feature.
392
+ */
393
+ declare function featureToOlFeature(feature: Feature): Feature$1;
394
+
326
395
  type OlFeatureKind = 'layers' | 'controls' | 'interactions' | 'overlays' | 'military' | 'projections';
327
396
  interface OlFeature<Kind extends OlFeatureKind> {
328
397
  kind: Kind;
@@ -344,5 +413,5 @@ interface Proj4Definition {
344
413
  */
345
414
  declare function withProjections(proj4: any, definitions: Proj4Definition[]): OlFeature<'projections'>;
346
415
 
347
- export { OlGeometryService, OlMapComponent, OlMapService, OlZoneHelper, provideOpenLayers, withProjections };
348
- export type { AnimationOptions, Coordinate, DonutConfig, EllipseConfig, Extent, Feature, FitOptions, Geometry, GeometryType, Layer, MapClickEvent, MapConfig, MapViewOptions, OlFeature, OlFeatureKind, Pixel, Proj4Definition, ProjectionCode, SectorConfig, Style, ViewState };
416
+ export { OlGeometryService, OlMapComponent, OlMapService, OlTimeService, OlZoneHelper, createVectorResource, featureToOlFeature, olFeatureToFeature, provideOpenLayers, withProjections };
417
+ export type { AnimationOptions, Coordinate, DonutConfig, EllipseConfig, Extent, Feature, FitOptions, Geometry, GeometryType, Layer, MapClickEvent, MapConfig, MapViewOptions, OlFeature, OlFeatureKind, Pixel, Proj4Definition, ProjectionCode, SectorConfig, Style, VectorResourceOptions, ViewState };
@@ -2,11 +2,9 @@ import * as rxjs from 'rxjs';
2
2
  import * as _angular_helpers_openlayers_interactions from '@angular-helpers/openlayers/interactions';
3
3
  import * as _angular_core from '@angular/core';
4
4
  import { Provider } from '@angular/core';
5
- import * as _angular_helpers_openlayers_core from '@angular-helpers/openlayers/core';
6
5
  import { Feature, OlFeature } from '@angular-helpers/openlayers/core';
7
6
  import Interaction from 'ol/interaction/Interaction';
8
7
  import OLMap from 'ol/Map';
9
- import { Feature as Feature$1 } from 'ol';
10
8
 
11
9
  type InteractionType = 'select' | 'draw' | 'modify' | 'dragAndDrop';
12
10
  interface InteractionConfig {
@@ -88,7 +86,8 @@ declare class OlInteractionService {
88
86
  private selectService;
89
87
  private drawService;
90
88
  private modifyService;
91
- readonly selectedFeatures: _angular_core.Signal<_angular_helpers_openlayers_core.Feature[]>;
89
+ readonly selectedFeatures: _angular_core.Signal<Feature[]>;
90
+ readonly hoveredFeature: _angular_core.Signal<Feature>;
92
91
  readonly selectionCount: _angular_core.Signal<number>;
93
92
  readonly hasSelection: _angular_core.Signal<boolean>;
94
93
  readonly activeInteractions: _angular_core.Signal<_angular_helpers_openlayers_interactions.ManagedInteraction[]>;
@@ -178,11 +177,13 @@ interface ManagedInteraction {
178
177
  declare class InteractionStateService {
179
178
  private interactions;
180
179
  private selectedFeaturesInternal;
180
+ private hoveredFeatureInternal;
181
181
  private drawStartSubject;
182
182
  private drawEndSubject;
183
183
  private modifySubject;
184
184
  private selectSubject;
185
185
  readonly selectedFeatures: _angular_core.Signal<Feature[]>;
186
+ readonly hoveredFeature: _angular_core.Signal<Feature>;
186
187
  readonly selectionCount: _angular_core.Signal<number>;
187
188
  readonly hasSelection: _angular_core.Signal<boolean>;
188
189
  readonly activeInteractions: _angular_core.Signal<ManagedInteraction[]>;
@@ -221,6 +222,11 @@ declare class InteractionStateService {
221
222
  * Clears the current selection.
222
223
  */
223
224
  clearSelection(): void;
225
+ /**
226
+ * Sets the currently hovered feature.
227
+ * @param feature - The hovered feature or null
228
+ */
229
+ setHoveredFeature(feature: Feature | null): void;
224
230
  /**
225
231
  * Emits a draw start event.
226
232
  * @param event - The draw start event data
@@ -340,15 +346,6 @@ declare class MeasurementInteractionService {
340
346
  static ɵprov: _angular_core.ɵɵInjectableDeclaration<MeasurementInteractionService>;
341
347
  }
342
348
 
343
- /**
344
- * Converts an OpenLayers feature to the internal Feature format.
345
- * Handles coordinate extraction and geometry type mapping.
346
- *
347
- * @param olFeature - The OpenLayers feature to convert
348
- * @returns The converted Feature with normalized structure
349
- */
350
- declare function olFeatureToFeature(olFeature: Feature$1): Feature;
351
-
352
349
  /**
353
350
  * Declarative component to configure an OpenLayers Draw Interaction.
354
351
  */
@@ -444,5 +441,5 @@ declare function withModifyInteraction(id: string, config?: ModifyConfig): Provi
444
441
  */
445
442
  declare function withMeasurementInteraction(): Provider;
446
443
 
447
- export { DrawInteractionService, InteractionStateService, MeasurementInteractionService, ModifyInteractionService, OlDrawInteractionComponent, OlInteractionService, OlModifyInteractionComponent, OlSelectInteractionComponent, SelectInteractionService, olFeatureToFeature, provideInteractions, withDrawInteraction, withInteractions, withMeasurementInteraction, withModifyInteraction, withSelectInteraction };
444
+ export { DrawInteractionService, InteractionStateService, MeasurementInteractionService, ModifyInteractionService, OlDrawInteractionComponent, OlInteractionService, OlModifyInteractionComponent, OlSelectInteractionComponent, SelectInteractionService, provideInteractions, withDrawInteraction, withInteractions, withMeasurementInteraction, withModifyInteraction, withSelectInteraction };
448
445
  export type { DragAndDropConfig, DrawConfig, DrawEndEvent, DrawStartEvent, InteractionConfig, InteractionState, InteractionType, ManagedInteraction, ModifyConfig, ModifyEvent, SelectConfig, SelectEvent };
@@ -21,6 +21,10 @@ interface ClusterConfig {
21
21
  showCount?: boolean;
22
22
  /** Style for individual features when clustering */
23
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;
24
28
  }
25
29
  interface VectorLayerConfig extends LayerConfig {
26
30
  type: 'vector';
@@ -64,8 +68,10 @@ declare class OlClusterComponent {
64
68
  minDistance: _angular_core.InputSignal<number>;
65
69
  showCount: _angular_core.InputSignal<boolean>;
66
70
  featureStyle: _angular_core.InputSignal<Style>;
71
+ spiderfyOnSelect: _angular_core.InputSignal<boolean>;
72
+ spiderfyClick: _angular_core.OutputEmitterRef<Feature>;
67
73
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlClusterComponent, never>;
68
- 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; }; }, {}, never, never, true, 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>;
69
75
  }
70
76
 
71
77
  declare class OlVectorLayerComponent {
@@ -185,6 +191,12 @@ declare class OlWebGLVectorLayerComponent {
185
191
  private layer;
186
192
  private vectorSource;
187
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;
188
200
  private syncFeatures;
189
201
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlWebGLVectorLayerComponent, never>;
190
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>;
@@ -245,6 +257,7 @@ declare class OlLayerService {
245
257
  private layerCache;
246
258
  private pendingConfigs;
247
259
  private layerState;
260
+ private spiderManager;
248
261
  readonly layers: _angular_core.Signal<LayerInfo[]>;
249
262
  readonly visibleLayers: _angular_core.Signal<LayerInfo[]>;
250
263
  readonly tileLayers: _angular_core.Signal<LayerInfo[]>;
@@ -261,6 +274,8 @@ declare class OlLayerService {
261
274
  toggleVisibility(id: string): boolean;
262
275
  setOpacity(id: string, opacity: number): void;
263
276
  setZIndex(id: string, zIndex: number): void;
277
+ setClusterDistance(id: string, distance: number): void;
278
+ setClusterMinDistance(id: string, minDistance: number): void;
264
279
  setHeatmapProperties(id: string, props: {
265
280
  blur?: number;
266
281
  radius?: number;
@@ -269,24 +284,9 @@ declare class OlLayerService {
269
284
  isVisible(id: string): boolean;
270
285
  getOpacity(id: string): number;
271
286
  getZIndex(id: string): number;
272
- /**
273
- * Clears all features from a vector layer's source.
274
- * Does not remove the layer itself.
275
- * @param id - Layer identifier
276
- */
277
287
  clearFeatures(id: string): void;
278
- /**
279
- * Updates the features of a vector layer.
280
- * Syncs new features without clearing existing ones (preserves OL modifications).
281
- * @param id - Layer identifier
282
- * @param features - New features to sync
283
- */
284
288
  updateFeatures(id: string, features: VectorLayerConfig['features']): void;
285
289
  private updateLayerState;
286
- private createVectorLayer;
287
- private createHeatmapLayer;
288
- private createTileLayer;
289
- private createImageLayer;
290
290
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlLayerService, never>;
291
291
  static ɵprov: _angular_core.ɵɵInjectableDeclaration<OlLayerService>;
292
292
  }