@versatiles/svelte 0.2.0 → 1.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/README.md +21 -4
- package/dist/components/BBoxMap/AutoComplete.svelte +176 -0
- package/dist/components/{AutoComplete.svelte.d.ts → BBoxMap/AutoComplete.svelte.d.ts} +12 -18
- package/dist/components/BBoxMap/BBoxMap.d.ts +1 -12
- package/dist/components/BBoxMap/BBoxMap.js +1 -200
- package/dist/components/BBoxMap/BBoxMap.svelte +43 -127
- package/dist/components/BBoxMap/BBoxMap.svelte.d.ts +4 -20
- package/dist/components/BasicMap/BasicMap.svelte +34 -37
- package/dist/components/BasicMap/BasicMap.svelte.d.ts +9 -24
- package/dist/components/LocatorMap/LocatorMap.svelte +75 -0
- package/dist/components/LocatorMap/LocatorMap.svelte.d.ts +19 -0
- package/dist/components/MapEditor/Editor.svelte +25 -0
- package/dist/components/MapEditor/Editor.svelte.d.ts +7 -0
- package/dist/components/MapEditor/EditorLine.svelte +27 -0
- package/dist/components/MapEditor/EditorLine.svelte.d.ts +7 -0
- package/dist/components/MapEditor/EditorMarker.svelte +42 -0
- package/dist/components/MapEditor/EditorMarker.svelte.d.ts +7 -0
- package/dist/components/MapEditor/MapEditor.svelte +99 -0
- package/dist/components/MapEditor/MapEditor.svelte.d.ts +4 -0
- package/dist/components/MapEditor/editor.scss +16 -0
- package/dist/components/MapEditor/lib/element_abstract.d.ts +20 -0
- package/dist/components/MapEditor/lib/element_abstract.js +58 -0
- package/dist/components/MapEditor/lib/element_line.d.ts +14 -0
- package/dist/components/MapEditor/lib/element_line.js +76 -0
- package/dist/components/MapEditor/lib/element_marker.d.ts +20 -0
- package/dist/components/MapEditor/lib/element_marker.js +191 -0
- package/dist/components/MapEditor/lib/geocoder.d.ts +1 -0
- package/dist/components/MapEditor/lib/geocoder.js +8 -0
- package/dist/components/MapEditor/lib/geometry_manager.d.ts +18 -0
- package/dist/components/MapEditor/lib/geometry_manager.js +117 -0
- package/dist/components/MapEditor/lib/map_layer.d.ts +14 -0
- package/dist/components/MapEditor/lib/map_layer.js +61 -0
- package/dist/components/MapEditor/lib/types.d.ts +112 -0
- package/dist/components/MapEditor/lib/types.js +1 -0
- package/dist/components/MapEditor/lib/utils.d.ts +2 -0
- package/dist/components/MapEditor/lib/utils.js +11 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +3 -1
- package/dist/utils/draw/bbox.d.ts +28 -0
- package/dist/utils/draw/bbox.js +193 -0
- package/dist/utils/location.d.ts +2 -1
- package/dist/utils/location.js +19 -10
- package/dist/utils/map_style.d.ts +6 -0
- package/dist/utils/map_style.js +28 -0
- package/dist/utils/sprite_library.d.ts +19 -0
- package/dist/utils/sprite_library.js +30 -0
- package/package.json +19 -14
- package/dist/components/AutoComplete.svelte +0 -197
- package/dist/components/BBoxMap/README.md +0 -70
- package/dist/components/BBoxMap/data/countries.jsonl +0 -258
- package/dist/components/BBoxMap/data/eu.jsonl +0 -1876
- package/dist/components/BBoxMap/data/us.jsonl +0 -52
- package/dist/components/BBoxMap/data/world.jsonl +0 -7
- package/dist/components/BBoxMap/helpers/geojson2bboxes.d.ts +0 -2
- package/dist/components/BBoxMap/helpers/geojson2bboxes.js +0 -183
- package/dist/components/BBoxMap/helpers/merge_bboxes.d.ts +0 -2
- package/dist/components/BBoxMap/helpers/merge_bboxes.js +0 -84
- package/dist/components/BBoxMap/helpers/population.raw.br +0 -0
- package/dist/utils/style.d.ts +0 -3
- package/dist/utils/style.js +0 -21
@@ -0,0 +1,20 @@
|
|
1
|
+
import { AbstractElement } from './element_abstract.js';
|
2
|
+
import type { GeometryManager } from './geometry_manager.js';
|
3
|
+
import type { ElementPoint, LayerSymbol, SelectionNode } from './types.js';
|
4
|
+
export declare const symbols: Map<string, {
|
5
|
+
image: string;
|
6
|
+
offset?: [number, number];
|
7
|
+
}>;
|
8
|
+
export declare class MarkerElement extends AbstractElement<LayerSymbol> {
|
9
|
+
readonly color: import("svelte/store").Writable<string>;
|
10
|
+
readonly halo: import("svelte/store").Writable<number>;
|
11
|
+
readonly rotate: import("svelte/store").Writable<number>;
|
12
|
+
readonly size: import("svelte/store").Writable<number>;
|
13
|
+
readonly symbol: import("svelte/store").Writable<string>;
|
14
|
+
readonly label: import("svelte/store").Writable<string>;
|
15
|
+
private point;
|
16
|
+
constructor(manager: GeometryManager, name: string, point?: ElementPoint);
|
17
|
+
getFeature(): GeoJSON.Feature<GeoJSON.Point>;
|
18
|
+
getSelectionNodes(): SelectionNode[];
|
19
|
+
getSelectionNodeUpdater(): ((lng: number, lat: number) => void) | undefined;
|
20
|
+
}
|
@@ -0,0 +1,191 @@
|
|
1
|
+
import { Color } from '@versatiles/style';
|
2
|
+
import { AbstractElement } from './element_abstract.js';
|
3
|
+
import { get, writable } from 'svelte/store';
|
4
|
+
export const symbols = new Map([
|
5
|
+
['airplane', { image: 'basics:icon-airfield' }],
|
6
|
+
['airport', { image: 'basics:icon-airport' }],
|
7
|
+
['alcohol shop', { image: 'basics:icon-alcohol_shop' }],
|
8
|
+
['art gallery', { image: 'basics:icon-art_gallery' }],
|
9
|
+
['artwork', { image: 'basics:icon-artwork' }],
|
10
|
+
['atm', { image: 'basics:icon-atm' }],
|
11
|
+
['bakery', { image: 'basics:icon-bakery' }],
|
12
|
+
['bank', { image: 'basics:icon-bank' }],
|
13
|
+
['beauty', { image: 'basics:icon-beauty' }],
|
14
|
+
['beer', { image: 'basics:icon-beer' }],
|
15
|
+
['beergarden', { image: 'basics:icon-beergarden' }],
|
16
|
+
['bench', { image: 'basics:icon-bench' }],
|
17
|
+
['beverages', { image: 'basics:icon-beverages' }],
|
18
|
+
['bicycle share', { image: 'basics:icon-bicycle_share' }],
|
19
|
+
['books', { image: 'basics:icon-books' }],
|
20
|
+
['bus', { image: 'basics:icon-bus' }],
|
21
|
+
['butcher', { image: 'basics:icon-butcher' }],
|
22
|
+
['cafe', { image: 'basics:icon-cafe', offset: [2, 0] }],
|
23
|
+
['car rental', { image: 'basics:icon-car_rental' }],
|
24
|
+
['car wash', { image: 'basics:icon-car_wash' }],
|
25
|
+
['castle', { image: 'basics:icon-castle' }],
|
26
|
+
['cemetery', { image: 'basics:icon-cemetery' }],
|
27
|
+
['chalet', { image: 'basics:icon-chalet' }],
|
28
|
+
['chemist', { image: 'basics:icon-chemist' }],
|
29
|
+
['cinema', { image: 'basics:icon-cinema' }],
|
30
|
+
['clothes', { image: 'basics:icon-clothes' }],
|
31
|
+
['college', { image: 'basics:icon-college' }],
|
32
|
+
['community', { image: 'basics:icon-community' }],
|
33
|
+
['defibrillator', { image: 'basics:icon-defibrillator' }],
|
34
|
+
['doctor', { image: 'basics:icon-doctor' }],
|
35
|
+
['dog park', { image: 'basics:icon-dog_park' }],
|
36
|
+
['doityourself', { image: 'basics:icon-doityourself' }],
|
37
|
+
['drinking water', { image: 'basics:icon-drinking_water' }],
|
38
|
+
['drycleaning', { image: 'basics:icon-drycleaning' }],
|
39
|
+
['emergency phone', { image: 'basics:icon-emergency_phone' }],
|
40
|
+
['fast food', { image: 'basics:icon-fast_food' }],
|
41
|
+
['fire station', { image: 'basics:icon-fire_station' }],
|
42
|
+
['flag', { image: 'basics:icon-embassy', offset: [7.5, -10] }],
|
43
|
+
['florist', { image: 'basics:icon-florist' }],
|
44
|
+
['fountain', { image: 'basics:icon-fountain' }],
|
45
|
+
['furniture', { image: 'basics:icon-furniture' }],
|
46
|
+
['garden centre', { image: 'basics:icon-garden_centre' }],
|
47
|
+
['gift', { image: 'basics:icon-gift' }],
|
48
|
+
['glasses', { image: 'basics:icon-optician' }],
|
49
|
+
['golf', { image: 'basics:icon-golf' }],
|
50
|
+
['greengrocer', { image: 'basics:icon-greengrocer' }],
|
51
|
+
['hardware', { image: 'basics:icon-hardware' }],
|
52
|
+
['hospital', { image: 'basics:icon-hospital' }],
|
53
|
+
['huntingstand', { image: 'basics:icon-huntingstand' }],
|
54
|
+
['hydrant', { image: 'basics:icon-hydrant' }],
|
55
|
+
['icerink', { image: 'basics:icon-icerink' }],
|
56
|
+
['information', { image: 'basics:transport-information' }],
|
57
|
+
['jewelry store', { image: 'basics:icon-jewelry_store' }],
|
58
|
+
['kiosk', { image: 'basics:icon-kiosk' }],
|
59
|
+
['laundry', { image: 'basics:icon-laundry' }],
|
60
|
+
['letter', { image: 'basics:icon-post' }],
|
61
|
+
['library', { image: 'basics:icon-library' }],
|
62
|
+
['lighthouse', { image: 'basics:icon-lighthouse' }],
|
63
|
+
['marketplace', { image: 'basics:icon-marketplace' }],
|
64
|
+
['money', { image: 'basics:icon-bar' }],
|
65
|
+
['monument', { image: 'basics:icon-monument' }],
|
66
|
+
['newsagent', { image: 'basics:icon-newsagent' }],
|
67
|
+
['nightclub', { image: 'basics:icon-nightclub' }],
|
68
|
+
['nursinghome', { image: 'basics:icon-nursinghome' }],
|
69
|
+
['observation tower', { image: 'basics:icon-observation_tower' }],
|
70
|
+
['outdoor', { image: 'basics:icon-outdoor' }],
|
71
|
+
['pharmacy', { image: 'basics:icon-pharmacy' }],
|
72
|
+
['picnic site', { image: 'basics:icon-picnic_site' }],
|
73
|
+
['place of worship', { image: 'basics:icon-place_of_worship' }],
|
74
|
+
['playground', { image: 'basics:icon-playground' }],
|
75
|
+
['police', { image: 'basics:icon-police', offset: [-1, -3] }],
|
76
|
+
['postbox', { image: 'basics:icon-postbox' }],
|
77
|
+
['prison', { image: 'basics:icon-prison' }],
|
78
|
+
['rail light', { image: 'basics:icon-rail_light' }],
|
79
|
+
['rail metro', { image: 'basics:icon-rail_metro' }],
|
80
|
+
['rail', { image: 'basics:icon-rail' }],
|
81
|
+
['recycling', { image: 'basics:icon-recycling' }],
|
82
|
+
['restaurant', { image: 'basics:icon-restaurant' }],
|
83
|
+
['run', { image: 'basics:icon-pitch' }],
|
84
|
+
['school', { image: 'basics:icon-school' }],
|
85
|
+
['scissor', { image: 'basics:icon-hairdresser' }],
|
86
|
+
['shield', { image: 'basics:icon-historic', offset: [0, -10] }],
|
87
|
+
['shoes', { image: 'basics:icon-shoes', offset: [-5, 0] }],
|
88
|
+
['shop', { image: 'basics:icon-shop' }],
|
89
|
+
['shop', { image: 'basics:icon-shop' }],
|
90
|
+
['shrine', { image: 'basics:icon-shrine' }],
|
91
|
+
['sports', { image: 'basics:icon-sports' }],
|
92
|
+
['stadium', { image: 'basics:icon-stadium' }],
|
93
|
+
['stationery', { image: 'basics:icon-stationery' }],
|
94
|
+
['surveillance', { image: 'basics:icon-surveillance' }],
|
95
|
+
['swimming', { image: 'basics:icon-swimming' }],
|
96
|
+
['telephone', { image: 'basics:icon-telephone' }],
|
97
|
+
['theatre', { image: 'basics:icon-theatre' }],
|
98
|
+
['toilet', { image: 'basics:icon-toilet' }],
|
99
|
+
['tooth', { image: 'basics:icon-dentist' }],
|
100
|
+
['town hall', { image: 'basics:icon-town_hall' }],
|
101
|
+
['toys', { image: 'basics:icon-toys' }],
|
102
|
+
['tram', { image: 'basics:transport-tram' }],
|
103
|
+
['travel agent', { image: 'basics:icon-travel_agent' }],
|
104
|
+
['vendingmachine', { image: 'basics:icon-vendingmachine' }],
|
105
|
+
['veterinary', { image: 'basics:icon-veterinary' }],
|
106
|
+
['video', { image: 'basics:icon-video' }],
|
107
|
+
['viewpoint', { image: 'basics:icon-viewpoint', offset: [0, -6] }],
|
108
|
+
['waste basket', { image: 'basics:icon-waste_basket' }],
|
109
|
+
['watermill', { image: 'basics:icon-watermill' }],
|
110
|
+
['waterpark', { image: 'basics:icon-waterpark' }],
|
111
|
+
['windmill', { image: 'basics:icon-windmill' }],
|
112
|
+
['zoo', { image: 'basics:icon-zoo' }]
|
113
|
+
]);
|
114
|
+
export class MarkerElement extends AbstractElement {
|
115
|
+
color = writable('#ff0000');
|
116
|
+
halo = writable(1);
|
117
|
+
rotate = writable(0);
|
118
|
+
size = writable(1);
|
119
|
+
symbol = writable('flag');
|
120
|
+
label = writable('');
|
121
|
+
point = [0, 0];
|
122
|
+
constructor(manager, name, point) {
|
123
|
+
super(manager, name, 'symbol');
|
124
|
+
this.point = point ?? this.randomPositions(name, 1)[0];
|
125
|
+
const getSymbol = () => {
|
126
|
+
const entry = symbols.get(get(this.symbol)) ?? symbols.get('flag');
|
127
|
+
return { image: entry.image, offset: entry.offset ?? [0, 0] };
|
128
|
+
};
|
129
|
+
this.layer.setLayout({
|
130
|
+
'icon-image': getSymbol().image,
|
131
|
+
'icon-offset': getSymbol().offset,
|
132
|
+
'icon-overlap': 'always',
|
133
|
+
'icon-rotate': get(this.rotate),
|
134
|
+
'icon-size': get(this.size),
|
135
|
+
'text-field': get(this.label),
|
136
|
+
'text-font': ['noto_sans_regular'],
|
137
|
+
'text-justify': 'left',
|
138
|
+
'text-anchor': 'right',
|
139
|
+
'text-offset': [-0.4, -0.6]
|
140
|
+
});
|
141
|
+
this.layer.setPaint({
|
142
|
+
'icon-color': Color.parse(get(this.color)).asString(),
|
143
|
+
'icon-halo-blur': 0,
|
144
|
+
'icon-halo-color': '#FFFFFF',
|
145
|
+
'icon-halo-width': get(this.halo) * get(this.size),
|
146
|
+
'icon-opacity': 1,
|
147
|
+
'text-halo-blur': 0,
|
148
|
+
'text-halo-color': '#FFFFFF',
|
149
|
+
'text-halo-width': get(this.halo) * get(this.size)
|
150
|
+
});
|
151
|
+
this.color.subscribe((value) => this.layer.updatePaint('icon-color', Color.parse(value)));
|
152
|
+
this.halo.subscribe((value) => {
|
153
|
+
this.layer.updatePaint('icon-halo-width', value * get(this.size));
|
154
|
+
this.layer.updatePaint('text-halo-width', value * get(this.size));
|
155
|
+
});
|
156
|
+
this.label.subscribe((value) => this.layer.updateLayout('text-field', value));
|
157
|
+
this.rotate.subscribe((value) => this.layer.updateLayout('icon-rotate', value));
|
158
|
+
this.size.subscribe((value) => {
|
159
|
+
this.layer.updateLayout('icon-size', value);
|
160
|
+
this.layer.updatePaint('icon-halo-width', value * get(this.halo));
|
161
|
+
this.layer.updateLayout('text-size', value * 16);
|
162
|
+
this.layer.updatePaint('text-halo-width', value * get(this.halo));
|
163
|
+
});
|
164
|
+
this.symbol.subscribe(() => {
|
165
|
+
const symbol = getSymbol();
|
166
|
+
this.layer.updateLayout('icon-image', symbol.image);
|
167
|
+
this.layer.updateLayout('icon-offset', symbol.offset);
|
168
|
+
});
|
169
|
+
this.source.setData(this.getFeature());
|
170
|
+
}
|
171
|
+
getFeature() {
|
172
|
+
return {
|
173
|
+
type: 'Feature',
|
174
|
+
properties: {},
|
175
|
+
geometry: {
|
176
|
+
type: 'Point',
|
177
|
+
coordinates: this.point
|
178
|
+
}
|
179
|
+
};
|
180
|
+
}
|
181
|
+
getSelectionNodes() {
|
182
|
+
return [{ index: 0, coordinates: this.point }];
|
183
|
+
}
|
184
|
+
getSelectionNodeUpdater() {
|
185
|
+
return (lng, lat) => {
|
186
|
+
this.point[0] = lng;
|
187
|
+
this.point[1] = lat;
|
188
|
+
this.source.setData(this.getFeature());
|
189
|
+
};
|
190
|
+
}
|
191
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
export declare function getLatLng(query: string): Promise<[number, number] | undefined>;
|
@@ -0,0 +1,8 @@
|
|
1
|
+
export async function getLatLng(query) {
|
2
|
+
const url = `https://photon.komoot.io/api/?${new URLSearchParams(query)}`;
|
3
|
+
const result = await fetch(url).then((r) => r.json());
|
4
|
+
const geometry = result?.features?.[0]?.geometry;
|
5
|
+
if (geometry?.type !== 'Point')
|
6
|
+
return;
|
7
|
+
return geometry.coordinates;
|
8
|
+
}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
import { type Writable } from 'svelte/store';
|
2
|
+
import type { AbstractElement } from './element_abstract.js';
|
3
|
+
import type maplibregl from 'maplibre-gl';
|
4
|
+
export declare class GeometryManager {
|
5
|
+
readonly elements: Writable<AbstractElement[]>;
|
6
|
+
readonly map: maplibregl.Map;
|
7
|
+
readonly activeElement: Writable<AbstractElement | undefined>;
|
8
|
+
private readonly selection_nodes;
|
9
|
+
private readonly canvas;
|
10
|
+
constructor(map: maplibregl.Map);
|
11
|
+
setActiveElement(element: AbstractElement | undefined): void;
|
12
|
+
private drawSelectionNodes;
|
13
|
+
getElement(index: number): AbstractElement;
|
14
|
+
getNewMarker(): AbstractElement;
|
15
|
+
getNewLine(): AbstractElement;
|
16
|
+
private addElement;
|
17
|
+
private newName;
|
18
|
+
}
|
@@ -0,0 +1,117 @@
|
|
1
|
+
import { get, writable } from 'svelte/store';
|
2
|
+
import { MarkerElement } from './element_marker.js';
|
3
|
+
import { LineElement } from './element_line.js';
|
4
|
+
export class GeometryManager {
|
5
|
+
elements;
|
6
|
+
map;
|
7
|
+
activeElement = writable(undefined);
|
8
|
+
selection_nodes;
|
9
|
+
canvas;
|
10
|
+
constructor(map) {
|
11
|
+
this.elements = writable([]);
|
12
|
+
this.map = map;
|
13
|
+
this.canvas = this.map.getCanvasContainer();
|
14
|
+
map.addSource('selection_nodes', {
|
15
|
+
type: 'geojson',
|
16
|
+
data: { type: 'FeatureCollection', features: [] }
|
17
|
+
});
|
18
|
+
this.selection_nodes = map.getSource('selection_nodes');
|
19
|
+
map.addLayer({
|
20
|
+
id: 'selection_nodes',
|
21
|
+
source: 'selection_nodes',
|
22
|
+
type: 'circle',
|
23
|
+
layout: {},
|
24
|
+
paint: {
|
25
|
+
'circle-color': '#ffffff',
|
26
|
+
'circle-opacity': ['get', 'opacity'],
|
27
|
+
'circle-radius': 4,
|
28
|
+
'circle-stroke-color': '#000000',
|
29
|
+
'circle-stroke-opacity': ['get', 'opacity'],
|
30
|
+
'circle-stroke-width': 1.5
|
31
|
+
}
|
32
|
+
});
|
33
|
+
map.on('mousedown', 'selection_nodes', (e) => {
|
34
|
+
const element = get(this.activeElement);
|
35
|
+
if (element == undefined)
|
36
|
+
return;
|
37
|
+
const feature = map.queryRenderedFeatures(e.point, { layers: ['selection_nodes'] })[0];
|
38
|
+
const updateSelectionNode = element.getSelectionNodeUpdater(feature.properties);
|
39
|
+
if (updateSelectionNode == undefined)
|
40
|
+
return;
|
41
|
+
e.preventDefault();
|
42
|
+
const onMove = (e) => {
|
43
|
+
e.preventDefault();
|
44
|
+
this.canvas.style.cursor = 'grabbing';
|
45
|
+
updateSelectionNode(e.lngLat.lng, e.lngLat.lat);
|
46
|
+
this.drawSelectionNodes(element.getSelectionNodes());
|
47
|
+
};
|
48
|
+
const onUp = () => {
|
49
|
+
map.off('mousemove', onMove);
|
50
|
+
this.canvas.style.cursor = 'default';
|
51
|
+
};
|
52
|
+
map.once('mouseup', onUp);
|
53
|
+
map.on('mousemove', onMove);
|
54
|
+
});
|
55
|
+
map.on('mouseover', 'selection_nodes', () => (this.canvas.style.cursor = 'move'));
|
56
|
+
map.on('mouseout', 'selection_nodes', () => (this.canvas.style.cursor = 'default'));
|
57
|
+
map.on('click', (e) => {
|
58
|
+
this.setActiveElement(undefined);
|
59
|
+
e.preventDefault();
|
60
|
+
});
|
61
|
+
}
|
62
|
+
setActiveElement(element) {
|
63
|
+
if (element) {
|
64
|
+
if (!get(this.elements).includes(element))
|
65
|
+
throw new Error('Element not in list');
|
66
|
+
this.drawSelectionNodes(element.getSelectionNodes());
|
67
|
+
}
|
68
|
+
else {
|
69
|
+
this.drawSelectionNodes([]);
|
70
|
+
}
|
71
|
+
this.activeElement.set(element);
|
72
|
+
}
|
73
|
+
drawSelectionNodes(nodes) {
|
74
|
+
this.selection_nodes.setData({
|
75
|
+
type: 'FeatureCollection',
|
76
|
+
features: nodes.map((n) => ({
|
77
|
+
type: 'Feature',
|
78
|
+
properties: { index: n.index, opacity: n.transparent ? 0.3 : 1 },
|
79
|
+
geometry: { type: 'Point', coordinates: n.coordinates }
|
80
|
+
}))
|
81
|
+
});
|
82
|
+
}
|
83
|
+
getElement(index) {
|
84
|
+
return get(this.elements)[index];
|
85
|
+
}
|
86
|
+
getNewMarker() {
|
87
|
+
const element = new MarkerElement(this, this.newName('Marker '));
|
88
|
+
this.addElement(element);
|
89
|
+
return element;
|
90
|
+
}
|
91
|
+
getNewLine() {
|
92
|
+
const element = new LineElement(this, this.newName('Line '));
|
93
|
+
this.addElement(element);
|
94
|
+
return element;
|
95
|
+
}
|
96
|
+
addElement(element) {
|
97
|
+
this.elements.update((elements) => [...elements, element]);
|
98
|
+
}
|
99
|
+
newName(prefix) {
|
100
|
+
const set = new Set();
|
101
|
+
const elements = get(this.elements);
|
102
|
+
elements.forEach((e) => {
|
103
|
+
const name = e.name;
|
104
|
+
if (!name.startsWith(prefix))
|
105
|
+
return;
|
106
|
+
const index = name.substring(prefix.length);
|
107
|
+
if (!/^[0-9]+/.test(index))
|
108
|
+
return;
|
109
|
+
set.add(parseInt(index, 10));
|
110
|
+
});
|
111
|
+
for (let i = 1; i <= elements.length + 1; i++) {
|
112
|
+
if (!set.has(i))
|
113
|
+
return prefix + i;
|
114
|
+
}
|
115
|
+
throw new Error('Unreachable');
|
116
|
+
}
|
117
|
+
}
|
@@ -0,0 +1,14 @@
|
|
1
|
+
import type { LayerFill, LayerLine, LayerSymbol } from './types.js';
|
2
|
+
type LayerSpec = LayerFill | LayerLine | LayerSymbol;
|
3
|
+
export declare class MapLayer<T extends LayerSpec> {
|
4
|
+
readonly map: maplibregl.Map;
|
5
|
+
readonly id: string;
|
6
|
+
readonly layoutProperties: T["layout"];
|
7
|
+
readonly paintProperties: T["paint"];
|
8
|
+
constructor(map: maplibregl.Map, id: string, source: string, type: 'symbol' | 'line' | 'fill');
|
9
|
+
setPaint(paint: T['paint']): void;
|
10
|
+
updatePaint<K extends keyof T['paint'], V extends T['paint'][K]>(key: K, value: V): void;
|
11
|
+
setLayout(layout: T['layout']): void;
|
12
|
+
updateLayout<K extends keyof T['layout'], V extends T['layout'][K]>(key: K, value: V): void;
|
13
|
+
}
|
14
|
+
export {};
|
@@ -0,0 +1,61 @@
|
|
1
|
+
import { Color } from '@versatiles/style';
|
2
|
+
export class MapLayer {
|
3
|
+
map;
|
4
|
+
id;
|
5
|
+
layoutProperties = {};
|
6
|
+
paintProperties = {};
|
7
|
+
constructor(map, id, source, type) {
|
8
|
+
this.map = map;
|
9
|
+
this.id = id;
|
10
|
+
let filter;
|
11
|
+
switch (type) {
|
12
|
+
case 'symbol':
|
13
|
+
filter = 'Point';
|
14
|
+
break;
|
15
|
+
case 'line':
|
16
|
+
filter = 'LineString';
|
17
|
+
break;
|
18
|
+
case 'fill':
|
19
|
+
filter = 'Polygon';
|
20
|
+
break;
|
21
|
+
default:
|
22
|
+
throw new Error('Invalid layer type');
|
23
|
+
}
|
24
|
+
this.map.addLayer({
|
25
|
+
id,
|
26
|
+
source,
|
27
|
+
type,
|
28
|
+
layout: this.layoutProperties,
|
29
|
+
paint: this.paintProperties,
|
30
|
+
filter: ['==', '$type', filter]
|
31
|
+
}, 'selection_nodes');
|
32
|
+
}
|
33
|
+
setPaint(paint) {
|
34
|
+
if (paint === undefined)
|
35
|
+
return;
|
36
|
+
const keys = new Set(Object.keys(paint).concat(Object.keys(this.paintProperties)));
|
37
|
+
for (const key of keys.values())
|
38
|
+
this.updatePaint(key, paint[key]);
|
39
|
+
}
|
40
|
+
updatePaint(key, value) {
|
41
|
+
if (value instanceof Color)
|
42
|
+
value = value.asString();
|
43
|
+
if (this.paintProperties[key] == value)
|
44
|
+
return;
|
45
|
+
this.map.setPaintProperty(this.id, key, value);
|
46
|
+
this.paintProperties[key] = value;
|
47
|
+
}
|
48
|
+
setLayout(layout) {
|
49
|
+
if (layout === undefined)
|
50
|
+
return;
|
51
|
+
const keys = new Set(Object.keys(layout).concat(Object.keys(this.layoutProperties)));
|
52
|
+
for (const key of keys.values())
|
53
|
+
this.updateLayout(key, layout[key]);
|
54
|
+
}
|
55
|
+
updateLayout(key, value) {
|
56
|
+
if (this.layoutProperties[key] == value)
|
57
|
+
return;
|
58
|
+
this.map.setLayoutProperty(this.id, key, value);
|
59
|
+
this.layoutProperties[key] = value;
|
60
|
+
}
|
61
|
+
}
|
@@ -0,0 +1,112 @@
|
|
1
|
+
import type { Color } from '@versatiles/style';
|
2
|
+
import type { ExpressionSpecification, FormattedSpecification, PaddingSpecification, ResolvedImageSpecification, VariableAnchorOffsetCollectionSpecification } from 'maplibre-gl';
|
3
|
+
export interface LayerFill {
|
4
|
+
layout: {
|
5
|
+
'fill-sort-key'?: number;
|
6
|
+
visibility?: 'visible' | 'none';
|
7
|
+
};
|
8
|
+
paint: {
|
9
|
+
'fill-antialias'?: boolean;
|
10
|
+
'fill-opacity'?: number;
|
11
|
+
'fill-color'?: string | Color;
|
12
|
+
'fill-outline-color'?: string | Color;
|
13
|
+
'fill-translate'?: [number, number];
|
14
|
+
'fill-translate-anchor'?: 'map' | 'viewport';
|
15
|
+
'fill-pattern'?: ResolvedImageSpecification;
|
16
|
+
};
|
17
|
+
}
|
18
|
+
export interface LayerLine {
|
19
|
+
layout: {
|
20
|
+
'line-cap'?: 'butt' | 'round' | 'square';
|
21
|
+
'line-join'?: 'bevel' | 'round' | 'miter';
|
22
|
+
'line-miter-limit'?: number;
|
23
|
+
'line-round-limit'?: number;
|
24
|
+
'line-sort-key'?: number;
|
25
|
+
visibility?: 'visible' | 'none';
|
26
|
+
};
|
27
|
+
paint: {
|
28
|
+
'line-opacity'?: number;
|
29
|
+
'line-color'?: string | Color;
|
30
|
+
'line-translate'?: [number, number];
|
31
|
+
'line-translate-anchor'?: 'map' | 'viewport';
|
32
|
+
'line-width'?: number;
|
33
|
+
'line-gap-width'?: number;
|
34
|
+
'line-offset'?: number;
|
35
|
+
'line-blur'?: number;
|
36
|
+
'line-dasharray'?: Array<number>;
|
37
|
+
'line-pattern'?: ResolvedImageSpecification;
|
38
|
+
'line-gradient'?: ExpressionSpecification;
|
39
|
+
};
|
40
|
+
}
|
41
|
+
export interface LayerSymbol {
|
42
|
+
layout: {
|
43
|
+
'symbol-placement'?: 'point' | 'line' | 'line-center';
|
44
|
+
'symbol-spacing'?: number;
|
45
|
+
'symbol-avoid-edges'?: boolean;
|
46
|
+
'symbol-sort-key'?: number;
|
47
|
+
'symbol-z-order'?: 'auto' | 'viewport-y' | 'source';
|
48
|
+
'icon-allow-overlap'?: boolean;
|
49
|
+
'icon-overlap'?: 'never' | 'always' | 'cooperative';
|
50
|
+
'icon-ignore-placement'?: boolean;
|
51
|
+
'icon-optional'?: boolean;
|
52
|
+
'icon-rotation-alignment'?: 'map' | 'viewport' | 'auto';
|
53
|
+
'icon-size'?: number;
|
54
|
+
'icon-text-fit'?: 'none' | 'width' | 'height' | 'both';
|
55
|
+
'icon-text-fit-padding'?: [number, number, number, number];
|
56
|
+
'icon-image'?: ResolvedImageSpecification;
|
57
|
+
'icon-rotate'?: number;
|
58
|
+
'icon-padding'?: PaddingSpecification;
|
59
|
+
'icon-keep-upright'?: boolean;
|
60
|
+
'icon-offset'?: [number, number];
|
61
|
+
'icon-anchor'?: 'center' | 'left' | 'right' | 'top' | 'bottom' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
|
62
|
+
'icon-pitch-alignment'?: 'map' | 'viewport' | 'auto';
|
63
|
+
'text-pitch-alignment'?: 'map' | 'viewport' | 'auto';
|
64
|
+
'text-rotation-alignment'?: 'map' | 'viewport' | 'viewport-glyph' | 'auto';
|
65
|
+
'text-field'?: FormattedSpecification;
|
66
|
+
'text-font'?: Array<string>;
|
67
|
+
'text-size'?: number;
|
68
|
+
'text-max-width'?: number;
|
69
|
+
'text-line-height'?: number;
|
70
|
+
'text-letter-spacing'?: number;
|
71
|
+
'text-justify'?: 'auto' | 'left' | 'center' | 'right';
|
72
|
+
'text-radial-offset'?: number;
|
73
|
+
'text-variable-anchor'?: Array<'center' | 'left' | 'right' | 'top' | 'bottom' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'>;
|
74
|
+
'text-variable-anchor-offset'?: VariableAnchorOffsetCollectionSpecification;
|
75
|
+
'text-anchor'?: 'center' | 'left' | 'right' | 'top' | 'bottom' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
|
76
|
+
'text-max-angle'?: number;
|
77
|
+
'text-writing-mode'?: Array<'horizontal' | 'vertical'>;
|
78
|
+
'text-rotate'?: number;
|
79
|
+
'text-padding'?: number;
|
80
|
+
'text-keep-upright'?: boolean;
|
81
|
+
'text-transform'?: 'none' | 'uppercase' | 'lowercase';
|
82
|
+
'text-offset'?: [number, number];
|
83
|
+
'text-allow-overlap'?: boolean;
|
84
|
+
'text-overlap'?: 'never' | 'always' | 'cooperative';
|
85
|
+
'text-ignore-placement'?: boolean;
|
86
|
+
'text-optional'?: boolean;
|
87
|
+
visibility?: 'visible' | 'none';
|
88
|
+
};
|
89
|
+
paint: {
|
90
|
+
'icon-opacity'?: number;
|
91
|
+
'icon-color'?: string | Color;
|
92
|
+
'icon-halo-color'?: string | Color;
|
93
|
+
'icon-halo-width'?: number;
|
94
|
+
'icon-halo-blur'?: number;
|
95
|
+
'icon-translate'?: [number, number];
|
96
|
+
'icon-translate-anchor'?: 'map' | 'viewport';
|
97
|
+
'text-opacity'?: number;
|
98
|
+
'text-color'?: string | Color;
|
99
|
+
'text-halo-color'?: string | Color;
|
100
|
+
'text-halo-width'?: number;
|
101
|
+
'text-halo-blur'?: number;
|
102
|
+
'text-translate'?: [number, number];
|
103
|
+
'text-translate-anchor'?: 'map' | 'viewport';
|
104
|
+
};
|
105
|
+
}
|
106
|
+
export type ElementPoint = [number, number];
|
107
|
+
export type ElementLine = ElementPoint[];
|
108
|
+
export interface SelectionNode {
|
109
|
+
coordinates: ElementPoint;
|
110
|
+
index: number;
|
111
|
+
transparent?: boolean;
|
112
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1,11 @@
|
|
1
|
+
export function getMiddlePoint(p0, p1) {
|
2
|
+
const y0 = lat2mercator(p0[1]);
|
3
|
+
const y1 = lat2mercator(p1[1]);
|
4
|
+
return [(p0[0] + p1[0]) / 2, mercator2lat((y0 + y1) / 2)];
|
5
|
+
}
|
6
|
+
function lat2mercator(lat) {
|
7
|
+
return Math.log(Math.tan(Math.PI / 4 + (lat * Math.PI) / 360));
|
8
|
+
}
|
9
|
+
function mercator2lat(y) {
|
10
|
+
return ((2 * Math.atan(Math.exp(y)) - Math.PI / 2) * 180) / Math.PI;
|
11
|
+
}
|
package/dist/index.d.ts
CHANGED
@@ -1,3 +1,5 @@
|
|
1
1
|
import BasicMap from './components/BasicMap/BasicMap.svelte';
|
2
2
|
import BBoxMap from './components/BBoxMap/BBoxMap.svelte';
|
3
|
-
|
3
|
+
import LocatorMap from './components/LocatorMap/LocatorMap.svelte';
|
4
|
+
import MapEditor from './components/MapEditor/MapEditor.svelte';
|
5
|
+
export { BasicMap, BBoxMap, LocatorMap, MapEditor };
|
package/dist/index.js
CHANGED
@@ -1,3 +1,5 @@
|
|
1
1
|
import BasicMap from './components/BasicMap/BasicMap.svelte';
|
2
2
|
import BBoxMap from './components/BBoxMap/BBoxMap.svelte';
|
3
|
-
|
3
|
+
import LocatorMap from './components/LocatorMap/LocatorMap.svelte';
|
4
|
+
import MapEditor from './components/MapEditor/MapEditor.svelte';
|
5
|
+
export { BasicMap, BBoxMap, LocatorMap, MapEditor };
|
@@ -0,0 +1,28 @@
|
|
1
|
+
import type geojson from 'geojson';
|
2
|
+
type DragPoint = 'n' | 'ne' | 'e' | 'se' | 's' | 'sw' | 'w' | 'nw' | false;
|
3
|
+
export declare const DragPointMap: Map<DragPoint, {
|
4
|
+
cursor: string;
|
5
|
+
flipH: DragPoint;
|
6
|
+
flipV: DragPoint;
|
7
|
+
}>;
|
8
|
+
export type BBox = [number, number, number, number];
|
9
|
+
export declare class BBoxDrawer {
|
10
|
+
private source?;
|
11
|
+
private dragPoint;
|
12
|
+
private isDragging;
|
13
|
+
private map;
|
14
|
+
private canvas;
|
15
|
+
private inverted;
|
16
|
+
private bbox;
|
17
|
+
constructor(map: maplibregl.Map, bbox: BBox, color: string, inverted?: boolean);
|
18
|
+
private updateDragPoint;
|
19
|
+
private getAsFeatureCollection;
|
20
|
+
setGeometry(bbox: geojson.BBox): void;
|
21
|
+
getBounds(): maplibregl.LngLatBounds;
|
22
|
+
private redraw;
|
23
|
+
private getAsPixel;
|
24
|
+
private checkDragPointAt;
|
25
|
+
private getCursor;
|
26
|
+
private doDrag;
|
27
|
+
}
|
28
|
+
export {};
|