@geogirafe/lib-geoportal 1.1.0-dev.2533501910 → 1.1.0-dev.2536443365

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.
@@ -1,11 +1,13 @@
1
1
  import { Color } from 'vanilla-picker';
2
- import DrawingFeature, { ArrowPosition, ArrowStyle, DrawingShape, DrawingState } from './drawingFeature.js';
3
- import OlDrawing from './olDrawing.js';
4
- import CesiumDrawing from './cesiumDrawing.js';
2
+ import DrawingFeature, { ArrowPosition, ArrowStyle, DrawingShape } from '../../tools/drawing/drawingFeature.js';
3
+ import DrawingState from '../../tools/drawing/drawingState.js';
4
+ import OlDrawing from '../../tools/drawing/olDrawing.js';
5
+ import CesiumDrawing from '../../tools/drawing/cesiumDrawing.js';
5
6
  import GirafeHTMLElement from '../../base/GirafeHTMLElement.js';
6
7
  import GirafeColorPicker from '../../tools/utils/girafecolorpicker.js';
7
8
  import LayerDrawing from '../../models/layers/layerdrawing.js';
8
9
  import IGirafePanel from '../../tools/state/igirafepanel.js';
10
+ export declare const DrawingStateLocation = "drawing";
9
11
  export default class DrawingComponent extends GirafeHTMLElement implements IGirafePanel {
10
12
  protected templateUrl: string | null;
11
13
  protected styleUrls: string[] | null;
@@ -7,9 +7,9 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
7
7
  import { htmlFor as uHtmlFor } from 'uhtml/keyed';
8
8
  import { html as uHtml } from 'uhtml';
9
9
  import { v4 as uuidv4 } from 'uuid';
10
- import DrawingFeature, { DrawingShape } from './drawingFeature.js';
11
- import OlDrawing from './olDrawing.js';
12
- import CesiumDrawing from './cesiumDrawing.js';
10
+ import DrawingFeature, { DrawingShape } from '../../tools/drawing/drawingFeature.js';
11
+ import OlDrawing from '../../tools/drawing/olDrawing.js';
12
+ import CesiumDrawing from '../../tools/drawing/cesiumDrawing.js';
13
13
  import { GeoJSON, GPX, KML } from 'ol/format.js';
14
14
  import { Polygon } from 'ol/geom.js';
15
15
  import Feature from 'ol/Feature.js';
@@ -25,6 +25,7 @@ import visibleIcon from './assets/visible.svg?raw';
25
25
  import notVisibleIcon from './assets/notVisible.svg?raw';
26
26
  import LayerDrawing from '../../models/layers/layerdrawing.js';
27
27
  import { UsedInTemplateOnly } from '../../decorators.js';
28
+ export const DrawingStateLocation = 'drawing';
28
29
  export default class DrawingComponent extends GirafeHTMLElement {
29
30
  templateUrl = null;
30
31
  styleUrls = null;
@@ -200,20 +201,20 @@ input{border:1px solid var(--bkg-color-grad1);width:inherit;background-color:var
200
201
  }
201
202
  connectedCallback() {
202
203
  super.connectedCallback();
203
- if (!this.state.extendedState.drawing) {
204
- throw new Error('ExtendedState has to be defined in main typescript file.');
204
+ if (!this.state.extendedState[DrawingStateLocation]) {
205
+ throw new Error(`ExtendedState '${DrawingStateLocation}' has to be defined in main typescript file.`);
205
206
  }
206
- this.drawingState = this.state.extendedState.drawing;
207
+ this.drawingState = this.state.extendedState[DrawingStateLocation];
207
208
  const map = this.context.componentManager.getComponents(MapComponent)[0];
208
- this.olDrawing = new OlDrawing(map, this.name, this.context, (featureId) => {
209
+ this.olDrawing = new OlDrawing(map, DrawingStateLocation, this.context, (featureId) => {
209
210
  const drawingFeature = this.drawingState.features.find((drawingFeature) => drawingFeature.id === featureId);
210
211
  if (drawingFeature) {
211
212
  this.deleteFeature(drawingFeature);
212
213
  }
213
214
  });
214
- this.cesiumDrawing = new CesiumDrawing(map, this.name, this.context);
215
+ this.cesiumDrawing = new CesiumDrawing(map, DrawingStateLocation, this.context);
215
216
  this.render();
216
- this.subscribe('extendedState.drawing.features', (olds, news) => this.onFeaturesChanged(olds, news));
217
+ this.subscribe(`extendedState.${DrawingStateLocation}.features`, (olds, news) => this.onFeaturesChanged(olds, news));
217
218
  this.subscribe('projection', (olds, news) => this.onProjectionChanged(olds, news));
218
219
  this.subscribe('globe.loaded', () => {
219
220
  if (this.state.globe.loaded && this.isPanelVisible) {
@@ -12,7 +12,7 @@ export { default as CrossSectionSettingsComponent } from './cross-section/cross-
12
12
  export { default as CrossSectionViewComponent } from './cross-section/cross-section-viewer/component.js';
13
13
  export { default as DisplayMenuButtonMobile } from './displaymenubutton-mobile/component.js';
14
14
  export { default as DisplaySelectorButtonMobile } from './displayselectorbutton-mobile/component.js';
15
- export { default as DrawingComponent } from './drawing/component.js';
15
+ export { default as DrawingComponent, DrawingStateLocation } from './drawing/component.js';
16
16
  export type { FixedDimensionValueChangedEventDetails, DimensionUnit } from './drawing/fixed-dimension/component.js';
17
17
  export { default as FixedDimensionComponent } from './drawing/fixed-dimension/component.js';
18
18
  export { default as DrawingContainerMobile } from './drawing-container-mobile/component.js';
@@ -12,7 +12,7 @@ export { default as CrossSectionSettingsComponent } from './cross-section/cross-
12
12
  export { default as CrossSectionViewComponent } from './cross-section/cross-section-viewer/component.js';
13
13
  export { default as DisplayMenuButtonMobile } from './displaymenubutton-mobile/component.js';
14
14
  export { default as DisplaySelectorButtonMobile } from './displayselectorbutton-mobile/component.js';
15
- export { default as DrawingComponent } from './drawing/component.js';
15
+ export { default as DrawingComponent, DrawingStateLocation } from './drawing/component.js';
16
16
  export { default as FixedDimensionComponent } from './drawing/fixed-dimension/component.js';
17
17
  export { default as DrawingContainerMobile } from './drawing-container-mobile/component.js';
18
18
  export { default as EditComponent } from './edit/component.js';
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "name": "GeoGirafe PSC",
6
6
  "url": "https://doc.geomapfish.dev"
7
7
  },
8
- "version": "1.1.0-dev.2533501910",
8
+ "version": "1.1.0-dev.2536443365",
9
9
  "type": "module",
10
10
  "engines": {
11
11
  "node": ">=20.19.0"
@@ -1 +1 @@
1
- {"version":"1.1.0-dev.2533501910", "build":"2533501910", "date":"18/05/2026"}
1
+ {"version":"1.1.0-dev.2536443365", "build":"2536443365", "date":"19/05/2026"}
@@ -9,7 +9,7 @@ import MapDefaultContextMenuComponent from '../../components/context-menu/defaul
9
9
  import MapCustomContextMenuComponent from '../../components/context-menu/custom-context-menu/component.js';
10
10
  import CrossSectionSettingsComponent from '../../components/cross-section/cross-section-settings/component.js';
11
11
  import CrossSectionViewComponent from '../../components/cross-section/cross-section-viewer/component.js';
12
- import DrawingComponent from '../../components/drawing/component.js';
12
+ import DrawingComponent, { DrawingStateLocation } from '../../components/drawing/component.js';
13
13
  import EditComponent from '../../components/edit/component.js';
14
14
  import EditFromComponent from '../../components/edit/editform/component.js';
15
15
  import HelpComponent from '../../components/help/component.js';
@@ -43,8 +43,8 @@ import TreeViewRootComponent from '../../components/treeview/treeviewroot/compon
43
43
  import TreeViewThemeComponent from '../../components/treeview/treeviewtheme/component.js';
44
44
  import UserPreferencesComponent from '../../components/userpreferences/component.js';
45
45
  import VideoRecordComponent from '../../components/videorecord/component.js';
46
- import { DrawingState } from '../../components/drawing/drawingFeature.js';
47
- import DrawingSerializer from '../../components/drawing/drawingSerializer.js';
46
+ import DrawingState from '../drawing/drawingState.js';
47
+ import DrawingSerializer from '../drawing/drawingSerializer.js';
48
48
  import { ShareState, ShareStateSerializer } from '../../components/share/sharestate.js';
49
49
  import SelectionToolComponent from '../../components/selectiontool/component.js';
50
50
  import AdvancedFilterComponent from '../../components/advancedfilter/component.js';
@@ -92,7 +92,7 @@ export default class GeoGirafeApp {
92
92
  }
93
93
  addCustomSerializers() {
94
94
  // Add custom state and serializers (need to be done early, because the shared state will need them)
95
- this.context.stateManager.state.extendedState.drawing = new DrawingState();
95
+ this.context.stateManager.state.extendedState[DrawingStateLocation] = new DrawingState();
96
96
  this.context.stateSerializer.addSerializer(DrawingState, new DrawingSerializer(this.context));
97
97
  this.context.stateManager.state.extendedState.share = new ShareState();
98
98
  this.context.stateSerializer.addSerializer(ShareState, new ShareStateSerializer(this.context, this.isIframe));
@@ -0,0 +1,42 @@
1
+ import MapComponent from '../../components/map/component.js';
2
+ import IGirafeContext from '../context/icontext.js';
3
+ export default class CesiumDrawing {
4
+ private readonly stateLocation;
5
+ private activeShapePoints;
6
+ private activeShapes;
7
+ private floatingPoint;
8
+ private scene;
9
+ private handler;
10
+ private entities;
11
+ private fixedLineLength;
12
+ private readonly context;
13
+ private get state();
14
+ private get drawingState();
15
+ private get config();
16
+ constructor(map: MapComponent, stateLocation: string, context: IGirafeContext);
17
+ setFixedLineLength(length: number): void;
18
+ private activateTool;
19
+ private deactivateTool;
20
+ private pickOnGlobe;
21
+ private removeLastPointAndTerminateShape;
22
+ private terminateShape;
23
+ private fixLastLength;
24
+ private updateShape;
25
+ private addPoint;
26
+ private leveledCenterToMouse;
27
+ private makeRectangle;
28
+ private makeRegularPolygon;
29
+ private getShapes;
30
+ registerInteractions(): void;
31
+ unregisterInteractions(): void;
32
+ private canExecute;
33
+ private getPosition;
34
+ private getLength;
35
+ private createLabel;
36
+ private createPoint;
37
+ private getPolygonCenter;
38
+ private getPolyLineLabels;
39
+ private getPolygonArea;
40
+ private getPolyline;
41
+ private getPolygonEntity;
42
+ }
@@ -6,7 +6,8 @@ import DrawingFeature, { DrawingShape } from './drawingFeature.js';
6
6
  import proj4 from 'proj4';
7
7
  const CLAMP_TO_GROUND = Cesium.HeightReference.CLAMP_TO_GROUND;
8
8
  export default class CesiumDrawing {
9
- toolName;
9
+ // Writes drawn features into the specified location in the extended state
10
+ stateLocation;
10
11
  activeShapePoints = [];
11
12
  activeShapes = [];
12
13
  floatingPoint = undefined;
@@ -19,20 +20,20 @@ export default class CesiumDrawing {
19
20
  return this.context.stateManager.state;
20
21
  }
21
22
  get drawingState() {
22
- return this.state.extendedState.drawing;
23
+ return this.state.extendedState[this.stateLocation];
23
24
  }
24
25
  get config() {
25
26
  return this.context.configManager.Config;
26
27
  }
27
- constructor(map, toolName, context) {
28
- this.toolName = toolName;
28
+ constructor(map, stateLocation, context) {
29
+ this.stateLocation = stateLocation;
29
30
  this.context = context;
30
31
  map.subscribe('globe.loaded', () => {
31
32
  if (this.state.globe.loaded) {
32
33
  this.scene = map.map3d.getCesiumScene();
33
34
  this.handler = new Cesium.ScreenSpaceEventHandler(this.scene.canvas);
34
35
  this.entities = map.map3d.getDataSourceDisplay().defaultDataSource.entities;
35
- map.subscribe('extendedState.drawing.activeTool', (_oldTool, newTool) => newTool === null ? this.deactivateTool() : this.activateTool(newTool));
36
+ map.subscribe(`extendedState.${this.stateLocation}.activeTool`, (_oldTool, newTool) => newTool === null ? this.deactivateTool() : this.activateTool(newTool));
36
37
  }
37
38
  });
38
39
  }
@@ -305,16 +306,16 @@ export default class CesiumDrawing {
305
306
  }
306
307
  }
307
308
  registerInteractions() {
308
- this.context.userInteractionManager.registerListener('globe.select', true, this.toolName);
309
- this.context.userInteractionManager.registerListener('globe.draw', true, this.toolName);
309
+ this.context.userInteractionManager.registerListener('globe.select', true, this.stateLocation);
310
+ this.context.userInteractionManager.registerListener('globe.draw', true, this.stateLocation);
310
311
  }
311
312
  unregisterInteractions() {
312
313
  this.deactivateTool();
313
- this.context.userInteractionManager.unregisterListener('globe.select', this.toolName);
314
- this.context.userInteractionManager.unregisterListener('globe.draw', this.toolName);
314
+ this.context.userInteractionManager.unregisterListener('globe.select', this.stateLocation);
315
+ this.context.userInteractionManager.unregisterListener('globe.draw', this.stateLocation);
315
316
  }
316
317
  canExecute(event) {
317
- return this.context.userInteractionManager.canListenerExecute(event, this.toolName);
318
+ return this.context.userInteractionManager.canListenerExecute(event, this.stateLocation);
318
319
  }
319
320
  getPosition(p) {
320
321
  const carto = Cartographic.fromCartesian(p);
@@ -1,8 +1,8 @@
1
1
  import { Style } from 'ol/style.js';
2
- import type { IBrainSerializable } from '../../tools/state/brain/decorators.js';
3
2
  import type { Circle as CircleGeom, Geometry } from 'ol/geom.js';
4
3
  import type Feature from 'ol/Feature.js';
5
- import IGirafeContext from '../../tools/context/icontext.js';
4
+ import IGirafeContext from '../context/icontext.js';
5
+ import DrawingState from './drawingState.js';
6
6
  export declare enum DrawingShape {
7
7
  Point = 0,
8
8
  Polyline = 1,
@@ -16,11 +16,6 @@ export declare enum DrawingShape {
16
16
  export type ArrowStyle = 'none' | 'start' | 'end' | 'both';
17
17
  export type ArrowPosition = 'whole' | 'each' | 'mid';
18
18
  export type LineStroke = 'full' | 'dash' | 'dot' | 'double';
19
- export declare class DrawingState implements IBrainSerializable {
20
- isBrainSerializable: boolean;
21
- activeTool: DrawingShape | null;
22
- features: DrawingFeature[];
23
- }
24
19
  export type SerializedFeature = {
25
20
  n: string;
26
21
  sc: string;
@@ -102,13 +97,13 @@ export default class DrawingFeature {
102
97
  getAzimuthText(circle: CircleGeom): string;
103
98
  isPointOrPolyline(): boolean;
104
99
  getVertexStyle(activeNode?: boolean): Style;
105
- static deserialize(serializedFeature: SerializedFeature, context: IGirafeContext): DrawingFeature;
100
+ static deserialize(serializedFeature: SerializedFeature, context: IGirafeContext, drawingState: DrawingState): DrawingFeature;
106
101
  static circleToPolygon(center: number[], radius: number, nbEdges?: number): number[][];
107
102
  static geojsonFromOlFeature(olFeature: Feature<Geometry>, shapeType: DrawingShape): object;
108
103
  /**
109
- * Finds an name composed of the shape type and a number.
110
- * The number starts from how many shape of the same type type are already in the state +1.
111
- * Then checks if such candidate name already exists and increments if so.
104
+ * Finds a name composed of the shape type and a number.
105
+ * The number starts from how many shapes of the same type are already in the state +1.
106
+ * Then checks if such a candidate name already exists and increments if so.
112
107
  * @param geometryTypename
113
108
  * @returns
114
109
  */
@@ -3,7 +3,7 @@ import { v4 as uuidv4 } from 'uuid';
3
3
  import { Fill, RegularShape, Stroke, Style } from 'ol/style.js';
4
4
  import { toRadians } from 'ol/math.js';
5
5
  import GeoJSON from 'ol/format/GeoJSON.js';
6
- import { getAreaAsMetricText, getAzimuthAsText, getLengthAsMetricText } from '../../tools/utils/olutils.js';
6
+ import { getAreaAsMetricText, getAzimuthAsText, getLengthAsMetricText } from '../utils/olutils.js';
7
7
  export var DrawingShape;
8
8
  (function (DrawingShape) {
9
9
  DrawingShape[DrawingShape["Point"] = 0] = "Point";
@@ -15,11 +15,6 @@ export var DrawingShape;
15
15
  DrawingShape[DrawingShape["FreehandPolyline"] = 6] = "FreehandPolyline";
16
16
  DrawingShape[DrawingShape["FreehandPolygon"] = 7] = "FreehandPolygon";
17
17
  })(DrawingShape || (DrawingShape = {}));
18
- export class DrawingState {
19
- isBrainSerializable = true;
20
- activeTool = null;
21
- features = [];
22
- }
23
18
  export default class DrawingFeature {
24
19
  _tool;
25
20
  _name;
@@ -230,9 +225,9 @@ export default class DrawingFeature {
230
225
  })
231
226
  });
232
227
  }
233
- static deserialize(serializedFeature, context) {
228
+ static deserialize(serializedFeature, context, drawingState) {
234
229
  console.log(serializedFeature);
235
- const newFeature = new DrawingFeature(serializedFeature.t, context.stateManager.state.extendedState.drawing, context.configManager.Config.drawing);
230
+ const newFeature = new DrawingFeature(serializedFeature.t, drawingState, context.configManager.Config.drawing);
236
231
  newFeature.geojson = serializedFeature.g;
237
232
  newFeature.name = serializedFeature.n;
238
233
  newFeature.strokeColor = serializedFeature.sc;
@@ -279,9 +274,9 @@ export default class DrawingFeature {
279
274
  return JSON.parse(new GeoJSON().writeFeature(olFeature));
280
275
  }
281
276
  /**
282
- * Finds an name composed of the shape type and a number.
283
- * The number starts from how many shape of the same type type are already in the state +1.
284
- * Then checks if such candidate name already exists and increments if so.
277
+ * Finds a name composed of the shape type and a number.
278
+ * The number starts from how many shapes of the same type are already in the state +1.
279
+ * Then checks if such a candidate name already exists and increments if so.
285
280
  * @param geometryTypename
286
281
  * @returns
287
282
  */
@@ -1,10 +1,10 @@
1
- import IGirafeContext from '../../tools/context/icontext.js';
2
- import type { IBrainSerializer } from '../../tools/state/brain/serialize.js';
3
- import { DrawingState } from './drawingFeature.js';
1
+ import IGirafeContext from '../context/icontext.js';
2
+ import type { IBrainSerializer } from '../state/brain/serialize.js';
3
+ import DrawingState from './drawingState.js';
4
4
  export default class DrawingSerializer implements IBrainSerializer<DrawingState> {
5
5
  private readonly context;
6
6
  constructor(context: IGirafeContext);
7
7
  private get state();
8
8
  brainSerialize(drawingState: DrawingState): string;
9
- brainDeserialize(str: string): void;
9
+ brainDeserialize(str: string, stateLocation: string): void;
10
10
  }
@@ -1,4 +1,5 @@
1
- import DrawingFeature, { DrawingState } from './drawingFeature.js';
1
+ import DrawingFeature from './drawingFeature.js';
2
+ import DrawingState from './drawingState.js';
2
3
  export default class DrawingSerializer {
3
4
  context;
4
5
  constructor(context) {
@@ -14,22 +15,23 @@ export default class DrawingSerializer {
14
15
  }
15
16
  return JSON.stringify(serializedDrawings);
16
17
  }
17
- brainDeserialize(str) {
18
+ brainDeserialize(str, stateLocation) {
18
19
  const serializedFeatures = JSON.parse(str);
19
20
  if (serializedFeatures) {
20
- if (this.state.extendedState.drawing) {
21
+ let drawingState = new DrawingState();
22
+ if (this.state.extendedState[stateLocation]) {
21
23
  // First, delete existing drawing features in the state before adding new ones.
22
24
  // This will trigger removal of the ol features in the map.
23
- const drawingState = this.state.extendedState.drawing;
25
+ drawingState = this.state.extendedState[stateLocation];
24
26
  drawingState.features.splice(0, drawingState.features.length);
25
27
  }
26
28
  else {
27
- this.state.extendedState.drawing = new DrawingState();
29
+ this.state.extendedState[stateLocation] = drawingState;
28
30
  }
29
- serializedFeatures.forEach((f) => DrawingFeature.deserialize(f, this.context));
31
+ serializedFeatures.forEach((f) => DrawingFeature.deserialize(f, this.context, drawingState));
30
32
  }
31
33
  else {
32
- throw new Error(`Cannot deserialize drawings`);
34
+ throw new Error(`Cannot deserialize the drawing state for ${stateLocation}`);
33
35
  }
34
36
  }
35
37
  }
@@ -0,0 +1,7 @@
1
+ import type { IBrainSerializable } from '../state/brain/decorators.js';
2
+ import DrawingFeature, { DrawingShape } from './drawingFeature.js';
3
+ export default class DrawingState implements IBrainSerializable {
4
+ isBrainSerializable: boolean;
5
+ activeTool: DrawingShape | null;
6
+ features: DrawingFeature[];
7
+ }
@@ -0,0 +1,5 @@
1
+ export default class DrawingState {
2
+ isBrainSerializable = true;
3
+ activeTool = null;
4
+ features = [];
5
+ }
@@ -1,45 +1,38 @@
1
- import DrawingFeature, { DrawingShape } from './drawingFeature.js';
2
- import MapComponent from '../map/component.js';
3
- import { Collection, Feature } from 'ol';
4
- import { Geometry, SimpleGeometry } from 'ol/geom.js';
5
- import { SketchCoordType } from 'ol/interaction/Draw.js';
6
- import { Style } from 'ol/style.js';
7
- import { Draw, Modify, Snap, Translate } from 'ol/interaction.js';
8
- import VectorSource, { VectorSourceEvent } from 'ol/source/Vector.js';
1
+ import DrawingFeature from './drawingFeature.js';
2
+ import MapComponent from '../../components/map/component.js';
3
+ import { Feature } from 'ol';
4
+ import { Geometry } from 'ol/geom.js';
5
+ import VectorSource from 'ol/source/Vector.js';
9
6
  import VectorLayer from 'ol/layer/Vector.js';
10
- import { Projection } from 'ol/proj.js';
11
- import { Coordinate } from 'ol/coordinate.js';
12
- import { ContextMenu } from '../map/tools/contextmenu.js';
13
- import IGirafeContext from '../../tools/context/icontext.js';
7
+ import IGirafeContext from '../context/icontext.js';
14
8
  import { StyleFunction } from 'ol/style/Style.js';
15
- import Transform from 'ol-ext/interaction/Transform.js';
16
9
  export default class OlDrawing {
17
10
  private readonly map;
18
- private readonly toolName;
11
+ private readonly stateLocation;
19
12
  private readonly context;
20
13
  private readonly deleteHandler;
21
- modifiableFeatures: Collection<Feature>;
22
- draw: Draw | null;
23
- modify: Modify | null;
24
- snap: Snap | null;
25
- editContextMenu: ContextMenu | null;
26
- currentShape: DrawingShape | null;
27
- fixedLineLength: number;
28
- fixedSquareSide: number;
29
- fixedRectangleWidth: number;
30
- fixedRectangleHeight: number;
31
- drawingSource: VectorSource;
32
- drawingLayer: VectorLayer;
33
- lastClosestFeature: Feature | null;
34
- translate: Translate | null;
35
- transform: Transform | null;
14
+ private readonly modifiableFeatures;
15
+ private draw;
16
+ private modify;
17
+ private snap;
18
+ private editContextMenu;
19
+ private currentShape;
20
+ private fixedLineLength;
21
+ private fixedSquareSide;
22
+ private fixedRectangleWidth;
23
+ private fixedRectangleHeight;
24
+ readonly drawingSource: VectorSource;
25
+ readonly drawingLayer: VectorLayer;
26
+ private lastClosestFeature;
27
+ private translate;
28
+ private transform;
36
29
  private readonly modifyFeatureChangeListeners;
37
30
  defaultStyle: StyleFunction | undefined;
38
31
  private readonly updateGeometryInState;
39
32
  private get state();
40
33
  private get drawingState();
41
34
  private get config();
42
- constructor(map: MapComponent, toolName: string, context: IGirafeContext, deleteHandler: (featureId: string) => void);
35
+ constructor(mapComponent: MapComponent, stateLocation: string, context: IGirafeContext, deleteHandler: (featureId: string) => void);
43
36
  private addModifyInteraction;
44
37
  private addSnapInteraction;
45
38
  private addTranslateInteraction;
@@ -51,15 +44,15 @@ export default class OlDrawing {
51
44
  * when the user does an alternate click ( = context event) on or near a vertex of a modifiable feature.
52
45
  */
53
46
  private addEditContextMenu;
54
- addEditInteractions(): void;
55
- removeEditInteractions(): void;
47
+ private addEditInteractions;
48
+ private removeEditInteractions;
56
49
  private readonly prepareMenuEntriesForVertex;
57
50
  private readonly prepareMenuEntriesForShape;
58
51
  /**
59
52
  Check if there is a vertex of a selected (=editable) feature within the pixel tolerance of the clicked coordinates.
60
53
  */
61
- hasEditableVertexAtCoordinate(coordinate: Coordinate): boolean;
62
- hasEditableShapeAtCoordinate(coordinate: Coordinate): boolean;
54
+ private hasEditableVertexAtCoordinate;
55
+ private hasEditableShapeAtCoordinate;
63
56
  /**
64
57
  Returns the closest vertex and feature to a coordinate from the drawing source.
65
58
  The feature source can be pre-filtered via an optional filter function.
@@ -97,7 +90,7 @@ export default class OlDrawing {
97
90
  *
98
91
  * @param {VectorSourceEvent} e - The add-feature event.
99
92
  */
100
- onFeatureAdded(e: VectorSourceEvent): void;
93
+ private onFeatureAdded;
101
94
  private getOlFeatureFromDrawingSource;
102
95
  private isOlFeatureInState;
103
96
  createOlFeature(dFeature: DrawingFeature): Feature<Geometry>;
@@ -105,14 +98,14 @@ export default class OlDrawing {
105
98
  setFixedSquareSide(length: number): void;
106
99
  setFixedRectangleWidth(width: number): void;
107
100
  setFixedRectangleHeight(height: number): void;
108
- createLineStringFixedLength(coordinates: SketchCoordType, geom: SimpleGeometry): SimpleGeometry;
109
- createSquareFixedLength(coordinates: SketchCoordType, geom: SimpleGeometry, proj: Projection): SimpleGeometry;
110
- createPolygonFixedLength(coordinates: SketchCoordType, geom: SimpleGeometry): SimpleGeometry;
111
- createDiskFixedLength(coordinates: SketchCoordType, geom: SimpleGeometry): SimpleGeometry;
112
- createRectangleFixedSides(coordinates: SketchCoordType, geom: SimpleGeometry, proj: Projection): SimpleGeometry;
113
- addDrawInteraction(tool: DrawingShape): void;
101
+ private createLineStringFixedLength;
102
+ private createSquareFixedLength;
103
+ private createPolygonFixedLength;
104
+ private createDiskFixedLength;
105
+ private createRectangleFixedSides;
106
+ private addDrawInteraction;
114
107
  centerViewOnFeature(drawingFeature: DrawingFeature): void;
115
- getStyle(dFeature: DrawingFeature, olFeature: Feature<Geometry>): Style[];
108
+ private getStyle;
116
109
  private removeDrawInteraction;
117
110
  private removeModifyInteraction;
118
111
  private getDrawingShapeType;
@@ -10,11 +10,11 @@ import VectorLayer from 'ol/layer/Vector.js';
10
10
  import GeoJSON from 'ol/format/GeoJSON.js';
11
11
  import { getPointResolution } from 'ol/proj.js';
12
12
  import { always, never, primaryAction } from 'ol/events/condition.js';
13
- import { ensurePolygonIsProperlyClosed, getAreaOfPolygon, getDistance, getHalfPoint, getLabelStyle, getRadiusDataForCircle, unByKeyAll } from '../../tools/utils/olutils.js';
14
- import { ContextMenu, EntryInteractionType } from '../map/tools/contextmenu.js';
15
- import { formatCoordinates } from '../../tools/geometrytools.js';
13
+ import { ensurePolygonIsProperlyClosed, getAreaOfPolygon, getDistance, getHalfPoint, getLabelStyle, getRadiusDataForCircle, unByKeyAll } from '../utils/olutils.js';
14
+ import { ContextMenu, EntryInteractionType } from '../../components/map/tools/contextmenu.js';
15
+ import { formatCoordinates } from '../geometrytools.js';
16
16
  import { v4 as uuidv4 } from 'uuid';
17
- import { isAlternateMouseClick, isPrimaryPointerAction } from '../../tools/state/userinteractionevent.js';
17
+ import { isAlternateMouseClick, isPrimaryPointerAction } from '../state/userinteractionevent.js';
18
18
  import { calculateCenterAndMinRadius, createScaledAndRotatedGeometry, getGeometryForRendering, shouldAllowVertexInsertionForShape } from './shapeConstraints.js';
19
19
  import Transform from 'ol-ext/interaction/Transform.js';
20
20
  function getLineStroke(strokeType, lineWidth) {
@@ -51,7 +51,8 @@ function extractVerticesFromGeometry(geometry) {
51
51
  }
52
52
  export default class OlDrawing {
53
53
  map;
54
- toolName;
54
+ // Writes drawn features into the specified location in the extended state
55
+ stateLocation;
55
56
  context;
56
57
  deleteHandler;
57
58
  modifiableFeatures = new Collection([]);
@@ -82,14 +83,14 @@ export default class OlDrawing {
82
83
  return this.context.stateManager.state;
83
84
  }
84
85
  get drawingState() {
85
- return this.state.extendedState.drawing;
86
+ return this.state.extendedState[this.stateLocation];
86
87
  }
87
88
  get config() {
88
89
  return this.context.configManager.Config;
89
90
  }
90
- constructor(map, toolName, context, deleteHandler) {
91
- this.map = map;
92
- this.toolName = toolName;
91
+ constructor(mapComponent, stateLocation, context, deleteHandler) {
92
+ this.map = mapComponent;
93
+ this.stateLocation = stateLocation;
93
94
  this.context = context;
94
95
  this.deleteHandler = deleteHandler;
95
96
  this.drawingSource = new VectorSource({ features: new Collection() });
@@ -103,7 +104,7 @@ export default class OlDrawing {
103
104
  }
104
105
  });
105
106
  this.defaultStyle = new Modify({ source: this.drawingSource }).getOverlay().getStyleFunction();
106
- this.map.subscribe('extendedState.drawing.activeTool', (_oldTool, newTool) => newTool === null ? this.removeDrawInteraction() : this.addDrawInteraction(newTool));
107
+ this.map.subscribe(`extendedState.${this.stateLocation}.activeTool`, (_oldTool, newTool) => newTool === null ? this.removeDrawInteraction() : this.addDrawInteraction(newTool));
107
108
  // Could be useful logic if we decide that the mobile UI should rely use a dedicated button
108
109
  // to remove a selected vetex from a polygon/line (rather than using a longpress context menu)
109
110
  // this.map.olMap.on("click", (e) => {
@@ -116,7 +117,7 @@ export default class OlDrawing {
116
117
  // console.log("Map Coordinate:", mapCoordinate, e.pixel, hasEditableVertex);
117
118
  // }
118
119
  // })
119
- this.map.subscribe(/extendedState.drawing.features.*\.selected/, (_old, _new) => this.updateModifiableFeatures());
120
+ this.map.subscribe(new RegExp(String.raw `extendedState.${this.stateLocation}.features.*\.selected`, 'g'), (_old, _new) => this.updateModifiableFeatures());
120
121
  // OlCesium duplicates drawn shapes when 3D view is open if its eventListener is not removed
121
122
  this.map.subscribe('globe.loaded', () => {
122
123
  if (this.state.globe.loaded) {
@@ -595,7 +596,7 @@ export default class OlDrawing {
595
596
  addDrawInteraction(tool) {
596
597
  this.removeDrawInteraction();
597
598
  // Block feature selection while drawing by registering 'map.select' exclusively
598
- this.context.userInteractionManager.registerListener('map.select', true, this.toolName);
599
+ this.context.userInteractionManager.registerListener('map.select', true, this.stateLocation);
599
600
  this.currentShape = tool;
600
601
  let geomFunction = undefined;
601
602
  let olTool;
@@ -836,7 +837,7 @@ export default class OlDrawing {
836
837
  this.draw = null;
837
838
  }
838
839
  // Reactivate feature selection by unregistering 'map.select'
839
- this.context.userInteractionManager.unregisterListener('map.select', this.toolName);
840
+ this.context.userInteractionManager.unregisterListener('map.select', this.stateLocation);
840
841
  }
841
842
  removeModifyInteraction() {
842
843
  this.clearModifyFeatureChangeListeners();
@@ -925,19 +926,19 @@ export default class OlDrawing {
925
926
  }
926
927
  }
927
928
  registerInteractions() {
928
- this.context.userInteractionManager.registerListener('map.draw', true, this.toolName);
929
- this.context.userInteractionManager.registerListener('map.modify', true, this.toolName);
930
- this.context.userInteractionManager.registerListener('map.snap', true, this.toolName);
929
+ this.context.userInteractionManager.registerListener('map.draw', true, this.stateLocation);
930
+ this.context.userInteractionManager.registerListener('map.modify', true, this.stateLocation);
931
+ this.context.userInteractionManager.registerListener('map.snap', true, this.stateLocation);
931
932
  }
932
933
  unregisterInteractions() {
933
934
  this.removeDrawInteraction();
934
935
  this.removeEditInteractions();
935
- this.context.userInteractionManager.unregisterListener('map.draw', this.toolName);
936
- this.context.userInteractionManager.unregisterListener('map.modify', this.toolName);
937
- this.context.userInteractionManager.unregisterListener('map.snap', this.toolName);
936
+ this.context.userInteractionManager.unregisterListener('map.draw', this.stateLocation);
937
+ this.context.userInteractionManager.unregisterListener('map.modify', this.stateLocation);
938
+ this.context.userInteractionManager.unregisterListener('map.snap', this.stateLocation);
938
939
  }
939
940
  canExecute(event) {
940
- return this.context.userInteractionManager.canListenerExecute(event, this.toolName);
941
+ return this.context.userInteractionManager.canListenerExecute(event, this.stateLocation);
941
942
  }
942
943
  fixLastLength(length, coordinates, scale = 1) {
943
944
  const coord = coordinates;
package/tools/main.d.ts CHANGED
@@ -12,6 +12,13 @@ export { default as ConfigManager } from './configuration/configmanager.js';
12
12
  export { default as GirafeConfig } from './configuration/girafeconfig.js';
13
13
  export { default as GirafeContext } from './context/context.js';
14
14
  export type { default as IGirafeContext } from './context/icontext.js';
15
+ export { default as CesiumDrawing } from './drawing/cesiumDrawing.js';
16
+ export type { DrawingShape, ArrowStyle, ArrowPosition, LineStroke, SerializedFeature } from './drawing/drawingFeature.js';
17
+ export { default as DrawingFeature } from './drawing/drawingFeature.js';
18
+ export { default as DrawingSerializer } from './drawing/drawingSerializer.js';
19
+ export { default as DrawingState } from './drawing/drawingState.js';
20
+ export { default as OlDrawing } from './drawing/olDrawing.js';
21
+ export { calculateCenterAndMinRadius, createScaledAndRotatedGeometry, getGeometryForRendering, shouldAllowVertexInsertionForShape } from './drawing/shapeConstraints.js';
15
22
  export { default as ErrorManager } from './error/errormanager.js';
16
23
  export { default as CsvManager } from './export/csvmanager.js';
17
24
  export { download } from './export/download.js';
package/tools/main.js CHANGED
@@ -11,6 +11,12 @@ export { default as PluginManager } from './auth/pluginmanager.js';
11
11
  export { default as ConfigManager } from './configuration/configmanager.js';
12
12
  export { default as GirafeConfig } from './configuration/girafeconfig.js';
13
13
  export { default as GirafeContext } from './context/context.js';
14
+ export { default as CesiumDrawing } from './drawing/cesiumDrawing.js';
15
+ export { default as DrawingFeature } from './drawing/drawingFeature.js';
16
+ export { default as DrawingSerializer } from './drawing/drawingSerializer.js';
17
+ export { default as DrawingState } from './drawing/drawingState.js';
18
+ export { default as OlDrawing } from './drawing/olDrawing.js';
19
+ export { calculateCenterAndMinRadius, createScaledAndRotatedGeometry, getGeometryForRendering, shouldAllowVertexInsertionForShape } from './drawing/shapeConstraints.js';
14
20
  export { default as ErrorManager } from './error/errormanager.js';
15
21
  export { default as CsvManager } from './export/csvmanager.js';
16
22
  export { download } from './export/download.js';
@@ -1,7 +1,7 @@
1
1
  export type Constructor<T> = new (...args: any[]) => T;
2
2
  export interface IBrainSerializer<T> {
3
3
  brainSerialize(obj: T): string;
4
- brainDeserialize(str: string): void;
4
+ brainDeserialize(str: string, stateLocation?: string): void;
5
5
  }
6
6
  export default class BrainSerializer<T extends Record<string | symbol, any>> {
7
7
  private readonly registry;
@@ -37,7 +37,7 @@ export default class BrainSerializer {
37
37
  const serializer = this.getSerializer(state[key]);
38
38
  if (serializer) {
39
39
  console.debug(`Deserializing ${key} with custom serializer`);
40
- serializer.brainDeserialize(serializedState[key]);
40
+ serializer.brainDeserialize(serializedState[key], key);
41
41
  }
42
42
  else {
43
43
  console.debug(`Deserializing ${key} with default serializer`);
@@ -1,45 +0,0 @@
1
- import * as Cesium from 'cesium';
2
- import { Cartesian2, Cartesian3, Entity } from 'cesium';
3
- import DrawingFeature, { DrawingShape } from './drawingFeature.js';
4
- import MapComponent from '../map/component.js';
5
- import IGirafeContext from '../../tools/context/icontext.js';
6
- export default class CesiumDrawing {
7
- toolName: string;
8
- activeShapePoints: Cartesian3[];
9
- activeShapes: Entity[];
10
- floatingPoint: Entity | undefined;
11
- scene: Cesium.Scene | undefined;
12
- handler: Cesium.ScreenSpaceEventHandler | undefined;
13
- entities: Cesium.EntityCollection | undefined;
14
- fixedLineLength: number;
15
- private readonly context;
16
- private get state();
17
- private get drawingState();
18
- private get config();
19
- constructor(map: MapComponent, toolName: string, context: IGirafeContext);
20
- setFixedLineLength(length: number): void;
21
- activateTool(tool: DrawingShape): void;
22
- deactivateTool(): void;
23
- pickOnGlobe(position: Cartesian2): Cesium.Cartesian3 | undefined;
24
- removeLastPointAndTerminateShape(tool: DrawingShape): () => void;
25
- terminateShape(tool: DrawingShape): void;
26
- fixLastLength(tool: DrawingShape, length: number, coord: Cartesian3[]): void;
27
- updateShape(tool: DrawingShape): (event: Cesium.ScreenSpaceEventHandler.MotionEvent) => void;
28
- addPoint(tool: DrawingShape): (event: Cesium.ScreenSpaceEventHandler.PositionedEvent) => void;
29
- leveledCenterToMouse(pos: Cartesian3[]): Cesium.Cartesian3;
30
- makeRectangle(pos: Cartesian3[]): Cesium.Cartesian3[];
31
- makeRegularPolygon(center: Cartesian3, firstPosition: Cartesian3, nbEdges: number): Cesium.Cartesian3[];
32
- getShapes(tool: DrawingShape, pos: Cartesian3[], feature: DrawingFeature): Cesium.Entity[];
33
- registerInteractions(): void;
34
- unregisterInteractions(): void;
35
- private canExecute;
36
- private getPosition;
37
- private getLength;
38
- private createLabel;
39
- private createPoint;
40
- private getPolygonCenter;
41
- private getPolyLineLabels;
42
- private getPolygonArea;
43
- private getPolyline;
44
- private getPolygonEntity;
45
- }