@versatiles/svelte 1.0.1 → 1.0.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 +116 -89
- package/dist/components/BBoxMap/BBoxMap.svelte +50 -40
- package/dist/components/BasicMap/BasicMap.svelte +59 -34
- package/dist/components/LocatorMap/LocatorMap.svelte +67 -60
- package/dist/components/MapEditor/MapEditor.svelte +35 -80
- 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 +9 -0
- package/dist/components/MapEditor/lib/cursor.js +31 -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 +158 -57
- package/dist/components/MapEditor/lib/map_layer/abstract.d.ts +30 -0
- package/dist/components/MapEditor/lib/map_layer/abstract.js +90 -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 +17 -17
- 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,21 @@
|
|
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
|
+
}
|
@@ -0,0 +1,36 @@
|
|
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
|
+
}
|
@@ -0,0 +1,26 @@
|
|
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
|
+
}
|
@@ -0,0 +1,31 @@
|
|
1
|
+
export class Cursor {
|
2
|
+
element;
|
3
|
+
#hover = 0;
|
4
|
+
#precise = 0;
|
5
|
+
#grab = 0;
|
6
|
+
constructor(element) {
|
7
|
+
this.element = element;
|
8
|
+
this.update();
|
9
|
+
}
|
10
|
+
update() {
|
11
|
+
if (this.#precise > 0)
|
12
|
+
return (this.element.style.cursor = 'crosshair');
|
13
|
+
if (this.#grab > 0)
|
14
|
+
return (this.element.style.cursor = 'grab');
|
15
|
+
if (this.#hover > 0)
|
16
|
+
return (this.element.style.cursor = 'pointer');
|
17
|
+
this.element.style.cursor = 'default';
|
18
|
+
}
|
19
|
+
hover(increase) {
|
20
|
+
this.#hover = Math.max(0, this.#hover + (increase ? 1 : -1));
|
21
|
+
this.update();
|
22
|
+
}
|
23
|
+
precise(increase) {
|
24
|
+
this.#precise = Math.max(0, this.#precise + (increase ? 1 : -1));
|
25
|
+
this.update();
|
26
|
+
}
|
27
|
+
grab(increase) {
|
28
|
+
this.#grab = Math.max(0, this.#grab + (increase ? 1 : -1));
|
29
|
+
this.update();
|
30
|
+
}
|
31
|
+
}
|
@@ -0,0 +1,21 @@
|
|
1
|
+
import type { ElementPoint, SelectionNode, SelectionNodeUpdater } from './types.js';
|
2
|
+
import type { GeometryManager } from '../geometry_manager.js';
|
3
|
+
import type { StateObject } from '../state/types.js';
|
4
|
+
export declare abstract class AbstractElement {
|
5
|
+
protected readonly canvas: HTMLElement;
|
6
|
+
protected readonly manager: GeometryManager;
|
7
|
+
protected readonly map: maplibregl.Map;
|
8
|
+
protected readonly source: maplibregl.GeoJSONSource;
|
9
|
+
protected readonly slug: string;
|
10
|
+
protected isSelected: boolean;
|
11
|
+
readonly sourceId: string;
|
12
|
+
constructor(manager: GeometryManager);
|
13
|
+
select(value: boolean): void;
|
14
|
+
protected randomPositions(length: number): ElementPoint[];
|
15
|
+
delete(): void;
|
16
|
+
abstract destroy(): void;
|
17
|
+
abstract getFeature(includeProperties: boolean): GeoJSON.Feature;
|
18
|
+
abstract getSelectionNodes(): SelectionNode[];
|
19
|
+
abstract getSelectionNodeUpdater(properties?: Record<string, unknown>): SelectionNodeUpdater | undefined;
|
20
|
+
abstract getState(): StateObject;
|
21
|
+
}
|
@@ -0,0 +1,39 @@
|
|
1
|
+
export class AbstractElement {
|
2
|
+
canvas;
|
3
|
+
manager;
|
4
|
+
map;
|
5
|
+
source;
|
6
|
+
slug = '_' + Math.random().toString(36).slice(2);
|
7
|
+
isSelected = false;
|
8
|
+
sourceId = 'source' + this.slug;
|
9
|
+
constructor(manager) {
|
10
|
+
this.manager = manager;
|
11
|
+
this.map = manager.map;
|
12
|
+
this.canvas = this.map.getCanvasContainer();
|
13
|
+
this.map.addSource(this.sourceId, {
|
14
|
+
type: 'geojson',
|
15
|
+
data: { type: 'FeatureCollection', features: [] }
|
16
|
+
});
|
17
|
+
this.source = this.map.getSource(this.sourceId);
|
18
|
+
}
|
19
|
+
select(value) {
|
20
|
+
this.isSelected = value;
|
21
|
+
}
|
22
|
+
randomPositions(length) {
|
23
|
+
const points = [];
|
24
|
+
for (let i = 0; i < length; i++) {
|
25
|
+
const xr = Math.random() * 0.5 + 0.25;
|
26
|
+
const yr = Math.random() * 0.5 + 0.25;
|
27
|
+
const bounds = this.map.getBounds();
|
28
|
+
points.push([
|
29
|
+
(1 - xr) * bounds.getWest() + xr * bounds.getEast(),
|
30
|
+
(1 - yr) * bounds.getSouth() + yr * bounds.getNorth()
|
31
|
+
]);
|
32
|
+
}
|
33
|
+
return points;
|
34
|
+
}
|
35
|
+
delete() {
|
36
|
+
this.destroy();
|
37
|
+
this.manager.deleteElement(this);
|
38
|
+
}
|
39
|
+
}
|
@@ -0,0 +1,11 @@
|
|
1
|
+
import { AbstractElement } from './abstract.js';
|
2
|
+
import type { GeometryManager } from '../geometry_manager.js';
|
3
|
+
import type { ElementPath, SelectionNode, SelectionNodeUpdater } from './types.js';
|
4
|
+
export declare abstract class AbstractPathElement extends AbstractElement {
|
5
|
+
path: ElementPath;
|
6
|
+
protected readonly isLine: boolean;
|
7
|
+
constructor(manager: GeometryManager, isLine: boolean);
|
8
|
+
protected handleDrag(e: maplibregl.MapMouseEvent): void;
|
9
|
+
getSelectionNodes(): SelectionNode[];
|
10
|
+
getSelectionNodeUpdater(properties?: Record<string, unknown>): SelectionNodeUpdater | undefined;
|
11
|
+
}
|
@@ -0,0 +1,79 @@
|
|
1
|
+
import { AbstractElement } from './abstract.js';
|
2
|
+
import { getMiddlePoint, lat2mercator, mercator2lat } from '../utils.js';
|
3
|
+
export class AbstractPathElement extends AbstractElement {
|
4
|
+
path = [];
|
5
|
+
isLine;
|
6
|
+
constructor(manager, isLine) {
|
7
|
+
super(manager);
|
8
|
+
this.isLine = isLine;
|
9
|
+
}
|
10
|
+
handleDrag(e) {
|
11
|
+
const { lng, lat } = e.lngLat;
|
12
|
+
let x0 = lng;
|
13
|
+
let y0 = lat2mercator(lat);
|
14
|
+
const moveHandler = (e) => {
|
15
|
+
const { lng, lat } = e.lngLat;
|
16
|
+
const y = lat2mercator(lat);
|
17
|
+
const dx = lng - x0;
|
18
|
+
const dy = y - y0;
|
19
|
+
y0 = y;
|
20
|
+
x0 = lng;
|
21
|
+
this.path = this.path.map(([x, y]) => [x + dx, mercator2lat(lat2mercator(y) + dy)]);
|
22
|
+
this.source.setData(this.getFeature(false));
|
23
|
+
this.manager.drawSelectionNodes();
|
24
|
+
e.preventDefault();
|
25
|
+
};
|
26
|
+
this.manager.map.on('mousemove', moveHandler);
|
27
|
+
this.manager.map.once('mouseup', () => this.manager.map.off('mousemove', moveHandler));
|
28
|
+
e.preventDefault();
|
29
|
+
}
|
30
|
+
getSelectionNodes() {
|
31
|
+
const points = [];
|
32
|
+
for (let i = 0; i < this.path.length; i++) {
|
33
|
+
points.push({ index: i, coordinates: this.path[i] });
|
34
|
+
if (this.isLine && i === this.path.length - 1)
|
35
|
+
continue;
|
36
|
+
const j = (i + 1) % this.path.length;
|
37
|
+
points.push({
|
38
|
+
index: i + 0.5,
|
39
|
+
transparent: true,
|
40
|
+
coordinates: getMiddlePoint(this.path[i], this.path[j])
|
41
|
+
});
|
42
|
+
}
|
43
|
+
return points;
|
44
|
+
}
|
45
|
+
getSelectionNodeUpdater(properties) {
|
46
|
+
if (properties == undefined)
|
47
|
+
return;
|
48
|
+
const index = properties.index;
|
49
|
+
let point;
|
50
|
+
if (index % 1 === 0) {
|
51
|
+
point = this.path[index];
|
52
|
+
}
|
53
|
+
else {
|
54
|
+
const i = Math.floor(index);
|
55
|
+
const j = (i + 1) % this.path.length;
|
56
|
+
point = getMiddlePoint(this.path[i], this.path[j]);
|
57
|
+
this.path.splice(j, 0, point);
|
58
|
+
}
|
59
|
+
return {
|
60
|
+
update: (lng, lat) => {
|
61
|
+
point[0] = lng;
|
62
|
+
point[1] = lat;
|
63
|
+
this.source.setData(this.getFeature(false));
|
64
|
+
},
|
65
|
+
delete: () => {
|
66
|
+
if (this.isLine) {
|
67
|
+
if (this.path.length <= 2)
|
68
|
+
return this.delete();
|
69
|
+
}
|
70
|
+
else {
|
71
|
+
if (this.path.length <= 3)
|
72
|
+
return this.delete();
|
73
|
+
}
|
74
|
+
this.path.splice(index, 1);
|
75
|
+
this.source.setData(this.getFeature(false));
|
76
|
+
}
|
77
|
+
};
|
78
|
+
}
|
79
|
+
}
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import type { GeometryManager } from '../geometry_manager.js';
|
2
|
+
import type { ElementPath } from './types.js';
|
3
|
+
import { MapLayerLine } from '../map_layer/line.js';
|
4
|
+
import { AbstractPathElement } from './abstract_path.js';
|
5
|
+
import type { StateObject } from '../state/types.js';
|
6
|
+
export declare class LineElement extends AbstractPathElement {
|
7
|
+
readonly layer: MapLayerLine;
|
8
|
+
readonly path: ElementPath;
|
9
|
+
constructor(manager: GeometryManager, line?: ElementPath);
|
10
|
+
select(value: boolean): void;
|
11
|
+
getFeature(includeProperties?: boolean): GeoJSON.Feature<GeoJSON.LineString>;
|
12
|
+
destroy(): void;
|
13
|
+
getState(): StateObject;
|
14
|
+
static fromState(manager: GeometryManager, state: StateObject): LineElement;
|
15
|
+
static fromGeoJSON(manager: GeometryManager, feature: GeoJSON.Feature<GeoJSON.LineString>): LineElement;
|
16
|
+
}
|
@@ -0,0 +1,53 @@
|
|
1
|
+
import { MapLayerLine } from '../map_layer/line.js';
|
2
|
+
import { AbstractPathElement } from './abstract_path.js';
|
3
|
+
export class LineElement extends AbstractPathElement {
|
4
|
+
layer;
|
5
|
+
path;
|
6
|
+
constructor(manager, line) {
|
7
|
+
super(manager, true);
|
8
|
+
this.path = line ?? this.randomPositions(2);
|
9
|
+
this.layer = new MapLayerLine(manager, 'line' + this.slug, this.sourceId);
|
10
|
+
this.layer.on('click', () => this.manager.selectElement(this));
|
11
|
+
this.layer.on('mousedown', (e) => {
|
12
|
+
if (!this.isSelected)
|
13
|
+
return;
|
14
|
+
if ('ignore' in e && e.ignore)
|
15
|
+
return;
|
16
|
+
this.handleDrag(e);
|
17
|
+
});
|
18
|
+
this.source.setData(this.getFeature());
|
19
|
+
}
|
20
|
+
select(value) {
|
21
|
+
super.select(value);
|
22
|
+
this.layer.isSelected = value;
|
23
|
+
}
|
24
|
+
getFeature(includeProperties = false) {
|
25
|
+
return {
|
26
|
+
type: 'Feature',
|
27
|
+
properties: includeProperties ? this.layer.getGeoJSONProperties() : {},
|
28
|
+
geometry: { type: 'LineString', coordinates: this.path }
|
29
|
+
};
|
30
|
+
}
|
31
|
+
destroy() {
|
32
|
+
this.layer.destroy();
|
33
|
+
this.map.removeSource(this.sourceId);
|
34
|
+
}
|
35
|
+
getState() {
|
36
|
+
return {
|
37
|
+
type: 'line',
|
38
|
+
points: this.path,
|
39
|
+
style: this.layer.getState()
|
40
|
+
};
|
41
|
+
}
|
42
|
+
static fromState(manager, state) {
|
43
|
+
const element = new LineElement(manager, state.points);
|
44
|
+
if (state.style)
|
45
|
+
element.layer.setState(state.style);
|
46
|
+
return element;
|
47
|
+
}
|
48
|
+
static fromGeoJSON(manager, feature) {
|
49
|
+
const element = new LineElement(manager, feature.geometry.coordinates);
|
50
|
+
element.layer.setGeoJSONProperties(feature.properties);
|
51
|
+
return element;
|
52
|
+
}
|
53
|
+
}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
import { AbstractElement } from './abstract.js';
|
2
|
+
import type { GeometryManager } from '../geometry_manager.js';
|
3
|
+
import type { ElementPoint, SelectionNode, SelectionNodeUpdater } from './types.js';
|
4
|
+
import { MapLayerSymbol } from '../map_layer/symbol.js';
|
5
|
+
import type { StateObject } from '../state/types.js';
|
6
|
+
export declare class MarkerElement extends AbstractElement {
|
7
|
+
readonly layer: MapLayerSymbol;
|
8
|
+
private point;
|
9
|
+
constructor(manager: GeometryManager, point?: ElementPoint);
|
10
|
+
select(value: boolean): void;
|
11
|
+
getFeature(includeProperties?: boolean): GeoJSON.Feature<GeoJSON.Point>;
|
12
|
+
getSelectionNodes(): SelectionNode[];
|
13
|
+
getSelectionNodeUpdater(): SelectionNodeUpdater | undefined;
|
14
|
+
destroy(): void;
|
15
|
+
getState(): StateObject;
|
16
|
+
static fromState(manager: GeometryManager, state: StateObject): MarkerElement;
|
17
|
+
static fromGeoJSON(manager: GeometryManager, feature: GeoJSON.Feature<GeoJSON.Point>): MarkerElement;
|
18
|
+
}
|
@@ -0,0 +1,62 @@
|
|
1
|
+
import { AbstractElement } from './abstract.js';
|
2
|
+
import { MapLayerSymbol } from '../map_layer/symbol.js';
|
3
|
+
export class MarkerElement extends AbstractElement {
|
4
|
+
layer;
|
5
|
+
point = [0, 0];
|
6
|
+
constructor(manager, point) {
|
7
|
+
super(manager);
|
8
|
+
this.point = point ?? this.randomPositions(1)[0];
|
9
|
+
this.layer = new MapLayerSymbol(manager, 'symbol' + this.slug, this.sourceId);
|
10
|
+
this.layer.on('click', () => this.manager.selectElement(this));
|
11
|
+
this.source.setData(this.getFeature());
|
12
|
+
}
|
13
|
+
select(value) {
|
14
|
+
super.select(value);
|
15
|
+
this.layer.isSelected = value;
|
16
|
+
}
|
17
|
+
getFeature(includeProperties = false) {
|
18
|
+
return {
|
19
|
+
type: 'Feature',
|
20
|
+
properties: includeProperties ? this.layer.getGeoJSONProperties() : {},
|
21
|
+
geometry: {
|
22
|
+
type: 'Point',
|
23
|
+
coordinates: this.point
|
24
|
+
}
|
25
|
+
};
|
26
|
+
}
|
27
|
+
getSelectionNodes() {
|
28
|
+
return [{ index: 0, coordinates: this.point }];
|
29
|
+
}
|
30
|
+
getSelectionNodeUpdater() {
|
31
|
+
return {
|
32
|
+
update: (lng, lat) => {
|
33
|
+
this.point[0] = lng;
|
34
|
+
this.point[1] = lat;
|
35
|
+
this.source.setData(this.getFeature());
|
36
|
+
},
|
37
|
+
delete: () => this.delete()
|
38
|
+
};
|
39
|
+
}
|
40
|
+
destroy() {
|
41
|
+
this.layer.destroy();
|
42
|
+
this.map.removeSource(this.sourceId);
|
43
|
+
}
|
44
|
+
getState() {
|
45
|
+
return {
|
46
|
+
type: 'marker',
|
47
|
+
point: this.point,
|
48
|
+
style: this.layer.getState()
|
49
|
+
};
|
50
|
+
}
|
51
|
+
static fromState(manager, state) {
|
52
|
+
const element = new MarkerElement(manager, state.point);
|
53
|
+
if (state.style)
|
54
|
+
element.layer.setState(state.style);
|
55
|
+
return element;
|
56
|
+
}
|
57
|
+
static fromGeoJSON(manager, feature) {
|
58
|
+
const element = new MarkerElement(manager, feature.geometry.coordinates);
|
59
|
+
element.layer.setGeoJSONProperties(feature.properties);
|
60
|
+
return element;
|
61
|
+
}
|
62
|
+
}
|
@@ -0,0 +1,17 @@
|
|
1
|
+
import type { GeometryManager } from '../geometry_manager.js';
|
2
|
+
import type { ElementPath } from './types.js';
|
3
|
+
import { MapLayerFill } from '../map_layer/fill.js';
|
4
|
+
import { MapLayerLine } from '../map_layer/line.js';
|
5
|
+
import { AbstractPathElement } from './abstract_path.js';
|
6
|
+
import type { StateObject } from '../state/types.js';
|
7
|
+
export declare class PolygonElement extends AbstractPathElement {
|
8
|
+
readonly fillLayer: MapLayerFill;
|
9
|
+
readonly strokeLayer: MapLayerLine;
|
10
|
+
constructor(manager: GeometryManager, polygon?: ElementPath);
|
11
|
+
select(value: boolean): void;
|
12
|
+
getFeature(includeProperties?: boolean): GeoJSON.Feature<GeoJSON.Polygon>;
|
13
|
+
destroy(): void;
|
14
|
+
getState(): StateObject;
|
15
|
+
static fromState(manager: GeometryManager, state: StateObject): PolygonElement;
|
16
|
+
static fromGeoJSON(manager: GeometryManager, feature: GeoJSON.Feature<GeoJSON.Polygon>): PolygonElement;
|
17
|
+
}
|
@@ -0,0 +1,63 @@
|
|
1
|
+
import { MapLayerFill } from '../map_layer/fill.js';
|
2
|
+
import { MapLayerLine } from '../map_layer/line.js';
|
3
|
+
import { AbstractPathElement } from './abstract_path.js';
|
4
|
+
export class PolygonElement extends AbstractPathElement {
|
5
|
+
fillLayer;
|
6
|
+
strokeLayer;
|
7
|
+
constructor(manager, polygon) {
|
8
|
+
super(manager, false);
|
9
|
+
this.path = polygon ?? this.randomPositions(3);
|
10
|
+
this.fillLayer = new MapLayerFill(manager, 'fill' + this.slug, this.sourceId);
|
11
|
+
this.fillLayer.on('click', () => this.manager.selectElement(this));
|
12
|
+
this.fillLayer.on('mousedown', (e) => {
|
13
|
+
if (!this.isSelected)
|
14
|
+
return;
|
15
|
+
this.handleDrag(e);
|
16
|
+
});
|
17
|
+
this.strokeLayer = new MapLayerLine(manager, 'line' + this.slug, this.sourceId);
|
18
|
+
this.strokeLayer.on('click', () => this.manager.selectElement(this));
|
19
|
+
this.source.setData(this.getFeature());
|
20
|
+
}
|
21
|
+
select(value) {
|
22
|
+
super.select(value);
|
23
|
+
this.fillLayer.isSelected = value;
|
24
|
+
this.strokeLayer.isSelected = value;
|
25
|
+
}
|
26
|
+
getFeature(includeProperties = false) {
|
27
|
+
return {
|
28
|
+
type: 'Feature',
|
29
|
+
properties: includeProperties
|
30
|
+
? { ...this.fillLayer.getGeoJSONProperties(), ...this.strokeLayer.getGeoJSONProperties() }
|
31
|
+
: {},
|
32
|
+
geometry: { type: 'Polygon', coordinates: [[...this.path, this.path[0]]] }
|
33
|
+
};
|
34
|
+
}
|
35
|
+
destroy() {
|
36
|
+
this.fillLayer.destroy();
|
37
|
+
this.strokeLayer.destroy();
|
38
|
+
this.map.removeSource(this.sourceId);
|
39
|
+
}
|
40
|
+
getState() {
|
41
|
+
return {
|
42
|
+
type: 'polygon',
|
43
|
+
points: this.path,
|
44
|
+
style: this.fillLayer.getState(),
|
45
|
+
strokeStyle: this.strokeLayer.getState()
|
46
|
+
};
|
47
|
+
}
|
48
|
+
static fromState(manager, state) {
|
49
|
+
const element = new PolygonElement(manager, state.points);
|
50
|
+
if (state.style)
|
51
|
+
element.fillLayer.setState(state.style);
|
52
|
+
if (state.strokeStyle)
|
53
|
+
element.strokeLayer.setState(state.strokeStyle);
|
54
|
+
return element;
|
55
|
+
}
|
56
|
+
static fromGeoJSON(manager, feature) {
|
57
|
+
const coordinates = feature.geometry.coordinates[0].slice(0, -1);
|
58
|
+
const element = new PolygonElement(manager, coordinates);
|
59
|
+
element.fillLayer.setGeoJSONProperties(feature.properties);
|
60
|
+
element.strokeLayer.setGeoJSONProperties(feature.properties);
|
61
|
+
return element;
|
62
|
+
}
|
63
|
+
}
|
@@ -0,0 +1,11 @@
|
|
1
|
+
export type ElementPoint = [number, number];
|
2
|
+
export type ElementPath = ElementPoint[];
|
3
|
+
export interface SelectionNode {
|
4
|
+
coordinates: ElementPoint;
|
5
|
+
index: number;
|
6
|
+
transparent?: boolean;
|
7
|
+
}
|
8
|
+
export interface SelectionNodeUpdater {
|
9
|
+
update: (lng: number, lat: number) => void;
|
10
|
+
delete: () => void;
|
11
|
+
}
|
@@ -1,18 +1,28 @@
|
|
1
1
|
import { type Writable } from 'svelte/store';
|
2
|
-
import type { AbstractElement } from './
|
3
|
-
import
|
2
|
+
import type { AbstractElement } from './element/abstract.js';
|
3
|
+
import { Cursor } from './cursor.js';
|
4
|
+
import type { StateObject } from './state/types.js';
|
5
|
+
import { SymbolLibrary } from './symbols.js';
|
4
6
|
export declare class GeometryManager {
|
5
7
|
readonly elements: Writable<AbstractElement[]>;
|
6
8
|
readonly map: maplibregl.Map;
|
7
|
-
readonly
|
8
|
-
|
9
|
-
|
9
|
+
readonly selectedElement: Writable<AbstractElement | undefined>;
|
10
|
+
readonly canvas: HTMLElement;
|
11
|
+
readonly cursor: Cursor;
|
12
|
+
readonly symbolLibrary: SymbolLibrary;
|
13
|
+
private readonly selectionNodes;
|
10
14
|
constructor(map: maplibregl.Map);
|
11
|
-
|
12
|
-
|
15
|
+
selectElement(element: AbstractElement | undefined): void;
|
16
|
+
drawSelectionNodes(): void;
|
17
|
+
getState(): StateObject;
|
18
|
+
saveState(): Promise<void>;
|
19
|
+
loadState(hash: string): Promise<void>;
|
13
20
|
getElement(index: number): AbstractElement;
|
14
|
-
|
15
|
-
|
21
|
+
addNewMarker(): AbstractElement;
|
22
|
+
addNewLine(): AbstractElement;
|
23
|
+
addNewPolygon(): AbstractElement;
|
16
24
|
private addElement;
|
17
|
-
|
25
|
+
deleteElement(element: AbstractElement): void;
|
26
|
+
getGeoJSON(): GeoJSON.FeatureCollection;
|
27
|
+
addGeoJSON(geojson: GeoJSON.FeatureCollection): void;
|
18
28
|
}
|