@versatiles/svelte 1.0.1 → 1.1.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 +117 -90
- package/dist/components/BBoxMap/BBoxMap.svelte +49 -40
- package/dist/components/BBoxMap/BBoxMap.svelte.d.ts +0 -1
- package/dist/components/BasicMap/BasicMap.svelte +60 -34
- package/dist/components/LocatorMap/LocatorMap.svelte +66 -60
- package/dist/components/LocatorMap/LocatorMap.svelte.d.ts +0 -1
- package/dist/components/MapEditor/MapEditor.svelte +34 -80
- package/dist/components/MapEditor/MapEditor.svelte.d.ts +0 -1
- package/dist/components/MapEditor/components/Editor.svelte +53 -0
- package/dist/components/MapEditor/{Editor.svelte.d.ts → components/Editor.svelte.d.ts} +1 -1
- package/dist/components/MapEditor/components/EditorFill.svelte +28 -0
- package/dist/components/MapEditor/components/EditorFill.svelte.d.ts +7 -0
- package/dist/components/MapEditor/components/EditorStroke.svelte +28 -0
- package/dist/components/MapEditor/components/EditorStroke.svelte.d.ts +7 -0
- package/dist/components/MapEditor/components/EditorSymbol.svelte +43 -0
- package/dist/components/MapEditor/components/EditorSymbol.svelte.d.ts +7 -0
- package/dist/components/MapEditor/components/Sidebar.svelte +179 -0
- package/dist/components/MapEditor/components/Sidebar.svelte.d.ts +8 -0
- package/dist/components/MapEditor/components/SymbolSelector.svelte +118 -0
- package/dist/components/MapEditor/components/SymbolSelector.svelte.d.ts +8 -0
- package/dist/components/MapEditor/lib/__mocks__/cursor.d.ts +5 -0
- package/dist/components/MapEditor/lib/__mocks__/cursor.js +6 -0
- package/dist/components/MapEditor/lib/__mocks__/geometry_manager.d.ts +22 -0
- package/dist/components/MapEditor/lib/__mocks__/geometry_manager.js +21 -0
- package/dist/components/MapEditor/lib/__mocks__/map.d.ts +36 -0
- package/dist/components/MapEditor/lib/__mocks__/map.js +26 -0
- package/dist/components/MapEditor/lib/cursor.d.ts +10 -0
- package/dist/components/MapEditor/lib/cursor.js +43 -0
- package/dist/components/MapEditor/lib/element/abstract.d.ts +21 -0
- package/dist/components/MapEditor/lib/element/abstract.js +39 -0
- package/dist/components/MapEditor/lib/element/abstract_path.d.ts +11 -0
- package/dist/components/MapEditor/lib/element/abstract_path.js +79 -0
- package/dist/components/MapEditor/lib/element/line.d.ts +16 -0
- package/dist/components/MapEditor/lib/element/line.js +53 -0
- package/dist/components/MapEditor/lib/element/marker.d.ts +18 -0
- package/dist/components/MapEditor/lib/element/marker.js +62 -0
- package/dist/components/MapEditor/lib/element/polygon.d.ts +17 -0
- package/dist/components/MapEditor/lib/element/polygon.js +63 -0
- package/dist/components/MapEditor/lib/element/types.d.ts +11 -0
- package/dist/components/MapEditor/lib/geometry_manager.d.ts +20 -10
- package/dist/components/MapEditor/lib/geometry_manager.js +163 -57
- package/dist/components/MapEditor/lib/map_layer/abstract.d.ts +30 -0
- package/dist/components/MapEditor/lib/map_layer/abstract.js +94 -0
- package/dist/components/MapEditor/lib/map_layer/fill.d.ts +24 -0
- package/dist/components/MapEditor/lib/map_layer/fill.js +104 -0
- package/dist/components/MapEditor/lib/map_layer/line.d.ts +20 -0
- package/dist/components/MapEditor/lib/map_layer/line.js +90 -0
- package/dist/components/MapEditor/lib/map_layer/symbol.d.ts +19 -0
- package/dist/components/MapEditor/lib/map_layer/symbol.js +123 -0
- package/dist/components/MapEditor/lib/{types.d.ts → map_layer/types.d.ts} +7 -15
- package/dist/components/MapEditor/lib/map_layer/types.js +1 -0
- package/dist/components/MapEditor/lib/state/reader.d.ts +17 -0
- package/dist/components/MapEditor/lib/state/reader.js +161 -0
- package/dist/components/MapEditor/lib/state/types.d.ts +20 -0
- package/dist/components/MapEditor/lib/state/types.js +1 -0
- package/dist/components/MapEditor/lib/state/writer.d.ts +17 -0
- package/dist/components/MapEditor/lib/state/writer.js +178 -0
- package/dist/components/MapEditor/lib/symbols.d.ts +16 -0
- package/dist/components/MapEditor/lib/symbols.js +173 -0
- package/dist/components/MapEditor/lib/utils.d.ts +8 -1
- package/dist/components/MapEditor/lib/utils.js +33 -2
- package/dist/utils/draw/bbox.d.ts +1 -0
- package/dist/utils/draw/bbox.js +1 -1
- package/package.json +29 -30
- package/dist/components/MapEditor/Editor.svelte +0 -25
- package/dist/components/MapEditor/EditorLine.svelte +0 -27
- package/dist/components/MapEditor/EditorLine.svelte.d.ts +0 -7
- package/dist/components/MapEditor/EditorMarker.svelte +0 -42
- package/dist/components/MapEditor/EditorMarker.svelte.d.ts +0 -7
- package/dist/components/MapEditor/editor.scss +0 -16
- package/dist/components/MapEditor/lib/element_abstract.d.ts +0 -20
- package/dist/components/MapEditor/lib/element_abstract.js +0 -58
- package/dist/components/MapEditor/lib/element_line.d.ts +0 -14
- package/dist/components/MapEditor/lib/element_line.js +0 -76
- package/dist/components/MapEditor/lib/element_marker.d.ts +0 -20
- package/dist/components/MapEditor/lib/element_marker.js +0 -191
- package/dist/components/MapEditor/lib/map_layer.d.ts +0 -14
- package/dist/components/MapEditor/lib/map_layer.js +0 -61
- package/dist/utils/sprite_library.d.ts +0 -19
- package/dist/utils/sprite_library.js +0 -30
- /package/dist/components/MapEditor/lib/{types.js → element/types.js} +0 -0
@@ -0,0 +1,173 @@
|
|
1
|
+
const entries = [
|
2
|
+
[0, 'none'],
|
3
|
+
[1, 'airplane', 'basics:icon-airfield'],
|
4
|
+
[2, 'airport', 'basics:icon-airport'],
|
5
|
+
[3, 'alcohol shop', 'basics:icon-alcohol_shop'],
|
6
|
+
[4, 'art gallery', 'basics:icon-art_gallery'],
|
7
|
+
[5, 'artwork', 'basics:icon-artwork'],
|
8
|
+
[6, 'atm', 'basics:icon-atm'],
|
9
|
+
[7, 'bakery', 'basics:icon-bakery'],
|
10
|
+
[8, 'bank', 'basics:icon-bank'],
|
11
|
+
[9, 'beauty', 'basics:icon-beauty'],
|
12
|
+
[10, 'beer', 'basics:icon-beer'],
|
13
|
+
[11, 'beergarden', 'basics:icon-beergarden'],
|
14
|
+
[12, 'bench', 'basics:icon-bench'],
|
15
|
+
[13, 'beverages', 'basics:icon-beverages'],
|
16
|
+
[14, 'bicycle share', 'basics:icon-bicycle_share'],
|
17
|
+
[15, 'books', 'basics:icon-books'],
|
18
|
+
[16, 'bus', 'basics:icon-bus'],
|
19
|
+
[17, 'butcher', 'basics:icon-butcher'],
|
20
|
+
[18, 'cafe', 'basics:icon-cafe', [2, 0]],
|
21
|
+
[19, 'car rental', 'basics:icon-car_rental'],
|
22
|
+
[20, 'car wash', 'basics:icon-car_wash'],
|
23
|
+
[21, 'castle', 'basics:icon-castle'],
|
24
|
+
[22, 'cemetery', 'basics:icon-cemetery'],
|
25
|
+
[23, 'chalet', 'basics:icon-chalet'],
|
26
|
+
[24, 'chemist', 'basics:icon-chemist'],
|
27
|
+
[25, 'cinema', 'basics:icon-cinema'],
|
28
|
+
[26, 'clothes', 'basics:icon-clothes'],
|
29
|
+
[27, 'college', 'basics:icon-college'],
|
30
|
+
[28, 'community', 'basics:icon-community'],
|
31
|
+
[29, 'defibrillator', 'basics:icon-defibrillator'],
|
32
|
+
[30, 'doctor', 'basics:icon-doctor'],
|
33
|
+
[31, 'dog park', 'basics:icon-dog_park'],
|
34
|
+
[32, 'doityourself', 'basics:icon-doityourself'],
|
35
|
+
[33, 'drinking water', 'basics:icon-drinking_water'],
|
36
|
+
[34, 'drycleaning', 'basics:icon-drycleaning'],
|
37
|
+
[35, 'emergency phone', 'basics:icon-emergency_phone'],
|
38
|
+
[36, 'fast food', 'basics:icon-fast_food'],
|
39
|
+
[37, 'fire station', 'basics:icon-fire_station'],
|
40
|
+
[38, 'flag', 'basics:icon-embassy', [0, 0]],
|
41
|
+
[39, 'florist', 'basics:icon-florist'],
|
42
|
+
[40, 'fountain', 'basics:icon-fountain'],
|
43
|
+
[41, 'furniture', 'basics:icon-furniture'],
|
44
|
+
[42, 'garden centre', 'basics:icon-garden_centre'],
|
45
|
+
[43, 'gift', 'basics:icon-gift'],
|
46
|
+
[44, 'glasses', 'basics:icon-optician'],
|
47
|
+
[45, 'golf', 'basics:icon-golf'],
|
48
|
+
[46, 'greengrocer', 'basics:icon-greengrocer'],
|
49
|
+
[47, 'hardware', 'basics:icon-hardware'],
|
50
|
+
[48, 'hospital', 'basics:icon-hospital'],
|
51
|
+
[49, 'huntingstand', 'basics:icon-huntingstand'],
|
52
|
+
[50, 'hydrant', 'basics:icon-hydrant'],
|
53
|
+
[51, 'icerink', 'basics:icon-icerink'],
|
54
|
+
[52, 'information', 'basics:transport-information'],
|
55
|
+
[53, 'jewelry store', 'basics:icon-jewelry_store'],
|
56
|
+
[54, 'kiosk', 'basics:icon-kiosk'],
|
57
|
+
[55, 'laundry', 'basics:icon-laundry'],
|
58
|
+
[56, 'letter', 'basics:icon-post'],
|
59
|
+
[57, 'library', 'basics:icon-library'],
|
60
|
+
[58, 'lighthouse', 'basics:icon-lighthouse'],
|
61
|
+
[59, 'marketplace', 'basics:icon-marketplace'],
|
62
|
+
[60, 'money', 'basics:icon-bar'],
|
63
|
+
[61, 'monument', 'basics:icon-monument'],
|
64
|
+
[62, 'newsagent', 'basics:icon-newsagent'],
|
65
|
+
[63, 'nightclub', 'basics:icon-nightclub'],
|
66
|
+
[64, 'nursinghome', 'basics:icon-nursinghome'],
|
67
|
+
[65, 'observation tower', 'basics:icon-observation_tower'],
|
68
|
+
[66, 'outdoor', 'basics:icon-outdoor'],
|
69
|
+
[67, 'pharmacy', 'basics:icon-pharmacy'],
|
70
|
+
[68, 'picnic site', 'basics:icon-picnic_site'],
|
71
|
+
[69, 'place of worship', 'basics:icon-place_of_worship'],
|
72
|
+
[70, 'playground', 'basics:icon-playground'],
|
73
|
+
[71, 'police', 'basics:icon-police', [-1, -3]],
|
74
|
+
[72, 'postbox', 'basics:icon-postbox'],
|
75
|
+
[73, 'prison', 'basics:icon-prison'],
|
76
|
+
[74, 'rail light', 'basics:icon-rail_light'],
|
77
|
+
[75, 'rail metro', 'basics:icon-rail_metro'],
|
78
|
+
[76, 'rail', 'basics:icon-rail'],
|
79
|
+
[77, 'recycling', 'basics:icon-recycling'],
|
80
|
+
[78, 'restaurant', 'basics:icon-restaurant'],
|
81
|
+
[79, 'run', 'basics:icon-pitch'],
|
82
|
+
[80, 'school', 'basics:icon-school'],
|
83
|
+
[81, 'scissor', 'basics:icon-hairdresser'],
|
84
|
+
[82, 'shield', 'basics:icon-historic', [0, -10]],
|
85
|
+
[83, 'shoes', 'basics:icon-shoes', [-5, 0]],
|
86
|
+
[84, 'shop', 'basics:icon-shop'],
|
87
|
+
[85, 'shop', 'basics:icon-shop'],
|
88
|
+
[86, 'shrine', 'basics:icon-shrine'],
|
89
|
+
[87, 'sports', 'basics:icon-sports'],
|
90
|
+
[88, 'stadium', 'basics:icon-stadium'],
|
91
|
+
[89, 'stationery', 'basics:icon-stationery'],
|
92
|
+
[90, 'surveillance', 'basics:icon-surveillance'],
|
93
|
+
[91, 'swimming', 'basics:icon-swimming'],
|
94
|
+
[92, 'telephone', 'basics:icon-telephone'],
|
95
|
+
[93, 'theatre', 'basics:icon-theatre'],
|
96
|
+
[94, 'toilet', 'basics:icon-toilet'],
|
97
|
+
[95, 'tooth', 'basics:icon-dentist'],
|
98
|
+
[96, 'town hall', 'basics:icon-town_hall'],
|
99
|
+
[97, 'toys', 'basics:icon-toys'],
|
100
|
+
[98, 'tram', 'basics:transport-tram'],
|
101
|
+
[99, 'travel agent', 'basics:icon-travel_agent'],
|
102
|
+
[100, 'vendingmachine', 'basics:icon-vendingmachine'],
|
103
|
+
[101, 'veterinary', 'basics:icon-veterinary'],
|
104
|
+
[102, 'video', 'basics:icon-video'],
|
105
|
+
[103, 'viewpoint', 'basics:icon-viewpoint', [0, -6]],
|
106
|
+
[104, 'waste basket', 'basics:icon-waste_basket'],
|
107
|
+
[105, 'watermill', 'basics:icon-watermill'],
|
108
|
+
[106, 'waterpark', 'basics:icon-waterpark'],
|
109
|
+
[107, 'windmill', 'basics:icon-windmill'],
|
110
|
+
[108, 'zoo', 'basics:icon-zoo']
|
111
|
+
];
|
112
|
+
const symbols = new Map(entries.map(([index, name, image, offset]) => [index, { index, name, image, offset }]));
|
113
|
+
const defaultSymbol = symbols.get(38);
|
114
|
+
export function getSymbol(index) {
|
115
|
+
return symbols.get(index) ?? defaultSymbol;
|
116
|
+
}
|
117
|
+
export function getSymbolIndexByName(name) {
|
118
|
+
const entry = entries.find((entry) => entry[1] === name);
|
119
|
+
return entry ? entry[0] : undefined;
|
120
|
+
}
|
121
|
+
export class SymbolLibrary {
|
122
|
+
map;
|
123
|
+
constructor(map) {
|
124
|
+
this.map = map;
|
125
|
+
}
|
126
|
+
getSymbol(index) {
|
127
|
+
return symbols.get(index) ?? defaultSymbol;
|
128
|
+
}
|
129
|
+
drawSymbol(canvas, index, halo = false) {
|
130
|
+
const symbol = this.getSymbol(index);
|
131
|
+
if (!symbol.image)
|
132
|
+
return;
|
133
|
+
const { sdf, data: imageData0 } = this.map.getImage(symbol.image);
|
134
|
+
const { data: data0, width: width0, height: height0 } = imageData0;
|
135
|
+
const { width: width1, height: height1 } = canvas;
|
136
|
+
const data1 = new Uint8ClampedArray(width1 * height1 * 4);
|
137
|
+
for (let y1 = 0; y1 < height1; y1++) {
|
138
|
+
const y0 = Math.floor((y1 / height1) * height0);
|
139
|
+
for (let x1 = 0; x1 < width1; x1++) {
|
140
|
+
const x0 = Math.floor((x1 / width1) * width0);
|
141
|
+
const i0 = (y0 * width0 + x0) * 4;
|
142
|
+
const i1 = (y1 * width1 + x1) * 4;
|
143
|
+
if (sdf) {
|
144
|
+
const v = (data0[i0 + 3] - 191) * 16;
|
145
|
+
let a, b;
|
146
|
+
if (halo) {
|
147
|
+
b = Math.min(255, Math.max(0, 255 - v));
|
148
|
+
a = Math.min(255, Math.max(0, 256 * 6 + v));
|
149
|
+
}
|
150
|
+
else {
|
151
|
+
b = 0;
|
152
|
+
a = Math.min(255, Math.max(0, v));
|
153
|
+
}
|
154
|
+
data1[i1] = b;
|
155
|
+
data1[i1 + 1] = b;
|
156
|
+
data1[i1 + 2] = b;
|
157
|
+
data1[i1 + 3] = a;
|
158
|
+
}
|
159
|
+
else {
|
160
|
+
data1[i1] = data0[i0];
|
161
|
+
data1[i1 + 1] = data0[i0 + 1];
|
162
|
+
data1[i1 + 2] = data0[i0 + 2];
|
163
|
+
data1[i1 + 3] = data0[i0 + 3];
|
164
|
+
}
|
165
|
+
}
|
166
|
+
}
|
167
|
+
const ctx = canvas.getContext('2d');
|
168
|
+
ctx.putImageData(new ImageData(data1, width1, height1), 0, 0);
|
169
|
+
}
|
170
|
+
asList() {
|
171
|
+
return Array.from(symbols.values());
|
172
|
+
}
|
173
|
+
}
|
@@ -1,2 +1,9 @@
|
|
1
|
-
import type { ElementPoint } from './types.js';
|
1
|
+
import type { ElementPoint } from './element/types.js';
|
2
2
|
export declare function getMiddlePoint(p0: ElementPoint, p1: ElementPoint): ElementPoint;
|
3
|
+
export declare function lat2mercator(lat: number): number;
|
4
|
+
export declare function mercator2lat(y: number): number;
|
5
|
+
export declare function base64ToUint8Array(base64: string): Uint8Array;
|
6
|
+
export declare function uint8ArrayToBase64(data: Uint8Array): string;
|
7
|
+
export declare function compress(data: Uint8Array): Promise<Uint8Array>;
|
8
|
+
export declare function decompress(data: Uint8Array): Promise<Uint8Array>;
|
9
|
+
export declare function removeDefaultFields<T extends Record<string, unknown>>(value: T, def: T): Partial<T> | undefined;
|
@@ -3,9 +3,40 @@ export function getMiddlePoint(p0, p1) {
|
|
3
3
|
const y1 = lat2mercator(p1[1]);
|
4
4
|
return [(p0[0] + p1[0]) / 2, mercator2lat((y0 + y1) / 2)];
|
5
5
|
}
|
6
|
-
function lat2mercator(lat) {
|
6
|
+
export function lat2mercator(lat) {
|
7
7
|
return Math.log(Math.tan(Math.PI / 4 + (lat * Math.PI) / 360));
|
8
8
|
}
|
9
|
-
function mercator2lat(y) {
|
9
|
+
export function mercator2lat(y) {
|
10
10
|
return ((2 * Math.atan(Math.exp(y)) - Math.PI / 2) * 180) / Math.PI;
|
11
11
|
}
|
12
|
+
export function base64ToUint8Array(base64) {
|
13
|
+
const binaryString = atob(base64);
|
14
|
+
return Uint8Array.from(binaryString, (c) => c.charCodeAt(0));
|
15
|
+
}
|
16
|
+
export function uint8ArrayToBase64(data) {
|
17
|
+
const binaryString = String.fromCharCode(...data);
|
18
|
+
return btoa(binaryString);
|
19
|
+
}
|
20
|
+
export async function compress(data) {
|
21
|
+
const stream = new Blob([data]).stream();
|
22
|
+
const compressedStream = stream.pipeThrough(new CompressionStream('deflate-raw'));
|
23
|
+
return new Uint8Array(await new Response(compressedStream).arrayBuffer());
|
24
|
+
}
|
25
|
+
export async function decompress(data) {
|
26
|
+
const stream = new Blob([data]).stream();
|
27
|
+
const decompressedStream = stream.pipeThrough(new DecompressionStream('deflate-raw'));
|
28
|
+
const arrayBuffer = await new Response(decompressedStream).arrayBuffer();
|
29
|
+
return new Uint8Array(arrayBuffer);
|
30
|
+
}
|
31
|
+
export function removeDefaultFields(value, def) {
|
32
|
+
const entries = Object.entries(value).filter(([k, v]) => {
|
33
|
+
if (v === undefined)
|
34
|
+
return false;
|
35
|
+
if (v === def[k])
|
36
|
+
return false;
|
37
|
+
return true;
|
38
|
+
});
|
39
|
+
if (entries.length === 0)
|
40
|
+
return undefined;
|
41
|
+
return Object.fromEntries(entries);
|
42
|
+
}
|
@@ -1,5 +1,6 @@
|
|
1
1
|
import type geojson from 'geojson';
|
2
2
|
import { type Writable } from 'svelte/store';
|
3
|
+
import maplibregl from 'maplibre-gl';
|
3
4
|
type DragPoint = 'n' | 'ne' | 'e' | 'se' | 's' | 'sw' | 'w' | 'nw' | false;
|
4
5
|
export declare const DragPointMap: Map<DragPoint, {
|
5
6
|
cursor: string;
|
package/dist/utils/draw/bbox.js
CHANGED
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@versatiles/svelte",
|
3
|
-
"version": "1.0
|
3
|
+
"version": "1.1.0",
|
4
4
|
"license": "MIT",
|
5
5
|
"scripts": {
|
6
6
|
"build": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json && vite build && npm run package",
|
@@ -10,16 +10,16 @@
|
|
10
10
|
"format": "prettier --write .",
|
11
11
|
"lint": "prettier --check . && eslint --color .",
|
12
12
|
"package": "svelte-kit sync && svelte-package && publint",
|
13
|
-
"prepack": "npm run
|
13
|
+
"prepack": "npm run build",
|
14
14
|
"prepublishOnly": "npm run package",
|
15
15
|
"preview": "vite preview",
|
16
16
|
"screenshots": "npm run build && npx tsx ./scripts/screenshots.ts && pngquant --nofs --force --ext .png screenshots/*.png && optipng -quiet screenshots/*.png",
|
17
|
-
"release": "
|
17
|
+
"release": "vrt release-npm",
|
18
18
|
"test:integration": "playwright test",
|
19
19
|
"test:unit": "vitest run",
|
20
20
|
"test:coverage": "vitest run --coverage",
|
21
21
|
"test": "npm run test:unit && npm run test:integration",
|
22
|
-
"upgrade": "
|
22
|
+
"upgrade": "vrt deps-upgrade"
|
23
23
|
},
|
24
24
|
"exports": {
|
25
25
|
".": {
|
@@ -35,46 +35,45 @@
|
|
35
35
|
"!dist/BBoxMap/helpers/*"
|
36
36
|
],
|
37
37
|
"peerDependencies": {
|
38
|
-
"
|
39
|
-
"
|
38
|
+
"sass-embedded": "^1.86.0",
|
39
|
+
"svelte": "^5.0.3"
|
40
40
|
},
|
41
41
|
"devDependencies": {
|
42
|
-
"@playwright/test": "^1.
|
42
|
+
"@playwright/test": "^1.51.1",
|
43
43
|
"@sveltejs/adapter-static": "^3.0.8",
|
44
|
-
"@sveltejs/kit": "^2.
|
45
|
-
"@sveltejs/package": "^2.3.
|
44
|
+
"@sveltejs/kit": "^2.20.0",
|
45
|
+
"@sveltejs/package": "^2.3.10",
|
46
46
|
"@sveltejs/vite-plugin-svelte": "^5.0.3",
|
47
47
|
"@turf/turf": "^7.2.0",
|
48
48
|
"@types/eslint": "^9.6.1",
|
49
|
-
"@types/node": "^22.
|
50
|
-
"@versatiles/release-tool": "^
|
51
|
-
"@vitest/coverage-v8": "^3.0.
|
49
|
+
"@types/node": "^22.13.10",
|
50
|
+
"@versatiles/release-tool": "^2.4.2",
|
51
|
+
"@vitest/coverage-v8": "^3.0.9",
|
52
52
|
"cookie": "^1.0.2",
|
53
|
-
"eslint": "^9.
|
54
|
-
"eslint-config-prettier": "^10.
|
55
|
-
"eslint-plugin-svelte": "^
|
53
|
+
"eslint": "^9.22.0",
|
54
|
+
"eslint-config-prettier": "^10.1.1",
|
55
|
+
"eslint-plugin-svelte": "^3.3.2",
|
56
56
|
"geojson": "^0.5.0",
|
57
|
-
"globals": "^
|
58
|
-
"happy-dom": "^
|
59
|
-
"
|
60
|
-
"prettier": "^3.4.2",
|
57
|
+
"globals": "^16.0.0",
|
58
|
+
"happy-dom": "^17.4.4",
|
59
|
+
"prettier": "^3.5.3",
|
61
60
|
"prettier-plugin-svelte": "^3.3.3",
|
62
|
-
"publint": "^0.3.
|
63
|
-
"sass": "^1.
|
64
|
-
"svelte": "^5.
|
65
|
-
"svelte-check": "^4.1.
|
61
|
+
"publint": "^0.3.9",
|
62
|
+
"sass": "^1.86.0",
|
63
|
+
"svelte": "^5.23.1",
|
64
|
+
"svelte-check": "^4.1.5",
|
66
65
|
"svelte-preprocess": "^6.0.3",
|
67
|
-
"tsx": "^4.19.
|
68
|
-
"typescript": "^5.
|
69
|
-
"typescript-eslint": "^8.
|
70
|
-
"vite": "^6.
|
71
|
-
"vitest": "^3.0.
|
66
|
+
"tsx": "^4.19.3",
|
67
|
+
"typescript": "^5.8.2",
|
68
|
+
"typescript-eslint": "^8.26.1",
|
69
|
+
"vite": "^6.2.2",
|
70
|
+
"vitest": "^3.0.9"
|
72
71
|
},
|
73
72
|
"svelte": "./dist/index.js",
|
74
73
|
"types": "./dist/index.d.ts",
|
75
74
|
"type": "module",
|
76
75
|
"dependencies": {
|
77
|
-
"@versatiles/style": "^5.
|
78
|
-
"maplibre-gl": "^5.
|
76
|
+
"@versatiles/style": "^5.6.0",
|
77
|
+
"maplibre-gl": "^5.2.0"
|
79
78
|
}
|
80
79
|
}
|
@@ -1,25 +0,0 @@
|
|
1
|
-
<script lang="ts">import {} from './editor.scss';
|
2
|
-
import EditorMarker from './EditorMarker.svelte';
|
3
|
-
import EditorLine from './EditorLine.svelte';
|
4
|
-
import { LineElement } from './lib/element_line.js';
|
5
|
-
import { MarkerElement } from './lib/element_marker.js';
|
6
|
-
const { element } = $props();
|
7
|
-
let name = $state(element.name);
|
8
|
-
$effect(() => {
|
9
|
-
name = element.name;
|
10
|
-
});
|
11
|
-
$effect(() => {
|
12
|
-
//element.name = name;
|
13
|
-
});
|
14
|
-
</script>
|
15
|
-
|
16
|
-
{#if element}
|
17
|
-
<label for="input-name">Name</label>
|
18
|
-
<input id="input-name" type="text" bind:value={name} />
|
19
|
-
{#if element instanceof MarkerElement}
|
20
|
-
<EditorMarker {element} />
|
21
|
-
{/if}
|
22
|
-
{#if element instanceof LineElement}
|
23
|
-
<EditorLine {element} />
|
24
|
-
{/if}
|
25
|
-
{/if}
|
@@ -1,27 +0,0 @@
|
|
1
|
-
<script lang="ts">import {} from './editor.scss';
|
2
|
-
import { get } from 'svelte/store';
|
3
|
-
import { dashArrays } from './lib/element_line.js';
|
4
|
-
const dashedList = Array.from(dashArrays.keys()).sort();
|
5
|
-
let { element } = $props();
|
6
|
-
let color = $state(get(element.color));
|
7
|
-
let width = $state(get(element.width));
|
8
|
-
let dashed = $state(get(element.dashed));
|
9
|
-
$effect(() => element.color.set(color));
|
10
|
-
$effect(() => element.width.set(width));
|
11
|
-
$effect(() => element.dashed.set(dashed));
|
12
|
-
</script>
|
13
|
-
|
14
|
-
<div class="row">
|
15
|
-
<label for="dashed-input">Dashed</label>
|
16
|
-
<select id="dashed-input" bind:value={dashed}>
|
17
|
-
{#each dashedList as d}
|
18
|
-
<option value={d}>{d}</option>
|
19
|
-
{/each}
|
20
|
-
</select>
|
21
|
-
|
22
|
-
<label for="color-input">Color</label>
|
23
|
-
<input id="color-input" type="color" bind:value={color} />
|
24
|
-
|
25
|
-
<label for="width-input">Width</label>
|
26
|
-
<input id="width-input" type="range" min="0.5" max="5" step="0.5" bind:value={width} />
|
27
|
-
</div>
|
@@ -1,7 +0,0 @@
|
|
1
|
-
import type { LineElement } from './lib/element_line.js';
|
2
|
-
type $$ComponentProps = {
|
3
|
-
element: LineElement;
|
4
|
-
};
|
5
|
-
declare const EditorLine: import("svelte").Component<$$ComponentProps, {}, "">;
|
6
|
-
type EditorLine = ReturnType<typeof EditorLine>;
|
7
|
-
export default EditorLine;
|
@@ -1,42 +0,0 @@
|
|
1
|
-
<script lang="ts">import {} from './editor.scss';
|
2
|
-
import { get } from 'svelte/store';
|
3
|
-
import { symbols } from './lib/element_marker.js';
|
4
|
-
const symbolList = Array.from(symbols.keys()).sort();
|
5
|
-
let { element } = $props();
|
6
|
-
let color = $state(get(element.color));
|
7
|
-
let halo = $state(get(element.halo));
|
8
|
-
let rotate = $state(get(element.rotate));
|
9
|
-
let size = $state(get(element.size));
|
10
|
-
let symbol = $state(get(element.symbol));
|
11
|
-
let label = $state(get(element.label));
|
12
|
-
$effect(() => element.color.set(color));
|
13
|
-
$effect(() => element.halo.set(halo));
|
14
|
-
$effect(() => element.rotate.set(rotate));
|
15
|
-
$effect(() => element.size.set(size));
|
16
|
-
$effect(() => element.label.set(label));
|
17
|
-
$effect(() => element.symbol.set(symbol));
|
18
|
-
</script>
|
19
|
-
|
20
|
-
<div class="row">
|
21
|
-
<label for="symbol-input">Symbol</label>
|
22
|
-
<select id="symbol-input" bind:value={symbol}>
|
23
|
-
{#each symbolList as s}
|
24
|
-
<option value={s}>{s}</option>
|
25
|
-
{/each}
|
26
|
-
</select>
|
27
|
-
|
28
|
-
<label for="color-input">Color</label>
|
29
|
-
<input id="color-input" type="color" bind:value={color} />
|
30
|
-
|
31
|
-
<label for="size-input">Size</label>
|
32
|
-
<input id="size-input" type="range" min="0.5" max="3" step="0.1" bind:value={size} />
|
33
|
-
|
34
|
-
<label for="rotate-input">Rotation</label>
|
35
|
-
<input id="rotate-input" type="range" min="-180" max="180" step="15" bind:value={rotate} />
|
36
|
-
|
37
|
-
<label for="halo-input">Halo</label>
|
38
|
-
<input id="halo-input" type="range" min="0" max="3" step="0.5" bind:value={halo} />
|
39
|
-
|
40
|
-
<label for="label-input">Label</label>
|
41
|
-
<input id="label-input" type="text" bind:value={label} />
|
42
|
-
</div>
|
@@ -1,7 +0,0 @@
|
|
1
|
-
import type { MarkerElement } from './lib/element_marker.js';
|
2
|
-
type $$ComponentProps = {
|
3
|
-
element: MarkerElement;
|
4
|
-
};
|
5
|
-
declare const EditorMarker: import("svelte").Component<$$ComponentProps, {}, "">;
|
6
|
-
type EditorMarker = ReturnType<typeof EditorMarker>;
|
7
|
-
export default EditorMarker;
|
@@ -1,20 +0,0 @@
|
|
1
|
-
import type { Feature } from 'geojson';
|
2
|
-
import type maplibregl from 'maplibre-gl';
|
3
|
-
import { MapLayer } from './map_layer.js';
|
4
|
-
import type { ElementPoint, LayerFill, LayerLine, LayerSymbol, SelectionNode } from './types.js';
|
5
|
-
import type { GeometryManager } from './geometry_manager.js';
|
6
|
-
export declare abstract class AbstractElement<T extends LayerSymbol | LayerFill | LayerLine = LayerSymbol | LayerFill | LayerLine> {
|
7
|
-
name: string;
|
8
|
-
protected canvas: HTMLElement;
|
9
|
-
protected manager: GeometryManager;
|
10
|
-
protected map: maplibregl.Map;
|
11
|
-
protected layer: MapLayer<T>;
|
12
|
-
protected source: maplibregl.GeoJSONSource;
|
13
|
-
private isActive;
|
14
|
-
private slug;
|
15
|
-
constructor(manager: GeometryManager, name: string, type: 'symbol' | 'fill' | 'line');
|
16
|
-
protected randomPositions(name: string, length: number): ElementPoint[];
|
17
|
-
abstract getFeature(): Feature;
|
18
|
-
abstract getSelectionNodes(): SelectionNode[];
|
19
|
-
abstract getSelectionNodeUpdater(properties?: Record<string, unknown>): ((lng: number, lat: number) => void) | undefined;
|
20
|
-
}
|
@@ -1,58 +0,0 @@
|
|
1
|
-
import { MapLayer } from './map_layer.js';
|
2
|
-
export class AbstractElement {
|
3
|
-
name;
|
4
|
-
canvas;
|
5
|
-
manager;
|
6
|
-
map;
|
7
|
-
layer;
|
8
|
-
source;
|
9
|
-
isActive = true;
|
10
|
-
slug = '_' + Math.random().toString(36).slice(2);
|
11
|
-
constructor(manager, name, type) {
|
12
|
-
this.manager = manager;
|
13
|
-
this.map = manager.map;
|
14
|
-
this.canvas = this.map.getCanvasContainer();
|
15
|
-
this.name = name;
|
16
|
-
this.map.addSource('source' + this.slug, {
|
17
|
-
type: 'geojson',
|
18
|
-
data: { type: 'FeatureCollection', features: [] }
|
19
|
-
});
|
20
|
-
this.source = this.map.getSource('source' + this.slug);
|
21
|
-
this.layer = new MapLayer(this.map, type + this.slug, 'source' + this.slug, type);
|
22
|
-
this.map.on('mouseenter', this.layer.id, () => {
|
23
|
-
if (this.isActive)
|
24
|
-
this.canvas.style.cursor = 'pointer';
|
25
|
-
});
|
26
|
-
this.map.on('mouseleave', this.layer.id, () => {
|
27
|
-
if (this.isActive)
|
28
|
-
this.canvas.style.cursor = 'default';
|
29
|
-
});
|
30
|
-
this.map.on('click', this.layer.id, (e) => {
|
31
|
-
if (this.isActive) {
|
32
|
-
this.manager.setActiveElement(this);
|
33
|
-
e.preventDefault();
|
34
|
-
}
|
35
|
-
});
|
36
|
-
}
|
37
|
-
randomPositions(name, length) {
|
38
|
-
let seed = name
|
39
|
-
.split('')
|
40
|
-
.reduce((acc, char) => (acc * 0x101 + char.charCodeAt(0)) % 0x100000000, 0);
|
41
|
-
const points = [];
|
42
|
-
for (let i = 0; i < length; i++) {
|
43
|
-
const xr = random() * 0.5 + 0.25;
|
44
|
-
const yr = random() * 0.5 + 0.25;
|
45
|
-
const bounds = this.map.getBounds();
|
46
|
-
points.push([
|
47
|
-
(1 - xr) * bounds.getWest() + xr * bounds.getEast(),
|
48
|
-
(1 - yr) * bounds.getSouth() + yr * bounds.getNorth()
|
49
|
-
]);
|
50
|
-
}
|
51
|
-
return points;
|
52
|
-
function random() {
|
53
|
-
for (let i = 0; i < 10; i++)
|
54
|
-
seed = ((Math.cos(seed * 3.14 + 0.0159) + 1.1) * 9631) % 1;
|
55
|
-
return seed;
|
56
|
-
}
|
57
|
-
}
|
58
|
-
}
|
@@ -1,14 +0,0 @@
|
|
1
|
-
import { AbstractElement } from './element_abstract.js';
|
2
|
-
import type { GeometryManager } from './geometry_manager.js';
|
3
|
-
import type { ElementLine, LayerLine, SelectionNode } from './types.js';
|
4
|
-
export declare const dashArrays: Map<string, number[] | undefined>;
|
5
|
-
export declare class LineElement extends AbstractElement<LayerLine> {
|
6
|
-
readonly color: import("svelte/store").Writable<string>;
|
7
|
-
readonly dashed: import("svelte/store").Writable<string>;
|
8
|
-
readonly width: import("svelte/store").Writable<number>;
|
9
|
-
private line;
|
10
|
-
constructor(manager: GeometryManager, name: string, line?: ElementLine);
|
11
|
-
getFeature(): GeoJSON.Feature<GeoJSON.LineString>;
|
12
|
-
getSelectionNodes(): SelectionNode[];
|
13
|
-
getSelectionNodeUpdater(properties?: Record<string, unknown>): ((lng: number, lat: number) => void) | undefined;
|
14
|
-
}
|
@@ -1,76 +0,0 @@
|
|
1
|
-
import { Color } from '@versatiles/style';
|
2
|
-
import { AbstractElement } from './element_abstract.js';
|
3
|
-
import { get, writable } from 'svelte/store';
|
4
|
-
import { getMiddlePoint } from './utils.js';
|
5
|
-
export const dashArrays = new Map([
|
6
|
-
['solid', undefined],
|
7
|
-
['dashed', [2, 4]],
|
8
|
-
['dotted', [0, 2]]
|
9
|
-
]);
|
10
|
-
export class LineElement extends AbstractElement {
|
11
|
-
color = writable('#ff0000');
|
12
|
-
dashed = writable('solid');
|
13
|
-
width = writable(2);
|
14
|
-
line = [
|
15
|
-
[0, 0],
|
16
|
-
[0, 0]
|
17
|
-
];
|
18
|
-
constructor(manager, name, line) {
|
19
|
-
super(manager, name, 'line');
|
20
|
-
this.line = line ?? this.randomPositions(name, 2);
|
21
|
-
const getDashArray = () => dashArrays.get(get(this.dashed));
|
22
|
-
this.layer.setLayout({
|
23
|
-
'line-cap': 'round',
|
24
|
-
'line-join': 'round'
|
25
|
-
});
|
26
|
-
this.layer.setPaint({
|
27
|
-
'line-color': Color.parse(get(this.color)).asString(),
|
28
|
-
'line-dasharray': getDashArray(),
|
29
|
-
'line-width': get(this.width)
|
30
|
-
});
|
31
|
-
this.color.subscribe((value) => this.layer.updatePaint('line-color', Color.parse(value)));
|
32
|
-
this.width.subscribe((value) => this.layer.updatePaint('line-width', value));
|
33
|
-
this.dashed.subscribe(() => this.layer.updatePaint('line-dasharray', getDashArray()));
|
34
|
-
this.source.setData(this.getFeature());
|
35
|
-
}
|
36
|
-
getFeature() {
|
37
|
-
return {
|
38
|
-
type: 'Feature',
|
39
|
-
properties: {},
|
40
|
-
geometry: { type: 'LineString', coordinates: this.line }
|
41
|
-
};
|
42
|
-
}
|
43
|
-
getSelectionNodes() {
|
44
|
-
const points = [];
|
45
|
-
for (let i = 0; i < this.line.length; i++) {
|
46
|
-
points.push({ index: i, coordinates: this.line[i] });
|
47
|
-
if (i === this.line.length - 1)
|
48
|
-
continue;
|
49
|
-
points.push({
|
50
|
-
index: i + 0.5,
|
51
|
-
transparent: true,
|
52
|
-
coordinates: getMiddlePoint(this.line[i], this.line[i + 1])
|
53
|
-
});
|
54
|
-
}
|
55
|
-
return points;
|
56
|
-
}
|
57
|
-
getSelectionNodeUpdater(properties) {
|
58
|
-
if (properties == undefined)
|
59
|
-
return;
|
60
|
-
const index = properties.index;
|
61
|
-
let point;
|
62
|
-
if (index % 1 === 0) {
|
63
|
-
point = this.line[index];
|
64
|
-
}
|
65
|
-
else {
|
66
|
-
const i = Math.ceil(index);
|
67
|
-
this.line.splice(i, 0, [0, 0]);
|
68
|
-
point = this.line[i];
|
69
|
-
}
|
70
|
-
return (lng, lat) => {
|
71
|
-
point[0] = lng;
|
72
|
-
point[1] = lat;
|
73
|
-
this.source.setData(this.getFeature());
|
74
|
-
};
|
75
|
-
}
|
76
|
-
}
|