aur-openlayers 0.0.3 → 1.0.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.
@@ -39,6 +39,28 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImpo
39
39
  ` }]
40
40
  }] });
41
41
 
42
+ /**
43
+ * Ошибка, выбрасываемая при нарушении уникальности id моделей слоя.
44
+ *
45
+ * Возникает при попытке:
46
+ * - добавить модель с уже существующим id;
47
+ * - передать в setModels массив с дублирующимися id.
48
+ */
49
+ class DuplicateModelIdError extends Error {
50
+ id;
51
+ layerId;
52
+ name = 'DuplicateModelIdError';
53
+ constructor(
54
+ /** Дублирующийся id. */
55
+ id,
56
+ /** Идентификатор слоя. */
57
+ layerId, message) {
58
+ super(message ?? `Model with id "${String(id)}" already exists on layer (${layerId}).`);
59
+ this.id = id;
60
+ this.layerId = layerId;
61
+ }
62
+ }
63
+
42
64
  class FlushScheduler {
43
65
  defaultPolicy;
44
66
  queue = new Map();
@@ -314,6 +336,54 @@ class InteractionManager {
314
336
  if (this.activeTranslates.has(entry.descriptor.id)) {
315
337
  continue;
316
338
  }
339
+ const modify = interactions?.modify;
340
+ if (modify && this.isEnabled(modify.enabled)) {
341
+ const { items: candidates } = this.hitTest({
342
+ layerId: entry.descriptor.id,
343
+ layer: entry.layer,
344
+ api: entry.api,
345
+ descriptor: entry.descriptor,
346
+ event,
347
+ hitTolerance: this.getHitTolerance(modify.hitTolerance),
348
+ });
349
+ if (candidates.length > 0) {
350
+ const modifyEvent = this.createModifyEvent(event, 'modifystart', candidates);
351
+ let target;
352
+ if (modify.pickTarget) {
353
+ target = modify.pickTarget({ candidates, ctx: this.ctx, event: modifyEvent });
354
+ }
355
+ else {
356
+ target = candidates[0];
357
+ }
358
+ if (target) {
359
+ const targetKey = entry.descriptor.feature.id(target.model);
360
+ const resolved = this.resolveTarget(entry, targetKey);
361
+ if (resolved) {
362
+ const active = {
363
+ targetKey,
364
+ lastItem: resolved,
365
+ moveThrottleMs: modify.moveThrottleMs ?? 0,
366
+ modify,
367
+ };
368
+ this.activeModifies.set(entry.descriptor.id, active);
369
+ this.lockDragPan();
370
+ if (modify.state) {
371
+ this.applyState([resolved], modify.state, true);
372
+ }
373
+ const handled = modify.onStart
374
+ ? this.isHandled(modify.onStart({ item: resolved, ctx: this.ctx, event: modifyEvent }))
375
+ : false;
376
+ active.lastHandled = handled;
377
+ if (handled && this.shouldStopPropagation(modify)) {
378
+ break;
379
+ }
380
+ }
381
+ }
382
+ }
383
+ }
384
+ if (this.activeModifies.has(entry.descriptor.id)) {
385
+ continue;
386
+ }
317
387
  }
318
388
  this.updateCursor(event);
319
389
  }
@@ -624,21 +694,27 @@ class InteractionManager {
624
694
  let needsPointerUp = false;
625
695
  this.schema.layers.forEach((descriptor) => {
626
696
  const state = this.enabledState.get(descriptor.id);
627
- if (state?.hover) {
697
+ const interactions = descriptor.feature.interactions;
698
+ const maybeHover = this.isMaybeEnabled(interactions?.hover?.enabled);
699
+ const maybeClick = this.isMaybeEnabled(interactions?.click?.enabled);
700
+ const maybeSelect = this.isMaybeEnabled(interactions?.select?.enabled);
701
+ const maybeDoubleClick = this.isMaybeEnabled(interactions?.doubleClick?.enabled);
702
+ const maybeTranslate = this.isMaybeEnabled(interactions?.translate?.enabled);
703
+ const maybeModify = this.isMaybeEnabled(interactions?.modify?.enabled);
704
+ if (state?.hover || maybeHover) {
628
705
  needsPointerMove = true;
629
706
  }
630
- if (state?.click || state?.select) {
707
+ if (state?.click || state?.select || maybeClick || maybeSelect) {
631
708
  needsSingleClick = true;
632
709
  }
633
- if (state?.doubleClick) {
710
+ if (state?.doubleClick || maybeDoubleClick) {
634
711
  needsDoubleClick = true;
635
712
  }
636
- if (state?.translate || state?.modify) {
713
+ if (state?.translate || state?.modify || maybeTranslate || maybeModify) {
637
714
  needsPointerDown = true;
638
715
  needsPointerDrag = true;
639
716
  needsPointerUp = true;
640
717
  }
641
- const interactions = descriptor.feature.interactions;
642
718
  if (interactions && this.hasCursorInteraction(interactions)) {
643
719
  needsPointerMove = true;
644
720
  }
@@ -759,7 +835,7 @@ class InteractionManager {
759
835
  interactions.translate,
760
836
  interactions.modify,
761
837
  ];
762
- return candidates.some((interaction) => interaction?.cursor && this.isEnabled(interaction.enabled));
838
+ return candidates.some((interaction) => interaction?.cursor && this.isMaybeEnabled(interaction.enabled));
763
839
  }
764
840
  toggleListener(type, enabled, handler) {
765
841
  if (enabled) {
@@ -1255,6 +1331,15 @@ class InteractionManager {
1255
1331
  }
1256
1332
  return enabled;
1257
1333
  }
1334
+ isMaybeEnabled(enabled) {
1335
+ if (enabled === undefined) {
1336
+ return true;
1337
+ }
1338
+ if (typeof enabled === 'function') {
1339
+ return true;
1340
+ }
1341
+ return enabled;
1342
+ }
1258
1343
  processHover(entry, hover, items, event) {
1259
1344
  const prev = this.hoverItems.get(entry.descriptor.id) ?? new Map();
1260
1345
  const next = this.itemsToMap(entry, items);
@@ -1313,15 +1398,9 @@ class InteractionManager {
1313
1398
  return handled;
1314
1399
  }
1315
1400
  processClick(entry, click, items, event) {
1316
- if (items.length === 0) {
1317
- return false;
1318
- }
1319
1401
  return this.isHandled(click.onClick({ items, ctx: this.ctx, event }));
1320
1402
  }
1321
1403
  processDoubleClick(entry, doubleClick, items, event) {
1322
- if (items.length === 0) {
1323
- return false;
1324
- }
1325
1404
  return this.isHandled(doubleClick.onDoubleClick({ items, ctx: this.ctx, event }));
1326
1405
  }
1327
1406
  itemsToMap(entry, items) {
@@ -1587,16 +1666,24 @@ class VectorLayerBase {
1587
1666
  registry = new FeatureRegistry();
1588
1667
  scheduleInvalidate;
1589
1668
  ctx;
1669
+ layerId;
1590
1670
  changeHandlers = new Set();
1671
+ collectionHandlers = new Set();
1672
+ models = [];
1591
1673
  constructor(options) {
1592
1674
  this.descriptor = options.descriptor.feature;
1593
1675
  this.layer = options.layer;
1594
1676
  this.source = options.source;
1595
1677
  this.ctx = options.ctx;
1596
1678
  this.scheduleInvalidate = options.scheduleInvalidate;
1679
+ this.layerId = options.descriptor.id;
1597
1680
  }
1598
1681
  setModels(models) {
1599
- this.setModelsInternal(models);
1682
+ this.assertUniqueIds(models);
1683
+ this.applyModelsUpdate({
1684
+ nextModels: models,
1685
+ reason: 'set',
1686
+ });
1600
1687
  }
1601
1688
  invalidate() {
1602
1689
  this.scheduleInvalidate();
@@ -1623,6 +1710,7 @@ class VectorLayerBase {
1623
1710
  }
1624
1711
  const reason = opts?.reason ?? 'mutate';
1625
1712
  this.registry.updateModel(id, next);
1713
+ this.replaceModelSnapshot(id, next);
1626
1714
  this.syncFeatureFromModel(next);
1627
1715
  this.scheduleInvalidate();
1628
1716
  if (!opts?.silent) {
@@ -1642,6 +1730,7 @@ class VectorLayerBase {
1642
1730
  return;
1643
1731
  }
1644
1732
  this.registry.updateModel(id, next);
1733
+ this.replaceModelSnapshot(id, next);
1645
1734
  this.syncFeatureFromModel(next);
1646
1735
  changes.push({ prev, next, reason });
1647
1736
  });
@@ -1657,6 +1746,66 @@ class VectorLayerBase {
1657
1746
  this.changeHandlers.add(cb);
1658
1747
  return () => this.changeHandlers.delete(cb);
1659
1748
  }
1749
+ onModelsCollectionChanged(cb) {
1750
+ this.collectionHandlers.add(cb);
1751
+ return () => this.collectionHandlers.delete(cb);
1752
+ }
1753
+ addModel(model) {
1754
+ this.addModels([model]);
1755
+ }
1756
+ addModels(models) {
1757
+ if (models.length === 0) {
1758
+ return;
1759
+ }
1760
+ const existingIds = new Set(this.models.map((item) => this.descriptor.id(item)));
1761
+ const batchIds = new Set();
1762
+ for (const model of models) {
1763
+ const id = this.descriptor.id(model);
1764
+ if (existingIds.has(id) || batchIds.has(id)) {
1765
+ this.throwDuplicateId(id);
1766
+ }
1767
+ batchIds.add(id);
1768
+ }
1769
+ this.applyModelsUpdate({
1770
+ nextModels: [...this.models, ...models],
1771
+ reason: 'add',
1772
+ added: models,
1773
+ });
1774
+ }
1775
+ removeModelsById(ids) {
1776
+ if (ids.length === 0 || this.models.length === 0) {
1777
+ return 0;
1778
+ }
1779
+ const idSet = new Set(ids);
1780
+ const removed = [];
1781
+ const nextModels = this.models.filter((model) => {
1782
+ const id = this.descriptor.id(model);
1783
+ if (idSet.has(id)) {
1784
+ removed.push(model);
1785
+ return false;
1786
+ }
1787
+ return true;
1788
+ });
1789
+ if (removed.length === 0) {
1790
+ return 0;
1791
+ }
1792
+ this.applyModelsUpdate({
1793
+ nextModels,
1794
+ reason: 'remove',
1795
+ removed,
1796
+ });
1797
+ return removed.length;
1798
+ }
1799
+ clear() {
1800
+ if (this.models.length === 0) {
1801
+ return;
1802
+ }
1803
+ this.applyModelsUpdate({
1804
+ nextModels: [],
1805
+ reason: 'clear',
1806
+ removed: [...this.models],
1807
+ });
1808
+ }
1660
1809
  /** Fit view to all features on the layer. No-op if extent is empty. */
1661
1810
  centerOnAllModels(opts) {
1662
1811
  const current = this.getCenterOnAllModelsSource();
@@ -1720,19 +1869,10 @@ class VectorLayerBase {
1720
1869
  return this.registry.getFeature(id) != null;
1721
1870
  }
1722
1871
  getAllModels() {
1723
- const out = [];
1724
- this.registry.forEachId((id) => {
1725
- const model = this.registry.getModel(id);
1726
- if (model !== undefined) {
1727
- out.push(model);
1728
- }
1729
- });
1730
- return out;
1872
+ return [...this.models];
1731
1873
  }
1732
1874
  getAllModelIds() {
1733
- const out = [];
1734
- this.registry.forEachId((id) => out.push(id));
1735
- return out;
1875
+ return this.models.map((model) => this.descriptor.id(model));
1736
1876
  }
1737
1877
  setFeatureStates(ids, states) {
1738
1878
  const targetIds = Array.isArray(ids) ? ids : [ids];
@@ -1789,6 +1929,43 @@ class VectorLayerBase {
1789
1929
  }
1790
1930
  this.changeHandlers.forEach((handler) => handler(changes));
1791
1931
  }
1932
+ emitCollectionChange(event) {
1933
+ this.collectionHandlers.forEach((handler) => handler(event));
1934
+ }
1935
+ assertUniqueIds(models) {
1936
+ const ids = new Set();
1937
+ for (const model of models) {
1938
+ const id = this.descriptor.id(model);
1939
+ if (ids.has(id)) {
1940
+ this.throwDuplicateId(id);
1941
+ }
1942
+ ids.add(id);
1943
+ }
1944
+ }
1945
+ throwDuplicateId(id) {
1946
+ throw new DuplicateModelIdError(id, this.layerId);
1947
+ }
1948
+ applyModelsUpdate(args) {
1949
+ const prevSnapshot = [...this.models];
1950
+ const internalNext = [...args.nextModels];
1951
+ this.models = internalNext;
1952
+ this.setModelsInternal(this.models);
1953
+ const nextSnapshot = [...internalNext];
1954
+ this.emitCollectionChange({
1955
+ prev: prevSnapshot,
1956
+ next: nextSnapshot,
1957
+ reason: args.reason,
1958
+ added: args.added ? [...args.added] : undefined,
1959
+ removed: args.removed ? [...args.removed] : undefined,
1960
+ });
1961
+ }
1962
+ replaceModelSnapshot(id, model) {
1963
+ const index = this.models.findIndex((item) => this.descriptor.id(item) === id);
1964
+ if (index === -1) {
1965
+ return;
1966
+ }
1967
+ this.models[index] = model;
1968
+ }
1792
1969
  }
1793
1970
 
1794
1971
  class ClusteredVectorLayer extends VectorLayerBase {
@@ -2120,5 +2297,5 @@ class LayerManager {
2120
2297
  * Generated bundle index. Do not edit.
2121
2298
  */
2122
2299
 
2123
- export { LayerManager, LibComponent, LibService };
2300
+ export { DuplicateModelIdError, LayerManager, LibComponent, LibService };
2124
2301
  //# sourceMappingURL=aur-openlayers.mjs.map