@versatiles/svelte 1.1.1 → 1.1.2
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 +5 -7
- package/dist/components/BasicMap/BasicMap.svelte.d.ts +5 -4
- package/dist/components/LocatorMap/LocatorMap.svelte +0 -2
- package/dist/components/MapEditor/components/Editor.svelte +1 -0
- package/dist/components/MapEditor/components/EditorSymbol.svelte +11 -1
- package/dist/components/MapEditor/components/Sidebar.svelte +8 -10
- package/dist/components/MapEditor/lib/geometry_manager.js +2 -0
- package/dist/components/MapEditor/lib/map_layer/abstract.d.ts +1 -1
- package/dist/components/MapEditor/lib/map_layer/abstract.js +27 -12
- package/dist/components/MapEditor/lib/map_layer/symbol.d.ts +17 -7
- package/dist/components/MapEditor/lib/map_layer/symbol.js +73 -14
- package/dist/components/MapEditor/lib/state/reader.js +4 -1
- package/dist/components/MapEditor/lib/state/types.d.ts +1 -0
- package/dist/components/MapEditor/lib/state/writer.js +15 -1
- package/package.json +13 -12
- 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
@@ -1,4 +1,3 @@
|
|
1
|
-
<!-- BBoxMap.svelte -->
|
2
1
|
<script lang="ts">
|
3
2
|
import type { CameraOptions, Map as MaplibreMapType } from 'maplibre-gl';
|
4
3
|
import AutoComplete from './AutoComplete.svelte';
|
@@ -7,7 +6,7 @@
|
|
7
6
|
import { isDarkMode } from '../../utils/map_style.js';
|
8
7
|
import type { BBox } from 'geojson';
|
9
8
|
import { loadBBoxes } from './BBoxMap.js';
|
10
|
-
import { BBoxDrawer } from '
|
9
|
+
import { BBoxDrawer } from './lib/bbox.js';
|
11
10
|
|
12
11
|
let { selectedBBox = $bindable() }: { selectedBBox?: BBox } = $props();
|
13
12
|
const startTime = Date.now();
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import type geojson from 'geojson';
|
2
2
|
import { type Writable } from 'svelte/store';
|
3
3
|
import maplibregl from 'maplibre-gl';
|
4
|
-
type DragPoint = 'n' | 'ne' | 'e' | 'se' | 's' | 'sw' | 'w' | 'nw' | false;
|
4
|
+
export type DragPoint = 'n' | 'ne' | 'e' | 'se' | 's' | 'sw' | 'w' | 'nw' | false;
|
5
5
|
export declare const DragPointMap: Map<DragPoint, {
|
6
6
|
cursor: string;
|
7
7
|
flipH: DragPoint;
|
@@ -27,4 +27,3 @@ export declare class BBoxDrawer {
|
|
27
27
|
private getCursor;
|
28
28
|
private doDrag;
|
29
29
|
}
|
30
|
-
export {};
|
@@ -1,10 +1,8 @@
|
|
1
|
-
<!-- BasicMap.svelte -->
|
2
1
|
<script lang="ts">
|
3
|
-
import type { Map as MaplibreMapType, MapOptions } from 'maplibre-gl';
|
4
2
|
import 'maplibre-gl/dist/maplibre-gl.css';
|
5
3
|
import { getMapStyle, isDarkMode } from '../../utils/map_style.js';
|
6
4
|
import maplibre from 'maplibre-gl';
|
7
|
-
|
5
|
+
import type { MapOptions } from 'maplibre-gl';
|
8
6
|
|
9
7
|
// Props
|
10
8
|
let {
|
@@ -18,9 +16,9 @@
|
|
18
16
|
style?: string;
|
19
17
|
styleOptions?: Parameters<typeof getMapStyle>[1];
|
20
18
|
mapOptions?: Partial<MapOptions>;
|
21
|
-
map?:
|
22
|
-
onMapInit?: (map:
|
23
|
-
onMapLoad?: (map:
|
19
|
+
map?: maplibre.Map;
|
20
|
+
onMapInit?: (map: maplibre.Map) => void;
|
21
|
+
onMapLoad?: (map: maplibre.Map) => void;
|
24
22
|
} = $props();
|
25
23
|
|
26
24
|
let container: HTMLDivElement;
|
@@ -40,7 +38,7 @@
|
|
40
38
|
|
41
39
|
const style = getMapStyle(darkMode, styleOptions);
|
42
40
|
style.transition = { duration: 0, delay: 0 };
|
43
|
-
map = new Map({
|
41
|
+
map = new maplibre.Map({
|
44
42
|
container,
|
45
43
|
style,
|
46
44
|
renderWorldCopies: false,
|
@@ -1,13 +1,14 @@
|
|
1
|
-
import type { Map as MaplibreMapType, MapOptions } from 'maplibre-gl';
|
2
1
|
import 'maplibre-gl/dist/maplibre-gl.css';
|
3
2
|
import { getMapStyle } from '../../utils/map_style.js';
|
3
|
+
import maplibre from 'maplibre-gl';
|
4
|
+
import type { MapOptions } from 'maplibre-gl';
|
4
5
|
type $$ComponentProps = {
|
5
6
|
style?: string;
|
6
7
|
styleOptions?: Parameters<typeof getMapStyle>[1];
|
7
8
|
mapOptions?: Partial<MapOptions>;
|
8
|
-
map?:
|
9
|
-
onMapInit?: (map:
|
10
|
-
onMapLoad?: (map:
|
9
|
+
map?: maplibre.Map;
|
10
|
+
onMapInit?: (map: maplibre.Map) => void;
|
11
|
+
onMapLoad?: (map: maplibre.Map) => void;
|
11
12
|
};
|
12
13
|
declare const BasicMap: import("svelte").Component<$$ComponentProps, {}, "map">;
|
13
14
|
type BasicMap = ReturnType<typeof BasicMap>;
|
@@ -1,4 +1,3 @@
|
|
1
|
-
<!-- LocatorMap.svelte -->
|
2
1
|
<script lang="ts">
|
3
2
|
import type { Map as MaplibreMapType, GeoJSONSource } from 'maplibre-gl';
|
4
3
|
import BasicMap from '../BasicMap/BasicMap.svelte';
|
@@ -10,7 +9,6 @@
|
|
10
9
|
let coordinates: [number, number] = [0, 0];
|
11
10
|
const initialHash = parseHash();
|
12
11
|
if (initialHash) {
|
13
|
-
console.log('initialHash', initialHash);
|
14
12
|
coordinates = [initialHash[1], initialHash[2]];
|
15
13
|
map.setZoom(initialHash[0]);
|
16
14
|
map.setCenter(coordinates);
|
@@ -1,5 +1,5 @@
|
|
1
1
|
<script lang="ts">
|
2
|
-
import { MapLayerSymbol } from '../lib/map_layer/symbol.js';
|
2
|
+
import { labelPositions, MapLayerSymbol } from '../lib/map_layer/symbol.js';
|
3
3
|
import SymbolSelector from './SymbolSelector.svelte';
|
4
4
|
|
5
5
|
const { layer }: { layer: MapLayerSymbol } = $props();
|
@@ -9,6 +9,7 @@
|
|
9
9
|
let rotate = $state(layer.rotate);
|
10
10
|
let halo = $state(layer.halo);
|
11
11
|
let label = $state(layer.label);
|
12
|
+
let labelAlign = $state(layer.labelAlign);
|
12
13
|
let size = $state(layer.size);
|
13
14
|
</script>
|
14
15
|
|
@@ -41,3 +42,12 @@
|
|
41
42
|
<label for="label">Label:</label>
|
42
43
|
<input id="label" type="label" bind:value={$label} />
|
43
44
|
</div>
|
45
|
+
|
46
|
+
<div class="row-input">
|
47
|
+
<label for="labelAlign">Align Label:</label>
|
48
|
+
<select id="labelAlign" bind:value={$labelAlign}>
|
49
|
+
{#each labelPositions as { index, name } (index)}
|
50
|
+
<option value={index}>{name}</option>
|
51
|
+
{/each}
|
52
|
+
</select>
|
53
|
+
</div>
|
@@ -1,14 +1,10 @@
|
|
1
1
|
<script lang="ts">
|
2
|
-
import type { AbstractElement } from '../lib/element/abstract.js';
|
3
2
|
import Editor from './Editor.svelte';
|
4
3
|
import type { GeometryManager } from '../lib/geometry_manager.js';
|
5
4
|
|
6
5
|
const { geometryManager, width }: { geometryManager: GeometryManager; width: number } = $props();
|
7
6
|
|
8
|
-
let activeElement
|
9
|
-
$effect(() => geometryManager.selectElement(activeElement));
|
10
|
-
|
11
|
-
geometryManager.selectedElement.subscribe((value) => (activeElement = value));
|
7
|
+
let activeElement = geometryManager.selectedElement;
|
12
8
|
|
13
9
|
function importGeoJSON() {
|
14
10
|
const input = document.createElement('input');
|
@@ -60,22 +56,24 @@
|
|
60
56
|
<input
|
61
57
|
type="button"
|
62
58
|
value="Marker"
|
63
|
-
onclick={() => (
|
59
|
+
onclick={() => activeElement.set(geometryManager.addNewMarker())}
|
64
60
|
/>
|
65
61
|
<input
|
66
62
|
type="button"
|
67
63
|
value="Line"
|
68
|
-
onclick={() => (
|
64
|
+
onclick={() => activeElement.set(geometryManager.addNewLine())}
|
69
65
|
/>
|
70
66
|
<input
|
71
67
|
type="button"
|
72
68
|
value="Polygon"
|
73
|
-
onclick={() => (
|
69
|
+
onclick={() => activeElement.set(geometryManager.addNewPolygon())}
|
74
70
|
/>
|
75
71
|
</div>
|
76
|
-
{#if activeElement != null}
|
72
|
+
{#if $activeElement != null}
|
77
73
|
<hr />
|
78
|
-
|
74
|
+
{#key $activeElement}
|
75
|
+
<Editor element={$activeElement} />
|
76
|
+
{/key}
|
79
77
|
{/if}
|
80
78
|
</div>
|
81
79
|
<div class="footer">
|
@@ -85,6 +85,8 @@ export class GeometryManager {
|
|
85
85
|
this.loadState(hash);
|
86
86
|
}
|
87
87
|
selectElement(element) {
|
88
|
+
if (element == get(this.selectedElement))
|
89
|
+
return;
|
88
90
|
const elements = get(this.elements);
|
89
91
|
elements.forEach((e) => e.select(e == element));
|
90
92
|
this.selectedElement.set(element);
|
@@ -20,7 +20,7 @@ export declare abstract class MapLayer<T extends LayerSpec> {
|
|
20
20
|
private addEvents;
|
21
21
|
setPaint(paint: T['paint']): void;
|
22
22
|
updatePaint<K extends keyof T['paint'], V extends T['paint'][K]>(key: K, value: V): void;
|
23
|
-
|
23
|
+
updateLayout(obj: T['layout']): void;
|
24
24
|
updateLayout<K extends keyof T['layout'], V extends T['layout'][K]>(key: K, value: V): void;
|
25
25
|
destroy(): void;
|
26
26
|
abstract getState(): StateObject | undefined;
|
@@ -13,10 +13,20 @@ export class MapLayer {
|
|
13
13
|
this.id = id;
|
14
14
|
}
|
15
15
|
addLayer(source, type, layout, paint) {
|
16
|
+
layout = cloneClean(layout);
|
17
|
+
paint = cloneClean(paint);
|
16
18
|
this.layout = layout;
|
17
19
|
this.paint = paint;
|
18
20
|
this.map.addLayer({ id: this.id, source, type, layout, paint }, 'selection_nodes');
|
19
21
|
this.addEvents();
|
22
|
+
function cloneClean(obj) {
|
23
|
+
const clone = { ...obj };
|
24
|
+
for (const key in clone) {
|
25
|
+
if (clone[key] == null)
|
26
|
+
delete clone[key];
|
27
|
+
}
|
28
|
+
return clone;
|
29
|
+
}
|
20
30
|
}
|
21
31
|
on(event, handler) {
|
22
32
|
if (!this.eventHandlers.has(event))
|
@@ -75,18 +85,23 @@ export class MapLayer {
|
|
75
85
|
this.map.setPaintProperty(this.id, key, value);
|
76
86
|
this.paint[key] = value;
|
77
87
|
}
|
78
|
-
|
79
|
-
if (
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
88
|
+
updateLayout(arg1, arg2) {
|
89
|
+
if (typeof arg1 === 'string') {
|
90
|
+
if (this.layout[arg1] == arg2)
|
91
|
+
return;
|
92
|
+
this.map.setLayoutProperty(this.id, arg1, arg2);
|
93
|
+
if (arg2 == null) {
|
94
|
+
delete this.layout[arg1];
|
95
|
+
}
|
96
|
+
else {
|
97
|
+
this.layout[arg1] = arg2;
|
98
|
+
}
|
99
|
+
}
|
100
|
+
else if (typeof arg1 === 'object') {
|
101
|
+
for (const [key, value] of Object.entries(arg1)) {
|
102
|
+
this.updateLayout(key, value);
|
103
|
+
}
|
104
|
+
}
|
90
105
|
}
|
91
106
|
destroy() {
|
92
107
|
this.map.removeLayer(this.id);
|
@@ -1,19 +1,29 @@
|
|
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
5
|
import type { StateObject } 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
|
-
color:
|
7
|
-
halo:
|
8
|
-
rotate:
|
9
|
-
size:
|
10
|
-
symbolIndex:
|
11
|
-
label:
|
12
|
-
|
13
|
+
color: Writable<string>;
|
14
|
+
halo: Writable<number>;
|
15
|
+
rotate: Writable<number>;
|
16
|
+
size: Writable<number>;
|
17
|
+
symbolIndex: Writable<number>;
|
18
|
+
label: Writable<string>;
|
19
|
+
labelAlign: Writable<0 | 2 | 1 | 4 | 3>;
|
13
20
|
symbolInfo: import("svelte/store").Readable<import("../symbols.js").SymbolInfo>;
|
21
|
+
textAnchor: import("svelte/store").Readable<"center" | "top" | "bottom" | "right" | "left" | undefined>;
|
22
|
+
textVariableAnchor: import("svelte/store").Readable<("center" | "top-left" | "top-right" | "bottom-left" | "bottom-right" | "top" | "bottom" | "right" | "left")[] | undefined>;
|
14
23
|
constructor(manager: GeometryManager, id: string, source: string);
|
15
24
|
getState(): StateObject | undefined;
|
16
25
|
setState(state: StateObject): void;
|
17
26
|
getGeoJSONProperties(): GeoJSON.GeoJsonProperties;
|
18
27
|
setGeoJSONProperties(properties: GeoJSON.GeoJsonProperties): void;
|
19
28
|
}
|
29
|
+
export {};
|
@@ -3,13 +3,21 @@ 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
|
+
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
|
+
];
|
6
13
|
const defaultStyle = {
|
7
14
|
color: '#ff0000',
|
8
15
|
rotate: 0,
|
9
16
|
size: 1,
|
10
17
|
halo: 1,
|
11
18
|
pattern: 38,
|
12
|
-
label: ''
|
19
|
+
label: '',
|
20
|
+
align: 0
|
13
21
|
};
|
14
22
|
export class MapLayerSymbol extends MapLayer {
|
15
23
|
color = writable(defaultStyle.color);
|
@@ -18,22 +26,34 @@ export class MapLayerSymbol extends MapLayer {
|
|
18
26
|
size = writable(defaultStyle.size);
|
19
27
|
symbolIndex = writable(defaultStyle.pattern);
|
20
28
|
label = writable(defaultStyle.label);
|
21
|
-
|
29
|
+
labelAlign = writable(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':
|
47
|
+
'icon-allow-overlap': true,
|
29
48
|
'icon-rotate': defaultStyle.rotate,
|
30
49
|
'icon-size': defaultStyle.size,
|
31
50
|
'text-field': defaultStyle.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
58
|
'icon-color': defaultStyle.color,
|
39
59
|
'icon-halo-blur': 0,
|
@@ -44,27 +64,45 @@ export class MapLayerSymbol extends MapLayer {
|
|
44
64
|
'text-halo-color': '#FFFFFF',
|
45
65
|
'text-halo-width': defaultStyle.halo
|
46
66
|
});
|
47
|
-
this.color.subscribe((v) =>
|
48
|
-
|
67
|
+
this.color.subscribe((v) => {
|
68
|
+
this.updatePaint('icon-color', Color.parse(v));
|
69
|
+
this.manager.saveState();
|
70
|
+
});
|
71
|
+
this.halo.subscribe((v) => {
|
49
72
|
this.updatePaint('icon-halo-width', v);
|
50
73
|
this.updatePaint('text-halo-width', v);
|
74
|
+
this.manager.saveState();
|
75
|
+
});
|
76
|
+
this.label.subscribe((v) => {
|
77
|
+
this.updateLayout('text-field', v);
|
78
|
+
this.manager.saveState();
|
79
|
+
});
|
80
|
+
this.textAnchor.subscribe((v) => {
|
81
|
+
this.updateLayout('text-anchor', v);
|
82
|
+
this.manager.saveState();
|
83
|
+
});
|
84
|
+
this.textVariableAnchor.subscribe((v) => {
|
85
|
+
this.updateLayout('text-variable-anchor', v);
|
86
|
+
this.manager.saveState();
|
87
|
+
});
|
88
|
+
this.rotate.subscribe((v) => {
|
89
|
+
this.updateLayout('icon-rotate', v);
|
90
|
+
this.manager.saveState();
|
51
91
|
});
|
52
|
-
this.label.subscribe((v) => this.updateLayout('text-field', v));
|
53
|
-
this.rotate.subscribe((v) => this.updateLayout('icon-rotate', v));
|
54
92
|
this.size.subscribe((v) => {
|
55
93
|
this.updateLayout('icon-size', v);
|
56
94
|
this.updateLayout('text-size', v * 16);
|
95
|
+
this.manager.saveState();
|
57
96
|
});
|
58
97
|
this.symbolInfo.subscribe((v) => {
|
59
98
|
if (v.image == null) {
|
60
99
|
this.updateLayout('icon-image', undefined);
|
61
|
-
this.updateLayout('text-variable-anchor', ['center']);
|
62
100
|
}
|
63
101
|
else {
|
64
102
|
this.updateLayout('icon-image', v.image);
|
65
|
-
this.updateLayout('text-variable-anchor', ['right', 'left', 'top', 'bottom']);
|
66
103
|
this.updateLayout('icon-offset', v.offset);
|
67
104
|
}
|
105
|
+
this.manager.saveState();
|
68
106
|
});
|
69
107
|
}
|
70
108
|
getState() {
|
@@ -74,7 +112,8 @@ export class MapLayerSymbol extends MapLayer {
|
|
74
112
|
size: get(this.size),
|
75
113
|
halo: get(this.halo),
|
76
114
|
pattern: get(this.symbolIndex),
|
77
|
-
label: get(this.label)
|
115
|
+
label: get(this.label),
|
116
|
+
align: get(this.labelAlign)
|
78
117
|
}, defaultStyle);
|
79
118
|
}
|
80
119
|
setState(state) {
|
@@ -90,6 +129,8 @@ export class MapLayerSymbol extends MapLayer {
|
|
90
129
|
this.symbolIndex.set(state.pattern);
|
91
130
|
if (state.label)
|
92
131
|
this.label.set(state.label);
|
132
|
+
if (state.align)
|
133
|
+
this.labelAlign.set(lookupLabelAlign(state.align).index);
|
93
134
|
}
|
94
135
|
getGeoJSONProperties() {
|
95
136
|
return {
|
@@ -98,7 +139,8 @@ export class MapLayerSymbol extends MapLayer {
|
|
98
139
|
'symbol-rotate': get(this.rotate),
|
99
140
|
'symbol-size': get(this.size),
|
100
141
|
'symbol-pattern': get(this.symbolInfo).name,
|
101
|
-
'symbol-label': get(this.label)
|
142
|
+
'symbol-label': get(this.label),
|
143
|
+
'symbol-label-align': lookupLabelAlign(this.labelAlign).name
|
102
144
|
};
|
103
145
|
}
|
104
146
|
setGeoJSONProperties(properties) {
|
@@ -114,6 +156,8 @@ export class MapLayerSymbol extends MapLayer {
|
|
114
156
|
this.size.set(properties['symbol-size']);
|
115
157
|
if (properties['symbol-label'])
|
116
158
|
this.label.set(properties['symbol-label']);
|
159
|
+
if (properties['symbol-label-align'])
|
160
|
+
this.labelAlign.set(lookupLabelAlign(properties['symbol-label-align']).index);
|
117
161
|
if (properties['symbol-pattern']) {
|
118
162
|
const index = getSymbolIndexByName(properties['symbol-pattern']);
|
119
163
|
if (index != null)
|
@@ -121,3 +165,18 @@ export class MapLayerSymbol extends MapLayer {
|
|
121
165
|
}
|
122
166
|
}
|
123
167
|
}
|
168
|
+
function lookupLabelAlign(index) {
|
169
|
+
let pos;
|
170
|
+
if (typeof index === 'object') {
|
171
|
+
index = get(index);
|
172
|
+
}
|
173
|
+
if (typeof index === 'number') {
|
174
|
+
pos = labelPositions.find((p) => p.index === index);
|
175
|
+
}
|
176
|
+
else if (typeof index === 'string') {
|
177
|
+
pos = labelPositions.find((p) => p.name === index);
|
178
|
+
}
|
179
|
+
if (pos == null)
|
180
|
+
return labelPositions[0];
|
181
|
+
return pos;
|
182
|
+
}
|
@@ -110,7 +110,7 @@ export class StateReader {
|
|
110
110
|
state.pattern = this.readUnsignedInteger();
|
111
111
|
break;
|
112
112
|
case 73:
|
113
|
-
state.rotate = this.
|
113
|
+
state.rotate = this.readSignedInteger();
|
114
114
|
break;
|
115
115
|
case 74:
|
116
116
|
state.size = this.readUnsignedInteger() / 10;
|
@@ -121,6 +121,9 @@ export class StateReader {
|
|
121
121
|
case 76:
|
122
122
|
state.zoom = this.readUnsignedInteger() / 20;
|
123
123
|
break;
|
124
|
+
case 77:
|
125
|
+
state.align = this.readUnsignedInteger();
|
126
|
+
break;
|
124
127
|
case 90:
|
125
128
|
state.visible = this.readBoolean();
|
126
129
|
break;
|
@@ -66,6 +66,8 @@ export class StateWriter {
|
|
66
66
|
case 'elements':
|
67
67
|
if (!Array.isArray(value))
|
68
68
|
throw new Error(`Invalid elements: ${value}`);
|
69
|
+
if (value.length === 0)
|
70
|
+
return;
|
69
71
|
this.writeByte(20);
|
70
72
|
this.writeUnsignedInteger(value.length);
|
71
73
|
value.forEach((element) => this.writeObject(element));
|
@@ -80,6 +82,8 @@ export class StateWriter {
|
|
80
82
|
case 'points':
|
81
83
|
if (!Array.isArray(value))
|
82
84
|
throw new Error(`Invalid points: ${value}`);
|
85
|
+
if (value.length === 0)
|
86
|
+
return;
|
83
87
|
this.writeByte(31);
|
84
88
|
this.writeUnsignedInteger(value.length);
|
85
89
|
this.writeDifferential(value.map((p) => Math.round(p[0] * 1e5)));
|
@@ -121,7 +125,7 @@ export class StateWriter {
|
|
121
125
|
writeInteger(72, value);
|
122
126
|
break;
|
123
127
|
case 'rotate':
|
124
|
-
|
128
|
+
writeSignedInteger(73, value);
|
125
129
|
break;
|
126
130
|
case 'size':
|
127
131
|
writeInteger(74, value, 10);
|
@@ -132,6 +136,9 @@ export class StateWriter {
|
|
132
136
|
case 'zoom':
|
133
137
|
writeInteger(76, value, 20);
|
134
138
|
break;
|
139
|
+
case 'align':
|
140
|
+
writeInteger(77, value);
|
141
|
+
break;
|
135
142
|
case 'visible':
|
136
143
|
if (typeof value !== 'boolean')
|
137
144
|
throw new Error(`Invalid boolean: ${value}`);
|
@@ -158,6 +165,13 @@ export class StateWriter {
|
|
158
165
|
me.writeByte(id);
|
159
166
|
me.writeUnsignedInteger(value * factor);
|
160
167
|
}
|
168
|
+
function writeSignedInteger(id, obj, factor = 1) {
|
169
|
+
if (typeof obj !== 'number')
|
170
|
+
throw new Error(`Invalid number: ${obj}`);
|
171
|
+
const value = Math.round(obj);
|
172
|
+
me.writeByte(id);
|
173
|
+
me.writeSignedInteger(value * factor);
|
174
|
+
}
|
161
175
|
}
|
162
176
|
writeColor(color) {
|
163
177
|
if (typeof color !== 'string')
|
package/package.json
CHANGED
@@ -1,24 +1,24 @@
|
|
1
1
|
{
|
2
2
|
"name": "@versatiles/svelte",
|
3
|
-
"version": "1.1.
|
3
|
+
"version": "1.1.2",
|
4
4
|
"license": "MIT",
|
5
5
|
"scripts": {
|
6
6
|
"build": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json && vite build && npm run package",
|
7
|
-
"check
|
8
|
-
"check": "npm run lint && npm run build && npm run test",
|
7
|
+
"check-watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
8
|
+
"check": "npm run format && npm run lint && npm run build && npm run test",
|
9
9
|
"dev": "vite dev",
|
10
|
-
"format": "prettier --write .",
|
10
|
+
"format": "prettier --write --log-level warn .",
|
11
11
|
"lint": "prettier --check . && eslint --color .",
|
12
12
|
"package": "svelte-kit sync && svelte-package && publint",
|
13
13
|
"prepack": "npm run build",
|
14
14
|
"prepublishOnly": "npm run package",
|
15
15
|
"preview": "vite preview",
|
16
|
-
"screenshots": "
|
16
|
+
"screenshots": "npx tsx ./scripts/screenshots.ts",
|
17
17
|
"release": "vrt release-npm",
|
18
|
-
"test
|
19
|
-
"test
|
20
|
-
"test
|
21
|
-
"test": "npm run test
|
18
|
+
"test-integration": "playwright test",
|
19
|
+
"test-unit": "vitest run",
|
20
|
+
"test-coverage": "vitest run --coverage",
|
21
|
+
"test": "npm run test-unit && npm run test-integration",
|
22
22
|
"upgrade": "vrt deps-upgrade"
|
23
23
|
},
|
24
24
|
"exports": {
|
@@ -30,18 +30,19 @@
|
|
30
30
|
"files": [
|
31
31
|
"dist",
|
32
32
|
"!dist/**/*.spec.*",
|
33
|
+
"!dist/**/__mocks__/*",
|
33
34
|
"!dist/**/*.test.*",
|
34
35
|
"!dist/BBoxMap/data/*",
|
35
36
|
"!dist/BBoxMap/helpers/*"
|
36
37
|
],
|
37
38
|
"peerDependencies": {
|
38
39
|
"sass-embedded": "^1.86.0",
|
39
|
-
"svelte": "^5.
|
40
|
+
"svelte": "^5.23.2"
|
40
41
|
},
|
41
42
|
"devDependencies": {
|
42
43
|
"@playwright/test": "^1.51.1",
|
43
44
|
"@sveltejs/adapter-static": "^3.0.8",
|
44
|
-
"@sveltejs/kit": "^2.20.
|
45
|
+
"@sveltejs/kit": "^2.20.1",
|
45
46
|
"@sveltejs/package": "^2.3.10",
|
46
47
|
"@sveltejs/vite-plugin-svelte": "^5.0.3",
|
47
48
|
"@turf/turf": "^7.2.0",
|
@@ -60,7 +61,7 @@
|
|
60
61
|
"prettier-plugin-svelte": "^3.3.3",
|
61
62
|
"publint": "^0.3.9",
|
62
63
|
"sass": "^1.86.0",
|
63
|
-
"svelte": "^5.23.
|
64
|
+
"svelte": "^5.23.2",
|
64
65
|
"svelte-check": "^4.1.5",
|
65
66
|
"svelte-preprocess": "^6.0.3",
|
66
67
|
"tsx": "^4.19.3",
|
@@ -1,22 +0,0 @@
|
|
1
|
-
import { type Writable } from 'svelte/store';
|
2
|
-
import type { AbstractElement } from '../element/abstract.js';
|
3
|
-
import type { StateObject } from '../state/types.js';
|
4
|
-
import { MockMap } from './map.js';
|
5
|
-
import { MockCursor } from './cursor.js';
|
6
|
-
export declare class MockGeometryManager {
|
7
|
-
readonly elements: Writable<AbstractElement[]>;
|
8
|
-
readonly activeElement: Writable<AbstractElement | undefined>;
|
9
|
-
readonly map: MockMap;
|
10
|
-
readonly cursor: MockCursor;
|
11
|
-
constructor();
|
12
|
-
setActiveElement: import("vitest").Mock<(...args: any[]) => any>;
|
13
|
-
getState: import("vitest").Mock<() => StateObject>;
|
14
|
-
saveState: import("vitest").Mock<(...args: any[]) => any>;
|
15
|
-
loadState: import("vitest").Mock<(...args: any[]) => any>;
|
16
|
-
getElement: import("vitest").Mock<(index: number) => AbstractElement>;
|
17
|
-
addNewMarker: import("vitest").Mock<() => AbstractElement>;
|
18
|
-
addNewLine: import("vitest").Mock<() => AbstractElement>;
|
19
|
-
addNewPolygon: import("vitest").Mock<() => AbstractElement>;
|
20
|
-
deleteElement: import("vitest").Mock<(...args: any[]) => any>;
|
21
|
-
drawSelectionNodes: import("vitest").Mock<(...args: any[]) => any>;
|
22
|
-
}
|
@@ -1,21 +0,0 @@
|
|
1
|
-
import { writable } from 'svelte/store';
|
2
|
-
import { vi } from 'vitest';
|
3
|
-
import { MockMap } from './map.js';
|
4
|
-
import { MockCursor } from './cursor.js';
|
5
|
-
export class MockGeometryManager {
|
6
|
-
elements = writable([]);
|
7
|
-
activeElement = writable(undefined);
|
8
|
-
map = new MockMap();
|
9
|
-
cursor = new MockCursor();
|
10
|
-
constructor() { }
|
11
|
-
setActiveElement = vi.fn();
|
12
|
-
getState = vi.fn(() => ({ map: { point: [0, 0], zoom: 10 }, elements: [] }));
|
13
|
-
saveState = vi.fn();
|
14
|
-
loadState = vi.fn();
|
15
|
-
getElement = vi.fn((index) => ({ index }));
|
16
|
-
addNewMarker = vi.fn(() => ({}));
|
17
|
-
addNewLine = vi.fn(() => ({}));
|
18
|
-
addNewPolygon = vi.fn(() => ({}));
|
19
|
-
deleteElement = vi.fn();
|
20
|
-
drawSelectionNodes = vi.fn();
|
21
|
-
}
|
@@ -1,36 +0,0 @@
|
|
1
|
-
export declare class MockMap {
|
2
|
-
getCanvasContainer: import("vitest").Mock<() => {
|
3
|
-
style: {
|
4
|
-
cursor: string;
|
5
|
-
};
|
6
|
-
}>;
|
7
|
-
addSource: import("vitest").Mock<(...args: any[]) => any>;
|
8
|
-
removeSource: import("vitest").Mock<(...args: any[]) => any>;
|
9
|
-
getSource: import("vitest").Mock<() => {
|
10
|
-
setData: import("vitest").Mock<(...args: any[]) => any>;
|
11
|
-
}>;
|
12
|
-
addLayer: import("vitest").Mock<(...args: any[]) => any>;
|
13
|
-
on: import("vitest").Mock<(...args: any[]) => any>;
|
14
|
-
setCenter: import("vitest").Mock<(...args: any[]) => any>;
|
15
|
-
setZoom: import("vitest").Mock<(...args: any[]) => any>;
|
16
|
-
getZoom: import("vitest").Mock<() => number>;
|
17
|
-
getCenter: import("vitest").Mock<() => {
|
18
|
-
lng: number;
|
19
|
-
lat: number;
|
20
|
-
}>;
|
21
|
-
queryRenderedFeatures: import("vitest").Mock<() => {
|
22
|
-
properties: {};
|
23
|
-
}[]>;
|
24
|
-
setPaintProperty: import("vitest").Mock<(...args: any[]) => any>;
|
25
|
-
setLayoutProperty: import("vitest").Mock<(...args: any[]) => any>;
|
26
|
-
removeLayer: import("vitest").Mock<(...args: any[]) => any>;
|
27
|
-
hasImage: import("vitest").Mock<(...args: any[]) => any>;
|
28
|
-
removeImage: import("vitest").Mock<(...args: any[]) => any>;
|
29
|
-
addImage: import("vitest").Mock<(...args: any[]) => any>;
|
30
|
-
getBounds: import("vitest").Mock<() => {
|
31
|
-
getWest: () => -180;
|
32
|
-
getEast: () => 180;
|
33
|
-
getSouth: () => -90;
|
34
|
-
getNorth: () => 90;
|
35
|
-
}>;
|
36
|
-
}
|
@@ -1,26 +0,0 @@
|
|
1
|
-
import { vi } from 'vitest';
|
2
|
-
export class MockMap {
|
3
|
-
getCanvasContainer = vi.fn(() => ({ style: { cursor: 'default' } }));
|
4
|
-
addSource = vi.fn();
|
5
|
-
removeSource = vi.fn();
|
6
|
-
getSource = vi.fn(() => ({ setData: vi.fn() }));
|
7
|
-
addLayer = vi.fn();
|
8
|
-
on = vi.fn();
|
9
|
-
setCenter = vi.fn();
|
10
|
-
setZoom = vi.fn();
|
11
|
-
getZoom = vi.fn(() => 10);
|
12
|
-
getCenter = vi.fn(() => ({ lng: 0, lat: 0 }));
|
13
|
-
queryRenderedFeatures = vi.fn(() => [{ properties: {} }]);
|
14
|
-
setPaintProperty = vi.fn();
|
15
|
-
setLayoutProperty = vi.fn();
|
16
|
-
removeLayer = vi.fn();
|
17
|
-
hasImage = vi.fn();
|
18
|
-
removeImage = vi.fn();
|
19
|
-
addImage = vi.fn();
|
20
|
-
getBounds = vi.fn(() => ({
|
21
|
-
getWest: () => -180,
|
22
|
-
getEast: () => 180,
|
23
|
-
getSouth: () => -90,
|
24
|
-
getNorth: () => 90
|
25
|
-
}));
|
26
|
-
}
|
File without changes
|