@open-pioneer/editing 1.4.0-dev.20260625074633 → 1.4.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/CHANGELOG.md CHANGED
@@ -1,10 +1,16 @@
1
1
  # @open-pioneer/editing
2
2
 
3
- ## 1.4.0-dev.20260625074633
3
+ ## 1.4.0
4
4
 
5
5
  ### Minor Changes
6
6
 
7
- - c30396d: Update Chakra to 3.36.0
7
+ - c30396d: Update Chakra to 3.36.1
8
+ - d862003: Update to trails core-packages 4.7.0
9
+
10
+ ### Patch Changes
11
+
12
+ - 078bef5: Use private JavaScript properties (#) instead of TypeScript keyword.
13
+ - c16a401: Migrated from eslint to oxlint and from prettier to oxfmt.
8
14
 
9
15
  ## 1.3.0
10
16
 
@@ -2,34 +2,11 @@ import { Draw } from "ol/interaction";
2
2
  import { EditingWorkflow, EditingWorkflowProps, EditingWorkflowState } from "./api";
3
3
  export declare class EditingCreateWorkflowImpl implements EditingWorkflow {
4
4
  #private;
5
- private _httpService;
6
- private _layerFactory;
7
- private _intl;
8
- private _map;
9
- private _polygonStyle;
10
- private _vertexStyle;
11
- private _state;
12
- private _editLayerURL;
13
- private _featureId;
14
- private _editingSource;
15
- private _editingLayer;
16
- private _drawInteraction;
17
- private _olMap;
18
- private _tooltip;
19
- private _enterHandler;
20
- private _escapeHandler;
21
- private _error;
22
- private _interactionListener;
23
- private _mapListener;
24
5
  constructor(options: EditingWorkflowProps);
25
6
  getDrawInteraction(): Draw;
26
7
  getState(): EditingWorkflowState;
27
- private _setState;
28
- private _save;
29
- private _start;
30
8
  reset(): void;
31
9
  stop(): void;
32
- private _destroy;
33
10
  triggerSave(): void;
34
11
  whenComplete(): Promise<Record<string, string> | undefined>;
35
12
  }
@@ -1,107 +1,107 @@
1
1
  import { reactive, effect } from '@conterra/reactivity-core';
2
2
  import { createLogger, createManualPromise } from '@open-pioneer/core';
3
3
  import { SimpleLayer } from '@open-pioneer/map';
4
- import { unByKey } from 'ol/Observable.js';
5
4
  import GeoJSON from 'ol/format/GeoJSON.js';
6
5
  import { Draw } from 'ol/interaction.js';
7
6
  import VectorLayer from 'ol/layer/Vector.js';
7
+ import { unByKey } from 'ol/Observable.js';
8
8
  import VectorSource from 'ol/source/Vector.js';
9
9
  import { sourceId } from './_virtual/source-info.js';
10
10
  import { saveCreatedFeature } from './SaveFeaturesHandler.js';
11
- import { createTooltip } from './Tooltip.js';
12
11
  import { createStyles } from './style-utils.js';
12
+ import { createTooltip } from './Tooltip.js';
13
13
 
14
14
  const LOG = createLogger(sourceId);
15
15
  class EditingCreateWorkflowImpl {
16
16
  #waiter;
17
- _httpService;
18
- _layerFactory;
19
- _intl;
20
- _map;
21
- _polygonStyle;
22
- _vertexStyle;
23
- _state;
24
- _editLayerURL;
25
- _featureId;
26
- _editingSource;
27
- _editingLayer;
28
- _drawInteraction;
29
- _olMap;
30
- _tooltip;
31
- _enterHandler;
32
- _escapeHandler;
33
- _error;
34
- _interactionListener;
35
- _mapListener;
17
+ #httpService;
18
+ #layerFactory;
19
+ #intl;
20
+ #map;
21
+ #polygonStyle;
22
+ #vertexStyle;
23
+ #state;
24
+ #editLayerURL;
25
+ #featureId;
26
+ #editingSource;
27
+ #editingLayer;
28
+ #drawInteraction;
29
+ #olMap;
30
+ #tooltip;
31
+ #enterHandler;
32
+ #escapeHandler;
33
+ #error;
34
+ #interactionListener;
35
+ #mapListener;
36
36
  constructor(options) {
37
- this._httpService = options.httpService;
38
- this._layerFactory = options.layerFactory;
39
- this._intl = options.intl;
40
- this._polygonStyle = options.polygonStyle;
41
- this._vertexStyle = options.vertexStyle;
42
- this._map = options.map;
43
- this._olMap = options.map.olMap;
44
- this._state = reactive("active:initialized");
45
- this._editLayerURL = options.ogcApiFeatureLayerUrl;
46
- this._editingSource = new VectorSource();
37
+ this.#httpService = options.httpService;
38
+ this.#layerFactory = options.layerFactory;
39
+ this.#intl = options.intl;
40
+ this.#polygonStyle = options.polygonStyle;
41
+ this.#vertexStyle = options.vertexStyle;
42
+ this.#map = options.map;
43
+ this.#olMap = options.map.olMap;
44
+ this.#state = reactive("active:initialized");
45
+ this.#editLayerURL = options.ogcApiFeatureLayerUrl;
46
+ this.#editingSource = new VectorSource();
47
47
  const olLayer = new VectorLayer({
48
- source: this._editingSource
48
+ source: this.#editingSource
49
49
  });
50
- this._editingLayer = this._layerFactory.create({
50
+ this.#editingLayer = this.#layerFactory.create({
51
51
  type: SimpleLayer,
52
52
  title: "editing-layer",
53
53
  internal: true,
54
54
  olLayer
55
55
  });
56
- this._drawInteraction = new Draw({
57
- source: this._editingSource,
56
+ this.#drawInteraction = new Draw({
57
+ source: this.#editingSource,
58
58
  type: "Polygon",
59
59
  style: createStyles({
60
- polygon: this._polygonStyle,
61
- vertex: this._vertexStyle
60
+ polygon: this.#polygonStyle,
61
+ vertex: this.#vertexStyle
62
62
  })
63
63
  });
64
- this._tooltip = createTooltip(
65
- this._map,
66
- this._intl.value.formatMessage({ id: "create.tooltip.begin" })
64
+ this.#tooltip = createTooltip(
65
+ this.#map,
66
+ this.#intl.value.formatMessage({ id: "create.tooltip.begin" })
67
67
  );
68
- this._enterHandler = (e) => {
69
- if ((e.code === "Enter" || e.code === "NumpadEnter") && e.target === this._olMap.getTargetElement()) {
70
- const features = this._drawInteraction.getOverlay().getSource()?.getFeatures() ?? [];
68
+ this.#enterHandler = (e) => {
69
+ if ((e.code === "Enter" || e.code === "NumpadEnter") && e.target === this.#olMap.getTargetElement()) {
70
+ const features = this.#drawInteraction.getOverlay().getSource()?.getFeatures() ?? [];
71
71
  if (features[0] && features[0].getGeometry().getCoordinates()[0].length > 4) {
72
72
  this.triggerSave();
73
73
  }
74
74
  }
75
75
  };
76
- this._escapeHandler = (e) => {
77
- if (e.code === "Escape" && e.target === this._olMap.getTargetElement()) {
76
+ this.#escapeHandler = (e) => {
77
+ if (e.code === "Escape" && e.target === this.#olMap.getTargetElement()) {
78
78
  this.reset();
79
79
  }
80
80
  };
81
- this._interactionListener = [];
82
- this._mapListener = [];
83
- this._start();
81
+ this.#interactionListener = [];
82
+ this.#mapListener = [];
83
+ this.#start();
84
84
  }
85
85
  getDrawInteraction() {
86
- return this._drawInteraction;
86
+ return this.#drawInteraction;
87
87
  }
88
88
  getState() {
89
- return this._state.value;
89
+ return this.#state.value;
90
90
  }
91
- _setState(state) {
92
- this._state.value = state;
91
+ #setState(state) {
92
+ this.#state.value = state;
93
93
  }
94
- _save(feature) {
95
- this._setState("active:saving");
96
- const layerUrl = this._editLayerURL;
94
+ #save(feature) {
95
+ this.#setState("active:saving");
96
+ const layerUrl = this.#editLayerURL;
97
97
  const geometry = feature.getGeometry();
98
98
  if (!geometry) {
99
- this._destroy();
100
- this._error = new Error("no geometry available");
101
- this.#waiter?.reject(this._error);
99
+ this.#destroy();
100
+ this.#error = new Error("no geometry available");
101
+ this.#waiter?.reject(this.#error);
102
102
  return;
103
103
  }
104
- const projection = this._olMap.getView().getProjection();
104
+ const projection = this.#olMap.getView().getProjection();
105
105
  const geoJson = new GeoJSON({
106
106
  dataProjection: projection
107
107
  });
@@ -109,92 +109,93 @@ class EditingCreateWorkflowImpl {
109
109
  rightHanded: true,
110
110
  decimals: 10
111
111
  });
112
- this._olMap.removeInteraction(this._drawInteraction);
113
- this._tooltip.destroy();
114
- saveCreatedFeature(this._httpService, layerUrl, geoJSONGeometry, projection).then((featureId) => {
115
- this._featureId = featureId;
116
- this._destroy();
117
- this.#waiter?.resolve({ featureId: this._featureId });
112
+ this.#olMap.removeInteraction(this.#drawInteraction);
113
+ this.#tooltip.destroy();
114
+ const httpService = this.#httpService;
115
+ saveCreatedFeature({ httpService, url: layerUrl, geometry: geoJSONGeometry, projection }).then((featureId) => {
116
+ this.#featureId = featureId;
117
+ this.#destroy();
118
+ this.#waiter?.resolve({ featureId: this.#featureId });
118
119
  }).catch((err) => {
119
120
  LOG.error(err);
120
- this._destroy();
121
- this._error = new Error("Failed to save feature", { cause: err });
122
- this.#waiter?.reject(this._error);
121
+ this.#destroy();
122
+ this.#error = new Error("Failed to save feature", { cause: err });
123
+ this.#waiter?.reject(this.#error);
123
124
  });
124
125
  }
125
- _start() {
126
- this._map.layers.addLayer(this._editingLayer, { at: "topmost" });
127
- this._olMap.addInteraction(this._drawInteraction);
126
+ #start() {
127
+ this.#map.layers.addLayer(this.#editingLayer, { at: "topmost" });
128
+ this.#olMap.addInteraction(this.#drawInteraction);
128
129
  const containerEvents = effect(() => {
129
- const container = this._map.container;
130
+ const container = this.#map.container;
130
131
  if (!container) {
131
132
  return;
132
133
  }
133
- container.addEventListener("keydown", this._enterHandler, false);
134
- container.addEventListener("keydown", this._escapeHandler, false);
134
+ container.addEventListener("keydown", this.#enterHandler, false);
135
+ container.addEventListener("keydown", this.#escapeHandler, false);
135
136
  return () => {
136
- container.removeEventListener("keydown", this._enterHandler);
137
- container.removeEventListener("keydown", this._escapeHandler);
137
+ container.removeEventListener("keydown", this.#enterHandler);
138
+ container.removeEventListener("keydown", this.#escapeHandler);
138
139
  };
139
140
  });
140
- this._tooltip.setVisible(true);
141
- const drawStart = this._drawInteraction.on("drawstart", () => {
142
- this._setState("active:drawing");
143
- this._tooltip.setText(
144
- this._intl.value.formatMessage({
141
+ this.#tooltip.setVisible(true);
142
+ const drawStart = this.#drawInteraction.on("drawstart", () => {
143
+ this.#setState("active:drawing");
144
+ this.#tooltip.setText(
145
+ this.#intl.value.formatMessage({
145
146
  id: "create.tooltip.continue"
146
147
  })
147
148
  );
148
149
  });
149
- const drawEnd = this._drawInteraction.on("drawend", (e) => {
150
+ const drawEnd = this.#drawInteraction.on("drawend", (e) => {
150
151
  const feature = e.feature;
151
152
  if (!feature) {
152
- this._destroy();
153
- this._error = new Error("no feature available");
154
- this.#waiter?.reject(this._error);
153
+ this.#destroy();
154
+ this.#error = new Error("no feature available");
155
+ this.#waiter?.reject(this.#error);
155
156
  return;
156
157
  }
157
- this._save(feature);
158
+ this.#save(feature);
158
159
  });
159
- this._interactionListener.push(drawStart, drawEnd);
160
- this._mapListener.push(containerEvents);
160
+ this.#interactionListener.push(drawStart, drawEnd);
161
+ this.#mapListener.push(containerEvents);
161
162
  }
162
163
  reset() {
163
- this._drawInteraction.abortDrawing();
164
- this._tooltip.setText(
165
- this._intl.value.formatMessage({
164
+ this.#drawInteraction.abortDrawing();
165
+ this.#tooltip.setText(
166
+ this.#intl.value.formatMessage({
166
167
  id: "create.tooltip.begin"
167
168
  })
168
169
  );
169
- this._setState("active:initialized");
170
+ this.#setState("active:initialized");
170
171
  }
171
172
  stop() {
172
- this._destroy();
173
+ this.#destroy();
173
174
  this.#waiter?.resolve(void 0);
174
175
  }
175
- _destroy() {
176
- this._map.layers.removeLayer(this._editingLayer);
177
- this._editingLayer.destroy();
178
- this._olMap.removeInteraction(this._drawInteraction);
179
- this._tooltip.destroy();
180
- this._interactionListener.forEach((listener) => {
176
+ #destroy() {
177
+ this.#map.layers.removeLayer(this.#editingLayer);
178
+ this.#editingLayer.destroy();
179
+ this.#olMap.removeInteraction(this.#drawInteraction);
180
+ this.#tooltip.destroy();
181
+ this.#interactionListener.forEach((listener) => {
181
182
  unByKey(listener);
182
183
  });
183
- this._mapListener.forEach((listener) => {
184
+ this.#mapListener.forEach((listener) => {
184
185
  listener.destroy();
185
186
  });
186
- this._setState("destroyed");
187
+ this.#setState("destroyed");
187
188
  }
188
189
  triggerSave() {
189
- this._drawInteraction.finishDrawing();
190
+ this.#drawInteraction.finishDrawing();
190
191
  }
191
192
  whenComplete() {
192
- if (this._state.value === "destroyed") {
193
- if (this._error) {
194
- return Promise.reject(this._error);
193
+ if (this.#state.value === "destroyed") {
194
+ if (this.#error) {
195
+ return Promise.reject(this.#error);
195
196
  } else {
196
- if (this._featureId) {
197
- return Promise.resolve({ featureId: this._featureId });
197
+ if (this.#featureId) {
198
+ return Promise.resolve({ featureId: this.#featureId });
198
199
  } else {
199
200
  return Promise.resolve(void 0);
200
201
  }
@@ -1 +1 @@
1
- {"version":3,"file":"EditingCreateWorkflowImpl.js","sources":["EditingCreateWorkflowImpl.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { effect, Reactive, reactive, ReadonlyReactive } from \"@conterra/reactivity-core\";\nimport { createLogger, createManualPromise, ManualPromise, Resource } from \"@open-pioneer/core\";\nimport { HttpService } from \"@open-pioneer/http\";\nimport { LayerFactory, MapModel, SimpleLayer } from \"@open-pioneer/map\";\nimport { PackageIntl } from \"@open-pioneer/runtime\";\nimport Feature from \"ol/Feature\";\nimport OlMap from \"ol/Map\";\nimport { unByKey } from \"ol/Observable\";\nimport { EventsKey } from \"ol/events\";\nimport {\n default as GeoJSON,\n default as GeoJSONGeometry,\n default as GeoJSONGeometryCollection\n} from \"ol/format/GeoJSON\";\nimport { Draw } from \"ol/interaction\";\nimport VectorLayer from \"ol/layer/Vector\";\nimport VectorSource from \"ol/source/Vector\";\nimport { FlatStyle } from \"ol/style/flat\";\nimport { sourceId } from \"open-pioneer:source-info\";\nimport { saveCreatedFeature } from \"./SaveFeaturesHandler\";\nimport { createTooltip, Tooltip } from \"./Tooltip\";\nimport { EditingWorkflow, EditingWorkflowProps, EditingWorkflowState } from \"./api\";\nimport { createStyles } from \"./style-utils\";\n\nconst LOG = createLogger(sourceId);\n\nexport class EditingCreateWorkflowImpl implements EditingWorkflow {\n #waiter: ManualPromise<Record<string, string> | undefined> | undefined;\n\n private _httpService: HttpService;\n private _layerFactory: LayerFactory;\n private _intl: ReadonlyReactive<PackageIntl>;\n\n private _map: MapModel;\n private _polygonStyle: FlatStyle;\n private _vertexStyle: FlatStyle;\n private _state: Reactive<EditingWorkflowState>;\n private _editLayerURL: URL;\n private _featureId: string | undefined;\n\n private _editingSource: VectorSource;\n private _editingLayer: SimpleLayer;\n private _drawInteraction: Draw;\n private _olMap: OlMap;\n private _tooltip: Tooltip;\n private _enterHandler: (e: KeyboardEvent) => void;\n private _escapeHandler: (e: KeyboardEvent) => void;\n\n private _error: Error | undefined;\n\n private _interactionListener: Array<EventsKey>;\n private _mapListener: Array<Resource>;\n\n constructor(options: EditingWorkflowProps) {\n this._httpService = options.httpService;\n this._layerFactory = options.layerFactory;\n this._intl = options.intl;\n\n this._polygonStyle = options.polygonStyle;\n this._vertexStyle = options.vertexStyle;\n\n this._map = options.map;\n this._olMap = options.map.olMap;\n this._state = reactive(\"active:initialized\");\n this._editLayerURL = options.ogcApiFeatureLayerUrl;\n\n this._editingSource = new VectorSource();\n const olLayer = new VectorLayer({\n source: this._editingSource\n });\n this._editingLayer = this._layerFactory.create({\n type: SimpleLayer,\n title: \"editing-layer\",\n internal: true,\n olLayer: olLayer\n });\n\n this._drawInteraction = new Draw({\n source: this._editingSource,\n type: \"Polygon\",\n style: createStyles({\n polygon: this._polygonStyle,\n vertex: this._vertexStyle\n })\n });\n\n this._tooltip = createTooltip(\n this._map,\n this._intl.value.formatMessage({ id: \"create.tooltip.begin\" })\n );\n\n this._enterHandler = (e: KeyboardEvent) => {\n if (\n (e.code === \"Enter\" || e.code === \"NumpadEnter\") &&\n e.target === this._olMap.getTargetElement()\n ) {\n const features =\n this._drawInteraction.getOverlay().getSource()?.getFeatures() ?? [];\n\n /**\n * Get the first linear ring of the polygon\n * Coordinates include closing vertex, so a triangle has 4, while drawing the\n * actual mouse position is an extra vertex, therefor we have to check\n * \"length > 4\" instead of \"length >= 4\"\n */\n if (features[0] && features[0].getGeometry().getCoordinates()[0].length > 4) {\n this.triggerSave();\n }\n }\n };\n\n this._escapeHandler = (e: KeyboardEvent) => {\n if (e.code === \"Escape\" && e.target === this._olMap.getTargetElement()) {\n this.reset();\n }\n };\n\n this._interactionListener = [];\n this._mapListener = [];\n\n this._start();\n }\n\n getDrawInteraction() {\n return this._drawInteraction;\n }\n\n getState() {\n return this._state.value;\n }\n\n private _setState(state: EditingWorkflowState) {\n this._state.value = state;\n }\n\n private _save(feature: Feature) {\n this._setState(\"active:saving\");\n\n const layerUrl = this._editLayerURL;\n\n const geometry = feature.getGeometry();\n if (!geometry) {\n this._destroy();\n this._error = new Error(\"no geometry available\");\n this.#waiter?.reject(this._error);\n return;\n }\n const projection = this._olMap.getView().getProjection();\n const geoJson = new GeoJSON({\n dataProjection: projection\n });\n const geoJSONGeometry: GeoJSONGeometry | GeoJSONGeometryCollection =\n geoJson.writeGeometryObject(geometry, {\n rightHanded: true,\n decimals: 10\n });\n\n this._olMap.removeInteraction(this._drawInteraction);\n this._tooltip.destroy();\n\n saveCreatedFeature(this._httpService, layerUrl, geoJSONGeometry, projection)\n .then((featureId) => {\n this._featureId = featureId;\n this._destroy();\n this.#waiter?.resolve({ featureId: this._featureId });\n })\n .catch((err: Error) => {\n LOG.error(err);\n this._destroy();\n this._error = new Error(\"Failed to save feature\", { cause: err });\n this.#waiter?.reject(this._error);\n });\n }\n\n private _start() {\n this._map.layers.addLayer(this._editingLayer, { at: \"topmost\" });\n this._olMap.addInteraction(this._drawInteraction);\n\n // Add EventListener on focused map to abort actual interaction via `Escape`\n const containerEvents = effect(() => {\n const container = this._map.container;\n if (!container) {\n return;\n }\n\n container.addEventListener(\"keydown\", this._enterHandler, false);\n container.addEventListener(\"keydown\", this._escapeHandler, false);\n return () => {\n container.removeEventListener(\"keydown\", this._enterHandler);\n container.removeEventListener(\"keydown\", this._escapeHandler);\n };\n });\n\n this._tooltip.setVisible(true);\n\n const drawStart = this._drawInteraction.on(\"drawstart\", () => {\n this._setState(\"active:drawing\");\n this._tooltip.setText(\n this._intl.value.formatMessage({\n id: \"create.tooltip.continue\"\n })\n );\n });\n\n const drawEnd = this._drawInteraction.on(\"drawend\", (e) => {\n const feature = e.feature;\n if (!feature) {\n this._destroy();\n this._error = new Error(\"no feature available\");\n this.#waiter?.reject(this._error);\n return;\n }\n this._save(feature);\n });\n\n this._interactionListener.push(drawStart, drawEnd);\n this._mapListener.push(containerEvents);\n }\n\n reset() {\n this._drawInteraction.abortDrawing();\n this._tooltip.setText(\n this._intl.value.formatMessage({\n id: \"create.tooltip.begin\"\n })\n );\n this._setState(\"active:initialized\");\n }\n\n stop() {\n this._destroy();\n this.#waiter?.resolve(undefined);\n }\n\n private _destroy() {\n this._map.layers.removeLayer(this._editingLayer);\n this._editingLayer.destroy();\n this._olMap.removeInteraction(this._drawInteraction);\n this._tooltip.destroy();\n\n // Remove event listener on interaction and on map\n this._interactionListener.forEach((listener) => {\n unByKey(listener);\n });\n this._mapListener.forEach((listener) => {\n listener.destroy();\n });\n\n this._setState(\"destroyed\");\n }\n\n triggerSave() {\n // Stop drawing - the `drawend` event is dispatched before inserting the feature.\n this._drawInteraction.finishDrawing();\n }\n\n whenComplete(): Promise<Record<string, string> | undefined> {\n if (this._state.value === \"destroyed\") {\n if (this._error) {\n return Promise.reject(this._error);\n } else {\n if (this._featureId) {\n return Promise.resolve({ featureId: this._featureId });\n } else {\n return Promise.resolve(undefined);\n }\n }\n }\n\n const manualPromise = (this.#waiter ??= createManualPromise());\n return manualPromise.promise;\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"EditingCreateWorkflowImpl.js","sources":["EditingCreateWorkflowImpl.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { effect, Reactive, reactive, ReadonlyReactive } from \"@conterra/reactivity-core\";\nimport { createLogger, createManualPromise, ManualPromise, Resource } from \"@open-pioneer/core\";\nimport { HttpService } from \"@open-pioneer/http\";\nimport { LayerFactory, MapModel, SimpleLayer } from \"@open-pioneer/map\";\nimport { PackageIntl } from \"@open-pioneer/runtime\";\nimport { EventsKey } from \"ol/events\";\nimport Feature from \"ol/Feature\";\nimport {\n default as GeoJSON,\n default as GeoJSONGeometry,\n default as GeoJSONGeometryCollection\n} from \"ol/format/GeoJSON\";\nimport { Draw } from \"ol/interaction\";\nimport VectorLayer from \"ol/layer/Vector\";\nimport OlMap from \"ol/Map\";\nimport { unByKey } from \"ol/Observable\";\nimport VectorSource from \"ol/source/Vector\";\nimport { FlatStyle } from \"ol/style/flat\";\nimport { sourceId } from \"open-pioneer:source-info\";\nimport { EditingWorkflow, EditingWorkflowProps, EditingWorkflowState } from \"./api\";\nimport { saveCreatedFeature } from \"./SaveFeaturesHandler\";\nimport { createStyles } from \"./style-utils\";\nimport { createTooltip, Tooltip } from \"./Tooltip\";\n\nconst LOG = createLogger(sourceId);\n\nexport class EditingCreateWorkflowImpl implements EditingWorkflow {\n #waiter: ManualPromise<Record<string, string> | undefined> | undefined;\n\n #httpService: HttpService;\n #layerFactory: LayerFactory;\n #intl: ReadonlyReactive<PackageIntl>;\n\n #map: MapModel;\n #polygonStyle: FlatStyle;\n #vertexStyle: FlatStyle;\n #state: Reactive<EditingWorkflowState>;\n #editLayerURL: URL;\n #featureId: string | undefined;\n\n #editingSource: VectorSource;\n #editingLayer: SimpleLayer;\n #drawInteraction: Draw;\n #olMap: OlMap;\n #tooltip: Tooltip;\n #enterHandler: (e: KeyboardEvent) => void;\n #escapeHandler: (e: KeyboardEvent) => void;\n\n #error: Error | undefined;\n\n #interactionListener: Array<EventsKey>;\n #mapListener: Array<Resource>;\n\n constructor(options: EditingWorkflowProps) {\n this.#httpService = options.httpService;\n this.#layerFactory = options.layerFactory;\n this.#intl = options.intl;\n\n this.#polygonStyle = options.polygonStyle;\n this.#vertexStyle = options.vertexStyle;\n\n this.#map = options.map;\n this.#olMap = options.map.olMap;\n this.#state = reactive(\"active:initialized\");\n this.#editLayerURL = options.ogcApiFeatureLayerUrl;\n\n this.#editingSource = new VectorSource();\n const olLayer = new VectorLayer({\n source: this.#editingSource\n });\n this.#editingLayer = this.#layerFactory.create({\n type: SimpleLayer,\n title: \"editing-layer\",\n internal: true,\n olLayer: olLayer\n });\n\n this.#drawInteraction = new Draw({\n source: this.#editingSource,\n type: \"Polygon\",\n style: createStyles({\n polygon: this.#polygonStyle,\n vertex: this.#vertexStyle\n })\n });\n\n this.#tooltip = createTooltip(\n this.#map,\n this.#intl.value.formatMessage({ id: \"create.tooltip.begin\" })\n );\n\n this.#enterHandler = (e: KeyboardEvent) => {\n if (\n (e.code === \"Enter\" || e.code === \"NumpadEnter\") &&\n e.target === this.#olMap.getTargetElement()\n ) {\n const features =\n this.#drawInteraction.getOverlay().getSource()?.getFeatures() ?? [];\n\n /**\n * Get the first linear ring of the polygon\n * Coordinates include closing vertex, so a triangle has 4, while drawing the\n * actual mouse position is an extra vertex, therefor we have to check\n * \"length > 4\" instead of \"length >= 4\"\n */\n if (features[0] && features[0].getGeometry().getCoordinates()[0].length > 4) {\n this.triggerSave();\n }\n }\n };\n\n this.#escapeHandler = (e: KeyboardEvent) => {\n if (e.code === \"Escape\" && e.target === this.#olMap.getTargetElement()) {\n this.reset();\n }\n };\n\n this.#interactionListener = [];\n this.#mapListener = [];\n\n this.#start();\n }\n\n getDrawInteraction() {\n return this.#drawInteraction;\n }\n\n getState() {\n return this.#state.value;\n }\n\n #setState(state: EditingWorkflowState) {\n this.#state.value = state;\n }\n\n #save(feature: Feature) {\n this.#setState(\"active:saving\");\n\n const layerUrl = this.#editLayerURL;\n\n const geometry = feature.getGeometry();\n if (!geometry) {\n this.#destroy();\n this.#error = new Error(\"no geometry available\");\n this.#waiter?.reject(this.#error);\n return;\n }\n const projection = this.#olMap.getView().getProjection();\n const geoJson = new GeoJSON({\n dataProjection: projection\n });\n const geoJSONGeometry: GeoJSONGeometry | GeoJSONGeometryCollection =\n geoJson.writeGeometryObject(geometry, {\n rightHanded: true,\n decimals: 10\n });\n\n this.#olMap.removeInteraction(this.#drawInteraction);\n this.#tooltip.destroy();\n\n const httpService = this.#httpService;\n saveCreatedFeature({ httpService, url: layerUrl, geometry: geoJSONGeometry, projection })\n .then((featureId) => {\n this.#featureId = featureId;\n this.#destroy();\n this.#waiter?.resolve({ featureId: this.#featureId });\n })\n .catch((err: Error) => {\n LOG.error(err);\n this.#destroy();\n this.#error = new Error(\"Failed to save feature\", { cause: err });\n this.#waiter?.reject(this.#error);\n });\n }\n\n #start() {\n this.#map.layers.addLayer(this.#editingLayer, { at: \"topmost\" });\n this.#olMap.addInteraction(this.#drawInteraction);\n\n // Add EventListener on focused map to abort actual interaction via `Escape`\n const containerEvents = effect(() => {\n const container = this.#map.container;\n if (!container) {\n return;\n }\n\n container.addEventListener(\"keydown\", this.#enterHandler, false);\n container.addEventListener(\"keydown\", this.#escapeHandler, false);\n return () => {\n container.removeEventListener(\"keydown\", this.#enterHandler);\n container.removeEventListener(\"keydown\", this.#escapeHandler);\n };\n });\n\n this.#tooltip.setVisible(true);\n\n const drawStart = this.#drawInteraction.on(\"drawstart\", () => {\n this.#setState(\"active:drawing\");\n this.#tooltip.setText(\n this.#intl.value.formatMessage({\n id: \"create.tooltip.continue\"\n })\n );\n });\n\n const drawEnd = this.#drawInteraction.on(\"drawend\", (e) => {\n const feature = e.feature;\n if (!feature) {\n this.#destroy();\n this.#error = new Error(\"no feature available\");\n this.#waiter?.reject(this.#error);\n return;\n }\n this.#save(feature);\n });\n\n this.#interactionListener.push(drawStart, drawEnd);\n this.#mapListener.push(containerEvents);\n }\n\n reset() {\n this.#drawInteraction.abortDrawing();\n this.#tooltip.setText(\n this.#intl.value.formatMessage({\n id: \"create.tooltip.begin\"\n })\n );\n this.#setState(\"active:initialized\");\n }\n\n stop() {\n this.#destroy();\n this.#waiter?.resolve(undefined);\n }\n\n #destroy() {\n this.#map.layers.removeLayer(this.#editingLayer);\n this.#editingLayer.destroy();\n this.#olMap.removeInteraction(this.#drawInteraction);\n this.#tooltip.destroy();\n\n // Remove event listener on interaction and on map\n this.#interactionListener.forEach((listener) => {\n unByKey(listener);\n });\n this.#mapListener.forEach((listener) => {\n listener.destroy();\n });\n\n this.#setState(\"destroyed\");\n }\n\n triggerSave() {\n // Stop drawing - the `drawend` event is dispatched before inserting the feature.\n this.#drawInteraction.finishDrawing();\n }\n\n whenComplete(): Promise<Record<string, string> | undefined> {\n if (this.#state.value === \"destroyed\") {\n if (this.#error) {\n return Promise.reject(this.#error);\n } else {\n if (this.#featureId) {\n return Promise.resolve({ featureId: this.#featureId });\n } else {\n return Promise.resolve(undefined);\n }\n }\n }\n\n const manualPromise = (this.#waiter ??= createManualPromise());\n return manualPromise.promise;\n }\n}\n"],"names":[],"mappings":"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"}
@@ -1,18 +1,17 @@
1
+ import { HttpService } from "@open-pioneer/http";
1
2
  import { LayerFactory, MapModel, MapRegistry } from "@open-pioneer/map";
3
+ import { ServiceOptions } from "@open-pioneer/runtime";
4
+ import { Feature } from "ol";
2
5
  import { EditingService } from "./api";
3
6
  import { EditingCreateWorkflowImpl } from "./EditingCreateWorkflowImpl";
4
7
  import { EditingUpdateWorkflowImpl } from "./EditingUpdateWorkflowImpl";
5
- import { ServiceOptions } from "@open-pioneer/runtime";
6
- import { HttpService } from "@open-pioneer/http";
7
- import { Feature } from "ol";
8
8
  export interface References {
9
9
  mapRegistry: MapRegistry;
10
10
  httpService: HttpService;
11
11
  layerFactory: LayerFactory;
12
12
  }
13
13
  export declare class EditingServiceImpl implements EditingService {
14
- private _serviceOptions;
15
- private _workflows;
14
+ #private;
16
15
  constructor(serviceOptions: ServiceOptions<References>);
17
16
  createFeature(map: MapModel, ogcApiFeatureLayerUrl: URL): EditingCreateWorkflowImpl;
18
17
  updateFeature(map: MapModel, ogcApiFeatureLayerUrl: URL, feature: Feature): EditingUpdateWorkflowImpl;
@@ -1,20 +1,20 @@
1
+ import { watch } from '@conterra/reactivity-core';
1
2
  import { EditingCreateWorkflowImpl } from './EditingCreateWorkflowImpl.js';
2
3
  import { EditingUpdateWorkflowImpl } from './EditingUpdateWorkflowImpl.js';
3
- import { watch } from '@conterra/reactivity-core';
4
4
 
5
5
  class EditingServiceImpl {
6
- _serviceOptions;
7
- _workflows;
6
+ #serviceOptions;
7
+ #workflows;
8
8
  constructor(serviceOptions) {
9
- this._serviceOptions = serviceOptions;
10
- this._workflows = /* @__PURE__ */ new Map();
9
+ this.#serviceOptions = serviceOptions;
10
+ this.#workflows = /* @__PURE__ */ new Map();
11
11
  }
12
12
  createFeature(map, ogcApiFeatureLayerUrl) {
13
13
  if (!ogcApiFeatureLayerUrl || !map || !map.id) {
14
14
  throw new Error("Map, mapId or url is undefined.");
15
15
  }
16
16
  const mapId = map.id;
17
- let workflow = this._workflows.get(mapId);
17
+ let workflow = this.#workflows.get(mapId);
18
18
  if (workflow) {
19
19
  throw new Error(
20
20
  "EditingWorkflow could not be started. EditingWorkflow already in progress for this map."
@@ -23,13 +23,13 @@ class EditingServiceImpl {
23
23
  workflow = new EditingCreateWorkflowImpl({
24
24
  map,
25
25
  ogcApiFeatureLayerUrl,
26
- polygonStyle: this._serviceOptions.properties.polygonStyle,
27
- vertexStyle: this._serviceOptions.properties.vertexStyle,
28
- httpService: this._serviceOptions.references.httpService,
29
- layerFactory: this._serviceOptions.references.layerFactory,
30
- intl: this._serviceOptions.currentIntl
26
+ polygonStyle: this.#serviceOptions.properties.polygonStyle,
27
+ vertexStyle: this.#serviceOptions.properties.vertexStyle,
28
+ httpService: this.#serviceOptions.references.httpService,
29
+ layerFactory: this.#serviceOptions.references.layerFactory,
30
+ intl: this.#serviceOptions.currentIntl
31
31
  });
32
- this._workflows.set(mapId, workflow);
32
+ this.#workflows.set(mapId, workflow);
33
33
  this._connectToWorkflowDestroyEvent(workflow, mapId);
34
34
  return workflow;
35
35
  }
@@ -38,7 +38,7 @@ class EditingServiceImpl {
38
38
  throw new Error("Map, mapId or url is undefined.");
39
39
  }
40
40
  const mapId = map.id;
41
- let workflow = this._workflows.get(mapId);
41
+ let workflow = this.#workflows.get(mapId);
42
42
  if (workflow) {
43
43
  throw new Error(
44
44
  "EditingWorkflow could not be started. EditingWorkflow already in progress for this map."
@@ -48,26 +48,26 @@ class EditingServiceImpl {
48
48
  map,
49
49
  ogcApiFeatureLayerUrl,
50
50
  feature,
51
- polygonStyle: this._serviceOptions.properties.polygonStyle,
52
- vertexStyle: this._serviceOptions.properties.vertexStyle,
53
- httpService: this._serviceOptions.references.httpService,
54
- layerFactory: this._serviceOptions.references.layerFactory,
55
- intl: this._serviceOptions.currentIntl
51
+ polygonStyle: this.#serviceOptions.properties.polygonStyle,
52
+ vertexStyle: this.#serviceOptions.properties.vertexStyle,
53
+ httpService: this.#serviceOptions.references.httpService,
54
+ layerFactory: this.#serviceOptions.references.layerFactory,
55
+ intl: this.#serviceOptions.currentIntl
56
56
  });
57
- this._workflows.set(mapId, workflow);
57
+ this.#workflows.set(mapId, workflow);
58
58
  this._connectToWorkflowDestroyEvent(workflow, mapId);
59
59
  return workflow;
60
60
  }
61
61
  stop(map) {
62
62
  const mapId = typeof map === "string" ? map : map.id;
63
- const workflow = this._workflows.get(mapId);
63
+ const workflow = this.#workflows.get(mapId);
64
64
  if (workflow) {
65
65
  workflow.stop();
66
66
  }
67
67
  }
68
68
  reset(map) {
69
69
  const mapId = typeof map === "string" ? map : map.id;
70
- const workflow = this._workflows.get(mapId);
70
+ const workflow = this.#workflows.get(mapId);
71
71
  if (workflow) {
72
72
  workflow.reset();
73
73
  } else {
@@ -79,8 +79,8 @@ class EditingServiceImpl {
79
79
  () => [workflow.getState()],
80
80
  ([newState]) => {
81
81
  if (newState === "destroyed") {
82
- if (this._workflows.get(mapId) === workflow) {
83
- this._workflows.delete(mapId);
82
+ if (this.#workflows.get(mapId) === workflow) {
83
+ this.#workflows.delete(mapId);
84
84
  }
85
85
  watchStateHandle.destroy();
86
86
  }
@@ -1 +1 @@
1
- {"version":3,"file":"EditingServiceImpl.js","sources":["EditingServiceImpl.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { LayerFactory, MapModel, MapRegistry } from \"@open-pioneer/map\";\nimport { EditingService } from \"./api\";\nimport { EditingCreateWorkflowImpl } from \"./EditingCreateWorkflowImpl\";\nimport { EditingUpdateWorkflowImpl } from \"./EditingUpdateWorkflowImpl\";\nimport { FlatStyle } from \"ol/style/flat\";\nimport { ServiceOptions } from \"@open-pioneer/runtime\";\nimport { HttpService } from \"@open-pioneer/http\";\nimport { Feature } from \"ol\";\nimport { watch } from \"@conterra/reactivity-core\";\n\nexport interface References {\n mapRegistry: MapRegistry;\n httpService: HttpService;\n layerFactory: LayerFactory;\n}\n\nexport class EditingServiceImpl implements EditingService {\n private _serviceOptions: ServiceOptions<References>;\n private _workflows: Map<string, EditingCreateWorkflowImpl | EditingUpdateWorkflowImpl>;\n\n constructor(serviceOptions: ServiceOptions<References>) {\n this._serviceOptions = serviceOptions;\n this._workflows = new Map();\n }\n\n createFeature(map: MapModel, ogcApiFeatureLayerUrl: URL): EditingCreateWorkflowImpl {\n if (!ogcApiFeatureLayerUrl || !map || !map.id) {\n throw new Error(\"Map, mapId or url is undefined.\");\n }\n\n const mapId = map.id;\n\n let workflow = this._workflows.get(mapId);\n if (workflow) {\n throw new Error(\n \"EditingWorkflow could not be started. EditingWorkflow already in progress for this map.\"\n );\n }\n\n workflow = new EditingCreateWorkflowImpl({\n map,\n ogcApiFeatureLayerUrl,\n polygonStyle: this._serviceOptions.properties.polygonStyle as FlatStyle,\n vertexStyle: this._serviceOptions.properties.vertexStyle as FlatStyle,\n httpService: this._serviceOptions.references.httpService,\n layerFactory: this._serviceOptions.references.layerFactory,\n intl: this._serviceOptions.currentIntl\n });\n this._workflows.set(mapId, workflow);\n this._connectToWorkflowDestroyEvent(workflow, mapId);\n\n return workflow;\n }\n\n updateFeature(\n map: MapModel,\n ogcApiFeatureLayerUrl: URL,\n feature: Feature\n ): EditingUpdateWorkflowImpl {\n if (!ogcApiFeatureLayerUrl || !map || !map.id) {\n throw new Error(\"Map, mapId or url is undefined.\");\n }\n\n const mapId = map.id;\n\n let workflow = this._workflows.get(mapId);\n if (workflow) {\n throw new Error(\n \"EditingWorkflow could not be started. EditingWorkflow already in progress for this map.\"\n );\n }\n\n workflow = new EditingUpdateWorkflowImpl({\n map,\n ogcApiFeatureLayerUrl,\n feature,\n polygonStyle: this._serviceOptions.properties.polygonStyle as FlatStyle,\n vertexStyle: this._serviceOptions.properties.vertexStyle as FlatStyle,\n httpService: this._serviceOptions.references.httpService,\n layerFactory: this._serviceOptions.references.layerFactory,\n intl: this._serviceOptions.currentIntl\n });\n this._workflows.set(mapId, workflow);\n this._connectToWorkflowDestroyEvent(workflow, mapId);\n\n return workflow;\n }\n\n stop(map: string | MapModel): void {\n const mapId = typeof map === \"string\" ? map : map.id;\n const workflow = this._workflows.get(mapId);\n if (workflow) {\n workflow.stop();\n }\n // A missing workflow is not an error if all we want to do is stop it.\n }\n\n reset(map: string | MapModel): void {\n const mapId = typeof map === \"string\" ? map : map.id;\n const workflow = this._workflows.get(mapId);\n if (workflow) {\n workflow.reset();\n } else {\n throw new Error(\"No workflow found for mapId: \" + mapId);\n }\n }\n\n _connectToWorkflowDestroyEvent(\n workflow: EditingCreateWorkflowImpl | EditingUpdateWorkflowImpl,\n mapId: string\n ) {\n const watchStateHandle = watch(\n () => [workflow.getState()],\n ([newState]) => {\n if (newState === \"destroyed\") {\n if (this._workflows.get(mapId) === workflow) {\n this._workflows.delete(mapId);\n }\n watchStateHandle.destroy();\n }\n },\n { dispatch: \"sync\" }\n );\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"EditingServiceImpl.js","sources":["EditingServiceImpl.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { watch } from \"@conterra/reactivity-core\";\nimport { HttpService } from \"@open-pioneer/http\";\nimport { LayerFactory, MapModel, MapRegistry } from \"@open-pioneer/map\";\nimport { ServiceOptions } from \"@open-pioneer/runtime\";\nimport { Feature } from \"ol\";\nimport { FlatStyle } from \"ol/style/flat\";\nimport { EditingService } from \"./api\";\nimport { EditingCreateWorkflowImpl } from \"./EditingCreateWorkflowImpl\";\nimport { EditingUpdateWorkflowImpl } from \"./EditingUpdateWorkflowImpl\";\n\nexport interface References {\n mapRegistry: MapRegistry;\n httpService: HttpService;\n layerFactory: LayerFactory;\n}\n\nexport class EditingServiceImpl implements EditingService {\n #serviceOptions: ServiceOptions<References>;\n #workflows: Map<string, EditingCreateWorkflowImpl | EditingUpdateWorkflowImpl>;\n\n constructor(serviceOptions: ServiceOptions<References>) {\n this.#serviceOptions = serviceOptions;\n this.#workflows = new Map();\n }\n\n createFeature(map: MapModel, ogcApiFeatureLayerUrl: URL): EditingCreateWorkflowImpl {\n if (!ogcApiFeatureLayerUrl || !map || !map.id) {\n throw new Error(\"Map, mapId or url is undefined.\");\n }\n\n const mapId = map.id;\n\n let workflow = this.#workflows.get(mapId);\n if (workflow) {\n throw new Error(\n \"EditingWorkflow could not be started. EditingWorkflow already in progress for this map.\"\n );\n }\n\n workflow = new EditingCreateWorkflowImpl({\n map,\n ogcApiFeatureLayerUrl,\n polygonStyle: this.#serviceOptions.properties.polygonStyle as FlatStyle,\n vertexStyle: this.#serviceOptions.properties.vertexStyle as FlatStyle,\n httpService: this.#serviceOptions.references.httpService,\n layerFactory: this.#serviceOptions.references.layerFactory,\n intl: this.#serviceOptions.currentIntl\n });\n this.#workflows.set(mapId, workflow);\n this._connectToWorkflowDestroyEvent(workflow, mapId);\n\n return workflow;\n }\n\n updateFeature(\n map: MapModel,\n ogcApiFeatureLayerUrl: URL,\n feature: Feature\n ): EditingUpdateWorkflowImpl {\n if (!ogcApiFeatureLayerUrl || !map || !map.id) {\n throw new Error(\"Map, mapId or url is undefined.\");\n }\n\n const mapId = map.id;\n\n let workflow = this.#workflows.get(mapId);\n if (workflow) {\n throw new Error(\n \"EditingWorkflow could not be started. EditingWorkflow already in progress for this map.\"\n );\n }\n\n workflow = new EditingUpdateWorkflowImpl({\n map,\n ogcApiFeatureLayerUrl,\n feature,\n polygonStyle: this.#serviceOptions.properties.polygonStyle as FlatStyle,\n vertexStyle: this.#serviceOptions.properties.vertexStyle as FlatStyle,\n httpService: this.#serviceOptions.references.httpService,\n layerFactory: this.#serviceOptions.references.layerFactory,\n intl: this.#serviceOptions.currentIntl\n });\n this.#workflows.set(mapId, workflow);\n this._connectToWorkflowDestroyEvent(workflow, mapId);\n\n return workflow;\n }\n\n stop(map: string | MapModel): void {\n const mapId = typeof map === \"string\" ? map : map.id;\n const workflow = this.#workflows.get(mapId);\n if (workflow) {\n workflow.stop();\n }\n // A missing workflow is not an error if all we want to do is stop it.\n }\n\n reset(map: string | MapModel): void {\n const mapId = typeof map === \"string\" ? map : map.id;\n const workflow = this.#workflows.get(mapId);\n if (workflow) {\n workflow.reset();\n } else {\n throw new Error(\"No workflow found for mapId: \" + mapId);\n }\n }\n\n _connectToWorkflowDestroyEvent(\n workflow: EditingCreateWorkflowImpl | EditingUpdateWorkflowImpl,\n mapId: string\n ) {\n const watchStateHandle = watch(\n () => [workflow.getState()],\n ([newState]) => {\n if (newState === \"destroyed\") {\n if (this.#workflows.get(mapId) === workflow) {\n this.#workflows.delete(mapId);\n }\n watchStateHandle.destroy();\n }\n },\n { dispatch: \"sync\" }\n );\n }\n}\n"],"names":[],"mappings":"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"}
@@ -3,38 +3,13 @@ import { Modify } from "ol/interaction";
3
3
  import { EditingWorkflow, EditingWorkflowProps, EditingWorkflowState } from "./api";
4
4
  export declare class EditingUpdateWorkflowImpl implements EditingWorkflow {
5
5
  #private;
6
- private _httpService;
7
- private _intl;
8
- private _layerFactory;
9
- private _map;
10
- private _polygonStyle;
11
- private _vertexStyle;
12
- private _state;
13
- private _editLayerURL;
14
- private _featureId;
15
- private _initialFeature;
16
- private _editFeature;
17
- private _editingSource;
18
- private _editingLayer;
19
- private _modifyInteraction;
20
- private _olMap;
21
- private _tooltip;
22
- private _enterHandler;
23
- private _escapeHandler;
24
- private _error;
25
- private _interactionListener;
26
- private _mapListener;
27
6
  constructor(options: {
28
7
  feature: Feature;
29
8
  } & EditingWorkflowProps);
30
9
  getModifyInteraction(): Modify;
31
10
  getState(): EditingWorkflowState;
32
- private _setState;
33
- private _save;
34
- private _start;
35
11
  reset(): void;
36
12
  stop(): void;
37
- private _destroy;
38
13
  triggerSave(): void;
39
14
  whenComplete(): Promise<Record<string, string> | undefined>;
40
15
  }
@@ -13,111 +13,111 @@ import { createTooltip } from './Tooltip.js';
13
13
 
14
14
  class EditingUpdateWorkflowImpl {
15
15
  #waiter;
16
- _httpService;
17
- _intl;
18
- _layerFactory;
19
- _map;
20
- _polygonStyle;
21
- _vertexStyle;
22
- _state;
23
- _editLayerURL;
24
- _featureId;
25
- _initialFeature;
26
- _editFeature;
27
- _editingSource;
28
- _editingLayer;
29
- _modifyInteraction;
30
- _olMap;
31
- _tooltip;
32
- _enterHandler;
33
- _escapeHandler;
34
- _error;
35
- _interactionListener;
36
- _mapListener;
16
+ #httpService;
17
+ #intl;
18
+ #layerFactory;
19
+ #map;
20
+ #polygonStyle;
21
+ #vertexStyle;
22
+ #state;
23
+ #editLayerURL;
24
+ #featureId;
25
+ #initialFeature;
26
+ #editFeature;
27
+ #editingSource;
28
+ #editingLayer;
29
+ #modifyInteraction;
30
+ #olMap;
31
+ #tooltip;
32
+ #enterHandler;
33
+ #escapeHandler;
34
+ #error;
35
+ #interactionListener;
36
+ #mapListener;
37
37
  constructor(options) {
38
- this._httpService = options.httpService;
39
- this._layerFactory = options.layerFactory;
40
- this._intl = options.intl;
41
- this._polygonStyle = options.polygonStyle;
42
- this._vertexStyle = options.vertexStyle;
43
- this._map = options.map;
44
- this._olMap = options.map.olMap;
45
- this._state = reactive("active:initialized");
46
- this._editLayerURL = options.ogcApiFeatureLayerUrl;
47
- this._initialFeature = options.feature.clone();
48
- this._initialFeature.setId(options.feature.getId());
49
- this._editFeature = options.feature.clone();
50
- this._editFeature.setId(options.feature.getId());
51
- this._editFeature.setStyle(
38
+ this.#httpService = options.httpService;
39
+ this.#layerFactory = options.layerFactory;
40
+ this.#intl = options.intl;
41
+ this.#polygonStyle = options.polygonStyle;
42
+ this.#vertexStyle = options.vertexStyle;
43
+ this.#map = options.map;
44
+ this.#olMap = options.map.olMap;
45
+ this.#state = reactive("active:initialized");
46
+ this.#editLayerURL = options.ogcApiFeatureLayerUrl;
47
+ this.#initialFeature = options.feature.clone();
48
+ this.#initialFeature.setId(options.feature.getId());
49
+ this.#editFeature = options.feature.clone();
50
+ this.#editFeature.setId(options.feature.getId());
51
+ this.#editFeature.setStyle(
52
52
  createStyles({
53
- polygon: this._polygonStyle,
54
- vertex: this._vertexStyle
53
+ polygon: this.#polygonStyle,
54
+ vertex: this.#vertexStyle
55
55
  })
56
56
  );
57
- this._editingSource = new VectorSource({
58
- features: new Collection([this._editFeature])
57
+ this.#editingSource = new VectorSource({
58
+ features: new Collection([this.#editFeature])
59
59
  });
60
60
  const olLayer = new VectorLayer({
61
- source: this._editingSource
61
+ source: this.#editingSource
62
62
  });
63
- this._editingLayer = this._layerFactory.create({
63
+ this.#editingLayer = this.#layerFactory.create({
64
64
  type: SimpleLayer,
65
65
  title: "editing-layer",
66
66
  internal: true,
67
67
  olLayer
68
68
  });
69
- this._modifyInteraction = new Modify({
70
- source: this._editingSource
69
+ this.#modifyInteraction = new Modify({
70
+ source: this.#editingSource
71
71
  });
72
- this._tooltip = createTooltip(
73
- this._map,
74
- this._intl.value.formatMessage({ id: "create.tooltip.deselect" })
72
+ this.#tooltip = createTooltip(
73
+ this.#map,
74
+ this.#intl.value.formatMessage({ id: "create.tooltip.deselect" })
75
75
  );
76
- this._enterHandler = (e) => {
77
- if ((e.code === "Enter" || e.code === "NumpadEnter") && e.target === this._olMap.getTargetElement()) {
78
- const updatedFeature = this._editingSource.getFeatures()[0];
76
+ this.#enterHandler = (e) => {
77
+ if ((e.code === "Enter" || e.code === "NumpadEnter") && e.target === this.#olMap.getTargetElement()) {
78
+ const updatedFeature = this.#editingSource.getFeatures()[0];
79
79
  if (!updatedFeature) {
80
80
  throw Error("no updated feature found");
81
81
  }
82
- this._save(updatedFeature);
82
+ this.#save(updatedFeature);
83
83
  }
84
84
  };
85
- this._escapeHandler = (e) => {
86
- if (e.code === "Escape" && e.target === this._olMap.getTargetElement()) {
85
+ this.#escapeHandler = (e) => {
86
+ if (e.code === "Escape" && e.target === this.#olMap.getTargetElement()) {
87
87
  this.reset();
88
88
  }
89
89
  };
90
- this._interactionListener = [];
91
- this._mapListener = [];
92
- this._start();
90
+ this.#interactionListener = [];
91
+ this.#mapListener = [];
92
+ this.#start();
93
93
  }
94
94
  getModifyInteraction() {
95
- return this._modifyInteraction;
95
+ return this.#modifyInteraction;
96
96
  }
97
97
  getState() {
98
- return this._state.value;
98
+ return this.#state.value;
99
99
  }
100
- _setState(state) {
101
- this._state.value = state;
100
+ #setState(state) {
101
+ this.#state.value = state;
102
102
  }
103
- _save(feature) {
104
- this._setState("active:saving");
105
- const layerUrl = this._editLayerURL;
106
- this._featureId = feature.getId()?.toString();
107
- if (!this._featureId) {
108
- this._destroy();
109
- this._error = new Error("no feature id available");
110
- this.#waiter?.reject(this._error);
103
+ #save(feature) {
104
+ this.#setState("active:saving");
105
+ const layerUrl = this.#editLayerURL;
106
+ this.#featureId = feature.getId()?.toString();
107
+ if (!this.#featureId) {
108
+ this.#destroy();
109
+ this.#error = new Error("no feature id available");
110
+ this.#waiter?.reject(this.#error);
111
111
  return;
112
112
  }
113
113
  const geometry = feature?.getGeometry();
114
114
  if (!geometry) {
115
- this._destroy();
116
- this._error = new Error("no geometry available");
117
- this.#waiter?.reject(this._error);
115
+ this.#destroy();
116
+ this.#error = new Error("no geometry available");
117
+ this.#waiter?.reject(this.#error);
118
118
  return;
119
119
  }
120
- const projection = this._olMap.getView().getProjection();
120
+ const projection = this.#olMap.getView().getProjection();
121
121
  const geoJson = new GeoJSON({
122
122
  dataProjection: projection
123
123
  });
@@ -125,50 +125,50 @@ class EditingUpdateWorkflowImpl {
125
125
  rightHanded: true,
126
126
  decimals: 10
127
127
  });
128
- this._olMap.removeInteraction(this._modifyInteraction);
129
- this._tooltip.destroy();
130
- saveUpdatedFeature(
131
- this._httpService,
132
- layerUrl,
133
- this._featureId,
134
- geoJSONGeometry,
128
+ this.#olMap.removeInteraction(this.#modifyInteraction);
129
+ this.#tooltip.destroy();
130
+ saveUpdatedFeature({
131
+ httpService: this.#httpService,
132
+ url: layerUrl,
133
+ featureId: this.#featureId,
134
+ geometry: geoJSONGeometry,
135
135
  projection
136
- ).then((featureId) => {
137
- this._destroy();
136
+ }).then((featureId) => {
137
+ this.#destroy();
138
138
  this.#waiter?.resolve({ featureId });
139
139
  }).catch((err) => {
140
- this._destroy();
141
- this._error = new Error("Failed to save feature", { cause: err });
142
- this.#waiter?.reject(this._error);
140
+ this.#destroy();
141
+ this.#error = new Error("Failed to save feature", { cause: err });
142
+ this.#waiter?.reject(this.#error);
143
143
  });
144
144
  }
145
- _start() {
146
- this._map.layers.addLayer(this._editingLayer, { at: "topmost" });
147
- this._olMap.addInteraction(this._modifyInteraction);
148
- const feature = this._editingSource.getFeatures()[0];
145
+ #start() {
146
+ this.#map.layers.addLayer(this.#editingLayer, { at: "topmost" });
147
+ this.#olMap.addInteraction(this.#modifyInteraction);
148
+ const feature = this.#editingSource.getFeatures()[0];
149
149
  if (feature && !feature.getId()?.toString()) {
150
- this._destroy();
151
- this._error = new Error("no feature id available");
152
- this.#waiter?.reject(this._error);
150
+ this.#destroy();
151
+ this.#error = new Error("no feature id available");
152
+ this.#waiter?.reject(this.#error);
153
153
  return;
154
154
  }
155
155
  const containerEvents = effect(() => {
156
- const container = this._map.container;
156
+ const container = this.#map.container;
157
157
  if (!container) {
158
158
  return;
159
159
  }
160
- container.addEventListener("keydown", this._enterHandler, false);
161
- container.addEventListener("keydown", this._escapeHandler, false);
160
+ container.addEventListener("keydown", this.#enterHandler, false);
161
+ container.addEventListener("keydown", this.#escapeHandler, false);
162
162
  return () => {
163
- container.removeEventListener("keydown", this._enterHandler);
164
- container.removeEventListener("keydown", this._escapeHandler);
163
+ container.removeEventListener("keydown", this.#enterHandler);
164
+ container.removeEventListener("keydown", this.#escapeHandler);
165
165
  };
166
166
  });
167
- this._tooltip.setVisible(true);
168
- const click = this._map.olMap.on("click", (e) => {
167
+ this.#tooltip.setVisible(true);
168
+ const click = this.#map.olMap.on("click", (e) => {
169
169
  const coordinate = e.coordinate;
170
170
  const altKeyPressed = e.originalEvent.altKey;
171
- const features = this._editingSource.getFeaturesAtCoordinate(coordinate);
171
+ const features = this.#editingSource.getFeaturesAtCoordinate(coordinate);
172
172
  if (altKeyPressed) {
173
173
  return;
174
174
  }
@@ -176,53 +176,53 @@ class EditingUpdateWorkflowImpl {
176
176
  this.triggerSave();
177
177
  }
178
178
  });
179
- const modify = this._modifyInteraction.on("modifystart", () => {
180
- this._setState("active:drawing");
179
+ const modify = this.#modifyInteraction.on("modifystart", () => {
180
+ this.#setState("active:drawing");
181
181
  });
182
- this._interactionListener.push(click, modify);
183
- this._mapListener.push(containerEvents);
182
+ this.#interactionListener.push(click, modify);
183
+ this.#mapListener.push(containerEvents);
184
184
  }
185
185
  reset() {
186
- const geometry = this._initialFeature.getGeometry()?.clone();
187
- const resetFeature = this._editingSource.getFeatures()[0];
186
+ const geometry = this.#initialFeature.getGeometry()?.clone();
187
+ const resetFeature = this.#editingSource.getFeatures()[0];
188
188
  if (!resetFeature) {
189
189
  throw Error("no updated feature found");
190
190
  }
191
191
  resetFeature.setGeometry(geometry);
192
- this._setState("active:initialized");
192
+ this.#setState("active:initialized");
193
193
  }
194
194
  stop() {
195
- this._destroy();
195
+ this.#destroy();
196
196
  this.#waiter?.resolve(void 0);
197
197
  }
198
- _destroy() {
199
- this._editingSource.clear();
200
- this._map.layers.removeLayer(this._editingLayer);
201
- this._editingLayer.destroy();
202
- this._olMap.removeInteraction(this._modifyInteraction);
203
- this._tooltip.destroy();
204
- this._interactionListener.forEach((listener) => {
198
+ #destroy() {
199
+ this.#editingSource.clear();
200
+ this.#map.layers.removeLayer(this.#editingLayer);
201
+ this.#editingLayer.destroy();
202
+ this.#olMap.removeInteraction(this.#modifyInteraction);
203
+ this.#tooltip.destroy();
204
+ this.#interactionListener.forEach((listener) => {
205
205
  unByKey(listener);
206
206
  });
207
- this._mapListener.forEach((listener) => {
207
+ this.#mapListener.forEach((listener) => {
208
208
  listener.destroy();
209
209
  });
210
- this._setState("destroyed");
210
+ this.#setState("destroyed");
211
211
  }
212
212
  triggerSave() {
213
- const feature = this._editingSource.getFeatures()[0];
213
+ const feature = this.#editingSource.getFeatures()[0];
214
214
  if (!feature) {
215
215
  throw Error("no updated feature found");
216
216
  }
217
- this._save(feature);
217
+ this.#save(feature);
218
218
  }
219
219
  whenComplete() {
220
- if (this._state.value === "destroyed") {
221
- if (this._error) {
222
- return Promise.reject(this._error);
220
+ if (this.#state.value === "destroyed") {
221
+ if (this.#error) {
222
+ return Promise.reject(this.#error);
223
223
  } else {
224
- if (this._featureId) {
225
- return Promise.resolve({ featureId: this._featureId });
224
+ if (this.#featureId) {
225
+ return Promise.resolve({ featureId: this.#featureId });
226
226
  } else {
227
227
  return Promise.resolve(void 0);
228
228
  }
@@ -1 +1 @@
1
- {"version":3,"file":"EditingUpdateWorkflowImpl.js","sources":["EditingUpdateWorkflowImpl.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { Reactive, ReadonlyReactive, effect, reactive } from \"@conterra/reactivity-core\";\nimport { ManualPromise, Resource, createManualPromise } from \"@open-pioneer/core\";\nimport { HttpService } from \"@open-pioneer/http\";\nimport { LayerFactory, MapModel, SimpleLayer } from \"@open-pioneer/map\";\nimport { PackageIntl } from \"@open-pioneer/runtime\";\nimport { Collection } from \"ol\";\nimport { EventsKey } from \"ol/events\";\nimport Feature from \"ol/Feature\";\nimport {\n default as GeoJSON,\n default as GeoJSONGeometry,\n default as GeoJSONGeometryCollection\n} from \"ol/format/GeoJSON\";\nimport { Modify } from \"ol/interaction\";\nimport VectorLayer from \"ol/layer/Vector\";\nimport OlMap from \"ol/Map\";\nimport { unByKey } from \"ol/Observable\";\nimport VectorSource from \"ol/source/Vector\";\nimport { FlatStyle } from \"ol/style/flat\";\nimport { EditingWorkflow, EditingWorkflowProps, EditingWorkflowState } from \"./api\";\nimport { saveUpdatedFeature } from \"./SaveFeaturesHandler\";\nimport { createStyles } from \"./style-utils\";\nimport { Tooltip, createTooltip } from \"./Tooltip\";\n\nexport class EditingUpdateWorkflowImpl implements EditingWorkflow {\n #waiter: ManualPromise<Record<string, string> | undefined> | undefined;\n\n private _httpService: HttpService;\n private _intl: ReadonlyReactive<PackageIntl>;\n private _layerFactory: LayerFactory;\n\n private _map: MapModel;\n private _polygonStyle: FlatStyle;\n private _vertexStyle: FlatStyle;\n private _state: Reactive<EditingWorkflowState>;\n private _editLayerURL: URL;\n private _featureId: string | undefined;\n\n private _initialFeature: Feature;\n private _editFeature: Feature;\n private _editingSource: VectorSource;\n private _editingLayer: SimpleLayer;\n private _modifyInteraction: Modify;\n private _olMap: OlMap;\n private _tooltip: Tooltip;\n private _enterHandler: (e: KeyboardEvent) => void;\n private _escapeHandler: (e: KeyboardEvent) => void;\n\n private _error: Error | undefined;\n\n private _interactionListener: Array<EventsKey>;\n private _mapListener: Array<Resource>;\n\n constructor(options: { feature: Feature } & EditingWorkflowProps) {\n this._httpService = options.httpService;\n this._layerFactory = options.layerFactory;\n this._intl = options.intl;\n\n this._polygonStyle = options.polygonStyle;\n this._vertexStyle = options.vertexStyle;\n\n this._map = options.map;\n this._olMap = options.map.olMap;\n this._state = reactive(\"active:initialized\");\n this._editLayerURL = options.ogcApiFeatureLayerUrl;\n\n // Save copy of initial state for reset feature\n this._initialFeature = options.feature.clone();\n this._initialFeature.setId(options.feature.getId());\n\n // Work on copied feature to avoid the style to be applied on the original feature\n this._editFeature = options.feature.clone();\n this._editFeature.setId(options.feature.getId());\n\n this._editFeature.setStyle(\n createStyles({\n polygon: this._polygonStyle,\n vertex: this._vertexStyle\n })\n );\n\n this._editingSource = new VectorSource({\n features: new Collection([this._editFeature])\n });\n\n const olLayer = new VectorLayer({\n source: this._editingSource\n });\n this._editingLayer = this._layerFactory.create({\n type: SimpleLayer,\n title: \"editing-layer\",\n internal: true,\n olLayer: olLayer\n });\n\n this._modifyInteraction = new Modify({\n source: this._editingSource\n });\n\n this._tooltip = createTooltip(\n this._map,\n this._intl.value.formatMessage({ id: \"create.tooltip.deselect\" })\n );\n\n this._enterHandler = (e: KeyboardEvent) => {\n if (\n (e.code === \"Enter\" || e.code === \"NumpadEnter\") &&\n e.target === this._olMap.getTargetElement()\n ) {\n const updatedFeature = this._editingSource.getFeatures()[0];\n if (!updatedFeature) {\n throw Error(\"no updated feature found\");\n }\n this._save(updatedFeature);\n }\n };\n\n this._escapeHandler = (e: KeyboardEvent) => {\n if (e.code === \"Escape\" && e.target === this._olMap.getTargetElement()) {\n this.reset();\n }\n };\n\n this._interactionListener = [];\n this._mapListener = [];\n\n this._start();\n }\n\n getModifyInteraction() {\n return this._modifyInteraction;\n }\n\n getState() {\n return this._state.value;\n }\n\n private _setState(state: EditingWorkflowState) {\n this._state.value = state;\n }\n\n private _save(feature: Feature) {\n this._setState(\"active:saving\");\n\n const layerUrl = this._editLayerURL;\n\n this._featureId = feature.getId()?.toString();\n if (!this._featureId) {\n this._destroy();\n this._error = new Error(\"no feature id available\");\n this.#waiter?.reject(this._error);\n return;\n }\n\n const geometry = feature?.getGeometry();\n if (!geometry) {\n this._destroy();\n this._error = new Error(\"no geometry available\");\n this.#waiter?.reject(this._error);\n return;\n }\n const projection = this._olMap.getView().getProjection();\n const geoJson = new GeoJSON({\n dataProjection: projection\n });\n const geoJSONGeometry: GeoJSONGeometry | GeoJSONGeometryCollection =\n geoJson.writeGeometryObject(geometry, {\n rightHanded: true,\n decimals: 10\n });\n\n this._olMap.removeInteraction(this._modifyInteraction);\n this._tooltip.destroy();\n\n saveUpdatedFeature(\n this._httpService,\n layerUrl,\n this._featureId,\n geoJSONGeometry,\n projection\n )\n .then((featureId) => {\n this._destroy();\n this.#waiter?.resolve({ featureId });\n })\n .catch((err: Error) => {\n this._destroy();\n this._error = new Error(\"Failed to save feature\", { cause: err });\n this.#waiter?.reject(this._error);\n });\n }\n\n private _start() {\n this._map.layers.addLayer(this._editingLayer, { at: \"topmost\" });\n this._olMap.addInteraction(this._modifyInteraction);\n\n const feature = this._editingSource.getFeatures()[0];\n if (feature && !feature.getId()?.toString()) {\n this._destroy();\n this._error = new Error(\"no feature id available\");\n this.#waiter?.reject(this._error);\n return;\n }\n\n // Add EventListener on focused map to abort actual interaction via `Escape`\n const containerEvents = effect(() => {\n const container = this._map.container;\n if (!container) {\n return;\n }\n\n container.addEventListener(\"keydown\", this._enterHandler, false);\n container.addEventListener(\"keydown\", this._escapeHandler, false);\n return () => {\n container.removeEventListener(\"keydown\", this._enterHandler);\n container.removeEventListener(\"keydown\", this._escapeHandler);\n };\n });\n\n this._tooltip.setVisible(true);\n\n const click = this._map.olMap.on(\"click\", (e) => {\n const coordinate = e.coordinate;\n const altKeyPressed = e.originalEvent.altKey;\n const features = this._editingSource.getFeaturesAtCoordinate(coordinate);\n\n if (altKeyPressed) {\n return;\n }\n\n if (features.length === 0) {\n this.triggerSave();\n }\n });\n\n const modify = this._modifyInteraction.on(\"modifystart\", () => {\n this._setState(\"active:drawing\");\n });\n\n this._interactionListener.push(click, modify);\n this._mapListener.push(containerEvents);\n }\n\n reset() {\n // Clone geometry to pass geometry, not reference\n const geometry = this._initialFeature.getGeometry()?.clone();\n\n const resetFeature = this._editingSource.getFeatures()[0];\n if (!resetFeature) {\n throw Error(\"no updated feature found\");\n }\n resetFeature.setGeometry(geometry);\n\n this._setState(\"active:initialized\");\n }\n\n stop() {\n this._destroy();\n this.#waiter?.resolve(undefined);\n }\n\n private _destroy() {\n this._editingSource.clear();\n this._map.layers.removeLayer(this._editingLayer);\n this._editingLayer.destroy();\n this._olMap.removeInteraction(this._modifyInteraction);\n this._tooltip.destroy();\n\n // Remove event listener on interaction and on map\n this._interactionListener.forEach((listener) => {\n unByKey(listener);\n });\n this._mapListener.forEach((listener) => {\n listener.destroy();\n });\n\n this._setState(\"destroyed\");\n }\n\n triggerSave() {\n const feature = this._editingSource.getFeatures()[0];\n if (!feature) {\n throw Error(\"no updated feature found\");\n }\n this._save(feature);\n }\n\n whenComplete(): Promise<Record<string, string> | undefined> {\n if (this._state.value === \"destroyed\") {\n if (this._error) {\n return Promise.reject(this._error);\n } else {\n if (this._featureId) {\n return Promise.resolve({ featureId: this._featureId });\n } else {\n return Promise.resolve(undefined);\n }\n }\n }\n\n const manualPromise = (this.#waiter ??= createManualPromise());\n return manualPromise.promise;\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"EditingUpdateWorkflowImpl.js","sources":["EditingUpdateWorkflowImpl.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Reactive, ReadonlyReactive, effect, reactive } from \"@conterra/reactivity-core\";\nimport { ManualPromise, Resource, createManualPromise } from \"@open-pioneer/core\";\nimport { HttpService } from \"@open-pioneer/http\";\nimport { LayerFactory, MapModel, SimpleLayer } from \"@open-pioneer/map\";\nimport { PackageIntl } from \"@open-pioneer/runtime\";\nimport { Collection } from \"ol\";\nimport { EventsKey } from \"ol/events\";\nimport Feature from \"ol/Feature\";\nimport {\n default as GeoJSON,\n default as GeoJSONGeometry,\n default as GeoJSONGeometryCollection\n} from \"ol/format/GeoJSON\";\nimport { Modify } from \"ol/interaction\";\nimport VectorLayer from \"ol/layer/Vector\";\nimport OlMap from \"ol/Map\";\nimport { unByKey } from \"ol/Observable\";\nimport VectorSource from \"ol/source/Vector\";\nimport { FlatStyle } from \"ol/style/flat\";\nimport { EditingWorkflow, EditingWorkflowProps, EditingWorkflowState } from \"./api\";\nimport { saveUpdatedFeature } from \"./SaveFeaturesHandler\";\nimport { createStyles } from \"./style-utils\";\nimport { Tooltip, createTooltip } from \"./Tooltip\";\n\nexport class EditingUpdateWorkflowImpl implements EditingWorkflow {\n #waiter: ManualPromise<Record<string, string> | undefined> | undefined;\n\n #httpService: HttpService;\n #intl: ReadonlyReactive<PackageIntl>;\n #layerFactory: LayerFactory;\n\n #map: MapModel;\n #polygonStyle: FlatStyle;\n #vertexStyle: FlatStyle;\n #state: Reactive<EditingWorkflowState>;\n #editLayerURL: URL;\n #featureId: string | undefined;\n\n #initialFeature: Feature;\n #editFeature: Feature;\n #editingSource: VectorSource;\n #editingLayer: SimpleLayer;\n #modifyInteraction: Modify;\n #olMap: OlMap;\n #tooltip: Tooltip;\n #enterHandler: (e: KeyboardEvent) => void;\n #escapeHandler: (e: KeyboardEvent) => void;\n\n #error: Error | undefined;\n\n #interactionListener: Array<EventsKey>;\n #mapListener: Array<Resource>;\n\n constructor(options: { feature: Feature } & EditingWorkflowProps) {\n this.#httpService = options.httpService;\n this.#layerFactory = options.layerFactory;\n this.#intl = options.intl;\n\n this.#polygonStyle = options.polygonStyle;\n this.#vertexStyle = options.vertexStyle;\n\n this.#map = options.map;\n this.#olMap = options.map.olMap;\n this.#state = reactive(\"active:initialized\");\n this.#editLayerURL = options.ogcApiFeatureLayerUrl;\n\n // Save copy of initial state for reset feature\n this.#initialFeature = options.feature.clone();\n this.#initialFeature.setId(options.feature.getId());\n\n // Work on copied feature to avoid the style to be applied on the original feature\n this.#editFeature = options.feature.clone();\n this.#editFeature.setId(options.feature.getId());\n\n this.#editFeature.setStyle(\n createStyles({\n polygon: this.#polygonStyle,\n vertex: this.#vertexStyle\n })\n );\n\n this.#editingSource = new VectorSource({\n features: new Collection([this.#editFeature])\n });\n\n const olLayer = new VectorLayer({\n source: this.#editingSource\n });\n this.#editingLayer = this.#layerFactory.create({\n type: SimpleLayer,\n title: \"editing-layer\",\n internal: true,\n olLayer: olLayer\n });\n\n this.#modifyInteraction = new Modify({\n source: this.#editingSource\n });\n\n this.#tooltip = createTooltip(\n this.#map,\n this.#intl.value.formatMessage({ id: \"create.tooltip.deselect\" })\n );\n\n this.#enterHandler = (e: KeyboardEvent) => {\n if (\n (e.code === \"Enter\" || e.code === \"NumpadEnter\") &&\n e.target === this.#olMap.getTargetElement()\n ) {\n const updatedFeature = this.#editingSource.getFeatures()[0];\n if (!updatedFeature) {\n throw Error(\"no updated feature found\");\n }\n this.#save(updatedFeature);\n }\n };\n\n this.#escapeHandler = (e: KeyboardEvent) => {\n if (e.code === \"Escape\" && e.target === this.#olMap.getTargetElement()) {\n this.reset();\n }\n };\n\n this.#interactionListener = [];\n this.#mapListener = [];\n\n this.#start();\n }\n\n getModifyInteraction() {\n return this.#modifyInteraction;\n }\n\n getState() {\n return this.#state.value;\n }\n\n #setState(state: EditingWorkflowState) {\n this.#state.value = state;\n }\n\n #save(feature: Feature) {\n this.#setState(\"active:saving\");\n\n const layerUrl = this.#editLayerURL;\n\n this.#featureId = feature.getId()?.toString();\n if (!this.#featureId) {\n this.#destroy();\n this.#error = new Error(\"no feature id available\");\n this.#waiter?.reject(this.#error);\n return;\n }\n\n const geometry = feature?.getGeometry();\n if (!geometry) {\n this.#destroy();\n this.#error = new Error(\"no geometry available\");\n this.#waiter?.reject(this.#error);\n return;\n }\n const projection = this.#olMap.getView().getProjection();\n const geoJson = new GeoJSON({\n dataProjection: projection\n });\n const geoJSONGeometry: GeoJSONGeometry | GeoJSONGeometryCollection =\n geoJson.writeGeometryObject(geometry, {\n rightHanded: true,\n decimals: 10\n });\n\n this.#olMap.removeInteraction(this.#modifyInteraction);\n this.#tooltip.destroy();\n\n saveUpdatedFeature({\n httpService: this.#httpService,\n url: layerUrl,\n featureId: this.#featureId,\n geometry: geoJSONGeometry,\n projection\n })\n .then((featureId) => {\n this.#destroy();\n this.#waiter?.resolve({ featureId });\n })\n .catch((err: Error) => {\n this.#destroy();\n this.#error = new Error(\"Failed to save feature\", { cause: err });\n this.#waiter?.reject(this.#error);\n });\n }\n\n #start() {\n this.#map.layers.addLayer(this.#editingLayer, { at: \"topmost\" });\n this.#olMap.addInteraction(this.#modifyInteraction);\n\n const feature = this.#editingSource.getFeatures()[0];\n if (feature && !feature.getId()?.toString()) {\n this.#destroy();\n this.#error = new Error(\"no feature id available\");\n this.#waiter?.reject(this.#error);\n return;\n }\n\n // Add EventListener on focused map to abort actual interaction via `Escape`\n const containerEvents = effect(() => {\n const container = this.#map.container;\n if (!container) {\n return;\n }\n\n container.addEventListener(\"keydown\", this.#enterHandler, false);\n container.addEventListener(\"keydown\", this.#escapeHandler, false);\n return () => {\n container.removeEventListener(\"keydown\", this.#enterHandler);\n container.removeEventListener(\"keydown\", this.#escapeHandler);\n };\n });\n\n this.#tooltip.setVisible(true);\n\n const click = this.#map.olMap.on(\"click\", (e) => {\n const coordinate = e.coordinate;\n const altKeyPressed = e.originalEvent.altKey;\n const features = this.#editingSource.getFeaturesAtCoordinate(coordinate);\n\n if (altKeyPressed) {\n return;\n }\n\n if (features.length === 0) {\n this.triggerSave();\n }\n });\n\n const modify = this.#modifyInteraction.on(\"modifystart\", () => {\n this.#setState(\"active:drawing\");\n });\n\n this.#interactionListener.push(click, modify);\n this.#mapListener.push(containerEvents);\n }\n\n reset() {\n // Clone geometry to pass geometry, not reference\n const geometry = this.#initialFeature.getGeometry()?.clone();\n\n const resetFeature = this.#editingSource.getFeatures()[0];\n if (!resetFeature) {\n throw Error(\"no updated feature found\");\n }\n resetFeature.setGeometry(geometry);\n\n this.#setState(\"active:initialized\");\n }\n\n stop() {\n this.#destroy();\n this.#waiter?.resolve(undefined);\n }\n\n #destroy() {\n this.#editingSource.clear();\n this.#map.layers.removeLayer(this.#editingLayer);\n this.#editingLayer.destroy();\n this.#olMap.removeInteraction(this.#modifyInteraction);\n this.#tooltip.destroy();\n\n // Remove event listener on interaction and on map\n this.#interactionListener.forEach((listener) => {\n unByKey(listener);\n });\n this.#mapListener.forEach((listener) => {\n listener.destroy();\n });\n\n this.#setState(\"destroyed\");\n }\n\n triggerSave() {\n const feature = this.#editingSource.getFeatures()[0];\n if (!feature) {\n throw Error(\"no updated feature found\");\n }\n this.#save(feature);\n }\n\n whenComplete(): Promise<Record<string, string> | undefined> {\n if (this.#state.value === \"destroyed\") {\n if (this.#error) {\n return Promise.reject(this.#error);\n } else {\n if (this.#featureId) {\n return Promise.resolve({ featureId: this.#featureId });\n } else {\n return Promise.resolve(undefined);\n }\n }\n }\n\n const manualPromise = (this.#waiter ??= createManualPromise());\n return manualPromise.promise;\n }\n}\n"],"names":[],"mappings":"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"}
@@ -1,14 +1,26 @@
1
1
  import { HttpService } from "@open-pioneer/http";
2
- import GeoJSONGeometry from "ol/format/GeoJSON";
3
- import GeoJSONGeometryCollection from "ol/format/GeoJSON";
2
+ import { GeoJSONGeometry, GeoJSONGeometryCollection } from "ol/format/GeoJSON";
4
3
  import { Projection } from "ol/proj";
4
+ export interface SaveCreatedFeatureOptions {
5
+ httpService: HttpService;
6
+ url: URL;
7
+ geometry: GeoJSONGeometry | GeoJSONGeometryCollection;
8
+ projection: Projection;
9
+ }
5
10
  /**
6
11
  * Function to save a created feature to an OGC API Features service.
7
12
  * Resolves with feature id, or rejects if an error occurs.
8
13
  */
9
- export declare function saveCreatedFeature(httpService: HttpService, url: URL, geometry: GeoJSONGeometry | GeoJSONGeometryCollection, projection: Projection): Promise<string>;
14
+ export declare function saveCreatedFeature({ httpService, url, geometry, projection }: SaveCreatedFeatureOptions): Promise<string>;
15
+ export interface SaveUpdatedFeatureOptions {
16
+ httpService: HttpService;
17
+ url: URL;
18
+ featureId: string;
19
+ geometry: GeoJSONGeometry | GeoJSONGeometryCollection;
20
+ projection: Projection;
21
+ }
10
22
  /**
11
23
  * Function to save an updated geometry to a feature to an OGC API Features service.
12
24
  * Resolves with feature id, or rejects if an error occurs.
13
25
  */
14
- export declare function saveUpdatedFeature(httpService: HttpService, url: URL, featureId: string, geometry: GeoJSONGeometry | GeoJSONGeometryCollection, projection: Projection): Promise<string>;
26
+ export declare function saveUpdatedFeature({ httpService, url, featureId, geometry, projection }: SaveUpdatedFeatureOptions): Promise<string>;
@@ -1,4 +1,9 @@
1
- async function saveCreatedFeature(httpService, url, geometry, projection) {
1
+ async function saveCreatedFeature({
2
+ httpService,
3
+ url,
4
+ geometry,
5
+ projection
6
+ }) {
2
7
  const epsgCode = projection.getCode();
3
8
  const crs = epsgCode.replace("EPSG:", "http://www.opengis.net/def/crs/EPSG/0/");
4
9
  const response = await httpService.fetch(url, {
@@ -19,7 +24,13 @@ async function saveCreatedFeature(httpService, url, geometry, projection) {
19
24
  const featureId = location.substring(location.lastIndexOf("/") + 1);
20
25
  return Promise.resolve(featureId);
21
26
  }
22
- async function saveUpdatedFeature(httpService, url, featureId, geometry, projection) {
27
+ async function saveUpdatedFeature({
28
+ httpService,
29
+ url,
30
+ featureId,
31
+ geometry,
32
+ projection
33
+ }) {
23
34
  const epsgCode = projection.getCode();
24
35
  const crs = epsgCode.replace("EPSG:", "http://www.opengis.net/def/crs/EPSG/0/");
25
36
  const featureUrl = new URL(`${url.toString()}/${featureId}`);
@@ -1 +1 @@
1
- {"version":3,"file":"SaveFeaturesHandler.js","sources":["SaveFeaturesHandler.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { HttpService } from \"@open-pioneer/http\";\nimport GeoJSONGeometry from \"ol/format/GeoJSON\";\nimport GeoJSONGeometryCollection from \"ol/format/GeoJSON\";\nimport { Projection } from \"ol/proj\";\n\n/**\n * Function to save a created feature to an OGC API Features service.\n * Resolves with feature id, or rejects if an error occurs.\n */\nexport async function saveCreatedFeature(\n httpService: HttpService,\n url: URL,\n geometry: GeoJSONGeometry | GeoJSONGeometryCollection,\n projection: Projection\n) {\n const epsgCode = projection.getCode();\n const crs = epsgCode.replace(\"EPSG:\", \"http://www.opengis.net/def/crs/EPSG/0/\");\n const response = await httpService.fetch(url, {\n method: \"POST\",\n body: JSON.stringify({ type: \"Feature\", properties: {}, geometry: geometry }),\n headers: {\n \"Content-Type\": \"application/geo+json; charset=utf-8\",\n \"Content-Crs\": `<${crs}>`\n }\n });\n\n if (!response || !response.ok || response.status !== 201) {\n throw new Error(\"Request failed: \" + response.status);\n }\n\n const location = response.headers.get(\"location\");\n if (!location) {\n throw new Error(\"Request failed: no Location response header\");\n }\n\n const featureId = location.substring(location.lastIndexOf(\"/\") + 1);\n return Promise.resolve(featureId);\n}\n\n/**\n * Function to save an updated geometry to a feature to an OGC API Features service.\n * Resolves with feature id, or rejects if an error occurs.\n */\nexport async function saveUpdatedFeature(\n httpService: HttpService,\n url: URL,\n featureId: string,\n geometry: GeoJSONGeometry | GeoJSONGeometryCollection,\n projection: Projection\n) {\n const epsgCode = projection.getCode();\n const crs = epsgCode.replace(\"EPSG:\", \"http://www.opengis.net/def/crs/EPSG/0/\");\n const featureUrl = new URL(`${url.toString()}/${featureId}`);\n const response = await httpService.fetch(featureUrl, {\n method: \"PATCH\",\n body: JSON.stringify({ type: \"Feature\", properties: {}, geometry: geometry }),\n headers: {\n \"Content-Type\": \"application/geo+json; charset=utf-8\",\n \"Content-Crs\": `<${crs}>`\n }\n });\n\n if (!response || !response.ok || response.status !== 204) {\n throw new Error(\"Request failed: \" + response.status);\n }\n\n return Promise.resolve(featureId);\n}\n"],"names":[],"mappings":"AAWA,eAAsB,kBAAA,CAClB,WAAA,EACA,GAAA,EACA,QAAA,EACA,UAAA,EACF;AACE,EAAA,MAAM,QAAA,GAAW,WAAW,OAAA,EAAQ;AACpC,EAAA,MAAM,GAAA,GAAM,QAAA,CAAS,OAAA,CAAQ,OAAA,EAAS,wCAAwC,CAAA;AAC9E,EAAA,MAAM,QAAA,GAAW,MAAM,WAAA,CAAY,KAAA,CAAM,GAAA,EAAK;AAAA,IAC1C,MAAA,EAAQ,MAAA;AAAA,IACR,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,EAAE,IAAA,EAAM,WAAW,UAAA,EAAY,EAAC,EAAG,QAAA,EAAoB,CAAA;AAAA,IAC5E,OAAA,EAAS;AAAA,MACL,cAAA,EAAgB,qCAAA;AAAA,MAChB,aAAA,EAAe,IAAI,GAAG,CAAA,CAAA;AAAA;AAC1B,GACH,CAAA;AAED,EAAA,IAAI,CAAC,QAAA,IAAY,CAAC,SAAS,EAAA,IAAM,QAAA,CAAS,WAAW,GAAA,EAAK;AACtD,IAAA,MAAM,IAAI,KAAA,CAAM,kBAAA,GAAqB,QAAA,CAAS,MAAM,CAAA;AAAA,EACxD;AAEA,EAAA,MAAM,QAAA,GAAW,QAAA,CAAS,OAAA,CAAQ,GAAA,CAAI,UAAU,CAAA;AAChD,EAAA,IAAI,CAAC,QAAA,EAAU;AACX,IAAA,MAAM,IAAI,MAAM,6CAA6C,CAAA;AAAA,EACjE;AAEA,EAAA,MAAM,YAAY,QAAA,CAAS,SAAA,CAAU,SAAS,WAAA,CAAY,GAAG,IAAI,CAAC,CAAA;AAClE,EAAA,OAAO,OAAA,CAAQ,QAAQ,SAAS,CAAA;AACpC;AAMA,eAAsB,kBAAA,CAClB,WAAA,EACA,GAAA,EACA,SAAA,EACA,UACA,UAAA,EACF;AACE,EAAA,MAAM,QAAA,GAAW,WAAW,OAAA,EAAQ;AACpC,EAAA,MAAM,GAAA,GAAM,QAAA,CAAS,OAAA,CAAQ,OAAA,EAAS,wCAAwC,CAAA;AAC9E,EAAA,MAAM,UAAA,GAAa,IAAI,GAAA,CAAI,CAAA,EAAG,IAAI,QAAA,EAAU,CAAA,CAAA,EAAI,SAAS,CAAA,CAAE,CAAA;AAC3D,EAAA,MAAM,QAAA,GAAW,MAAM,WAAA,CAAY,KAAA,CAAM,UAAA,EAAY;AAAA,IACjD,MAAA,EAAQ,OAAA;AAAA,IACR,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,EAAE,IAAA,EAAM,WAAW,UAAA,EAAY,EAAC,EAAG,QAAA,EAAoB,CAAA;AAAA,IAC5E,OAAA,EAAS;AAAA,MACL,cAAA,EAAgB,qCAAA;AAAA,MAChB,aAAA,EAAe,IAAI,GAAG,CAAA,CAAA;AAAA;AAC1B,GACH,CAAA;AAED,EAAA,IAAI,CAAC,QAAA,IAAY,CAAC,SAAS,EAAA,IAAM,QAAA,CAAS,WAAW,GAAA,EAAK;AACtD,IAAA,MAAM,IAAI,KAAA,CAAM,kBAAA,GAAqB,QAAA,CAAS,MAAM,CAAA;AAAA,EACxD;AAEA,EAAA,OAAO,OAAA,CAAQ,QAAQ,SAAS,CAAA;AACpC;;;;"}
1
+ {"version":3,"file":"SaveFeaturesHandler.js","sources":["SaveFeaturesHandler.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { HttpService } from \"@open-pioneer/http\";\nimport { GeoJSONGeometry, GeoJSONGeometryCollection } from \"ol/format/GeoJSON\";\nimport { Projection } from \"ol/proj\";\n\nexport interface SaveCreatedFeatureOptions {\n httpService: HttpService;\n url: URL;\n geometry: GeoJSONGeometry | GeoJSONGeometryCollection;\n projection: Projection;\n}\n\n/**\n * Function to save a created feature to an OGC API Features service.\n * Resolves with feature id, or rejects if an error occurs.\n */\nexport async function saveCreatedFeature({\n httpService,\n url,\n geometry,\n projection\n}: SaveCreatedFeatureOptions) {\n const epsgCode = projection.getCode();\n const crs = epsgCode.replace(\"EPSG:\", \"http://www.opengis.net/def/crs/EPSG/0/\");\n const response = await httpService.fetch(url, {\n method: \"POST\",\n body: JSON.stringify({ type: \"Feature\", properties: {}, geometry: geometry }),\n headers: {\n \"Content-Type\": \"application/geo+json; charset=utf-8\",\n \"Content-Crs\": `<${crs}>`\n }\n });\n\n if (!response || !response.ok || response.status !== 201) {\n throw new Error(\"Request failed: \" + response.status);\n }\n\n const location = response.headers.get(\"location\");\n if (!location) {\n throw new Error(\"Request failed: no Location response header\");\n }\n\n const featureId = location.substring(location.lastIndexOf(\"/\") + 1);\n return Promise.resolve(featureId);\n}\n\nexport interface SaveUpdatedFeatureOptions {\n httpService: HttpService;\n url: URL;\n featureId: string;\n geometry: GeoJSONGeometry | GeoJSONGeometryCollection;\n projection: Projection;\n}\n\n/**\n * Function to save an updated geometry to a feature to an OGC API Features service.\n * Resolves with feature id, or rejects if an error occurs.\n */\nexport async function saveUpdatedFeature({\n httpService,\n url,\n featureId,\n geometry,\n projection\n}: SaveUpdatedFeatureOptions) {\n const epsgCode = projection.getCode();\n const crs = epsgCode.replace(\"EPSG:\", \"http://www.opengis.net/def/crs/EPSG/0/\");\n const featureUrl = new URL(`${url.toString()}/${featureId}`);\n const response = await httpService.fetch(featureUrl, {\n method: \"PATCH\",\n body: JSON.stringify({ type: \"Feature\", properties: {}, geometry: geometry }),\n headers: {\n \"Content-Type\": \"application/geo+json; charset=utf-8\",\n \"Content-Crs\": `<${crs}>`\n }\n });\n\n if (!response || !response.ok || response.status !== 204) {\n throw new Error(\"Request failed: \" + response.status);\n }\n\n return Promise.resolve(featureId);\n}\n"],"names":[],"mappings":"AAkBA,eAAsB,kBAAA,CAAmB;AAAA,EACrC,WAAA;AAAA,EACA,GAAA;AAAA,EACA,QAAA;AAAA,EACA;AACJ,CAAA,EAA8B;AAC1B,EAAA,MAAM,QAAA,GAAW,WAAW,OAAA,EAAQ;AACpC,EAAA,MAAM,GAAA,GAAM,QAAA,CAAS,OAAA,CAAQ,OAAA,EAAS,wCAAwC,CAAA;AAC9E,EAAA,MAAM,QAAA,GAAW,MAAM,WAAA,CAAY,KAAA,CAAM,GAAA,EAAK;AAAA,IAC1C,MAAA,EAAQ,MAAA;AAAA,IACR,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,EAAE,IAAA,EAAM,WAAW,UAAA,EAAY,EAAC,EAAG,QAAA,EAAoB,CAAA;AAAA,IAC5E,OAAA,EAAS;AAAA,MACL,cAAA,EAAgB,qCAAA;AAAA,MAChB,aAAA,EAAe,IAAI,GAAG,CAAA,CAAA;AAAA;AAC1B,GACH,CAAA;AAED,EAAA,IAAI,CAAC,QAAA,IAAY,CAAC,SAAS,EAAA,IAAM,QAAA,CAAS,WAAW,GAAA,EAAK;AACtD,IAAA,MAAM,IAAI,KAAA,CAAM,kBAAA,GAAqB,QAAA,CAAS,MAAM,CAAA;AAAA,EACxD;AAEA,EAAA,MAAM,QAAA,GAAW,QAAA,CAAS,OAAA,CAAQ,GAAA,CAAI,UAAU,CAAA;AAChD,EAAA,IAAI,CAAC,QAAA,EAAU;AACX,IAAA,MAAM,IAAI,MAAM,6CAA6C,CAAA;AAAA,EACjE;AAEA,EAAA,MAAM,YAAY,QAAA,CAAS,SAAA,CAAU,SAAS,WAAA,CAAY,GAAG,IAAI,CAAC,CAAA;AAClE,EAAA,OAAO,OAAA,CAAQ,QAAQ,SAAS,CAAA;AACpC;AAcA,eAAsB,kBAAA,CAAmB;AAAA,EACrC,WAAA;AAAA,EACA,GAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAA;AAAA,EACA;AACJ,CAAA,EAA8B;AAC1B,EAAA,MAAM,QAAA,GAAW,WAAW,OAAA,EAAQ;AACpC,EAAA,MAAM,GAAA,GAAM,QAAA,CAAS,OAAA,CAAQ,OAAA,EAAS,wCAAwC,CAAA;AAC9E,EAAA,MAAM,UAAA,GAAa,IAAI,GAAA,CAAI,CAAA,EAAG,IAAI,QAAA,EAAU,CAAA,CAAA,EAAI,SAAS,CAAA,CAAE,CAAA;AAC3D,EAAA,MAAM,QAAA,GAAW,MAAM,WAAA,CAAY,KAAA,CAAM,UAAA,EAAY;AAAA,IACjD,MAAA,EAAQ,OAAA;AAAA,IACR,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,EAAE,IAAA,EAAM,WAAW,UAAA,EAAY,EAAC,EAAG,QAAA,EAAoB,CAAA;AAAA,IAC5E,OAAA,EAAS;AAAA,MACL,cAAA,EAAgB,qCAAA;AAAA,MAChB,aAAA,EAAe,IAAI,GAAG,CAAA,CAAA;AAAA;AAC1B,GACH,CAAA;AAED,EAAA,IAAI,CAAC,QAAA,IAAY,CAAC,SAAS,EAAA,IAAM,QAAA,CAAS,WAAW,GAAA,EAAK;AACtD,IAAA,MAAM,IAAI,KAAA,CAAM,kBAAA,GAAqB,QAAA,CAAS,MAAM,CAAA;AAAA,EACxD;AAEA,EAAA,OAAO,OAAA,CAAQ,QAAQ,SAAS,CAAA;AACpC;;;;"}
package/Tooltip.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Tooltip.js","sources":["Tooltip.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { Resource } from \"@open-pioneer/core\";\nimport { MapModel } from \"@open-pioneer/map\";\n\n/**\n * Represents a tooltip rendered on the OpenLayers map\n */\nexport interface Tooltip extends Resource {\n setVisible(visible: boolean): void;\n setText(text: string): void;\n}\n\n/**\n * Creates a new tooltip on the given map, with the given text content.\n *\n * The tooltip will follow the mouse while it moves over the map.\n *\n * Note: the tooltip starts invisible, and must be toggled on via `setVisible(true)`.\n */\nexport function createTooltip(map: MapModel, text: string): Tooltip {\n const overlay = map.overlays.add({\n content: text,\n position: \"follow-pointer\",\n offset: [15, 0],\n positioning: \"center-left\",\n ariaRole: \"tooltip\",\n className: \"editing-tooltip\"\n });\n\n return {\n destroy() {\n overlay.destroy();\n },\n setVisible(visible) {\n overlay.element.classList.toggle(\"editing-tooltip-hidden\", !visible);\n },\n setText(text) {\n overlay.setContent(text);\n }\n };\n}\n"],"names":["text"],"mappings":"AAoBO,SAAS,aAAA,CAAc,KAAe,IAAA,EAAuB;AAChE,EAAA,MAAM,OAAA,GAAU,GAAA,CAAI,QAAA,CAAS,GAAA,CAAI;AAAA,IAC7B,OAAA,EAAS,IAAA;AAAA,IACT,QAAA,EAAU,gBAAA;AAAA,IACV,MAAA,EAAQ,CAAC,EAAA,EAAI,CAAC,CAAA;AAAA,IACd,WAAA,EAAa,aAAA;AAAA,IACb,QAAA,EAAU,SAAA;AAAA,IACV,SAAA,EAAW;AAAA,GACd,CAAA;AAED,EAAA,OAAO;AAAA,IACH,OAAA,GAAU;AACN,MAAA,OAAA,CAAQ,OAAA,EAAQ;AAAA,IACpB,CAAA;AAAA,IACA,WAAW,OAAA,EAAS;AAChB,MAAA,OAAA,CAAQ,OAAA,CAAQ,SAAA,CAAU,MAAA,CAAO,wBAAA,EAA0B,CAAC,OAAO,CAAA;AAAA,IACvE,CAAA;AAAA,IACA,QAAQA,KAAAA,EAAM;AACV,MAAA,OAAA,CAAQ,WAAWA,KAAI,CAAA;AAAA,IAC3B;AAAA,GACJ;AACJ;;;;"}
1
+ {"version":3,"file":"Tooltip.js","sources":["Tooltip.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Resource } from \"@open-pioneer/core\";\nimport { MapModel } from \"@open-pioneer/map\";\n\n/**\n * Represents a tooltip rendered on the OpenLayers map\n */\nexport interface Tooltip extends Resource {\n setVisible(visible: boolean): void;\n setText(text: string): void;\n}\n\n/**\n * Creates a new tooltip on the given map, with the given text content.\n *\n * The tooltip will follow the mouse while it moves over the map.\n *\n * Note: the tooltip starts invisible, and must be toggled on via `setVisible(true)`.\n */\nexport function createTooltip(map: MapModel, text: string): Tooltip {\n const overlay = map.overlays.add({\n content: text,\n position: \"follow-pointer\",\n offset: [15, 0],\n positioning: \"center-left\",\n ariaRole: \"tooltip\",\n className: \"editing-tooltip\"\n });\n\n return {\n destroy() {\n overlay.destroy();\n },\n setVisible(visible) {\n overlay.element.classList.toggle(\"editing-tooltip-hidden\", !visible);\n },\n setText(text) {\n overlay.setContent(text);\n }\n };\n}\n"],"names":["text"],"mappings":"AAqBO,SAAS,aAAA,CAAc,KAAe,IAAA,EAAuB;AAChE,EAAA,MAAM,OAAA,GAAU,GAAA,CAAI,QAAA,CAAS,GAAA,CAAI;AAAA,IAC7B,OAAA,EAAS,IAAA;AAAA,IACT,QAAA,EAAU,gBAAA;AAAA,IACV,MAAA,EAAQ,CAAC,EAAA,EAAI,CAAC,CAAA;AAAA,IACd,WAAA,EAAa,aAAA;AAAA,IACb,QAAA,EAAU,SAAA;AAAA,IACV,SAAA,EAAW;AAAA,GACd,CAAA;AAED,EAAA,OAAO;AAAA,IACH,OAAA,GAAU;AACN,MAAA,OAAA,CAAQ,OAAA,EAAQ;AAAA,IACpB,CAAA;AAAA,IACA,WAAW,OAAA,EAAS;AAChB,MAAA,OAAA,CAAQ,OAAA,CAAQ,SAAA,CAAU,MAAA,CAAO,wBAAA,EAA0B,CAAC,OAAO,CAAA;AAAA,IACvE,CAAA;AAAA,IACA,QAAQA,KAAAA,EAAM;AACV,MAAA,OAAA,CAAQ,WAAWA,KAAI,CAAA;AAAA,IAC3B;AAAA,GACJ;AACJ;;;;"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@open-pioneer/editing",
4
- "version": "1.4.0-dev.20260625074633",
4
+ "version": "1.4.0",
5
5
  "description": "This package provides an editing service that allows to start and handle geometry editing workflows.",
6
6
  "keywords": [
7
7
  "open-pioneer-trails"
@@ -14,12 +14,12 @@
14
14
  "directory": "src/packages/editing"
15
15
  },
16
16
  "dependencies": {
17
- "@open-pioneer/core": "4.7.0-dev.20260624141040",
18
- "@open-pioneer/http": "4.7.0-dev.20260624141040",
19
- "@open-pioneer/runtime": "4.7.0-dev.20260624141040",
20
- "ol": "^10.9.0",
21
17
  "@conterra/reactivity-core": "^0.8.6",
22
- "@open-pioneer/map": "1.4.0-dev.20260625074633"
18
+ "@open-pioneer/core": "^4.7.0",
19
+ "@open-pioneer/http": "^4.7.0",
20
+ "@open-pioneer/runtime": "^4.7.0",
21
+ "ol": "^10.9.0",
22
+ "@open-pioneer/map": "1.4.0"
23
23
  },
24
24
  "exports": {
25
25
  "./package.json": "./package.json",
package/style-utils.js CHANGED
@@ -1,6 +1,6 @@
1
+ import { Feature } from 'ol';
1
2
  import { MultiPoint } from 'ol/geom.js';
2
3
  import VectorLayer from 'ol/layer/Vector.js';
3
- import { Feature } from 'ol';
4
4
 
5
5
  function createStyles(editingStyle) {
6
6
  let polygonStyle = convertFlatStyleToStyle(editingStyle.polygon);
@@ -1 +1 @@
1
- {"version":3,"file":"style-utils.js","sources":["style-utils.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { Style } from \"ol/style\";\nimport { MultiPoint, Polygon } from \"ol/geom\";\nimport { GeometryFunction } from \"ol/style/Style\";\nimport { FlatStyle } from \"ol/style/flat\";\nimport VectorLayer from \"ol/layer/Vector\";\nimport { Feature } from \"ol\";\n\ninterface EditingStyleProps {\n polygon: FlatStyle;\n vertex: FlatStyle;\n}\n\n/**\n * Function to retrieve an OpenLayers style for an editing workflow\n * from editing polygon and vertex style.\n *\n * The polygon OpenLayers FlatStyle is convert to an OpenLayers style.\n *\n * The vertex OpenLayers FlatStyle is convert to an OpenLayers style\n * by setting an geometry to the style to render a vertex geometry instead of the feature's geometry.\n */\nexport function createStyles(editingStyle: EditingStyleProps) {\n let polygonStyle = convertFlatStyleToStyle(editingStyle.polygon);\n if (Array.isArray(polygonStyle)) {\n polygonStyle = polygonStyle[0];\n }\n\n let vertexStyle = convertFlatStyleToStyle(editingStyle.vertex);\n if (Array.isArray(vertexStyle)) {\n vertexStyle = vertexStyle[0];\n }\n\n const style = [];\n if (polygonStyle) {\n style.push(polygonStyle);\n }\n\n // Set a vertex geometry that is rendered instead of the feature's geometry\n if (vertexStyle) {\n vertexStyle.setGeometry(createVertexGeometry);\n style.push(vertexStyle);\n }\n\n return style;\n}\n\n/**\n * Function to create a new multi point geometry from a given feature (to style the point as a vertex).\n * Returns an Openlayers geometry function.\n */\nconst createVertexGeometry: GeometryFunction = (feature) => {\n if (feature) {\n const geometry = feature.getGeometry() as Polygon;\n if (geometry && geometry.getType() === \"Polygon\") {\n const coordinates = geometry.getCoordinates()[0];\n if (coordinates) {\n return new MultiPoint(coordinates);\n }\n }\n }\n return undefined;\n};\n\n/**\n * Function to convert a OpenLayers FlatStyle to an OpenLayers Style by setting the FlatStyle\n * to an OpenLayers feature and retrieving the style from a vector layer's style function.\n */\nconst convertFlatStyleToStyle = (flatStyle: FlatStyle): Style | Style[] | undefined => {\n const feature = new Feature();\n const vectorLayer = new VectorLayer({ style: flatStyle });\n\n const styleFunction = vectorLayer.getStyleFunction();\n if (!styleFunction) {\n throw new Error(\"can't retrieve style function\");\n }\n\n const styles = styleFunction(feature, 1);\n if (!styles) {\n throw new Error(\"can't retrieve styles from feature style function\");\n }\n\n // Return only first style in array\n if (Array.isArray(styles) && styles.length) {\n return styles.length > 1 ? styles : styles[0];\n } else {\n return styles;\n }\n};\n"],"names":[],"mappings":";;;;AAuBO,SAAS,aAAa,YAAA,EAAiC;AAC1D,EAAA,IAAI,YAAA,GAAe,uBAAA,CAAwB,YAAA,CAAa,OAAO,CAAA;AAC/D,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,YAAY,CAAA,EAAG;AAC7B,IAAA,YAAA,GAAe,aAAa,CAAC,CAAA;AAAA,EACjC;AAEA,EAAA,IAAI,WAAA,GAAc,uBAAA,CAAwB,YAAA,CAAa,MAAM,CAAA;AAC7D,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,WAAW,CAAA,EAAG;AAC5B,IAAA,WAAA,GAAc,YAAY,CAAC,CAAA;AAAA,EAC/B;AAEA,EAAA,MAAM,QAAQ,EAAC;AACf,EAAA,IAAI,YAAA,EAAc;AACd,IAAA,KAAA,CAAM,KAAK,YAAY,CAAA;AAAA,EAC3B;AAGA,EAAA,IAAI,WAAA,EAAa;AACb,IAAA,WAAA,CAAY,YAAY,oBAAoB,CAAA;AAC5C,IAAA,KAAA,CAAM,KAAK,WAAW,CAAA;AAAA,EAC1B;AAEA,EAAA,OAAO,KAAA;AACX;AAMA,MAAM,oBAAA,GAAyC,CAAC,OAAA,KAAY;AACxD,EAAA,IAAI,OAAA,EAAS;AACT,IAAA,MAAM,QAAA,GAAW,QAAQ,WAAA,EAAY;AACrC,IAAA,IAAI,QAAA,IAAY,QAAA,CAAS,OAAA,EAAQ,KAAM,SAAA,EAAW;AAC9C,MAAA,MAAM,WAAA,GAAc,QAAA,CAAS,cAAA,EAAe,CAAE,CAAC,CAAA;AAC/C,MAAA,IAAI,WAAA,EAAa;AACb,QAAA,OAAO,IAAI,WAAW,WAAW,CAAA;AAAA,MACrC;AAAA,IACJ;AAAA,EACJ;AACA,EAAA,OAAO,MAAA;AACX,CAAA;AAMA,MAAM,uBAAA,GAA0B,CAAC,SAAA,KAAsD;AACnF,EAAA,MAAM,OAAA,GAAU,IAAI,OAAA,EAAQ;AAC5B,EAAA,MAAM,cAAc,IAAI,WAAA,CAAY,EAAE,KAAA,EAAO,WAAW,CAAA;AAExD,EAAA,MAAM,aAAA,GAAgB,YAAY,gBAAA,EAAiB;AACnD,EAAA,IAAI,CAAC,aAAA,EAAe;AAChB,IAAA,MAAM,IAAI,MAAM,+BAA+B,CAAA;AAAA,EACnD;AAEA,EAAA,MAAM,MAAA,GAAS,aAAA,CAAc,OAAA,EAAS,CAAC,CAAA;AACvC,EAAA,IAAI,CAAC,MAAA,EAAQ;AACT,IAAA,MAAM,IAAI,MAAM,mDAAmD,CAAA;AAAA,EACvE;AAGA,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,MAAM,CAAA,IAAK,OAAO,MAAA,EAAQ;AACxC,IAAA,OAAO,MAAA,CAAO,MAAA,GAAS,CAAA,GAAI,MAAA,GAAS,OAAO,CAAC,CAAA;AAAA,EAChD,CAAA,MAAO;AACH,IAAA,OAAO,MAAA;AAAA,EACX;AACJ,CAAA;;;;"}
1
+ {"version":3,"file":"style-utils.js","sources":["style-utils.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Feature } from \"ol\";\nimport { MultiPoint, Polygon } from \"ol/geom\";\nimport VectorLayer from \"ol/layer/Vector\";\nimport { Style } from \"ol/style\";\nimport { FlatStyle } from \"ol/style/flat\";\nimport { GeometryFunction } from \"ol/style/Style\";\n\ninterface EditingStyleProps {\n polygon: FlatStyle;\n vertex: FlatStyle;\n}\n\n/**\n * Function to retrieve an OpenLayers style for an editing workflow\n * from editing polygon and vertex style.\n *\n * The polygon OpenLayers FlatStyle is convert to an OpenLayers style.\n *\n * The vertex OpenLayers FlatStyle is convert to an OpenLayers style\n * by setting an geometry to the style to render a vertex geometry instead of the feature's geometry.\n */\nexport function createStyles(editingStyle: EditingStyleProps) {\n let polygonStyle = convertFlatStyleToStyle(editingStyle.polygon);\n if (Array.isArray(polygonStyle)) {\n polygonStyle = polygonStyle[0];\n }\n\n let vertexStyle = convertFlatStyleToStyle(editingStyle.vertex);\n if (Array.isArray(vertexStyle)) {\n vertexStyle = vertexStyle[0];\n }\n\n const style = [];\n if (polygonStyle) {\n style.push(polygonStyle);\n }\n\n // Set a vertex geometry that is rendered instead of the feature's geometry\n if (vertexStyle) {\n vertexStyle.setGeometry(createVertexGeometry);\n style.push(vertexStyle);\n }\n\n return style;\n}\n\n/**\n * Function to create a new multi point geometry from a given feature (to style the point as a vertex).\n * Returns an Openlayers geometry function.\n */\nconst createVertexGeometry: GeometryFunction = (feature) => {\n if (feature) {\n const geometry = feature.getGeometry() as Polygon;\n if (geometry && geometry.getType() === \"Polygon\") {\n const coordinates = geometry.getCoordinates()[0];\n if (coordinates) {\n return new MultiPoint(coordinates);\n }\n }\n }\n return undefined;\n};\n\n/**\n * Function to convert a OpenLayers FlatStyle to an OpenLayers Style by setting the FlatStyle\n * to an OpenLayers feature and retrieving the style from a vector layer's style function.\n */\nconst convertFlatStyleToStyle = (flatStyle: FlatStyle): Style | Style[] | undefined => {\n const feature = new Feature();\n const vectorLayer = new VectorLayer({ style: flatStyle });\n\n const styleFunction = vectorLayer.getStyleFunction();\n if (!styleFunction) {\n throw new Error(\"can't retrieve style function\");\n }\n\n const styles = styleFunction(feature, 1);\n if (!styles) {\n throw new Error(\"can't retrieve styles from feature style function\");\n }\n\n // Return only first style in array\n if (Array.isArray(styles) && styles.length) {\n return styles.length > 1 ? styles : styles[0];\n } else {\n return styles;\n }\n};\n"],"names":[],"mappings":";;;;AAwBO,SAAS,aAAa,YAAA,EAAiC;AAC1D,EAAA,IAAI,YAAA,GAAe,uBAAA,CAAwB,YAAA,CAAa,OAAO,CAAA;AAC/D,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,YAAY,CAAA,EAAG;AAC7B,IAAA,YAAA,GAAe,aAAa,CAAC,CAAA;AAAA,EACjC;AAEA,EAAA,IAAI,WAAA,GAAc,uBAAA,CAAwB,YAAA,CAAa,MAAM,CAAA;AAC7D,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,WAAW,CAAA,EAAG;AAC5B,IAAA,WAAA,GAAc,YAAY,CAAC,CAAA;AAAA,EAC/B;AAEA,EAAA,MAAM,QAAQ,EAAC;AACf,EAAA,IAAI,YAAA,EAAc;AACd,IAAA,KAAA,CAAM,KAAK,YAAY,CAAA;AAAA,EAC3B;AAGA,EAAA,IAAI,WAAA,EAAa;AACb,IAAA,WAAA,CAAY,YAAY,oBAAoB,CAAA;AAC5C,IAAA,KAAA,CAAM,KAAK,WAAW,CAAA;AAAA,EAC1B;AAEA,EAAA,OAAO,KAAA;AACX;AAMA,MAAM,oBAAA,GAAyC,CAAC,OAAA,KAAY;AACxD,EAAA,IAAI,OAAA,EAAS;AACT,IAAA,MAAM,QAAA,GAAW,QAAQ,WAAA,EAAY;AACrC,IAAA,IAAI,QAAA,IAAY,QAAA,CAAS,OAAA,EAAQ,KAAM,SAAA,EAAW;AAC9C,MAAA,MAAM,WAAA,GAAc,QAAA,CAAS,cAAA,EAAe,CAAE,CAAC,CAAA;AAC/C,MAAA,IAAI,WAAA,EAAa;AACb,QAAA,OAAO,IAAI,WAAW,WAAW,CAAA;AAAA,MACrC;AAAA,IACJ;AAAA,EACJ;AACA,EAAA,OAAO,MAAA;AACX,CAAA;AAMA,MAAM,uBAAA,GAA0B,CAAC,SAAA,KAAsD;AACnF,EAAA,MAAM,OAAA,GAAU,IAAI,OAAA,EAAQ;AAC5B,EAAA,MAAM,cAAc,IAAI,WAAA,CAAY,EAAE,KAAA,EAAO,WAAW,CAAA;AAExD,EAAA,MAAM,aAAA,GAAgB,YAAY,gBAAA,EAAiB;AACnD,EAAA,IAAI,CAAC,aAAA,EAAe;AAChB,IAAA,MAAM,IAAI,MAAM,+BAA+B,CAAA;AAAA,EACnD;AAEA,EAAA,MAAM,MAAA,GAAS,aAAA,CAAc,OAAA,EAAS,CAAC,CAAA;AACvC,EAAA,IAAI,CAAC,MAAA,EAAQ;AACT,IAAA,MAAM,IAAI,MAAM,mDAAmD,CAAA;AAAA,EACvE;AAGA,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,MAAM,CAAA,IAAK,OAAO,MAAA,EAAQ;AACxC,IAAA,OAAO,MAAA,CAAO,MAAA,GAAS,CAAA,GAAI,MAAA,GAAS,OAAO,CAAC,CAAA;AAAA,EAChD,CAAA,MAAO;AACH,IAAA,OAAO,MAAA;AAAA,EACX;AACJ,CAAA;;;;"}