@geogirafe/lib-geoportal 1.1.0-dev.2533501910 → 1.1.0-dev.2545448597
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/api/apigeogirafeapp.d.ts +1 -0
- package/api/apigeogirafeapp.js +42 -11
- package/components/drawing/component.d.ts +5 -3
- package/components/drawing/component.js +10 -9
- package/components/main.d.ts +1 -1
- package/components/main.js +1 -1
- package/components/map/component.js +9 -8
- package/package.json +1 -1
- package/templates/api.html +16 -1
- package/templates/public/about.json +1 -1
- package/tools/app/geogirafeapp.js +4 -4
- package/tools/drawing/cesiumDrawing.d.ts +42 -0
- package/{components → tools}/drawing/cesiumDrawing.js +11 -10
- package/{components → tools}/drawing/drawingFeature.d.ts +6 -11
- package/{components → tools}/drawing/drawingFeature.js +6 -11
- package/{components → tools}/drawing/drawingSerializer.d.ts +4 -4
- package/{components → tools}/drawing/drawingSerializer.js +9 -7
- package/tools/drawing/drawingState.d.ts +7 -0
- package/tools/drawing/drawingState.js +5 -0
- package/{components → tools}/drawing/olDrawing.d.ts +35 -42
- package/{components → tools}/drawing/olDrawing.js +21 -20
- package/tools/main.d.ts +8 -1
- package/tools/main.js +7 -1
- package/tools/state/brain/serialize.d.ts +1 -1
- package/tools/state/brain/serialize.js +1 -1
- package/tools/state/mapposition.d.ts +2 -0
- package/tools/state/mapposition.js +3 -1
- package/tools/url/permalinkmanager.d.ts +5 -0
- package/tools/url/permalinkmanager.js +55 -27
- package/tools/utils/utils.d.ts +5 -0
- package/tools/utils/utils.js +10 -0
- package/components/drawing/cesiumDrawing.d.ts +0 -45
- /package/{components → tools}/drawing/shapeConstraints.d.ts +0 -0
- /package/{components → tools}/drawing/shapeConstraints.js +0 -0
package/api/apigeogirafeapp.d.ts
CHANGED
|
@@ -26,6 +26,7 @@ export default class GeoGirafeApi extends GirafeHTMLElement {
|
|
|
26
26
|
private manageCrosshairAttribute;
|
|
27
27
|
private manageTooltipAttribute;
|
|
28
28
|
private manageMarkersAttribute;
|
|
29
|
+
private markerStringToMapMarker;
|
|
29
30
|
private initialize;
|
|
30
31
|
private injectConfigMetaTags;
|
|
31
32
|
}
|
package/api/apigeogirafeapp.js
CHANGED
|
@@ -10,6 +10,7 @@ import MenuButtonComponent from '../components/menubutton/component.js';
|
|
|
10
10
|
import MapCustomContextMenuComponent from '../components/context-menu/custom-context-menu/component.js';
|
|
11
11
|
import SearchComponent from '../components/search/component.js';
|
|
12
12
|
import SelectionWindowComponent from '../components/selectionwindow/component.js';
|
|
13
|
+
import { splitTrimAndConvertToNumber } from '../tools/utils/utils.js';
|
|
13
14
|
export default class GeoGirafeApi extends GirafeHTMLElement {
|
|
14
15
|
templateUrl = null;
|
|
15
16
|
styleUrls = null;
|
|
@@ -245,17 +246,10 @@ export default class GeoGirafeApi extends GirafeHTMLElement {
|
|
|
245
246
|
const markers = this.getAttributeFromConfig('markers');
|
|
246
247
|
if (markers) {
|
|
247
248
|
const markerValues = markers.split(';');
|
|
248
|
-
for (const
|
|
249
|
-
const
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
const y = Number(coords[1].trim());
|
|
253
|
-
if (!Number.isNaN(x) && !Number.isNaN(y)) {
|
|
254
|
-
const imageUrl = content[1].trim();
|
|
255
|
-
this.context.stateManager.state.position.markers.push({
|
|
256
|
-
position: [x, y],
|
|
257
|
-
imageUrl: imageUrl
|
|
258
|
-
});
|
|
249
|
+
for (const markerValue of markerValues) {
|
|
250
|
+
const marker = this.markerStringToMapMarker(markerValue);
|
|
251
|
+
if (marker) {
|
|
252
|
+
this.context.stateManager.state.position.markers.push(marker);
|
|
259
253
|
}
|
|
260
254
|
else {
|
|
261
255
|
console.warn('Invalid marker coordinates');
|
|
@@ -263,6 +257,43 @@ export default class GeoGirafeApi extends GirafeHTMLElement {
|
|
|
263
257
|
}
|
|
264
258
|
}
|
|
265
259
|
}
|
|
260
|
+
markerStringToMapMarker(markerValue) {
|
|
261
|
+
console.log('markerStringToMapMarker', markerValue);
|
|
262
|
+
const contentParts = markerValue.split('|');
|
|
263
|
+
const needToGuessThirdParameter = contentParts.length == 3;
|
|
264
|
+
if (needToGuessThirdParameter) {
|
|
265
|
+
console.warn(`Marker has only 3 Parameters! Guessing if third Parameter '${contentParts[2]}' is Size or Offset`);
|
|
266
|
+
}
|
|
267
|
+
const coords = contentParts[0].split(',');
|
|
268
|
+
const x = Number(coords[0].trim());
|
|
269
|
+
const y = Number(coords[1].trim());
|
|
270
|
+
if (!Number.isNaN(x) && !Number.isNaN(y)) {
|
|
271
|
+
const imageUrl = contentParts[1].trim();
|
|
272
|
+
let size;
|
|
273
|
+
let offset;
|
|
274
|
+
if (needToGuessThirdParameter) {
|
|
275
|
+
if (contentParts[2].match(/[+-]+/gm)) {
|
|
276
|
+
offset = splitTrimAndConvertToNumber(contentParts[2]);
|
|
277
|
+
}
|
|
278
|
+
else {
|
|
279
|
+
size = splitTrimAndConvertToNumber(contentParts[2]);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
else if (contentParts.length > 2) {
|
|
283
|
+
size = splitTrimAndConvertToNumber(contentParts[2]);
|
|
284
|
+
offset = splitTrimAndConvertToNumber(contentParts[3]);
|
|
285
|
+
}
|
|
286
|
+
return {
|
|
287
|
+
position: [x, y],
|
|
288
|
+
imageUrl: imageUrl,
|
|
289
|
+
size: size,
|
|
290
|
+
offset: offset
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
else {
|
|
294
|
+
return undefined;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
266
297
|
async initialize() {
|
|
267
298
|
await this.context.initialize();
|
|
268
299
|
// Register Coordinate Reference Systems (CRS) definitions in PROJ4
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { Color } from 'vanilla-picker';
|
|
2
|
-
import DrawingFeature, { ArrowPosition, ArrowStyle, DrawingShape
|
|
3
|
-
import
|
|
4
|
-
import
|
|
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 '
|
|
11
|
-
import OlDrawing from '
|
|
12
|
-
import CesiumDrawing from '
|
|
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
|
|
204
|
-
throw new Error(
|
|
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
|
|
207
|
+
this.drawingState = this.state.extendedState[DrawingStateLocation];
|
|
207
208
|
const map = this.context.componentManager.getComponents(MapComponent)[0];
|
|
208
|
-
this.olDrawing = new OlDrawing(map,
|
|
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,
|
|
215
|
+
this.cesiumDrawing = new CesiumDrawing(map, DrawingStateLocation, this.context);
|
|
215
216
|
this.render();
|
|
216
|
-
this.subscribe(
|
|
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) {
|
package/components/main.d.ts
CHANGED
|
@@ -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';
|
package/components/main.js
CHANGED
|
@@ -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';
|
|
@@ -135,7 +135,7 @@ export default class MapComponent extends GirafeHTMLElement {
|
|
|
135
135
|
this.subscribe('position.markers', () => {
|
|
136
136
|
this.clearAllMarkers();
|
|
137
137
|
for (const marker of this.state.position.markers) {
|
|
138
|
-
this.addMarker(marker
|
|
138
|
+
this.addMarker(marker);
|
|
139
139
|
}
|
|
140
140
|
});
|
|
141
141
|
this.subscribe('globe.display', async () => {
|
|
@@ -177,7 +177,7 @@ export default class MapComponent extends GirafeHTMLElement {
|
|
|
177
177
|
}
|
|
178
178
|
this.showCrosshair(this.state.position);
|
|
179
179
|
for (const marker of this.state.position.markers) {
|
|
180
|
-
this.addMarker(marker
|
|
180
|
+
this.addMarker(marker);
|
|
181
181
|
}
|
|
182
182
|
}
|
|
183
183
|
});
|
|
@@ -1017,23 +1017,24 @@ export default class MapComponent extends GirafeHTMLElement {
|
|
|
1017
1017
|
this.state.position = position;
|
|
1018
1018
|
if (position.markers.length > 0) {
|
|
1019
1019
|
// Add marker to the map
|
|
1020
|
-
this.addMarker(position.markers[0]
|
|
1020
|
+
this.addMarker(position.markers[0]);
|
|
1021
1021
|
}
|
|
1022
1022
|
}
|
|
1023
1023
|
}
|
|
1024
1024
|
clearAllMarkers() {
|
|
1025
1025
|
this.markerSource.clear();
|
|
1026
1026
|
}
|
|
1027
|
-
addMarker(
|
|
1027
|
+
addMarker(mapMarker) {
|
|
1028
1028
|
const iconStyle = new Style({
|
|
1029
1029
|
image: new Icon({
|
|
1030
|
-
|
|
1031
|
-
src: imageUrl
|
|
1032
|
-
|
|
1030
|
+
displacement: mapMarker.offset,
|
|
1031
|
+
src: mapMarker.imageUrl,
|
|
1032
|
+
width: mapMarker.size ? mapMarker.size[0] : undefined,
|
|
1033
|
+
height: mapMarker.size ? mapMarker.size[1] : undefined
|
|
1033
1034
|
})
|
|
1034
1035
|
});
|
|
1035
1036
|
const marker = new Feature({
|
|
1036
|
-
geometry: new Point(position)
|
|
1037
|
+
geometry: new Point(mapMarker.position)
|
|
1037
1038
|
});
|
|
1038
1039
|
marker.setStyle(iconStyle);
|
|
1039
1040
|
this.markerSource.addFeature(marker);
|
package/package.json
CHANGED
package/templates/api.html
CHANGED
|
@@ -290,6 +290,21 @@
|
|
|
290
290
|
</div>
|
|
291
291
|
</section>
|
|
292
292
|
|
|
293
|
+
<!-- Multiple markers with size and/or offset -->
|
|
294
|
+
<h2>Add multiple markers with size and/or offset on the map</h2>
|
|
295
|
+
<p class="descr">Add multiple markers at the defined coordinates. You can specify size and offset. If you only
|
|
296
|
+
specify three parameters, the third parameter can be the size if you <strong>don't</strong> include a sign
|
|
297
|
+
(e.g. <code>24,24</code>) or the offset if you <strong>do</strong> include a sign (e.g. <code>+2,-6</code>).
|
|
298
|
+
</p>
|
|
299
|
+
<section>
|
|
300
|
+
<div class="row">
|
|
301
|
+
<div class="left">
|
|
302
|
+
<geogirafe-map markers="api.demo.markersWithSizeAndOrOffset" />
|
|
303
|
+
</div>
|
|
304
|
+
<div class="right"></div>
|
|
305
|
+
</div>
|
|
306
|
+
</section>
|
|
307
|
+
|
|
293
308
|
<!-- Layers -->
|
|
294
309
|
<h2>Add a layer to the map</h2>
|
|
295
310
|
<p class="descr">Add a layer to the map. The layer name must be defined in the themes.json file.</p>
|
|
@@ -302,7 +317,7 @@
|
|
|
302
317
|
</div>
|
|
303
318
|
</section>
|
|
304
319
|
|
|
305
|
-
<!--
|
|
320
|
+
<!-- Multiple layers -->
|
|
306
321
|
<h2>Add multiple layers to the map</h2>
|
|
307
322
|
<p class="descr">Add multiple layers to the map. The layer names must be defined in the themes.json file.</p>
|
|
308
323
|
<section>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"1.1.0-dev.
|
|
1
|
+
{"version":"1.1.0-dev.2545448597", "build":"2545448597", "date":"22/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
|
|
47
|
-
import DrawingSerializer from '
|
|
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
|
|
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
|
-
|
|
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.
|
|
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,
|
|
28
|
-
this.
|
|
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(
|
|
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.
|
|
309
|
-
this.context.userInteractionManager.registerListener('globe.draw', true, this.
|
|
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.
|
|
314
|
-
this.context.userInteractionManager.unregisterListener('globe.draw', this.
|
|
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.
|
|
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 '
|
|
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
|
|
110
|
-
* The number starts from how many
|
|
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 '
|
|
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,
|
|
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
|
|
283
|
-
* The number starts from how many
|
|
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 '
|
|
2
|
-
import type { IBrainSerializer } from '
|
|
3
|
-
import
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
25
|
+
drawingState = this.state.extendedState[stateLocation];
|
|
24
26
|
drawingState.features.splice(0, drawingState.features.length);
|
|
25
27
|
}
|
|
26
28
|
else {
|
|
27
|
-
this.state.extendedState
|
|
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
|
|
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
|
+
}
|
|
@@ -1,45 +1,38 @@
|
|
|
1
|
-
import DrawingFeature
|
|
2
|
-
import MapComponent from '
|
|
3
|
-
import {
|
|
4
|
-
import { Geometry
|
|
5
|
-
import
|
|
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
|
|
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
|
|
11
|
+
private readonly stateLocation;
|
|
19
12
|
private readonly context;
|
|
20
13
|
private readonly deleteHandler;
|
|
21
|
-
modifiableFeatures
|
|
22
|
-
draw
|
|
23
|
-
modify
|
|
24
|
-
snap
|
|
25
|
-
editContextMenu
|
|
26
|
-
currentShape
|
|
27
|
-
fixedLineLength
|
|
28
|
-
fixedSquareSide
|
|
29
|
-
fixedRectangleWidth
|
|
30
|
-
fixedRectangleHeight
|
|
31
|
-
drawingSource: VectorSource;
|
|
32
|
-
drawingLayer: VectorLayer;
|
|
33
|
-
lastClosestFeature
|
|
34
|
-
translate
|
|
35
|
-
transform
|
|
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(
|
|
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
|
|
55
|
-
removeEditInteractions
|
|
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
|
|
62
|
-
hasEditableShapeAtCoordinate
|
|
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
|
|
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
|
|
109
|
-
createSquareFixedLength
|
|
110
|
-
createPolygonFixedLength
|
|
111
|
-
createDiskFixedLength
|
|
112
|
-
createRectangleFixedSides
|
|
113
|
-
addDrawInteraction
|
|
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
|
|
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 '
|
|
14
|
-
import { ContextMenu, EntryInteractionType } from '
|
|
15
|
-
import { formatCoordinates } from '
|
|
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 '
|
|
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
|
-
|
|
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.
|
|
86
|
+
return this.state.extendedState[this.stateLocation];
|
|
86
87
|
}
|
|
87
88
|
get config() {
|
|
88
89
|
return this.context.configManager.Config;
|
|
89
90
|
}
|
|
90
|
-
constructor(
|
|
91
|
-
this.map =
|
|
92
|
-
this.
|
|
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(
|
|
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(
|
|
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.
|
|
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.
|
|
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.
|
|
929
|
-
this.context.userInteractionManager.registerListener('map.modify', true, this.
|
|
930
|
-
this.context.userInteractionManager.registerListener('map.snap', true, this.
|
|
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.
|
|
936
|
-
this.context.userInteractionManager.unregisterListener('map.modify', this.
|
|
937
|
-
this.context.userInteractionManager.unregisterListener('map.snap', this.
|
|
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.
|
|
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';
|
|
@@ -113,7 +120,7 @@ export { unByKeyAll, getOlayerByName, removeUnwantedOlParams, polygonFromCircle,
|
|
|
113
120
|
export { getPropertyByPath, setPropertyByPath, createObjectFromPath, deletePropertyByPath, mergeObjects } from './utils/pathUtils.js';
|
|
114
121
|
export { generateQrCode } from './utils/qrcode.js';
|
|
115
122
|
export { default as ServiceWorkerHelper } from './utils/swhelper.js';
|
|
116
|
-
export { systemIsInDarkMode, isSafari, isFirefox, getValidIndex, minMax, hexToRgbaArray, rgbStrToRgbaArray, colorToRgbaArray, isValidEmail, applyOpacityToLayers, applyFeaturesToSelection, linkify, applyDefaultPrefixToUrl } from './utils/utils.js';
|
|
123
|
+
export { systemIsInDarkMode, isSafari, isFirefox, getValidIndex, minMax, hexToRgbaArray, rgbStrToRgbaArray, colorToRgbaArray, isValidEmail, applyOpacityToLayers, applyFeaturesToSelection, linkify, applyDefaultPrefixToUrl, splitTrimAndConvertToNumber } from './utils/utils.js';
|
|
117
124
|
export { default as VendorSpecificOgcServerManager } from './vendorspecificogcservermanager.js';
|
|
118
125
|
export type { WfsClientOptions, WfsClientOptionalOptions, QueryableLayerWms, GetFeatureOptionsPartial } from './wfs/wfsclient.js';
|
|
119
126
|
export { default as WfsClient, WfsClientMapServer, WfsClientQgis, WfsClientGeorama, WfsClientDefault, WfsClientGeoServer } from './wfs/wfsclient.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';
|
|
@@ -88,7 +94,7 @@ export { unByKeyAll, getOlayerByName, removeUnwantedOlParams, polygonFromCircle,
|
|
|
88
94
|
export { getPropertyByPath, setPropertyByPath, createObjectFromPath, deletePropertyByPath, mergeObjects } from './utils/pathUtils.js';
|
|
89
95
|
export { generateQrCode } from './utils/qrcode.js';
|
|
90
96
|
export { default as ServiceWorkerHelper } from './utils/swhelper.js';
|
|
91
|
-
export { systemIsInDarkMode, isSafari, isFirefox, getValidIndex, minMax, hexToRgbaArray, rgbStrToRgbaArray, colorToRgbaArray, isValidEmail, applyOpacityToLayers, applyFeaturesToSelection, linkify, applyDefaultPrefixToUrl } from './utils/utils.js';
|
|
97
|
+
export { systemIsInDarkMode, isSafari, isFirefox, getValidIndex, minMax, hexToRgbaArray, rgbStrToRgbaArray, colorToRgbaArray, isValidEmail, applyOpacityToLayers, applyFeaturesToSelection, linkify, applyDefaultPrefixToUrl, splitTrimAndConvertToNumber } from './utils/utils.js';
|
|
92
98
|
export { default as VendorSpecificOgcServerManager } from './vendorspecificogcservermanager.js';
|
|
93
99
|
export { default as WfsClient, WfsClientMapServer, WfsClientQgis, WfsClientGeorama, WfsClientDefault, WfsClientGeoServer } from './wfs/wfsclient.js';
|
|
94
100
|
export { default as WfsFilter } from './wfs/wfsfilter.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`);
|
|
@@ -21,7 +21,12 @@ export default class PermalinkManager extends GirafeSingleton {
|
|
|
21
21
|
hasMapPosition(): boolean | "" | null;
|
|
22
22
|
private hasToolTip;
|
|
23
23
|
private hasMarker;
|
|
24
|
+
private hasMarkerSize;
|
|
25
|
+
private hasMarkerOffset;
|
|
24
26
|
getMapPosition(targetProjection: Projection): MapPosition | undefined;
|
|
27
|
+
private addCenter;
|
|
28
|
+
private addTooltip;
|
|
29
|
+
private addMarker;
|
|
25
30
|
hasSearch(): boolean;
|
|
26
31
|
getSearchTerm(): string;
|
|
27
32
|
hasThemes(): boolean;
|
|
@@ -5,6 +5,7 @@ import MapPosition from '../state/mapposition.js';
|
|
|
5
5
|
import { get as getProjection, transform } from 'ol/proj.js';
|
|
6
6
|
import { isCoordinateInDegrees } from '../utils/olutils.js';
|
|
7
7
|
import { BASEMAP_VISIBLE_PARAMETER, SEARCH_VISIBLE_PARAMETER } from './permalinkmanager-constants.js';
|
|
8
|
+
import { splitTrimAndConvertToNumber } from '../utils/utils.js';
|
|
8
9
|
export default class PermalinkManager extends GirafeSingleton {
|
|
9
10
|
urlParamKeys = [
|
|
10
11
|
'map_x',
|
|
@@ -13,6 +14,8 @@ export default class PermalinkManager extends GirafeSingleton {
|
|
|
13
14
|
'map_crosshair',
|
|
14
15
|
'map_tooltip',
|
|
15
16
|
'map_marker',
|
|
17
|
+
'map_marker_size',
|
|
18
|
+
'map_marker_offset',
|
|
16
19
|
'search',
|
|
17
20
|
'basemap',
|
|
18
21
|
'themes',
|
|
@@ -83,46 +86,71 @@ export default class PermalinkManager extends GirafeSingleton {
|
|
|
83
86
|
hasMarker() {
|
|
84
87
|
return this.params['map_marker'] !== null;
|
|
85
88
|
}
|
|
89
|
+
hasMarkerSize() {
|
|
90
|
+
return this.params['map_marker_size'] !== null;
|
|
91
|
+
}
|
|
92
|
+
hasMarkerOffset() {
|
|
93
|
+
return this.params['map_marker_offset'] !== null;
|
|
94
|
+
}
|
|
86
95
|
getMapPosition(targetProjection) {
|
|
87
96
|
if (this.hasMapPosition()) {
|
|
88
97
|
const position = new MapPosition();
|
|
89
|
-
|
|
90
|
-
// Transform position to the target projection by making an educated guess about the current CRS
|
|
91
|
-
// of the permalink map position
|
|
92
|
-
const defaultProjection = this.context.configManager.getDefaultConfigValue('map.srid');
|
|
93
|
-
const projectionInUrl = getProjection(isCoordinateInDegrees(position.center) ? 'EPSG:4326' : defaultProjection);
|
|
94
|
-
if (projectionInUrl.getCode() !== this.state.projection) {
|
|
95
|
-
center = transform(center, projectionInUrl, targetProjection);
|
|
96
|
-
}
|
|
97
|
-
position.center = center;
|
|
98
|
+
this.addCenter(position, targetProjection);
|
|
98
99
|
const defaultZoom = this.context.configManager.getDefaultConfigValue('map.startZoom');
|
|
99
100
|
position.zoom = Number.parseInt(this.params['map_zoom'] ?? defaultZoom);
|
|
100
101
|
if (this.params['map_crosshair'] === 'true') {
|
|
101
|
-
position.crosshair = center;
|
|
102
|
-
}
|
|
103
|
-
if (this.hasToolTip()) {
|
|
104
|
-
const content = DOMPurify.sanitize(this.params['map_tooltip'], {
|
|
105
|
-
ALLOWED_TAGS: ['br', 'b', 'div', 'em', 'i', 'p', 'strong'],
|
|
106
|
-
ALLOWED_ATTR: []
|
|
107
|
-
});
|
|
108
|
-
position.tooltip = {
|
|
109
|
-
content: content,
|
|
110
|
-
position: center
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
if (this.hasMarker()) {
|
|
114
|
-
const imageUrl = DOMPurify.sanitize(this.params['map_marker']);
|
|
115
|
-
position.markers.push({
|
|
116
|
-
imageUrl: imageUrl,
|
|
117
|
-
position: center
|
|
118
|
-
});
|
|
102
|
+
position.crosshair = position.center;
|
|
119
103
|
}
|
|
104
|
+
this.addTooltip(position);
|
|
105
|
+
this.addMarker(position);
|
|
120
106
|
if (position.isValid) {
|
|
121
107
|
return position;
|
|
122
108
|
}
|
|
123
109
|
}
|
|
124
110
|
return undefined;
|
|
125
111
|
}
|
|
112
|
+
addCenter(position, targetProjection) {
|
|
113
|
+
let center = [Number.parseFloat(this.params['map_x']), Number.parseFloat(this.params['map_y'])];
|
|
114
|
+
// Transform position to the target projection by making an educated guess about the current CRS
|
|
115
|
+
// of the permalink map position
|
|
116
|
+
const defaultProjection = this.context.configManager.getDefaultConfigValue('map.srid');
|
|
117
|
+
const projectionInUrl = getProjection(isCoordinateInDegrees(position.center) ? 'EPSG:4326' : defaultProjection);
|
|
118
|
+
if (projectionInUrl.getCode() !== this.state.projection) {
|
|
119
|
+
center = transform(center, projectionInUrl, targetProjection);
|
|
120
|
+
}
|
|
121
|
+
position.center = center;
|
|
122
|
+
}
|
|
123
|
+
addTooltip(position) {
|
|
124
|
+
if (this.hasToolTip()) {
|
|
125
|
+
const content = DOMPurify.sanitize(this.params['map_tooltip'], {
|
|
126
|
+
ALLOWED_TAGS: ['br', 'b', 'div', 'em', 'i', 'p', 'strong'],
|
|
127
|
+
ALLOWED_ATTR: []
|
|
128
|
+
});
|
|
129
|
+
position.tooltip = {
|
|
130
|
+
content: content,
|
|
131
|
+
position: position.center
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
addMarker(position) {
|
|
136
|
+
if (this.hasMarker()) {
|
|
137
|
+
const imageUrl = DOMPurify.sanitize(this.params['map_marker']);
|
|
138
|
+
let size;
|
|
139
|
+
let offset;
|
|
140
|
+
if (this.hasMarkerSize()) {
|
|
141
|
+
size = splitTrimAndConvertToNumber(DOMPurify.sanitize(this.params['map_marker_size']));
|
|
142
|
+
}
|
|
143
|
+
if (this.hasMarkerOffset()) {
|
|
144
|
+
offset = splitTrimAndConvertToNumber(DOMPurify.sanitize(this.params['map_marker_offset']));
|
|
145
|
+
}
|
|
146
|
+
position.markers.push({
|
|
147
|
+
imageUrl: imageUrl,
|
|
148
|
+
position: position.center,
|
|
149
|
+
size: size,
|
|
150
|
+
offset: offset
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
}
|
|
126
154
|
hasSearch() {
|
|
127
155
|
return this.params['search'] !== null;
|
|
128
156
|
}
|
package/tools/utils/utils.d.ts
CHANGED
|
@@ -77,3 +77,8 @@ export declare const linkify: (str: string) => string;
|
|
|
77
77
|
* @returns
|
|
78
78
|
*/
|
|
79
79
|
export declare function applyDefaultPrefixToUrl(context: IGirafeContext, metadataUrl?: string): string | undefined;
|
|
80
|
+
/**
|
|
81
|
+
* Splits a String containing Numbers into an Array of Numbers. The Separator is a comma.
|
|
82
|
+
* @param numbersAsString The String containing Numbers.
|
|
83
|
+
*/
|
|
84
|
+
export declare const splitTrimAndConvertToNumber: (numbersAsString: string) => number[];
|
package/tools/utils/utils.js
CHANGED
|
@@ -199,3 +199,13 @@ export function applyDefaultPrefixToUrl(context, metadataUrl) {
|
|
|
199
199
|
}
|
|
200
200
|
return metadataUrl;
|
|
201
201
|
}
|
|
202
|
+
/**
|
|
203
|
+
* Splits a String containing Numbers into an Array of Numbers. The Separator is a comma.
|
|
204
|
+
* @param numbersAsString The String containing Numbers.
|
|
205
|
+
*/
|
|
206
|
+
export const splitTrimAndConvertToNumber = (numbersAsString) => {
|
|
207
|
+
return numbersAsString
|
|
208
|
+
.split(',')
|
|
209
|
+
.map((e) => e.trim())
|
|
210
|
+
.map(Number);
|
|
211
|
+
};
|
|
@@ -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
|
-
}
|
|
File without changes
|
|
File without changes
|