@versatiles/svelte 1.1.1 → 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/BBoxMap/AutoComplete.svelte +0 -1
- package/dist/components/BBoxMap/BBoxMap.svelte +1 -2
- package/dist/{utils/draw → components/BBoxMap/lib}/bbox.d.ts +1 -2
- package/dist/components/BasicMap/BasicMap.svelte +7 -9
- package/dist/components/BasicMap/BasicMap.svelte.d.ts +5 -4
- package/dist/components/LocatorMap/LocatorMap.svelte +0 -2
- package/dist/components/MapEditor/MapEditor.svelte +16 -3
- package/dist/components/MapEditor/components/Editor.svelte +46 -39
- 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 +23 -19
- 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 +116 -111
- 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 +46 -52
- package/dist/components/MapEditor/lib/map_layer/abstract.d.ts +4 -3
- package/dist/components/MapEditor/lib/map_layer/abstract.js +30 -12
- 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 +21 -10
- package/dist/components/MapEditor/lib/map_layer/symbol.js +72 -31
- 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 -139
- package/dist/components/MapEditor/lib/state/types.d.ts +28 -12
- package/dist/components/MapEditor/lib/state/writer.d.ts +18 -14
- package/dist/components/MapEditor/lib/state/writer.js +183 -156
- package/dist/components/MapEditor/lib/utils.d.ts +2 -5
- package/dist/components/MapEditor/lib/utils.js +0 -19
- package/package.json +28 -27
- package/dist/components/MapEditor/lib/__mocks__/cursor.d.ts +0 -5
- package/dist/components/MapEditor/lib/__mocks__/cursor.js +0 -6
- package/dist/components/MapEditor/lib/__mocks__/geometry_manager.d.ts +0 -22
- package/dist/components/MapEditor/lib/__mocks__/geometry_manager.js +0 -21
- package/dist/components/MapEditor/lib/__mocks__/map.d.ts +0 -36
- package/dist/components/MapEditor/lib/__mocks__/map.js +0 -26
- /package/dist/{utils/draw → components/BBoxMap/lib}/bbox.js +0 -0
@@ -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,12 +78,11 @@ 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) {
|
84
|
+
if (element == get(this.selectedElement))
|
85
|
+
return;
|
88
86
|
const elements = get(this.elements);
|
89
87
|
elements.forEach((e) => e.select(e == element));
|
90
88
|
this.selectedElement.set(element);
|
@@ -105,48 +103,42 @@ export class GeometryManager {
|
|
105
103
|
const center = this.map.getCenter();
|
106
104
|
return {
|
107
105
|
map: {
|
108
|
-
|
106
|
+
center: [center.lng, center.lat],
|
109
107
|
zoom: this.map.getZoom()
|
110
108
|
},
|
111
109
|
elements: get(this.elements).map((element) => element.getState())
|
112
110
|
};
|
113
111
|
}
|
114
|
-
|
115
|
-
|
116
|
-
writer.writeObject(this.getState());
|
117
|
-
location.hash = await writer.getBase64compressed();
|
118
|
-
}
|
119
|
-
async loadState(hash) {
|
120
|
-
if (!hash)
|
112
|
+
setState(state) {
|
113
|
+
if (!state)
|
121
114
|
return;
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
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)
|
128
122
|
this.map.setZoom(state.map.zoom);
|
129
|
-
if (state.map
|
130
|
-
|
131
|
-
|
132
|
-
if (state.elements) {
|
133
|
-
const elements = state.elements.map((element) => {
|
134
|
-
switch (element.type) {
|
135
|
-
case 'marker':
|
136
|
-
return MarkerElement.fromState(this, element);
|
137
|
-
case 'line':
|
138
|
-
return LineElement.fromState(this, element);
|
139
|
-
case 'polygon':
|
140
|
-
return PolygonElement.fromState(this, element);
|
141
|
-
default:
|
142
|
-
throw new Error('Unknown element type');
|
143
|
-
}
|
144
|
-
});
|
145
|
-
this.elements.set(elements);
|
123
|
+
if (state.map.center) {
|
124
|
+
const [lng, lat] = state.map.center;
|
125
|
+
this.map.setCenter({ lng, lat });
|
146
126
|
}
|
147
127
|
}
|
148
|
-
|
149
|
-
|
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);
|
150
142
|
}
|
151
143
|
}
|
152
144
|
getElement(index) {
|
@@ -154,28 +146,31 @@ export class GeometryManager {
|
|
154
146
|
}
|
155
147
|
addNewMarker() {
|
156
148
|
const element = new MarkerElement(this);
|
157
|
-
this.
|
149
|
+
this.appendElement(element);
|
150
|
+
this.selectElement(element);
|
158
151
|
return element;
|
159
152
|
}
|
160
153
|
addNewLine() {
|
161
154
|
const element = new LineElement(this);
|
162
|
-
this.
|
155
|
+
this.appendElement(element);
|
156
|
+
this.selectElement(element);
|
163
157
|
return element;
|
164
158
|
}
|
165
159
|
addNewPolygon() {
|
166
160
|
const element = new PolygonElement(this);
|
167
|
-
this.
|
161
|
+
this.appendElement(element);
|
162
|
+
this.selectElement(element);
|
168
163
|
return element;
|
169
164
|
}
|
170
|
-
|
165
|
+
appendElement(element) {
|
171
166
|
this.elements.update((elements) => [...elements, element]);
|
172
|
-
this.
|
167
|
+
this.state.log();
|
173
168
|
}
|
174
|
-
|
175
|
-
this.elements.update((elements) => elements.filter((e) => e !== element));
|
169
|
+
removeElement(element) {
|
176
170
|
if (get(this.selectedElement) === element)
|
177
171
|
this.selectElement(undefined);
|
178
|
-
this.
|
172
|
+
this.elements.update((elements) => elements.filter((e) => e !== element));
|
173
|
+
this.state.log();
|
179
174
|
}
|
180
175
|
getGeoJSON() {
|
181
176
|
const center = this.map.getCenter();
|
@@ -189,7 +184,7 @@ export class GeometryManager {
|
|
189
184
|
};
|
190
185
|
}
|
191
186
|
addGeoJSON(geojson) {
|
192
|
-
if ('map' in geojson) {
|
187
|
+
if ('map' in geojson && geojson.map) {
|
193
188
|
const { map } = geojson;
|
194
189
|
if (typeof map.zoom === 'number') {
|
195
190
|
this.map.setZoom(map.zoom);
|
@@ -216,8 +211,7 @@ export class GeometryManager {
|
|
216
211
|
default:
|
217
212
|
throw new Error(`Unknown geometry type "${feature.geometry.type}"`);
|
218
213
|
}
|
219
|
-
this.
|
214
|
+
this.appendElement(element);
|
220
215
|
}
|
221
|
-
this.saveState();
|
222
216
|
}
|
223
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;
|
@@ -20,10 +21,10 @@ export declare abstract class MapLayer<T extends LayerSpec> {
|
|
20
21
|
private addEvents;
|
21
22
|
setPaint(paint: T['paint']): void;
|
22
23
|
updatePaint<K extends keyof T['paint'], V extends T['paint'][K]>(key: K, value: V): void;
|
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
|
}
|
@@ -12,11 +12,24 @@ export class MapLayer {
|
|
12
12
|
this.map = manager.map;
|
13
13
|
this.id = id;
|
14
14
|
}
|
15
|
+
pushState() {
|
16
|
+
this.manager.state.log();
|
17
|
+
}
|
15
18
|
addLayer(source, type, layout, paint) {
|
19
|
+
layout = cloneClean(layout);
|
20
|
+
paint = cloneClean(paint);
|
16
21
|
this.layout = layout;
|
17
22
|
this.paint = paint;
|
18
23
|
this.map.addLayer({ id: this.id, source, type, layout, paint }, 'selection_nodes');
|
19
24
|
this.addEvents();
|
25
|
+
function cloneClean(obj) {
|
26
|
+
const clone = { ...obj };
|
27
|
+
for (const key in clone) {
|
28
|
+
if (clone[key] == null)
|
29
|
+
delete clone[key];
|
30
|
+
}
|
31
|
+
return clone;
|
32
|
+
}
|
20
33
|
}
|
21
34
|
on(event, handler) {
|
22
35
|
if (!this.eventHandlers.has(event))
|
@@ -75,18 +88,23 @@ export class MapLayer {
|
|
75
88
|
this.map.setPaintProperty(this.id, key, value);
|
76
89
|
this.paint[key] = value;
|
77
90
|
}
|
78
|
-
|
79
|
-
if (
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
91
|
+
updateLayout(arg1, arg2) {
|
92
|
+
if (typeof arg1 === 'string') {
|
93
|
+
if (this.layout[arg1] == arg2)
|
94
|
+
return;
|
95
|
+
this.map.setLayoutProperty(this.id, arg1, arg2);
|
96
|
+
if (arg2 == null) {
|
97
|
+
delete this.layout[arg1];
|
98
|
+
}
|
99
|
+
else {
|
100
|
+
this.layout[arg1] = arg2;
|
101
|
+
}
|
102
|
+
}
|
103
|
+
else if (typeof arg1 === 'object') {
|
104
|
+
for (const [key, value] of Object.entries(arg1)) {
|
105
|
+
this.updateLayout(key, value);
|
106
|
+
}
|
107
|
+
}
|
90
108
|
}
|
91
109
|
destroy() {
|
92
110
|
this.map.removeLayer(this.id);
|
@@ -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
|
}
|
@@ -8,10 +8,16 @@ export const dashArrays = new Map([
|
|
8
8
|
[2, { name: 'dotted', array: [0, 2] }]
|
9
9
|
]);
|
10
10
|
export class MapLayerLine extends MapLayer {
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
static defaultStyle = {
|
12
|
+
color: '#ff0000',
|
13
|
+
pattern: 0,
|
14
|
+
visible: true,
|
15
|
+
width: 2
|
16
|
+
};
|
17
|
+
color = writable(MapLayerLine.defaultStyle.color);
|
18
|
+
dashed = writable(MapLayerLine.defaultStyle.pattern);
|
19
|
+
visible = writable(MapLayerLine.defaultStyle.visible);
|
20
|
+
width = writable(MapLayerLine.defaultStyle.width);
|
15
21
|
dashArray = derived(this.dashed, (dashed) => dashArrays.get(dashed)?.array ?? [100]);
|
16
22
|
constructor(manager, id, source) {
|
17
23
|
super(manager, id);
|
@@ -26,19 +32,19 @@ export class MapLayerLine extends MapLayer {
|
|
26
32
|
});
|
27
33
|
this.color.subscribe((v) => {
|
28
34
|
this.updatePaint('line-color', Color.parse(v));
|
29
|
-
this.manager.
|
35
|
+
this.manager.state.log();
|
30
36
|
});
|
31
37
|
this.dashArray.subscribe((v) => {
|
32
38
|
this.updatePaint('line-dasharray', v);
|
33
|
-
this.manager.
|
39
|
+
this.manager.state.log();
|
34
40
|
});
|
35
41
|
this.visible.subscribe((v) => {
|
36
42
|
this.updateLayout('visibility', v ? 'visible' : 'none');
|
37
|
-
this.manager.
|
43
|
+
this.manager.state.log();
|
38
44
|
});
|
39
45
|
this.width.subscribe((v) => {
|
40
46
|
this.updatePaint('line-width', v);
|
41
|
-
this.manager.
|
47
|
+
this.manager.state.log();
|
42
48
|
});
|
43
49
|
}
|
44
50
|
getState() {
|
@@ -47,12 +53,7 @@ export class MapLayerLine extends MapLayer {
|
|
47
53
|
pattern: get(this.dashed),
|
48
54
|
visible: get(this.visible),
|
49
55
|
width: get(this.width)
|
50
|
-
},
|
51
|
-
color: '#ff0000',
|
52
|
-
pattern: 0,
|
53
|
-
visible: true,
|
54
|
-
width: 2
|
55
|
-
});
|
56
|
+
}, MapLayerLine.defaultStyle);
|
56
57
|
}
|
57
58
|
setState(state) {
|
58
59
|
if (state.color)
|
@@ -1,19 +1,30 @@
|
|
1
|
+
import { type Writable } from 'svelte/store';
|
1
2
|
import type { LayerSymbol } from './types.js';
|
2
3
|
import { MapLayer } from './abstract.js';
|
3
4
|
import type { GeometryManager } from '../geometry_manager.js';
|
4
|
-
import type {
|
5
|
+
import type { StateStyle } from '../state/types.js';
|
6
|
+
interface LabelAlign {
|
7
|
+
index: 0 | 1 | 2 | 3 | 4;
|
8
|
+
name: string;
|
9
|
+
anchor?: 'center' | 'left' | 'right' | 'bottom' | 'top';
|
10
|
+
}
|
11
|
+
export declare const labelPositions: LabelAlign[];
|
5
12
|
export declare class MapLayerSymbol extends MapLayer<LayerSymbol> {
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
+
static readonly defaultStyle: StateStyle;
|
14
|
+
color: Writable<string>;
|
15
|
+
halo: Writable<number>;
|
16
|
+
rotate: Writable<number>;
|
17
|
+
size: Writable<number>;
|
18
|
+
symbolIndex: Writable<number>;
|
19
|
+
label: Writable<string>;
|
20
|
+
labelAlign: Writable<number>;
|
13
21
|
symbolInfo: import("svelte/store").Readable<import("../symbols.js").SymbolInfo>;
|
22
|
+
textAnchor: import("svelte/store").Readable<"center" | "top" | "bottom" | "right" | "left" | undefined>;
|
23
|
+
textVariableAnchor: import("svelte/store").Readable<("center" | "top-left" | "top-right" | "bottom-left" | "bottom-right" | "top" | "bottom" | "right" | "left")[] | undefined>;
|
14
24
|
constructor(manager: GeometryManager, id: string, source: string);
|
15
|
-
getState():
|
16
|
-
setState(state:
|
25
|
+
getState(): StateStyle | undefined;
|
26
|
+
setState(state: StateStyle): void;
|
17
27
|
getGeoJSONProperties(): GeoJSON.GeoJsonProperties;
|
18
28
|
setGeoJSONProperties(properties: GeoJSON.GeoJsonProperties): void;
|
19
29
|
}
|
30
|
+
export {};
|
@@ -3,53 +3,75 @@ import { MapLayer } from './abstract.js';
|
|
3
3
|
import { Color } from '@versatiles/style';
|
4
4
|
import { getSymbol, getSymbolIndexByName } from '../symbols.js';
|
5
5
|
import { removeDefaultFields } from '../utils.js';
|
6
|
-
const
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
};
|
6
|
+
export const labelPositions = [
|
7
|
+
{ index: 0, name: 'auto' },
|
8
|
+
{ index: 1, name: 'right', anchor: 'left' },
|
9
|
+
{ index: 2, name: 'left', anchor: 'right' },
|
10
|
+
{ index: 3, name: 'top', anchor: 'bottom' },
|
11
|
+
{ index: 4, name: 'bottom', anchor: 'top' }
|
12
|
+
];
|
14
13
|
export class MapLayerSymbol extends MapLayer {
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
14
|
+
static defaultStyle = {
|
15
|
+
color: '#ff0000',
|
16
|
+
rotate: 0,
|
17
|
+
size: 1,
|
18
|
+
halo: 1,
|
19
|
+
pattern: 38,
|
20
|
+
label: '',
|
21
|
+
align: 0
|
22
|
+
};
|
23
|
+
color = writable(MapLayerSymbol.defaultStyle.color);
|
24
|
+
halo = writable(MapLayerSymbol.defaultStyle.halo);
|
25
|
+
rotate = writable(MapLayerSymbol.defaultStyle.rotate);
|
26
|
+
size = writable(MapLayerSymbol.defaultStyle.size);
|
27
|
+
symbolIndex = writable(MapLayerSymbol.defaultStyle.pattern);
|
28
|
+
label = writable(MapLayerSymbol.defaultStyle.label);
|
29
|
+
labelAlign = writable(MapLayerSymbol.defaultStyle.align);
|
22
30
|
symbolInfo = derived(this.symbolIndex, (index) => getSymbol(index));
|
31
|
+
textAnchor = derived(this.labelAlign, (index) => {
|
32
|
+
return lookupLabelAlign(index).anchor;
|
33
|
+
});
|
34
|
+
textVariableAnchor = derived([this.labelAlign, this.symbolInfo], ([index, symbol]) => {
|
35
|
+
if (index !== 0)
|
36
|
+
return undefined;
|
37
|
+
if (symbol.image == null) {
|
38
|
+
return ['center', 'left', 'right', 'top', 'bottom'];
|
39
|
+
}
|
40
|
+
return ['left', 'right', 'top', 'bottom'];
|
41
|
+
});
|
23
42
|
constructor(manager, id, source) {
|
24
43
|
super(manager, id);
|
25
44
|
this.addLayer(source, 'symbol', {
|
26
45
|
'icon-image': get(this.symbolInfo).image,
|
27
46
|
'icon-offset': get(this.symbolInfo).offset,
|
28
|
-
'icon-overlap':
|
29
|
-
'icon-rotate':
|
30
|
-
'icon-size':
|
31
|
-
'text-field':
|
47
|
+
'icon-allow-overlap': true,
|
48
|
+
'icon-rotate': get(this.rotate),
|
49
|
+
'icon-size': get(this.size),
|
50
|
+
'text-field': get(this.label),
|
32
51
|
'text-font': ['noto_sans_regular'],
|
33
52
|
'text-justify': 'left',
|
34
|
-
'text-
|
35
|
-
'text-offset':
|
36
|
-
'text-variable-anchor':
|
53
|
+
'text-overlap': 'always',
|
54
|
+
'text-radial-offset': 0.7,
|
55
|
+
'text-variable-anchor': get(this.textVariableAnchor),
|
56
|
+
'text-anchor': get(this.textAnchor)
|
37
57
|
}, {
|
38
|
-
'icon-color':
|
58
|
+
'icon-color': get(this.color),
|
39
59
|
'icon-halo-blur': 0,
|
40
60
|
'icon-halo-color': '#FFFFFF',
|
41
|
-
'icon-halo-width':
|
61
|
+
'icon-halo-width': get(this.halo),
|
42
62
|
'icon-opacity': 1,
|
43
63
|
'text-halo-blur': 0,
|
44
64
|
'text-halo-color': '#FFFFFF',
|
45
|
-
'text-halo-width':
|
65
|
+
'text-halo-width': get(this.halo)
|
46
66
|
});
|
47
67
|
this.color.subscribe((v) => this.updatePaint('icon-color', Color.parse(v)));
|
48
|
-
this.
|
68
|
+
this.halo.subscribe((v) => {
|
49
69
|
this.updatePaint('icon-halo-width', v);
|
50
70
|
this.updatePaint('text-halo-width', v);
|
51
71
|
});
|
52
72
|
this.label.subscribe((v) => this.updateLayout('text-field', v));
|
73
|
+
this.textAnchor.subscribe((v) => this.updateLayout('text-anchor', v));
|
74
|
+
this.textVariableAnchor.subscribe((v) => this.updateLayout('text-variable-anchor', v));
|
53
75
|
this.rotate.subscribe((v) => this.updateLayout('icon-rotate', v));
|
54
76
|
this.size.subscribe((v) => {
|
55
77
|
this.updateLayout('icon-size', v);
|
@@ -58,11 +80,9 @@ export class MapLayerSymbol extends MapLayer {
|
|
58
80
|
this.symbolInfo.subscribe((v) => {
|
59
81
|
if (v.image == null) {
|
60
82
|
this.updateLayout('icon-image', undefined);
|
61
|
-
this.updateLayout('text-variable-anchor', ['center']);
|
62
83
|
}
|
63
84
|
else {
|
64
85
|
this.updateLayout('icon-image', v.image);
|
65
|
-
this.updateLayout('text-variable-anchor', ['right', 'left', 'top', 'bottom']);
|
66
86
|
this.updateLayout('icon-offset', v.offset);
|
67
87
|
}
|
68
88
|
});
|
@@ -74,8 +94,9 @@ export class MapLayerSymbol extends MapLayer {
|
|
74
94
|
size: get(this.size),
|
75
95
|
halo: get(this.halo),
|
76
96
|
pattern: get(this.symbolIndex),
|
77
|
-
label: get(this.label)
|
78
|
-
|
97
|
+
label: get(this.label),
|
98
|
+
align: get(this.labelAlign)
|
99
|
+
}, MapLayerSymbol.defaultStyle);
|
79
100
|
}
|
80
101
|
setState(state) {
|
81
102
|
if (state.color)
|
@@ -90,6 +111,8 @@ export class MapLayerSymbol extends MapLayer {
|
|
90
111
|
this.symbolIndex.set(state.pattern);
|
91
112
|
if (state.label)
|
92
113
|
this.label.set(state.label);
|
114
|
+
if (state.align)
|
115
|
+
this.labelAlign.set(lookupLabelAlign(state.align).index);
|
93
116
|
}
|
94
117
|
getGeoJSONProperties() {
|
95
118
|
return {
|
@@ -98,7 +121,8 @@ export class MapLayerSymbol extends MapLayer {
|
|
98
121
|
'symbol-rotate': get(this.rotate),
|
99
122
|
'symbol-size': get(this.size),
|
100
123
|
'symbol-pattern': get(this.symbolInfo).name,
|
101
|
-
'symbol-label': get(this.label)
|
124
|
+
'symbol-label': get(this.label),
|
125
|
+
'symbol-label-align': lookupLabelAlign(this.labelAlign).name
|
102
126
|
};
|
103
127
|
}
|
104
128
|
setGeoJSONProperties(properties) {
|
@@ -114,6 +138,8 @@ export class MapLayerSymbol extends MapLayer {
|
|
114
138
|
this.size.set(properties['symbol-size']);
|
115
139
|
if (properties['symbol-label'])
|
116
140
|
this.label.set(properties['symbol-label']);
|
141
|
+
if (properties['symbol-label-align'])
|
142
|
+
this.labelAlign.set(lookupLabelAlign(properties['symbol-label-align']).index);
|
117
143
|
if (properties['symbol-pattern']) {
|
118
144
|
const index = getSymbolIndexByName(properties['symbol-pattern']);
|
119
145
|
if (index != null)
|
@@ -121,3 +147,18 @@ export class MapLayerSymbol extends MapLayer {
|
|
121
147
|
}
|
122
148
|
}
|
123
149
|
}
|
150
|
+
function lookupLabelAlign(index) {
|
151
|
+
let pos;
|
152
|
+
if (typeof index === 'object') {
|
153
|
+
index = get(index);
|
154
|
+
}
|
155
|
+
if (typeof index === 'number') {
|
156
|
+
pos = labelPositions.find((p) => p.index === index);
|
157
|
+
}
|
158
|
+
else if (typeof index === 'string') {
|
159
|
+
pos = labelPositions.find((p) => p.name === index);
|
160
|
+
}
|
161
|
+
if (pos == null)
|
162
|
+
return labelPositions[0];
|
163
|
+
return pos;
|
164
|
+
}
|
@@ -0,0 +1,4 @@
|
|
1
|
+
export declare const BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
|
2
|
+
export declare const BASE64_CODE2BITS: [boolean, boolean, boolean, boolean, boolean, boolean][];
|
3
|
+
export declare const CHAR_VALUE2CODE: number[];
|
4
|
+
export declare const CHAR_CODE2VALUE: number[];
|