@treasuryspatial/map-kit 0.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.
@@ -0,0 +1,17 @@
1
+ import type { Feature, MultiPolygon, Polygon } from 'geojson';
2
+ import type { FootprintStats } from './types';
3
+ export declare function getOuterRing(geometry: Polygon | MultiPolygon): number[][];
4
+ export declare function toPolygonFeature(feature: Feature<Polygon | MultiPolygon>): Feature<Polygon> | null;
5
+ export declare function computeCentroid(ring: number[][]): {
6
+ lng: number;
7
+ lat: number;
8
+ } | null;
9
+ export declare function ensureClosedRing(ring: number[][]): number[][];
10
+ export declare function toLocalMeters(ring: number[][], origin: {
11
+ lng: number;
12
+ lat: number;
13
+ }, mapboxgl: typeof import('mapbox-gl')): number[][];
14
+ export declare function buildGeoJsonPolygon(pointsLocal: number[][]): string;
15
+ export declare function computeFootprintStats(pointsLocal: number[][]): FootprintStats;
16
+ export declare function simplifyRing(pointsLocal: number[][], epsilon: number): number[][];
17
+ //# sourceMappingURL=footprint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"footprint.d.ts","sourceRoot":"","sources":["../src/footprint.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAE9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C,wBAAgB,YAAY,CAAC,QAAQ,EAAE,OAAO,GAAG,YAAY,GAAG,MAAM,EAAE,EAAE,CAKzE;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,GAAG,YAAY,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,CAgBlG;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAcrF;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,MAAM,EAAE,EAAE,CAM7D;AAED,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EAAE,EAAE,EAChB,MAAM,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,EACpC,QAAQ,EAAE,cAAc,WAAW,CAAC,GACnC,MAAM,EAAE,EAAE,CAWZ;AAED,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,GAAG,MAAM,CAMnE;AAQD,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,GAAG,cAAc,CAyB7E;AAkCD,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,CAMjF"}
@@ -0,0 +1,147 @@
1
+ export function getOuterRing(geometry) {
2
+ if (geometry.type === 'Polygon') {
3
+ return geometry.coordinates?.[0] ?? [];
4
+ }
5
+ return geometry.coordinates?.[0]?.[0] ?? [];
6
+ }
7
+ export function toPolygonFeature(feature) {
8
+ if (!feature.geometry)
9
+ return null;
10
+ const geometry = feature.geometry;
11
+ if (geometry.type === 'Polygon') {
12
+ return { type: 'Feature', properties: feature.properties ?? {}, geometry };
13
+ }
14
+ if (geometry.type === 'MultiPolygon') {
15
+ const coords = geometry.coordinates?.[0];
16
+ if (!coords)
17
+ return null;
18
+ return {
19
+ type: 'Feature',
20
+ properties: feature.properties ?? {},
21
+ geometry: { type: 'Polygon', coordinates: coords },
22
+ };
23
+ }
24
+ return null;
25
+ }
26
+ export function computeCentroid(ring) {
27
+ if (!ring.length)
28
+ return null;
29
+ let minLng = Number.POSITIVE_INFINITY;
30
+ let maxLng = Number.NEGATIVE_INFINITY;
31
+ let minLat = Number.POSITIVE_INFINITY;
32
+ let maxLat = Number.NEGATIVE_INFINITY;
33
+ ring.forEach(([lng, lat]) => {
34
+ if (lng < minLng)
35
+ minLng = lng;
36
+ if (lng > maxLng)
37
+ maxLng = lng;
38
+ if (lat < minLat)
39
+ minLat = lat;
40
+ if (lat > maxLat)
41
+ maxLat = lat;
42
+ });
43
+ if (!Number.isFinite(minLng) || !Number.isFinite(minLat))
44
+ return null;
45
+ return { lng: (minLng + maxLng) / 2, lat: (minLat + maxLat) / 2 };
46
+ }
47
+ export function ensureClosedRing(ring) {
48
+ if (ring.length < 3)
49
+ return ring;
50
+ const [x0, y0] = ring[0];
51
+ const [x1, y1] = ring[ring.length - 1];
52
+ if (x0 === x1 && y0 === y1)
53
+ return ring;
54
+ return [...ring, [x0, y0]];
55
+ }
56
+ export function toLocalMeters(ring, origin, mapboxgl) {
57
+ const originMc = mapboxgl.MercatorCoordinate.fromLngLat(origin);
58
+ const unitsPerMeter = originMc.meterInMercatorCoordinateUnits();
59
+ return ring
60
+ .map(([lng, lat]) => {
61
+ const mc = mapboxgl.MercatorCoordinate.fromLngLat({ lng, lat });
62
+ const dx = (mc.x - originMc.x) / unitsPerMeter;
63
+ const dy = (originMc.y - mc.y) / unitsPerMeter; // north-positive
64
+ return [Number(dx.toFixed(3)), Number(dy.toFixed(3))];
65
+ })
66
+ .filter((pt) => Number.isFinite(pt[0]) && Number.isFinite(pt[1]));
67
+ }
68
+ export function buildGeoJsonPolygon(pointsLocal) {
69
+ const ring = ensureClosedRing(pointsLocal);
70
+ return JSON.stringify({
71
+ type: 'Polygon',
72
+ coordinates: [ring],
73
+ });
74
+ }
75
+ function distance(a, b) {
76
+ const dx = a[0] - b[0];
77
+ const dy = a[1] - b[1];
78
+ return Math.hypot(dx, dy);
79
+ }
80
+ export function computeFootprintStats(pointsLocal) {
81
+ const ring = ensureClosedRing(pointsLocal);
82
+ const vertexCount = ring.length;
83
+ let area = 0;
84
+ let perimeter = 0;
85
+ let minEdge = Number.POSITIVE_INFINITY;
86
+ let maxEdge = 0;
87
+ for (let i = 0; i < ring.length - 1; i += 1) {
88
+ const [x1, y1] = ring[i];
89
+ const [x2, y2] = ring[i + 1];
90
+ area += x1 * y2 - x2 * y1;
91
+ const edge = distance(ring[i], ring[i + 1]);
92
+ perimeter += edge;
93
+ if (edge < minEdge)
94
+ minEdge = edge;
95
+ if (edge > maxEdge)
96
+ maxEdge = edge;
97
+ }
98
+ area = Math.abs(area) / 2;
99
+ if (!Number.isFinite(minEdge))
100
+ minEdge = 0;
101
+ const warnings = [];
102
+ if (vertexCount > 200)
103
+ warnings.push('Footprint is very detailed (>200 vertices).');
104
+ if (minEdge > 0 && minEdge < 0.5)
105
+ warnings.push('Footprint has tiny edges (<0.5m).');
106
+ return { vertexCount, area, perimeter, minEdge, maxEdge, warnings };
107
+ }
108
+ function perpendicularDistance(point, lineStart, lineEnd) {
109
+ const [x, y] = point;
110
+ const [x1, y1] = lineStart;
111
+ const [x2, y2] = lineEnd;
112
+ const dx = x2 - x1;
113
+ const dy = y2 - y1;
114
+ if (dx === 0 && dy === 0)
115
+ return Math.hypot(x - x1, y - y1);
116
+ const t = ((x - x1) * dx + (y - y1) * dy) / (dx * dx + dy * dy);
117
+ const projX = x1 + t * dx;
118
+ const projY = y1 + t * dy;
119
+ return Math.hypot(x - projX, y - projY);
120
+ }
121
+ function simplifyRdp(points, epsilon) {
122
+ if (points.length <= 2)
123
+ return points;
124
+ let maxDistance = 0;
125
+ let index = 0;
126
+ for (let i = 1; i < points.length - 1; i += 1) {
127
+ const dist = perpendicularDistance(points[i], points[0], points[points.length - 1]);
128
+ if (dist > maxDistance) {
129
+ maxDistance = dist;
130
+ index = i;
131
+ }
132
+ }
133
+ if (maxDistance > epsilon) {
134
+ const left = simplifyRdp(points.slice(0, index + 1), epsilon);
135
+ const right = simplifyRdp(points.slice(index), epsilon);
136
+ return [...left.slice(0, -1), ...right];
137
+ }
138
+ return [points[0], points[points.length - 1]];
139
+ }
140
+ export function simplifyRing(pointsLocal, epsilon) {
141
+ if (epsilon <= 0)
142
+ return ensureClosedRing(pointsLocal);
143
+ const ring = ensureClosedRing(pointsLocal);
144
+ const open = ring.slice(0, -1);
145
+ const simplified = simplifyRdp(open, epsilon);
146
+ return ensureClosedRing(simplified);
147
+ }
@@ -0,0 +1,5 @@
1
+ export * from './types';
2
+ export * from './footprint';
3
+ export * from './mapLayers';
4
+ export * from './mapThreeLayer';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export * from './types';
2
+ export * from './footprint';
3
+ export * from './mapLayers';
4
+ export * from './mapThreeLayer';
@@ -0,0 +1,8 @@
1
+ import type { Feature, Polygon } from 'geojson';
2
+ export type FootprintLayerController = {
3
+ setHover: (feature: Feature<Polygon> | null) => void;
4
+ setSelected: (feature: Feature<Polygon> | null) => void;
5
+ destroy: () => void;
6
+ };
7
+ export declare function ensureFootprintLayers(map: mapboxgl.Map): FootprintLayerController;
8
+ //# sourceMappingURL=mapLayers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mapLayers.d.ts","sourceRoot":"","sources":["../src/mapLayers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAKhD,MAAM,MAAM,wBAAwB,GAAG;IACrC,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,KAAK,IAAI,CAAC;IACrD,WAAW,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,KAAK,IAAI,CAAC;IACxD,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAiBF,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,QAAQ,CAAC,GAAG,GAAG,wBAAwB,CAkFjF"}
@@ -0,0 +1,95 @@
1
+ const EMPTY_FC = { type: 'FeatureCollection', features: [] };
2
+ function ensureCompositeSource(map) {
3
+ if (!map.getSource('composite')) {
4
+ map.addSource('composite', {
5
+ type: 'vector',
6
+ url: 'mapbox://mapbox.mapbox-streets-v8',
7
+ });
8
+ }
9
+ }
10
+ function ensureLayer(map, layer, beforeId) {
11
+ if (!map.getLayer(layer.id)) {
12
+ map.addLayer(layer, beforeId);
13
+ }
14
+ }
15
+ export function ensureFootprintLayers(map) {
16
+ ensureCompositeSource(map);
17
+ ensureLayer(map, {
18
+ id: 'building-footprints-fill',
19
+ type: 'fill',
20
+ source: 'composite',
21
+ 'source-layer': 'building',
22
+ paint: {
23
+ 'fill-color': '#000000',
24
+ 'fill-opacity': 0.01,
25
+ },
26
+ });
27
+ ensureLayer(map, {
28
+ id: 'building-footprints-outline',
29
+ type: 'line',
30
+ source: 'composite',
31
+ 'source-layer': 'building',
32
+ paint: {
33
+ 'line-color': '#ffffff',
34
+ 'line-width': 1,
35
+ 'line-opacity': 0.5,
36
+ },
37
+ });
38
+ if (!map.getSource('footprint-hover')) {
39
+ map.addSource('footprint-hover', {
40
+ type: 'geojson',
41
+ data: EMPTY_FC,
42
+ });
43
+ }
44
+ ensureLayer(map, {
45
+ id: 'footprint-hover-line',
46
+ type: 'line',
47
+ source: 'footprint-hover',
48
+ paint: {
49
+ 'line-color': '#f8d34a',
50
+ 'line-width': 2,
51
+ 'line-opacity': 0.9,
52
+ },
53
+ });
54
+ if (!map.getSource('footprint-selected')) {
55
+ map.addSource('footprint-selected', {
56
+ type: 'geojson',
57
+ data: EMPTY_FC,
58
+ });
59
+ }
60
+ ensureLayer(map, {
61
+ id: 'footprint-selected-line',
62
+ type: 'line',
63
+ source: 'footprint-selected',
64
+ paint: {
65
+ 'line-color': '#6ee7ff',
66
+ 'line-width': 3,
67
+ 'line-opacity': 1,
68
+ },
69
+ });
70
+ const setSource = (id, feature) => {
71
+ const src = map.getSource(id);
72
+ if (!src)
73
+ return;
74
+ if (!feature) {
75
+ src.setData(EMPTY_FC);
76
+ return;
77
+ }
78
+ src.setData({ type: 'FeatureCollection', features: [feature] });
79
+ };
80
+ return {
81
+ setHover: (feature) => setSource('footprint-hover', feature),
82
+ setSelected: (feature) => setSource('footprint-selected', feature),
83
+ destroy: () => {
84
+ const layers = ['footprint-selected-line', 'footprint-hover-line', 'building-footprints-outline', 'building-footprints-fill'];
85
+ layers.forEach((id) => {
86
+ if (map.getLayer(id))
87
+ map.removeLayer(id);
88
+ });
89
+ if (map.getSource('footprint-selected'))
90
+ map.removeSource('footprint-selected');
91
+ if (map.getSource('footprint-hover'))
92
+ map.removeSource('footprint-hover');
93
+ },
94
+ };
95
+ }
@@ -0,0 +1,18 @@
1
+ import * as THREE from 'three';
2
+ export type MapThreeLayer = {
3
+ layer: mapboxgl.CustomLayerInterface;
4
+ setGroup: (group: THREE.Group | null) => void;
5
+ setOrigin: (origin: {
6
+ lng: number;
7
+ lat: number;
8
+ } | null) => void;
9
+ setZOffsetMeters: (offset: number) => void;
10
+ dispose: () => void;
11
+ };
12
+ export type MapThreeLayerOptions = {
13
+ id: string;
14
+ zOffsetMeters?: number;
15
+ onInit?: (scene: THREE.Scene, renderer: THREE.WebGLRenderer, camera: THREE.Camera) => void;
16
+ };
17
+ export declare function createMapThreeLayer(options: MapThreeLayerOptions): MapThreeLayer;
18
+ //# sourceMappingURL=mapThreeLayer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mapThreeLayer.d.ts","sourceRoot":"","sources":["../src/mapThreeLayer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,EAAE,QAAQ,CAAC,oBAAoB,CAAC;IACrC,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,GAAG,IAAI,KAAK,IAAI,CAAC;IAC9C,SAAS,EAAE,CAAC,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,KAAK,IAAI,CAAC;IACjE,gBAAgB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,aAAa,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,KAAK,IAAI,CAAC;CAC5F,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa,CA0FhF"}
@@ -0,0 +1,87 @@
1
+ import mapboxgl from 'mapbox-gl';
2
+ import * as THREE from 'three';
3
+ export function createMapThreeLayer(options) {
4
+ const { id, zOffsetMeters = 0.02, onInit } = options;
5
+ let mapRef = null;
6
+ let scene = null;
7
+ let camera = null;
8
+ let renderer = null;
9
+ let rootGroup = null;
10
+ let meshGroup = null;
11
+ let mercatorOrigin = null;
12
+ let meterScale = 1;
13
+ let zOffset = zOffsetMeters;
14
+ const layer = {
15
+ id,
16
+ type: 'custom',
17
+ renderingMode: '3d',
18
+ onAdd: (map, gl) => {
19
+ mapRef = map;
20
+ scene = new THREE.Scene();
21
+ camera = new THREE.Camera();
22
+ renderer = new THREE.WebGLRenderer({
23
+ canvas: map.getCanvas(),
24
+ context: gl,
25
+ antialias: true,
26
+ });
27
+ renderer.autoClear = false;
28
+ renderer.outputColorSpace = THREE.SRGBColorSpace;
29
+ renderer.toneMapping = THREE.NeutralToneMapping;
30
+ renderer.toneMappingExposure = 1.05;
31
+ rootGroup = new THREE.Group();
32
+ rootGroup.matrixAutoUpdate = false;
33
+ scene.add(rootGroup);
34
+ if (meshGroup)
35
+ rootGroup.add(meshGroup);
36
+ if (onInit && renderer && camera)
37
+ onInit(scene, renderer, camera);
38
+ },
39
+ render: (_gl, matrix) => {
40
+ if (!renderer || !scene || !camera || !rootGroup)
41
+ return;
42
+ camera.projectionMatrix = new THREE.Matrix4().fromArray(matrix);
43
+ if (mercatorOrigin) {
44
+ const translate = new THREE.Matrix4().makeTranslation(mercatorOrigin.x, mercatorOrigin.y, (mercatorOrigin.z ?? 0) + zOffset * meterScale);
45
+ const scale = new THREE.Matrix4().makeScale(meterScale, -meterScale, meterScale);
46
+ rootGroup.matrix = new THREE.Matrix4().multiplyMatrices(translate, scale);
47
+ rootGroup.matrixWorldNeedsUpdate = true;
48
+ }
49
+ renderer.resetState();
50
+ renderer.render(scene, camera);
51
+ mapRef?.triggerRepaint();
52
+ },
53
+ };
54
+ return {
55
+ layer,
56
+ setGroup: (group) => {
57
+ meshGroup = group;
58
+ if (rootGroup) {
59
+ rootGroup.clear();
60
+ if (meshGroup)
61
+ rootGroup.add(meshGroup);
62
+ }
63
+ },
64
+ setOrigin: (origin) => {
65
+ if (!origin) {
66
+ mercatorOrigin = null;
67
+ return;
68
+ }
69
+ mercatorOrigin = mapboxgl.MercatorCoordinate.fromLngLat(origin);
70
+ meterScale = mercatorOrigin.meterInMercatorCoordinateUnits();
71
+ },
72
+ setZOffsetMeters: (offset) => {
73
+ zOffset = offset;
74
+ },
75
+ dispose: () => {
76
+ if (rootGroup) {
77
+ rootGroup.clear();
78
+ }
79
+ meshGroup = null;
80
+ scene = null;
81
+ camera = null;
82
+ renderer = null;
83
+ mapRef = null;
84
+ mercatorOrigin = null;
85
+ },
86
+ };
87
+ }
@@ -0,0 +1,26 @@
1
+ export type MapView = {
2
+ center: {
3
+ lng: number;
4
+ lat: number;
5
+ };
6
+ zoom: number;
7
+ bearing: number;
8
+ pitch: number;
9
+ };
10
+ export type MapFootprintSelection = {
11
+ geojson: string;
12
+ origin: {
13
+ lng: number;
14
+ lat: number;
15
+ };
16
+ mapView: MapView;
17
+ };
18
+ export type FootprintStats = {
19
+ vertexCount: number;
20
+ area: number;
21
+ perimeter: number;
22
+ minEdge: number;
23
+ maxEdge: number;
24
+ warnings: string[];
25
+ };
26
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,OAAO,GAAG;IACpB,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IACrC,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB,CAAC"}
package/dist/types.js ADDED
@@ -0,0 +1 @@
1
+ export {};
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "@treasuryspatial/map-kit",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "license": "UNLICENSED",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "default": "./dist/index.js"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist"
16
+ ],
17
+ "peerDependencies": {
18
+ "mapbox-gl": "^3.13.0",
19
+ "three": "^0.178.0"
20
+ },
21
+ "devDependencies": {
22
+ "mapbox-gl": "^3.13.0",
23
+ "three": "^0.178.0",
24
+ "@types/mapbox-gl": "^2.7.21",
25
+ "@types/geojson": "^7946.0.16"
26
+ },
27
+ "scripts": {
28
+ "build": "tsc -b",
29
+ "typecheck": "tsc -b --pretty false --noEmit"
30
+ }
31
+ }