@versatiles/svelte 1.1.2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/BasicMap/BasicMap.svelte +4 -4
- package/dist/components/BasicMap/BasicMap.svelte.d.ts +2 -2
- package/dist/components/MapEditor/MapEditor.svelte +16 -3
- package/dist/components/MapEditor/components/Editor.svelte +46 -40
- package/dist/components/MapEditor/components/Editor.svelte.d.ts +1 -1
- package/dist/components/MapEditor/components/EditorFill.svelte +7 -9
- package/dist/components/MapEditor/components/EditorStroke.svelte +9 -11
- package/dist/components/MapEditor/components/EditorSymbol.svelte +15 -21
- package/dist/components/MapEditor/components/InputRow.svelte +34 -0
- package/dist/components/MapEditor/components/InputRow.svelte.d.ts +9 -0
- package/dist/components/MapEditor/components/Sidebar.svelte +115 -108
- package/dist/components/MapEditor/components/SidebarPanel.svelte +92 -0
- package/dist/components/MapEditor/components/SidebarPanel.svelte.d.ts +10 -0
- package/dist/components/MapEditor/components/SymbolSelector.svelte +7 -15
- package/dist/components/MapEditor/lib/element/abstract.d.ts +3 -3
- package/dist/components/MapEditor/lib/element/abstract.js +1 -1
- package/dist/components/MapEditor/lib/element/line.d.ts +3 -4
- package/dist/components/MapEditor/lib/element/line.js +0 -1
- package/dist/components/MapEditor/lib/element/marker.d.ts +4 -4
- package/dist/components/MapEditor/lib/element/polygon.d.ts +3 -3
- package/dist/components/MapEditor/lib/geometry_manager.d.ts +20 -10
- package/dist/components/MapEditor/lib/geometry_manager.js +44 -52
- package/dist/components/MapEditor/lib/map_layer/abstract.d.ts +3 -2
- package/dist/components/MapEditor/lib/map_layer/abstract.js +3 -0
- package/dist/components/MapEditor/lib/map_layer/fill.d.ts +4 -3
- package/dist/components/MapEditor/lib/map_layer/fill.js +9 -8
- package/dist/components/MapEditor/lib/map_layer/line.d.ts +4 -3
- package/dist/components/MapEditor/lib/map_layer/line.js +15 -14
- package/dist/components/MapEditor/lib/map_layer/symbol.d.ts +5 -4
- package/dist/components/MapEditor/lib/map_layer/symbol.js +28 -46
- package/dist/components/MapEditor/lib/state/constants.d.ts +4 -0
- package/dist/components/MapEditor/lib/state/constants.js +22 -0
- package/dist/components/MapEditor/lib/state/manager.d.ts +16 -0
- package/dist/components/MapEditor/lib/state/manager.js +76 -0
- package/dist/components/MapEditor/lib/state/reader.d.ts +21 -14
- package/dist/components/MapEditor/lib/state/reader.js +259 -142
- package/dist/components/MapEditor/lib/state/types.d.ts +27 -12
- package/dist/components/MapEditor/lib/state/writer.d.ts +18 -14
- package/dist/components/MapEditor/lib/state/writer.js +182 -169
- package/dist/components/MapEditor/lib/utils.d.ts +2 -5
- package/dist/components/MapEditor/lib/utils.js +0 -19
- package/package.json +19 -19
@@ -0,0 +1,92 @@
|
|
1
|
+
<script lang="ts">
|
2
|
+
import type { Snippet } from 'svelte';
|
3
|
+
|
4
|
+
let {
|
5
|
+
children,
|
6
|
+
open = true,
|
7
|
+
title,
|
8
|
+
disabled = false
|
9
|
+
}: { children: Snippet; disabled?: boolean; open?: boolean; title: string } = $props();
|
10
|
+
</script>
|
11
|
+
|
12
|
+
<div class={{ panel: true, open, disabled }}>
|
13
|
+
<button class="header" onclick={() => (open = !open)}>
|
14
|
+
<span class="title">{title}</span>
|
15
|
+
<div class="chevron">
|
16
|
+
<svg viewBox="0 0 7 12">
|
17
|
+
<path d="M1,0L7,6L1,12L0,11,L5,6L0,1z" />
|
18
|
+
</svg>
|
19
|
+
</div>
|
20
|
+
</button>
|
21
|
+
<div class="content">
|
22
|
+
{@render children()}
|
23
|
+
</div>
|
24
|
+
</div>
|
25
|
+
|
26
|
+
<style>
|
27
|
+
.panel {
|
28
|
+
margin: 1em 0;
|
29
|
+
|
30
|
+
.header {
|
31
|
+
background: none;
|
32
|
+
border: none;
|
33
|
+
color: var(--color-text);
|
34
|
+
cursor: pointer;
|
35
|
+
font-weight: 600;
|
36
|
+
margin: 0;
|
37
|
+
padding: 0;
|
38
|
+
position: relative;
|
39
|
+
text-align: left;
|
40
|
+
width: 100%;
|
41
|
+
|
42
|
+
.title {
|
43
|
+
text-transform: uppercase;
|
44
|
+
opacity: 0.8;
|
45
|
+
}
|
46
|
+
.chevron {
|
47
|
+
box-sizing: border-box;
|
48
|
+
display: block;
|
49
|
+
height: 1em;
|
50
|
+
opacity: 0.7;
|
51
|
+
padding: 0;
|
52
|
+
position: absolute;
|
53
|
+
right: 0.4em;
|
54
|
+
top: 0;
|
55
|
+
width: 1em;
|
56
|
+
svg {
|
57
|
+
fill: var(--color-fg);
|
58
|
+
width: 100%;
|
59
|
+
height: 100%;
|
60
|
+
rotate: 0deg;
|
61
|
+
transition: rotate 0.1s linear;
|
62
|
+
transform-origin: 40% 50%;
|
63
|
+
}
|
64
|
+
}
|
65
|
+
}
|
66
|
+
.content {
|
67
|
+
height: 0;
|
68
|
+
overflow: hidden;
|
69
|
+
padding: 0;
|
70
|
+
box-sizing: border-box;
|
71
|
+
}
|
72
|
+
}
|
73
|
+
.open {
|
74
|
+
margin-bottom: 2em;
|
75
|
+
.header {
|
76
|
+
.chevron {
|
77
|
+
svg {
|
78
|
+
rotate: 90deg;
|
79
|
+
}
|
80
|
+
}
|
81
|
+
}
|
82
|
+
.content {
|
83
|
+
height: auto;
|
84
|
+
}
|
85
|
+
}
|
86
|
+
.disabled {
|
87
|
+
opacity: 0.3;
|
88
|
+
.content {
|
89
|
+
display: none;
|
90
|
+
}
|
91
|
+
}
|
92
|
+
</style>
|
@@ -0,0 +1,10 @@
|
|
1
|
+
import type { Snippet } from 'svelte';
|
2
|
+
type $$ComponentProps = {
|
3
|
+
children: Snippet;
|
4
|
+
disabled?: boolean;
|
5
|
+
open?: boolean;
|
6
|
+
title: string;
|
7
|
+
};
|
8
|
+
declare const SidebarPanel: import("svelte").Component<$$ComponentProps, {}, "">;
|
9
|
+
type SidebarPanel = ReturnType<typeof SidebarPanel>;
|
10
|
+
export default SidebarPanel;
|
@@ -7,17 +7,17 @@
|
|
7
7
|
symbolLibrary
|
8
8
|
}: { symbolIndex: number; symbolLibrary: SymbolLibrary } = $props();
|
9
9
|
|
10
|
-
let open = $state(false);
|
11
|
-
|
12
10
|
const drawIconHalo: Action<HTMLCanvasElement, number> = (canvas, index) =>
|
13
11
|
symbolLibrary.drawSymbol(canvas, index, true);
|
14
12
|
|
15
13
|
const drawIcon: Action<HTMLCanvasElement, number> = (canvas, index) =>
|
16
14
|
symbolLibrary.drawSymbol(canvas, index);
|
15
|
+
|
16
|
+
let dialog: HTMLDialogElement | null = null;
|
17
17
|
</script>
|
18
18
|
|
19
19
|
<button
|
20
|
-
onclick={() => (
|
20
|
+
onclick={() => dialog?.showModal()}
|
21
21
|
style="text-align: left; white-space: nowrap; overflow: hidden; padding: 1px"
|
22
22
|
>
|
23
23
|
{#key symbolIndex}
|
@@ -35,28 +35,20 @@
|
|
35
35
|
{/if}
|
36
36
|
</button>
|
37
37
|
|
38
|
-
<
|
39
|
-
<button class="close" onclick={() => (
|
38
|
+
<dialog class="modal" bind:this={dialog}>
|
39
|
+
<button class="close" onclick={() => dialog?.close()}>✕</button>
|
40
40
|
<div class="inner">
|
41
41
|
{#each symbolLibrary.asList() as symbol (symbol.index)}
|
42
|
-
<button
|
43
|
-
class="icon"
|
44
|
-
onclick={() => {
|
45
|
-
symbolIndex = symbol.index;
|
46
|
-
open = false;
|
47
|
-
}}
|
42
|
+
<button class="icon" onclick={() => (symbolIndex = symbol.index)}
|
48
43
|
><canvas width="64" height="64" use:drawIconHalo={symbol.index}></canvas><br
|
49
44
|
/>{symbol.name}</button
|
50
45
|
>
|
51
46
|
{/each}
|
52
47
|
</div>
|
53
|
-
</
|
48
|
+
</dialog>
|
54
49
|
|
55
50
|
<style>
|
56
51
|
.modal {
|
57
|
-
position: fixed;
|
58
|
-
top: max(calc(50vh - 250px), 0px);
|
59
|
-
left: max(calc(50vw - 250px), 0px);
|
60
52
|
width: min(500px, 100vw);
|
61
53
|
height: min(500px, 100vh);
|
62
54
|
background-color: rgba(255, 255, 255, 0.5);
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import type { ElementPoint, SelectionNode, SelectionNodeUpdater } from './types.js';
|
2
2
|
import type { GeometryManager } from '../geometry_manager.js';
|
3
|
-
import type {
|
3
|
+
import type { StateElement } from '../state/types.js';
|
4
4
|
export declare abstract class AbstractElement {
|
5
5
|
protected readonly canvas: HTMLElement;
|
6
6
|
protected readonly manager: GeometryManager;
|
@@ -14,8 +14,8 @@ export declare abstract class AbstractElement {
|
|
14
14
|
protected randomPositions(length: number): ElementPoint[];
|
15
15
|
delete(): void;
|
16
16
|
abstract destroy(): void;
|
17
|
-
abstract getFeature(includeProperties
|
17
|
+
abstract getFeature(includeProperties?: boolean): GeoJSON.Feature;
|
18
18
|
abstract getSelectionNodes(): SelectionNode[];
|
19
19
|
abstract getSelectionNodeUpdater(properties?: Record<string, unknown>): SelectionNodeUpdater | undefined;
|
20
|
-
abstract getState():
|
20
|
+
abstract getState(): StateElement;
|
21
21
|
}
|
@@ -2,15 +2,14 @@ import type { GeometryManager } from '../geometry_manager.js';
|
|
2
2
|
import type { ElementPath } from './types.js';
|
3
3
|
import { MapLayerLine } from '../map_layer/line.js';
|
4
4
|
import { AbstractPathElement } from './abstract_path.js';
|
5
|
-
import type {
|
5
|
+
import type { StateElementLine } from '../state/types.js';
|
6
6
|
export declare class LineElement extends AbstractPathElement {
|
7
7
|
readonly layer: MapLayerLine;
|
8
|
-
readonly path: ElementPath;
|
9
8
|
constructor(manager: GeometryManager, line?: ElementPath);
|
10
9
|
select(value: boolean): void;
|
11
10
|
getFeature(includeProperties?: boolean): GeoJSON.Feature<GeoJSON.LineString>;
|
12
11
|
destroy(): void;
|
13
|
-
getState():
|
14
|
-
static fromState(manager: GeometryManager, state:
|
12
|
+
getState(): StateElementLine;
|
13
|
+
static fromState(manager: GeometryManager, state: StateElementLine): LineElement;
|
15
14
|
static fromGeoJSON(manager: GeometryManager, feature: GeoJSON.Feature<GeoJSON.LineString>): LineElement;
|
16
15
|
}
|
@@ -2,7 +2,6 @@ import { MapLayerLine } from '../map_layer/line.js';
|
|
2
2
|
import { AbstractPathElement } from './abstract_path.js';
|
3
3
|
export class LineElement extends AbstractPathElement {
|
4
4
|
layer;
|
5
|
-
path;
|
6
5
|
constructor(manager, line) {
|
7
6
|
super(manager, true);
|
8
7
|
this.path = line ?? this.randomPositions(2);
|
@@ -2,17 +2,17 @@ import { AbstractElement } from './abstract.js';
|
|
2
2
|
import type { GeometryManager } from '../geometry_manager.js';
|
3
3
|
import type { ElementPoint, SelectionNode, SelectionNodeUpdater } from './types.js';
|
4
4
|
import { MapLayerSymbol } from '../map_layer/symbol.js';
|
5
|
-
import type {
|
5
|
+
import type { StateElementMarker } from '../state/types.js';
|
6
6
|
export declare class MarkerElement extends AbstractElement {
|
7
7
|
readonly layer: MapLayerSymbol;
|
8
|
-
|
8
|
+
point: ElementPoint;
|
9
9
|
constructor(manager: GeometryManager, point?: ElementPoint);
|
10
10
|
select(value: boolean): void;
|
11
11
|
getFeature(includeProperties?: boolean): GeoJSON.Feature<GeoJSON.Point>;
|
12
12
|
getSelectionNodes(): SelectionNode[];
|
13
13
|
getSelectionNodeUpdater(): SelectionNodeUpdater | undefined;
|
14
14
|
destroy(): void;
|
15
|
-
getState():
|
16
|
-
static fromState(manager: GeometryManager, state:
|
15
|
+
getState(): StateElementMarker;
|
16
|
+
static fromState(manager: GeometryManager, state: StateElementMarker): MarkerElement;
|
17
17
|
static fromGeoJSON(manager: GeometryManager, feature: GeoJSON.Feature<GeoJSON.Point>): MarkerElement;
|
18
18
|
}
|
@@ -3,7 +3,7 @@ import type { ElementPath } from './types.js';
|
|
3
3
|
import { MapLayerFill } from '../map_layer/fill.js';
|
4
4
|
import { MapLayerLine } from '../map_layer/line.js';
|
5
5
|
import { AbstractPathElement } from './abstract_path.js';
|
6
|
-
import type {
|
6
|
+
import type { StateElementPolygon } from '../state/types.js';
|
7
7
|
export declare class PolygonElement extends AbstractPathElement {
|
8
8
|
readonly fillLayer: MapLayerFill;
|
9
9
|
readonly strokeLayer: MapLayerLine;
|
@@ -11,7 +11,7 @@ export declare class PolygonElement extends AbstractPathElement {
|
|
11
11
|
select(value: boolean): void;
|
12
12
|
getFeature(includeProperties?: boolean): GeoJSON.Feature<GeoJSON.Polygon>;
|
13
13
|
destroy(): void;
|
14
|
-
getState():
|
15
|
-
static fromState(manager: GeometryManager, state:
|
14
|
+
getState(): StateElementPolygon;
|
15
|
+
static fromState(manager: GeometryManager, state: StateElementPolygon): PolygonElement;
|
16
16
|
static fromGeoJSON(manager: GeometryManager, feature: GeoJSON.Feature<GeoJSON.Polygon>): PolygonElement;
|
17
17
|
}
|
@@ -1,8 +1,18 @@
|
|
1
1
|
import { type Writable } from 'svelte/store';
|
2
2
|
import type { AbstractElement } from './element/abstract.js';
|
3
|
+
import { MarkerElement } from './element/marker.js';
|
4
|
+
import { LineElement } from './element/line.js';
|
5
|
+
import { PolygonElement } from './element/polygon.js';
|
3
6
|
import { Cursor } from './cursor.js';
|
4
|
-
import type { StateObject } from './state/types.js';
|
5
7
|
import { SymbolLibrary } from './symbols.js';
|
8
|
+
import { StateManager } from './state/manager.js';
|
9
|
+
import type { StateRoot } from './state/types.js';
|
10
|
+
export type ExtendedGeoJSON = GeoJSON.FeatureCollection & {
|
11
|
+
map?: {
|
12
|
+
center: [number, number];
|
13
|
+
zoom: number;
|
14
|
+
};
|
15
|
+
};
|
6
16
|
export declare class GeometryManager {
|
7
17
|
readonly elements: Writable<AbstractElement[]>;
|
8
18
|
readonly map: maplibregl.Map;
|
@@ -10,19 +20,19 @@ export declare class GeometryManager {
|
|
10
20
|
readonly canvas: HTMLElement;
|
11
21
|
readonly cursor: Cursor;
|
12
22
|
readonly symbolLibrary: SymbolLibrary;
|
23
|
+
readonly state: StateManager;
|
13
24
|
private readonly selectionNodes;
|
14
25
|
constructor(map: maplibregl.Map);
|
15
26
|
selectElement(element: AbstractElement | undefined): void;
|
16
27
|
drawSelectionNodes(): void;
|
17
|
-
getState():
|
18
|
-
|
19
|
-
loadState(hash: string): Promise<void>;
|
28
|
+
getState(): StateRoot;
|
29
|
+
setState(state: StateRoot): void;
|
20
30
|
getElement(index: number): AbstractElement;
|
21
|
-
addNewMarker():
|
22
|
-
addNewLine():
|
23
|
-
addNewPolygon():
|
24
|
-
private
|
25
|
-
|
31
|
+
addNewMarker(): MarkerElement;
|
32
|
+
addNewLine(): LineElement;
|
33
|
+
addNewPolygon(): PolygonElement;
|
34
|
+
private appendElement;
|
35
|
+
removeElement(element: AbstractElement): void;
|
26
36
|
getGeoJSON(): GeoJSON.FeatureCollection;
|
27
|
-
addGeoJSON(geojson:
|
37
|
+
addGeoJSON(geojson: ExtendedGeoJSON): void;
|
28
38
|
}
|
@@ -3,9 +3,8 @@ import { MarkerElement } from './element/marker.js';
|
|
3
3
|
import { LineElement } from './element/line.js';
|
4
4
|
import { PolygonElement } from './element/polygon.js';
|
5
5
|
import { Cursor } from './cursor.js';
|
6
|
-
import { StateWriter } from './state/writer.js';
|
7
|
-
import { StateReader } from './state/reader.js';
|
8
6
|
import { SymbolLibrary } from './symbols.js';
|
7
|
+
import { StateManager } from './state/manager.js';
|
9
8
|
export class GeometryManager {
|
10
9
|
elements;
|
11
10
|
map;
|
@@ -13,6 +12,7 @@ export class GeometryManager {
|
|
13
12
|
canvas;
|
14
13
|
cursor;
|
15
14
|
symbolLibrary;
|
15
|
+
state;
|
16
16
|
selectionNodes;
|
17
17
|
constructor(map) {
|
18
18
|
this.elements = writable([]);
|
@@ -53,7 +53,6 @@ export class GeometryManager {
|
|
53
53
|
if (e.originalEvent.shiftKey) {
|
54
54
|
selectedNode.delete();
|
55
55
|
this.drawSelectionNodes();
|
56
|
-
this.saveState();
|
57
56
|
}
|
58
57
|
else {
|
59
58
|
const onMove = (e) => {
|
@@ -63,8 +62,8 @@ export class GeometryManager {
|
|
63
62
|
};
|
64
63
|
map.on('mousemove', onMove);
|
65
64
|
map.once('mouseup', () => {
|
66
|
-
this.saveState();
|
67
65
|
map.off('mousemove', onMove);
|
66
|
+
this.state.log();
|
68
67
|
});
|
69
68
|
}
|
70
69
|
});
|
@@ -79,10 +78,7 @@ export class GeometryManager {
|
|
79
78
|
this.selectElement(undefined);
|
80
79
|
e.preventDefault();
|
81
80
|
});
|
82
|
-
|
83
|
-
const hash = location.hash.slice(1);
|
84
|
-
if (hash)
|
85
|
-
this.loadState(hash);
|
81
|
+
this.state = new StateManager(this);
|
86
82
|
}
|
87
83
|
selectElement(element) {
|
88
84
|
if (element == get(this.selectedElement))
|
@@ -107,48 +103,42 @@ export class GeometryManager {
|
|
107
103
|
const center = this.map.getCenter();
|
108
104
|
return {
|
109
105
|
map: {
|
110
|
-
|
106
|
+
center: [center.lng, center.lat],
|
111
107
|
zoom: this.map.getZoom()
|
112
108
|
},
|
113
109
|
elements: get(this.elements).map((element) => element.getState())
|
114
110
|
};
|
115
111
|
}
|
116
|
-
|
117
|
-
|
118
|
-
writer.writeObject(this.getState());
|
119
|
-
location.hash = await writer.getBase64compressed();
|
120
|
-
}
|
121
|
-
async loadState(hash) {
|
122
|
-
if (!hash)
|
112
|
+
setState(state) {
|
113
|
+
if (!state)
|
123
114
|
return;
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
115
|
+
this.selectElement(undefined);
|
116
|
+
this.elements.update((elements) => {
|
117
|
+
elements.forEach((e) => e.destroy());
|
118
|
+
return [];
|
119
|
+
});
|
120
|
+
if (state.map) {
|
121
|
+
if (state.map.zoom)
|
130
122
|
this.map.setZoom(state.map.zoom);
|
131
|
-
if (state.map
|
132
|
-
|
133
|
-
|
134
|
-
if (state.elements) {
|
135
|
-
const elements = state.elements.map((element) => {
|
136
|
-
switch (element.type) {
|
137
|
-
case 'marker':
|
138
|
-
return MarkerElement.fromState(this, element);
|
139
|
-
case 'line':
|
140
|
-
return LineElement.fromState(this, element);
|
141
|
-
case 'polygon':
|
142
|
-
return PolygonElement.fromState(this, element);
|
143
|
-
default:
|
144
|
-
throw new Error('Unknown element type');
|
145
|
-
}
|
146
|
-
});
|
147
|
-
this.elements.set(elements);
|
123
|
+
if (state.map.center) {
|
124
|
+
const [lng, lat] = state.map.center;
|
125
|
+
this.map.setCenter({ lng, lat });
|
148
126
|
}
|
149
127
|
}
|
150
|
-
|
151
|
-
|
128
|
+
if (state.elements) {
|
129
|
+
const elements = state.elements.map((element) => {
|
130
|
+
switch (element.type) {
|
131
|
+
case 'marker':
|
132
|
+
return MarkerElement.fromState(this, element);
|
133
|
+
case 'line':
|
134
|
+
return LineElement.fromState(this, element);
|
135
|
+
case 'polygon':
|
136
|
+
return PolygonElement.fromState(this, element);
|
137
|
+
default:
|
138
|
+
throw new Error('Unknown element type');
|
139
|
+
}
|
140
|
+
});
|
141
|
+
this.elements.set(elements);
|
152
142
|
}
|
153
143
|
}
|
154
144
|
getElement(index) {
|
@@ -156,28 +146,31 @@ export class GeometryManager {
|
|
156
146
|
}
|
157
147
|
addNewMarker() {
|
158
148
|
const element = new MarkerElement(this);
|
159
|
-
this.
|
149
|
+
this.appendElement(element);
|
150
|
+
this.selectElement(element);
|
160
151
|
return element;
|
161
152
|
}
|
162
153
|
addNewLine() {
|
163
154
|
const element = new LineElement(this);
|
164
|
-
this.
|
155
|
+
this.appendElement(element);
|
156
|
+
this.selectElement(element);
|
165
157
|
return element;
|
166
158
|
}
|
167
159
|
addNewPolygon() {
|
168
160
|
const element = new PolygonElement(this);
|
169
|
-
this.
|
161
|
+
this.appendElement(element);
|
162
|
+
this.selectElement(element);
|
170
163
|
return element;
|
171
164
|
}
|
172
|
-
|
165
|
+
appendElement(element) {
|
173
166
|
this.elements.update((elements) => [...elements, element]);
|
174
|
-
this.
|
167
|
+
this.state.log();
|
175
168
|
}
|
176
|
-
|
177
|
-
this.elements.update((elements) => elements.filter((e) => e !== element));
|
169
|
+
removeElement(element) {
|
178
170
|
if (get(this.selectedElement) === element)
|
179
171
|
this.selectElement(undefined);
|
180
|
-
this.
|
172
|
+
this.elements.update((elements) => elements.filter((e) => e !== element));
|
173
|
+
this.state.log();
|
181
174
|
}
|
182
175
|
getGeoJSON() {
|
183
176
|
const center = this.map.getCenter();
|
@@ -191,7 +184,7 @@ export class GeometryManager {
|
|
191
184
|
};
|
192
185
|
}
|
193
186
|
addGeoJSON(geojson) {
|
194
|
-
if ('map' in geojson) {
|
187
|
+
if ('map' in geojson && geojson.map) {
|
195
188
|
const { map } = geojson;
|
196
189
|
if (typeof map.zoom === 'number') {
|
197
190
|
this.map.setZoom(map.zoom);
|
@@ -218,8 +211,7 @@ export class GeometryManager {
|
|
218
211
|
default:
|
219
212
|
throw new Error(`Unknown geometry type "${feature.geometry.type}"`);
|
220
213
|
}
|
221
|
-
this.
|
214
|
+
this.appendElement(element);
|
222
215
|
}
|
223
|
-
this.saveState();
|
224
216
|
}
|
225
217
|
}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import type { LayerFill, LayerLine, LayerSymbol } from './types.js';
|
2
2
|
import type { GeometryManager } from '../geometry_manager.js';
|
3
|
-
import type {
|
3
|
+
import type { StateStyle } from '../state/types.js';
|
4
4
|
type LayerSpec = LayerFill | LayerLine | LayerSymbol;
|
5
5
|
type Events = 'click' | 'mousedown' | 'mousemove' | 'mouseup';
|
6
6
|
type MouseEventHandler = (event: maplibregl.MapMouseEvent) => void;
|
@@ -13,6 +13,7 @@ export declare abstract class MapLayer<T extends LayerSpec> {
|
|
13
13
|
eventHandlers: Map<Events, MouseEventHandler[]>;
|
14
14
|
isSelected: boolean;
|
15
15
|
constructor(manager: GeometryManager, id: string);
|
16
|
+
pushState(): void;
|
16
17
|
addLayer(source: string, type: 'symbol' | 'line' | 'fill', layout: T['layout'], paint: T['paint']): void;
|
17
18
|
on(event: Events, handler: MouseEventHandler): void;
|
18
19
|
off(event: Events, handler: MouseEventHandler): void;
|
@@ -23,7 +24,7 @@ export declare abstract class MapLayer<T extends LayerSpec> {
|
|
23
24
|
updateLayout(obj: T['layout']): void;
|
24
25
|
updateLayout<K extends keyof T['layout'], V extends T['layout'][K]>(key: K, value: V): void;
|
25
26
|
destroy(): void;
|
26
|
-
abstract getState():
|
27
|
+
abstract getState(): StateStyle | undefined;
|
27
28
|
abstract getGeoJSONProperties(): GeoJSON.GeoJsonProperties;
|
28
29
|
abstract setGeoJSONProperties(properties: GeoJSON.GeoJsonProperties): void;
|
29
30
|
}
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import type { LayerFill } from './types.js';
|
2
2
|
import { MapLayer } from './abstract.js';
|
3
3
|
import type { GeometryManager } from '../geometry_manager.js';
|
4
|
-
import type {
|
4
|
+
import type { StateStyle } from '../state/types.js';
|
5
5
|
interface Fill {
|
6
6
|
xf: number;
|
7
7
|
yf: number;
|
@@ -15,9 +15,10 @@ export declare class MapLayerFill extends MapLayer<LayerFill> {
|
|
15
15
|
color: import("svelte/store").Writable<string>;
|
16
16
|
opacity: import("svelte/store").Writable<number>;
|
17
17
|
pattern: import("svelte/store").Writable<number>;
|
18
|
+
static readonly defaultStyle: StateStyle;
|
18
19
|
constructor(manager: GeometryManager, id: string, source: string);
|
19
|
-
getState():
|
20
|
-
setState(state:
|
20
|
+
getState(): StateStyle | undefined;
|
21
|
+
setState(state: StateStyle): void;
|
21
22
|
getGeoJSONProperties(): GeoJSON.GeoJsonProperties;
|
22
23
|
setGeoJSONProperties(properties: GeoJSON.GeoJsonProperties): void;
|
23
24
|
}
|
@@ -12,6 +12,11 @@ export class MapLayerFill extends MapLayer {
|
|
12
12
|
color = writable('#ff0000');
|
13
13
|
opacity = writable(1);
|
14
14
|
pattern = writable(0);
|
15
|
+
static defaultStyle = {
|
16
|
+
color: '#ff0000',
|
17
|
+
opacity: 1,
|
18
|
+
pattern: 0
|
19
|
+
};
|
15
20
|
constructor(manager, id, source) {
|
16
21
|
super(manager, id);
|
17
22
|
this.addLayer(source, 'fill', {}, {
|
@@ -49,15 +54,15 @@ export class MapLayerFill extends MapLayer {
|
|
49
54
|
};
|
50
55
|
this.color.subscribe(() => {
|
51
56
|
updatePattern();
|
52
|
-
this.manager.
|
57
|
+
this.manager.state.log();
|
53
58
|
});
|
54
59
|
this.pattern.subscribe(() => {
|
55
60
|
updatePattern();
|
56
|
-
this.manager.
|
61
|
+
this.manager.state.log();
|
57
62
|
});
|
58
63
|
this.opacity.subscribe((value) => {
|
59
64
|
this.updatePaint('fill-opacity', value);
|
60
|
-
this.manager.
|
65
|
+
this.manager.state.log();
|
61
66
|
});
|
62
67
|
}
|
63
68
|
getState() {
|
@@ -65,11 +70,7 @@ export class MapLayerFill extends MapLayer {
|
|
65
70
|
color: get(this.color),
|
66
71
|
opacity: get(this.opacity),
|
67
72
|
pattern: get(this.pattern)
|
68
|
-
},
|
69
|
-
color: '#ff0000',
|
70
|
-
opacity: 1,
|
71
|
-
pattern: 0
|
72
|
-
});
|
73
|
+
}, MapLayerFill.defaultStyle);
|
73
74
|
}
|
74
75
|
setState(state) {
|
75
76
|
if (state.color)
|
@@ -1,20 +1,21 @@
|
|
1
1
|
import type { LayerLine } from './types.js';
|
2
2
|
import { MapLayer } from './abstract.js';
|
3
3
|
import type { GeometryManager } from '../geometry_manager.js';
|
4
|
-
import type {
|
4
|
+
import type { StateStyle } from '../state/types.js';
|
5
5
|
export declare const dashArrays: Map<number, {
|
6
6
|
name: string;
|
7
7
|
array: number[] | undefined;
|
8
8
|
}>;
|
9
9
|
export declare class MapLayerLine extends MapLayer<LayerLine> {
|
10
|
+
static readonly defaultStyle: StateStyle;
|
10
11
|
color: import("svelte/store").Writable<string>;
|
11
12
|
dashed: import("svelte/store").Writable<number>;
|
12
13
|
visible: import("svelte/store").Writable<boolean>;
|
13
14
|
width: import("svelte/store").Writable<number>;
|
14
15
|
dashArray: import("svelte/store").Readable<number[]>;
|
15
16
|
constructor(manager: GeometryManager, id: string, source: string);
|
16
|
-
getState():
|
17
|
-
setState(state:
|
17
|
+
getState(): StateStyle | undefined;
|
18
|
+
setState(state: StateStyle): void;
|
18
19
|
getGeoJSONProperties(): GeoJSON.GeoJsonProperties;
|
19
20
|
setGeoJSONProperties(properties: GeoJSON.GeoJsonProperties): void;
|
20
21
|
}
|