@jupytergis/schema 0.15.0 → 0.16.0-alpha.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.
Files changed (77) hide show
  1. package/lib/_interface/forms.json +7816 -555
  2. package/lib/_interface/processing/clipRasterByExtent.d.ts +39 -0
  3. package/lib/_interface/processing/clipRasterByVector.d.ts +32 -0
  4. package/lib/_interface/processing/clipVectorByMaskLayer.d.ts +28 -0
  5. package/lib/_interface/processing/rasterize.d.ts +42 -0
  6. package/lib/_interface/project/jgis.d.ts +20 -5
  7. package/lib/_interface/project/layers/geoTiffLayer.d.ts +351 -0
  8. package/lib/_interface/project/layers/{heatmapLayer.d.ts → openeoTileLayer.d.ts} +2 -19
  9. package/lib/_interface/project/layers/storySegmentLayer.d.ts +6 -0
  10. package/lib/_interface/project/layers/vectorLayer.d.ts +599 -5
  11. package/lib/_interface/project/layers/vectorTileLayer.d.ts +566 -2
  12. package/lib/_interface/project/sources/geoJsonSource.d.ts +8 -0
  13. package/lib/_interface/project/sources/geoPackageRasterSource.d.ts +36 -0
  14. package/lib/_interface/project/sources/geoPackageVectorSource.d.ts +28 -0
  15. package/lib/_interface/project/sources/geoParquetSource.d.ts +8 -0
  16. package/lib/_interface/project/sources/geoTiffSource.d.ts +8 -0
  17. package/lib/_interface/project/sources/imageSource.d.ts +8 -0
  18. package/lib/_interface/project/sources/openeoTileSource.d.ts +26 -0
  19. package/lib/_interface/project/sources/rasterDemSource.d.ts +8 -0
  20. package/lib/_interface/project/sources/rasterSource.d.ts +8 -0
  21. package/lib/_interface/project/sources/shapefileSource.d.ts +8 -0
  22. package/lib/_interface/project/sources/vectorTileSource.d.ts +8 -0
  23. package/lib/_interface/project/sources/videoSource.d.ts +8 -0
  24. package/lib/_interface/project/sources/wmsTileSource.d.ts +8 -0
  25. package/lib/_interface/project/symbology.d.ts +305 -0
  26. package/lib/_interface/version.d.ts +1 -1
  27. package/lib/_interface/version.js +1 -1
  28. package/lib/doc.d.ts +9 -3
  29. package/lib/doc.js +47 -4
  30. package/lib/grammar/grammarConversions.d.ts +50 -0
  31. package/lib/grammar/grammarConversions.js +137 -0
  32. package/lib/index.d.ts +4 -0
  33. package/lib/index.js +2 -0
  34. package/lib/interfaces.d.ts +88 -20
  35. package/lib/interfaces.js +10 -1
  36. package/lib/migrations/index.d.ts +16 -0
  37. package/lib/migrations/index.js +52 -0
  38. package/lib/migrations/v0_5_to_v0_6.d.ts +11 -0
  39. package/lib/migrations/v0_5_to_v0_6.js +154 -0
  40. package/lib/model.d.ts +49 -13
  41. package/lib/model.js +212 -21
  42. package/lib/processing/ProcessingMerge.d.ts +4 -0
  43. package/lib/processing/ProcessingMerge.js +4 -0
  44. package/lib/processing/_generated/exportProcessingSchema.d.ts +8 -4
  45. package/lib/processing/_generated/exportProcessingSchema.js +8 -4
  46. package/lib/processing/_generated/processingType.d.ts +1 -1
  47. package/lib/processing/_generated/processingType.js +8 -4
  48. package/lib/processing/_generated/processing_merge.json +84 -29
  49. package/lib/schema/processing/clipRasterByExtent.json +39 -0
  50. package/lib/schema/processing/clipRasterByVector.json +33 -0
  51. package/lib/schema/processing/clipVectorByMaskLayer.json +27 -0
  52. package/lib/schema/processing/rasterize.json +45 -0
  53. package/lib/schema/project/jgis.json +34 -6
  54. package/lib/schema/project/layers/{webGlLayer.json → geoTiffLayer.json} +9 -3
  55. package/lib/schema/project/layers/openeoTileLayer.json +21 -0
  56. package/lib/schema/project/layers/storySegmentLayer.json +14 -3
  57. package/lib/schema/project/layers/vectorLayer.json +73 -14
  58. package/lib/schema/project/layers/vectorTileLayer.json +14 -10
  59. package/lib/schema/project/sources/geoJsonSource.json +13 -0
  60. package/lib/schema/project/sources/geoPackageRasterSource.json +45 -0
  61. package/lib/schema/project/sources/geoPackageVectorSource.json +29 -0
  62. package/lib/schema/project/sources/geoParquetSource.json +13 -0
  63. package/lib/schema/project/sources/geoTiffSource.json +13 -0
  64. package/lib/schema/project/sources/imageSource.json +13 -0
  65. package/lib/schema/project/sources/openeoTileSource.json +23 -0
  66. package/lib/schema/project/sources/rasterDemSource.json +13 -0
  67. package/lib/schema/project/sources/rasterSource.json +13 -0
  68. package/lib/schema/project/sources/shapefileSource.json +13 -0
  69. package/lib/schema/project/sources/vectorTileSource.json +13 -0
  70. package/lib/schema/project/sources/videoSource.json +13 -0
  71. package/lib/schema/project/sources/wmsTileSource.json +13 -0
  72. package/lib/schema/project/symbology.json +418 -0
  73. package/lib/types.d.ts +15 -2
  74. package/lib/types.js +7 -2
  75. package/package.json +2 -1
  76. package/lib/_interface/project/layers/webGlLayer.d.ts +0 -39
  77. package/lib/schema/project/layers/heatmapLayer.json +0 -54
package/lib/model.d.ts CHANGED
@@ -7,8 +7,8 @@ import { PartialJSONObject } from '@lumino/coreutils';
7
7
  import { ISignal, Signal } from '@lumino/signaling';
8
8
  import { FeatureLike } from 'ol/Feature';
9
9
  import { IJGISContent, IJGISLayer, IJGISLayerGroup, IJGISLayerTree, IJGISLayers, IJGISOptions, IJGISSource, IJGISSources, IJGISStoryMap } from './_interface/project/jgis';
10
- import { IAnnotationModel, IDict, IJGISLayerDocChange, IJGISLayerTreeDocChange, IJGISSourceDocChange, IJupyterGISClientState, IJupyterGISDoc, IJupyterGISModel, ISelection, IUserData, IViewPortState, JgisCoordinates, Pointer, IJupyterGISSettings, SelectionType } from './interfaces';
11
- import { Modes } from './types';
10
+ import { IAwarenessFieldChange, IAnnotationModel, IIdentifiedFeatures, IJGISLayerDocChange, IJGISLayerTreeDocChange, IJGISSourceDocChange, IJGISUIState, IJupyterGISClientState, IJupyterGISDoc, IJupyterGISModel, ISelection, IStorySegmentRef, IUserData, IViewPortState, JgisCoordinates, Pointer, IJupyterGISSettings, SelectionType } from './interfaces';
11
+ import { IViewState, Modes } from './types';
12
12
  export declare class JupyterGISModel implements IJupyterGISModel {
13
13
  constructor(options: JupyterGISModel.IOptions);
14
14
  /**
@@ -48,7 +48,12 @@ export declare class JupyterGISModel implements IJupyterGISModel {
48
48
  get readOnly(): boolean;
49
49
  set readOnly(value: boolean);
50
50
  get localState(): IJupyterGISClientState | null;
51
- get clientStateChanged(): ISignal<this, Map<number, IJupyterGISClientState>>;
51
+ get selectedChanged(): ISignal<this, IAwarenessFieldChange<IJupyterGISClientState['selected']>>;
52
+ get pointerChanged(): ISignal<this, IAwarenessFieldChange<IJupyterGISClientState['pointer']>>;
53
+ get viewportStateChanged(): ISignal<this, IAwarenessFieldChange<IJupyterGISClientState['viewportState']>>;
54
+ get identifiedFeaturesChanged(): ISignal<this, IAwarenessFieldChange<IJupyterGISClientState['identifiedFeatures']>>;
55
+ get remoteUserChanged(): ISignal<this, IAwarenessFieldChange<IJupyterGISClientState['remoteUser']>>;
56
+ get temporalControllerActiveChanged(): ISignal<this, IAwarenessFieldChange<IJupyterGISClientState['isTemporalControllerActive']>>;
52
57
  get sharedOptionsChanged(): ISignal<IJupyterGISDoc, MapChange>;
53
58
  get sharedLayersChanged(): ISignal<IJupyterGISDoc, IJGISLayerDocChange>;
54
59
  get sharedLayerTreeChanged(): ISignal<IJupyterGISDoc, IJGISLayerTreeDocChange>;
@@ -72,7 +77,9 @@ export declare class JupyterGISModel implements IJupyterGISModel {
72
77
  readonly flyToGeometrySignal: Signal<this, any>;
73
78
  readonly highlightFeatureSignal: Signal<this, any>;
74
79
  readonly updateBboxSignal: Signal<this, any>;
80
+ readonly editingVectorLayerChanged: Signal<this, boolean>;
75
81
  getContent(): IJGISContent;
82
+ getViewState(): IViewState;
76
83
  /**
77
84
  * Getter for the contents manager.
78
85
  */
@@ -94,6 +101,7 @@ export declare class JupyterGISModel implements IJupyterGISModel {
94
101
  getSources(): IJGISSources;
95
102
  getLayerTree(): IJGISLayerTree;
96
103
  getLayer(id: string): IJGISLayer | undefined;
104
+ getExtent(id: string): number[] | undefined;
97
105
  getLayerOrSource(id: string): IJGISLayer | IJGISSource | undefined;
98
106
  getSource(id: string): IJGISSource | undefined;
99
107
  /**
@@ -124,6 +132,10 @@ export declare class JupyterGISModel implements IJupyterGISModel {
124
132
  * from root of layer tree.
125
133
  */
126
134
  addLayer(id: string, layer: IJGISLayer, groupName?: string, position?: number): void;
135
+ /**
136
+ * Update layer's extent and zoom in model's view state
137
+ */
138
+ updateLayerViewState(id: string, view: IViewState[string]): void;
127
139
  removeLayer(layer_id: string): void;
128
140
  removeSource(sourceId: string): void;
129
141
  setOptions(value: IJGISOptions): void;
@@ -133,13 +145,14 @@ export declare class JupyterGISModel implements IJupyterGISModel {
133
145
  syncSelected(value: {
134
146
  [key: string]: ISelection;
135
147
  }, emitter?: string): void;
148
+ syncLastAddedLayer(layerId: string): void;
136
149
  get selected(): {
137
150
  [key: string]: ISelection;
138
151
  } | undefined;
139
152
  set selected(value: {
140
153
  [key: string]: ISelection;
141
154
  } | undefined);
142
- syncIdentifiedFeatures(features: IDict<any>, emitter?: string): void;
155
+ syncIdentifiedFeatures(features: IIdentifiedFeatures, emitter?: string): void;
143
156
  setUserToFollow(userId?: number): void;
144
157
  setEditingItem(type: SelectionType, itemId: string): void;
145
158
  clearEditingItem(): void;
@@ -180,14 +193,17 @@ export declare class JupyterGISModel implements IJupyterGISModel {
180
193
  * Adds a story segment from the current map view
181
194
  * @returns Object with storySegmentId and storyMapId, or null if no extent/zoom found
182
195
  */
183
- addStorySegment(): {
184
- storySegmentId: string;
185
- storyId: string;
186
- } | null;
187
- get segmentAdded(): ISignal<this, {
188
- storySegmentId: string;
189
- storyId: string;
190
- }>;
196
+ addStorySegment(viewState?: IViewState[string]): IStorySegmentRef | null;
197
+ /**
198
+ * Generates a name for the next story segment based on the number of existing segments in the current story.
199
+ */
200
+ private _generateStorySegmentName;
201
+ /**
202
+ * Adds a story segment from a layer
203
+ * @returns Object with storySegmentId and storyMapId, or null if no extent/zoom found
204
+ */
205
+ createStorySegmentFromLayer(layerId: string): IStorySegmentRef | null;
206
+ get segmentAdded(): ISignal<this, IStorySegmentRef>;
191
207
  /**
192
208
  * Add an item in the layer tree.
193
209
  *
@@ -216,13 +232,21 @@ export declare class JupyterGISModel implements IJupyterGISModel {
216
232
  toggleMode(mode: Modes): void;
217
233
  get currentMode(): Modes;
218
234
  set currentMode(value: Modes);
235
+ setUIState(value: Partial<IJGISUIState>): void;
236
+ getUIState(): IJGISUIState;
237
+ get uiStateChanged(): ISignal<this, IJGISUIState>;
219
238
  toggleTemporalController(): void;
220
239
  private _getLayerTreeInfo;
221
240
  private _onClientStateChanged;
241
+ private _emitAwarenessFieldDeltas;
222
242
  addFeatureAsMs: (id: string, selectedFeature: string) => void;
223
243
  get addFeatureAsMsSignal(): Signal<this, string>;
224
244
  get updateLayerSignal(): Signal<this, string>;
225
245
  triggerLayerUpdate: (layerId: string, layer: IJGISLayer | IJGISSource) => void;
246
+ checkIfIsADrawVectorLayer(layer: IJGISLayer): boolean;
247
+ updateEditingVectorLayer(): void;
248
+ get editingVectorLayer(): boolean;
249
+ set editingVectorLayer(editingVectorLayer: boolean);
226
250
  get geolocation(): JgisCoordinates;
227
251
  set geolocation(geolocation: JgisCoordinates);
228
252
  get geolocationChanged(): Signal<this, JgisCoordinates>;
@@ -230,6 +254,8 @@ export declare class JupyterGISModel implements IJupyterGISModel {
230
254
  readonly defaultKernelLanguage: string;
231
255
  readonly annotationModel?: IAnnotationModel;
232
256
  readonly settingRegistry?: ISettingRegistry;
257
+ settingsReady: Promise<void>;
258
+ private _settingsReadyResolve;
233
259
  private _settings;
234
260
  private _settingsChanged;
235
261
  private _jgisSettings;
@@ -243,11 +269,18 @@ export declare class JupyterGISModel implements IJupyterGISModel {
243
269
  private _userChanged;
244
270
  private _usersMap?;
245
271
  private _pathChanged;
272
+ private _viewState;
246
273
  private _disposed;
247
274
  private _contentChanged;
248
275
  private _stateChanged;
249
276
  private _themeChanged;
250
- private _clientStateChanged;
277
+ private _selectedChanged;
278
+ private _pointerChanged;
279
+ private _viewportStateChanged;
280
+ private _identifiedFeaturesChanged;
281
+ private _remoteUserChanged;
282
+ private _temporalControllerActiveChanged;
283
+ private _previousClientStates;
251
284
  private _sharedMetadataChanged;
252
285
  private _zoomToPositionSignal;
253
286
  private _addFeatureAsMsSignal;
@@ -256,6 +289,7 @@ export declare class JupyterGISModel implements IJupyterGISModel {
256
289
  private _isTemporalControllerActive;
257
290
  private _editing;
258
291
  private _editingChanged;
292
+ private _editingVectorLayer;
259
293
  static worker: Worker;
260
294
  private _geolocation;
261
295
  private _geolocationChanged;
@@ -263,6 +297,8 @@ export declare class JupyterGISModel implements IJupyterGISModel {
263
297
  private _currentSegmentIndex;
264
298
  private _currentSegmentIndexChanged;
265
299
  stories: Map<string, IJGISStoryMap>;
300
+ private _localUIState;
301
+ private _uiStateChanged;
266
302
  }
267
303
  export declare namespace JupyterGISModel {
268
304
  /**
package/lib/model.js CHANGED
@@ -2,8 +2,14 @@ import { UUID } from '@lumino/coreutils';
2
2
  import { Signal } from '@lumino/signaling';
3
3
  import Ajv from 'ajv';
4
4
  import { DEFAULT_PROJECTION, JupyterGISDoc } from './doc';
5
+ import { AWARENESS_FIELD_KEYS, AWARENESS_STATE_FIELDS, } from './interfaces';
6
+ import { migrateDocument } from './migrations';
5
7
  import jgisSchema from './schema/project/jgis.json';
6
8
  const SETTINGS_ID = '@jupytergis/jupytergis-core:jupytergis-settings';
9
+ const SPECTA_STORY_TYPES = [
10
+ 'guided',
11
+ 'Vertical Scroll',
12
+ ];
7
13
  const DEFAULT_SETTINGS = {
8
14
  proxyUrl: 'https://corsproxy.io',
9
15
  leftPanelDisabled: false,
@@ -15,6 +21,7 @@ const DEFAULT_SETTINGS = {
15
21
  identifyDisabled: false,
16
22
  storyMapsDisabled: false,
17
23
  zoomButtonsEnabled: false,
24
+ useServerGdalProcessing: null,
18
25
  };
19
26
  export class JupyterGISModel {
20
27
  constructor(options) {
@@ -29,12 +36,11 @@ export class JupyterGISModel {
29
36
  this.flyToGeometrySignal = new Signal(this);
30
37
  this.highlightFeatureSignal = new Signal(this);
31
38
  this.updateBboxSignal = new Signal(this);
39
+ this.editingVectorLayerChanged = new Signal(this);
32
40
  this._onClientStateChanged = (changed) => {
33
41
  const clients = this.sharedModel.awareness.getStates();
34
- this._clientStateChanged.emit(clients);
35
- if (changed.added.length || changed.removed.length) {
36
- this._userChanged.emit(this.users);
37
- }
42
+ this._emitAwarenessFieldDeltas(changed, clients);
43
+ this._previousClientStates = new Map(clients);
38
44
  };
39
45
  this.addFeatureAsMs = (id, selectedFeature) => {
40
46
  this.addFeatureAsMsSignal.emit(JSON.stringify({ id, selectedFeature }));
@@ -52,7 +58,13 @@ export class JupyterGISModel {
52
58
  this._contentChanged = new Signal(this);
53
59
  this._stateChanged = new Signal(this);
54
60
  this._themeChanged = new Signal(this);
55
- this._clientStateChanged = new Signal(this);
61
+ this._selectedChanged = new Signal(this);
62
+ this._pointerChanged = new Signal(this);
63
+ this._viewportStateChanged = new Signal(this);
64
+ this._identifiedFeaturesChanged = new Signal(this);
65
+ this._remoteUserChanged = new Signal(this);
66
+ this._temporalControllerActiveChanged = new Signal(this);
67
+ this._previousClientStates = new Map();
56
68
  this._sharedMetadataChanged = new Signal(this);
57
69
  this._zoomToPositionSignal = new Signal(this);
58
70
  this._addFeatureAsMsSignal = new Signal(this);
@@ -65,6 +77,8 @@ export class JupyterGISModel {
65
77
  this._tileFeatureCache = new Map();
66
78
  this._currentSegmentIndexChanged = new Signal(this);
67
79
  this.stories = new Map();
80
+ this._localUIState = {};
81
+ this._uiStateChanged = new Signal(this);
68
82
  const { annotationModel, sharedModel, settingRegistry } = options;
69
83
  if (sharedModel) {
70
84
  this._sharedModel = sharedModel;
@@ -79,7 +93,12 @@ export class JupyterGISModel {
79
93
  this.settingRegistry = settingRegistry;
80
94
  this._pathChanged = new Signal(this);
81
95
  this._settingsChanged = new Signal(this);
96
+ this._editingVectorLayer = false;
82
97
  this._jgisSettings = Object.assign({}, DEFAULT_SETTINGS);
98
+ this._viewState = {};
99
+ this.settingsReady = new Promise(resolve => {
100
+ this._settingsReadyResolve = resolve;
101
+ });
83
102
  this.initSettings();
84
103
  }
85
104
  /**
@@ -91,6 +110,7 @@ export class JupyterGISModel {
91
110
  const setting = await this.settingRegistry.load(SETTINGS_ID);
92
111
  this._settings = setting;
93
112
  this._updateLocalSettings();
113
+ this._settingsReadyResolve();
94
114
  setting.changed.connect(() => {
95
115
  const oldSettings = Object.assign({}, this._jgisSettings);
96
116
  this._updateLocalSettings();
@@ -106,8 +126,12 @@ export class JupyterGISModel {
106
126
  catch (error) {
107
127
  console.error(`Failed to load settings for ${SETTINGS_ID}:`, error);
108
128
  this._jgisSettings = Object.assign({}, DEFAULT_SETTINGS);
129
+ this._settingsReadyResolve();
109
130
  }
110
131
  }
132
+ else {
133
+ this._settingsReadyResolve();
134
+ }
111
135
  }
112
136
  _updateLocalSettings() {
113
137
  const composite = this._settings.composite;
@@ -196,8 +220,23 @@ export class JupyterGISModel {
196
220
  get localState() {
197
221
  return this.sharedModel.awareness.getLocalState();
198
222
  }
199
- get clientStateChanged() {
200
- return this._clientStateChanged;
223
+ get selectedChanged() {
224
+ return this._selectedChanged;
225
+ }
226
+ get pointerChanged() {
227
+ return this._pointerChanged;
228
+ }
229
+ get viewportStateChanged() {
230
+ return this._viewportStateChanged;
231
+ }
232
+ get identifiedFeaturesChanged() {
233
+ return this._identifiedFeaturesChanged;
234
+ }
235
+ get remoteUserChanged() {
236
+ return this._remoteUserChanged;
237
+ }
238
+ get temporalControllerActiveChanged() {
239
+ return this._temporalControllerActiveChanged;
201
240
  }
202
241
  get sharedOptionsChanged() {
203
242
  return this.sharedModel.optionsChanged;
@@ -248,10 +287,11 @@ export class JupyterGISModel {
248
287
  Signal.clearData(this);
249
288
  }
250
289
  toString() {
251
- return JSON.stringify(this.getContent(), null, 2);
290
+ // Trailing newline for POSIX compliance (e.g. end-of-file-fixer pre-commit hook)
291
+ return JSON.stringify(this.getContent(), null, 2) + '\n';
252
292
  }
253
293
  fromString(data) {
254
- const jsonData = JSON.parse(data);
294
+ const jsonData = migrateDocument(JSON.parse(data));
255
295
  const ajv = new Ajv();
256
296
  const validate = ajv.compile(jgisSchema);
257
297
  const valid = validate(jsonData);
@@ -301,6 +341,9 @@ export class JupyterGISModel {
301
341
  metadata: this.sharedModel.metadata,
302
342
  };
303
343
  }
344
+ getViewState() {
345
+ return this._viewState;
346
+ }
304
347
  /**
305
348
  * Getter for the contents manager.
306
349
  */
@@ -339,6 +382,10 @@ export class JupyterGISModel {
339
382
  getLayer(id) {
340
383
  return this.sharedModel.getLayer(id);
341
384
  }
385
+ getExtent(id) {
386
+ var _a;
387
+ return (_a = this._viewState[id]) === null || _a === void 0 ? void 0 : _a.extent;
388
+ }
342
389
  getLayerOrSource(id) {
343
390
  var _a;
344
391
  return (_a = this.sharedModel.getLayer(id)) !== null && _a !== void 0 ? _a : this.sharedModel.getLayerSource(id);
@@ -394,9 +441,16 @@ export class JupyterGISModel {
394
441
  addLayer(id, layer, groupName, position) {
395
442
  if (!this.getLayer(id)) {
396
443
  this.sharedModel.addLayer(id, layer);
444
+ this.syncLastAddedLayer(id);
397
445
  }
398
446
  this._addLayerTreeItem(id, groupName, position);
399
- this.syncSelected({ [id]: { type: 'layer' } }, this.getClientId().toString());
447
+ }
448
+ /**
449
+ * Update layer's extent and zoom in model's view state
450
+ */
451
+ updateLayerViewState(id, view) {
452
+ const layer = this.getLayer(id);
453
+ this._viewState[id] = Object.assign(Object.assign(Object.assign({}, this._viewState[id]), view), { layerId: id, layerName: layer === null || layer === void 0 ? void 0 : layer.name });
400
454
  }
401
455
  removeLayer(layer_id) {
402
456
  var _a;
@@ -430,23 +484,28 @@ export class JupyterGISModel {
430
484
  return this._sharedModel.options;
431
485
  }
432
486
  syncViewport(viewport, emitter) {
433
- this.sharedModel.awareness.setLocalStateField('viewportState', {
487
+ this.sharedModel.awareness.setLocalStateField(AWARENESS_STATE_FIELDS.viewportState, {
434
488
  value: viewport,
435
489
  emitter,
436
490
  });
437
491
  }
438
492
  syncPointer(pointer, emitter) {
439
- this.sharedModel.awareness.setLocalStateField('pointer', {
493
+ this.sharedModel.awareness.setLocalStateField(AWARENESS_STATE_FIELDS.pointer, {
440
494
  value: pointer,
441
495
  emitter,
442
496
  });
443
497
  }
444
498
  syncSelected(value, emitter) {
445
- this.sharedModel.awareness.setLocalStateField('selected', {
499
+ this.sharedModel.awareness.setLocalStateField(AWARENESS_STATE_FIELDS.selected, {
446
500
  value,
447
501
  emitter,
448
502
  });
449
503
  }
504
+ syncLastAddedLayer(layerId) {
505
+ this.sharedModel.awareness.setLocalStateField(AWARENESS_STATE_FIELDS.lastAddedLayer, {
506
+ layerId,
507
+ });
508
+ }
450
509
  get selected() {
451
510
  var _a, _b;
452
511
  return (_b = (_a = this.localState) === null || _a === void 0 ? void 0 : _a.selected) === null || _b === void 0 ? void 0 : _b.value;
@@ -455,14 +514,14 @@ export class JupyterGISModel {
455
514
  this.syncSelected(value || {}, this.getClientId().toString());
456
515
  }
457
516
  syncIdentifiedFeatures(features, emitter) {
458
- this.sharedModel.awareness.setLocalStateField('identifiedFeatures', {
517
+ this.sharedModel.awareness.setLocalStateField(AWARENESS_STATE_FIELDS.identifiedFeatures, {
459
518
  value: features,
460
519
  emitter,
461
520
  });
462
521
  }
463
522
  setUserToFollow(userId) {
464
523
  if (this._sharedModel) {
465
- this._sharedModel.awareness.setLocalStateField('remoteUser', userId);
524
+ this._sharedModel.awareness.setLocalStateField(AWARENESS_STATE_FIELDS.remoteUser, userId);
466
525
  }
467
526
  }
468
527
  setEditingItem(type, itemId) {
@@ -492,8 +551,9 @@ export class JupyterGISModel {
492
551
  var _a;
493
552
  const hasStories = Object.keys(this.sharedModel.stories).length > 0;
494
553
  const isSpecta = !!document.querySelector('meta[name="specta-config"]');
495
- const guidedMode = ((_a = this.getSelectedStory().story) === null || _a === void 0 ? void 0 : _a.storyType) === 'guided';
496
- return isSpecta && hasStories && guidedMode;
554
+ const storyType = (_a = this.getSelectedStory().story) === null || _a === void 0 ? void 0 : _a.storyType;
555
+ const isModeForSpecta = storyType !== undefined && SPECTA_STORY_TYPES.includes(storyType);
556
+ return isSpecta && hasStories && isModeForSpecta;
497
557
  }
498
558
  /**
499
559
  * Placeholder in case we eventually want to support multiple stories
@@ -527,9 +587,11 @@ export class JupyterGISModel {
527
587
  * Adds a story segment from the current map view
528
588
  * @returns Object with storySegmentId and storyMapId, or null if no extent/zoom found
529
589
  */
530
- addStorySegment() {
590
+ addStorySegment(viewState) {
531
591
  var _a;
532
- const { zoom, extent } = this.getOptions();
592
+ const state = viewState !== null && viewState !== void 0 ? viewState : this.getOptions();
593
+ const extent = state === null || state === void 0 ? void 0 : state.extent;
594
+ const zoom = state === null || state === void 0 ? void 0 : state.zoom;
533
595
  const { storyId } = this.getSelectedStory();
534
596
  if (!zoom || !extent) {
535
597
  console.warn('No extent or zoom found');
@@ -540,11 +602,16 @@ export class JupyterGISModel {
540
602
  extent,
541
603
  zoom,
542
604
  transition: { type: 'linear', time: 1 },
605
+ content: {
606
+ contentMode: 'map',
607
+ title: '',
608
+ image: '',
609
+ },
543
610
  };
544
611
  const layerModel = {
545
612
  type: 'StorySegmentLayer',
546
613
  visible: true,
547
- name: 'Story Segment',
614
+ name: this._generateStorySegmentName(viewState),
548
615
  parameters: layerParams,
549
616
  };
550
617
  this.addLayer(newStorySegmentId, layerModel);
@@ -578,6 +645,52 @@ export class JupyterGISModel {
578
645
  return { storySegmentId: newStorySegmentId, storyId };
579
646
  }
580
647
  }
648
+ /**
649
+ * Generates a name for the next story segment based on the number of existing segments in the current story.
650
+ */
651
+ _generateStorySegmentName(viewState) {
652
+ var _a, _b;
653
+ const { story } = this.getSelectedStory();
654
+ const count = (_b = (_a = story === null || story === void 0 ? void 0 : story.storySegments) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0;
655
+ const basename = count === 0 ? 'Story Segment' : `Story Segment ${count}`;
656
+ return (viewState === null || viewState === void 0 ? void 0 : viewState.layerName)
657
+ ? `${viewState.layerName} - ${basename}`
658
+ : basename;
659
+ }
660
+ /**
661
+ * Adds a story segment from a layer
662
+ * @returns Object with storySegmentId and storyMapId, or null if no extent/zoom found
663
+ */
664
+ createStorySegmentFromLayer(layerId) {
665
+ const layer = this.getLayer(layerId);
666
+ if (!layer) {
667
+ return null;
668
+ }
669
+ const viewState = this.getViewState()[layerId];
670
+ if (!viewState) {
671
+ return null;
672
+ }
673
+ const segment = this.addStorySegment(viewState);
674
+ if (!segment) {
675
+ return null;
676
+ }
677
+ const segmentLayer = this.getLayer(segment.storySegmentId);
678
+ if (!segmentLayer) {
679
+ return null;
680
+ }
681
+ const segmentParams = segmentLayer.parameters;
682
+ const layerParams = layer.parameters;
683
+ const override = {
684
+ targetLayer: layerId,
685
+ visible: layer.visible,
686
+ color: layerParams === null || layerParams === void 0 ? void 0 : layerParams.color,
687
+ opacity: layerParams === null || layerParams === void 0 ? void 0 : layerParams.opacity,
688
+ symbologyState: layerParams === null || layerParams === void 0 ? void 0 : layerParams.symbologyState,
689
+ };
690
+ segmentParams.layerOverride = [override];
691
+ segmentLayer.parameters = segmentParams;
692
+ return segment;
693
+ }
581
694
  get segmentAdded() {
582
695
  return this._segmentAdded;
583
696
  }
@@ -735,9 +848,19 @@ export class JupyterGISModel {
735
848
  set currentMode(value) {
736
849
  this._currentMode = value;
737
850
  }
851
+ setUIState(value) {
852
+ this._localUIState = Object.assign(Object.assign({}, this._localUIState), value);
853
+ this._uiStateChanged.emit(this._localUIState);
854
+ }
855
+ getUIState() {
856
+ return this._localUIState;
857
+ }
858
+ get uiStateChanged() {
859
+ return this._uiStateChanged;
860
+ }
738
861
  toggleTemporalController() {
739
862
  this._isTemporalControllerActive = !this._isTemporalControllerActive;
740
- this.sharedModel.awareness.setLocalStateField('isTemporalControllerActive', this._isTemporalControllerActive);
863
+ this.sharedModel.awareness.setLocalStateField(AWARENESS_STATE_FIELDS.isTemporalControllerActive, this._isTemporalControllerActive);
741
864
  }
742
865
  _getLayerTreeInfo(groupName) {
743
866
  const layerTree = this.getLayerTree();
@@ -765,12 +888,80 @@ export class JupyterGISModel {
765
888
  mainGroupIndex,
766
889
  };
767
890
  }
891
+ _emitAwarenessFieldDeltas(changed, clients) {
892
+ var _a, _b, _c;
893
+ const changedClientIds = new Set([
894
+ ...((_a = changed.added) !== null && _a !== void 0 ? _a : []),
895
+ ...((_b = changed.updated) !== null && _b !== void 0 ? _b : []),
896
+ ...((_c = changed.removed) !== null && _c !== void 0 ? _c : []),
897
+ ]);
898
+ if (!changedClientIds.size) {
899
+ return;
900
+ }
901
+ const fields = AWARENESS_FIELD_KEYS;
902
+ const localClientId = this.getClientId();
903
+ changedClientIds.forEach(clientId => {
904
+ const previousState = this._previousClientStates.get(clientId);
905
+ const currentState = clients.get(clientId);
906
+ fields.forEach(field => {
907
+ const previousValue = previousState === null || previousState === void 0 ? void 0 : previousState[field];
908
+ const currentValue = currentState === null || currentState === void 0 ? void 0 : currentState[field];
909
+ if (previousValue === currentValue) {
910
+ return;
911
+ }
912
+ const payload = {
913
+ clientId,
914
+ field,
915
+ previousValue,
916
+ currentValue,
917
+ fullState: currentState,
918
+ isLocalClient: clientId === localClientId,
919
+ };
920
+ switch (field) {
921
+ case AWARENESS_STATE_FIELDS.selected:
922
+ this._selectedChanged.emit(payload);
923
+ break;
924
+ case AWARENESS_STATE_FIELDS.pointer:
925
+ this._pointerChanged.emit(payload);
926
+ break;
927
+ case AWARENESS_STATE_FIELDS.viewportState:
928
+ this._viewportStateChanged.emit(payload);
929
+ break;
930
+ case AWARENESS_STATE_FIELDS.identifiedFeatures:
931
+ this._identifiedFeaturesChanged.emit(payload);
932
+ break;
933
+ case AWARENESS_STATE_FIELDS.remoteUser:
934
+ this._remoteUserChanged.emit(payload);
935
+ break;
936
+ case AWARENESS_STATE_FIELDS.isTemporalControllerActive:
937
+ this._temporalControllerActiveChanged.emit(payload);
938
+ break;
939
+ }
940
+ });
941
+ });
942
+ }
768
943
  get addFeatureAsMsSignal() {
769
944
  return this._addFeatureAsMsSignal;
770
945
  }
771
946
  get updateLayerSignal() {
772
947
  return this._updateLayerSignal;
773
948
  }
949
+ checkIfIsADrawVectorLayer(layer) {
950
+ var _a, _b, _c;
951
+ const selectedSource = this.getSource((_a = layer.parameters) === null || _a === void 0 ? void 0 : _a.source);
952
+ return ((selectedSource === null || selectedSource === void 0 ? void 0 : selectedSource.type) === 'GeoJSONSource' &&
953
+ ((_c = (_b = selectedSource === null || selectedSource === void 0 ? void 0 : selectedSource.parameters) === null || _b === void 0 ? void 0 : _b.data) === null || _c === void 0 ? void 0 : _c.type) === 'FeatureCollection');
954
+ }
955
+ updateEditingVectorLayer() {
956
+ this.editingVectorLayerChanged.emit(this._editingVectorLayer);
957
+ }
958
+ get editingVectorLayer() {
959
+ return this._editingVectorLayer;
960
+ }
961
+ set editingVectorLayer(editingVectorLayer) {
962
+ this._editingVectorLayer = editingVectorLayer;
963
+ this.editingVectorLayerChanged.emit(this._editingVectorLayer);
964
+ }
774
965
  get geolocation() {
775
966
  return this._geolocation;
776
967
  }
@@ -9,6 +9,10 @@ type ProcessingElement = {
9
9
  };
10
10
  export declare const ProcessingLogicType: {
11
11
  vector: string;
12
+ raster: string;
13
+ rasterClip: string;
14
+ rasterClipVector: string;
15
+ clip: string;
12
16
  };
13
17
  export declare const ProcessingMerge: ProcessingElement[];
14
18
  export declare const ProcessingCommandIDs: IDict;
@@ -1,6 +1,10 @@
1
1
  import _ProcessingMerge from './_generated/processing_merge.json';
2
2
  export const ProcessingLogicType = {
3
3
  vector: 'vector',
4
+ raster: 'raster',
5
+ rasterClip: 'rasterClip',
6
+ rasterClipVector: 'rasterClipVector',
7
+ clip: 'clip',
4
8
  };
5
9
  export const ProcessingMerge = _ProcessingMerge;
6
10
  export const ProcessingCommandIDs = {};
@@ -1,6 +1,10 @@
1
- export * from '../../_interface/processing/boundingBoxes';
2
1
  export * from '../../_interface/processing/concaveHull';
3
- export * from '../../_interface/processing/dissolve';
4
- export * from '../../_interface/processing/buffer';
5
- export * from '../../_interface/processing/convexHull';
6
2
  export * from '../../_interface/processing/centroids';
3
+ export * from '../../_interface/processing/clipRasterByVector';
4
+ export * from '../../_interface/processing/boundingBoxes';
5
+ export * from '../../_interface/processing/convexHull';
6
+ export * from '../../_interface/processing/clipVectorByMaskLayer';
7
+ export * from '../../_interface/processing/clipRasterByExtent';
8
+ export * from '../../_interface/processing/rasterize';
9
+ export * from '../../_interface/processing/buffer';
10
+ export * from '../../_interface/processing/dissolve';
@@ -1,7 +1,11 @@
1
1
  //Generated automatically please don't modify directly
2
- export * from '../../_interface/processing/boundingBoxes';
3
2
  export * from '../../_interface/processing/concaveHull';
4
- export * from '../../_interface/processing/dissolve';
5
- export * from '../../_interface/processing/buffer';
6
- export * from '../../_interface/processing/convexHull';
7
3
  export * from '../../_interface/processing/centroids';
4
+ export * from '../../_interface/processing/clipRasterByVector';
5
+ export * from '../../_interface/processing/boundingBoxes';
6
+ export * from '../../_interface/processing/convexHull';
7
+ export * from '../../_interface/processing/clipVectorByMaskLayer';
8
+ export * from '../../_interface/processing/clipRasterByExtent';
9
+ export * from '../../_interface/processing/rasterize';
10
+ export * from '../../_interface/processing/buffer';
11
+ export * from '../../_interface/processing/dissolve';
@@ -1,2 +1,2 @@
1
- export type ProcessingType = 'BoundingBoxes' | 'ConcaveHull' | 'Dissolve' | 'Buffer' | 'ConvexHull' | 'Centroids';
1
+ export type ProcessingType = 'ConcaveHull' | 'Centroids' | 'ClipRasterByVector' | 'BoundingBoxes' | 'ConvexHull' | 'ClipVectorByMaskLayer' | 'ClipRasterByExtent' | 'Rasterize' | 'Buffer' | 'Dissolve';
2
2
  export declare const processingList: string[];
@@ -1,8 +1,12 @@
1
1
  export const processingList = [
2
- 'BoundingBoxes',
3
2
  'ConcaveHull',
4
- 'Dissolve',
5
- 'Buffer',
6
- 'ConvexHull',
7
3
  'Centroids',
4
+ 'ClipRasterByVector',
5
+ 'BoundingBoxes',
6
+ 'ConvexHull',
7
+ 'ClipVectorByMaskLayer',
8
+ 'ClipRasterByExtent',
9
+ 'Rasterize',
10
+ 'Buffer',
11
+ 'Dissolve',
8
12
  ];