@accelint/map-toolkit 0.4.1 → 0.6.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/CHANGELOG.md +30 -0
- package/README.md +3 -0
- package/catalog-info.yaml +6 -3
- package/dist/camera/events.d.ts +15 -0
- package/dist/camera/events.js +29 -0
- package/dist/camera/events.js.map +1 -0
- package/dist/camera/index.d.ts +16 -0
- package/dist/camera/index.js +17 -0
- package/dist/camera/types.d.ts +84 -0
- package/dist/{decorators/deckgl.d.ts → camera/types.js} +0 -7
- package/dist/camera/use-camera-state.d.ts +153 -0
- package/dist/camera/use-camera-state.js +418 -0
- package/dist/camera/use-camera-state.js.map +1 -0
- package/dist/cursor-coordinates/use-cursor-coordinates.js +1 -1
- package/dist/deckgl/base-map/constants.d.ts +14 -2
- package/dist/deckgl/base-map/constants.js +14 -2
- package/dist/deckgl/base-map/constants.js.map +1 -1
- package/dist/deckgl/base-map/controls.d.ts +34 -0
- package/dist/deckgl/base-map/controls.js +50 -0
- package/dist/deckgl/base-map/controls.js.map +1 -0
- package/dist/deckgl/base-map/events.d.ts +4 -0
- package/dist/deckgl/base-map/events.js +5 -1
- package/dist/deckgl/base-map/events.js.map +1 -1
- package/dist/deckgl/base-map/index.d.ts +10 -23
- package/dist/deckgl/base-map/index.js +81 -42
- package/dist/deckgl/base-map/index.js.map +1 -1
- package/dist/deckgl/base-map/types.d.ts +48 -2
- package/dist/deckgl/index.d.ts +11 -4
- package/dist/deckgl/index.js +7 -2
- package/dist/deckgl/saved-viewports/index.d.ts +32 -0
- package/dist/deckgl/saved-viewports/index.js +51 -0
- package/dist/deckgl/saved-viewports/index.js.map +1 -0
- package/dist/deckgl/saved-viewports/storage.d.ts +21 -0
- package/dist/deckgl/saved-viewports/storage.js +39 -0
- package/dist/deckgl/saved-viewports/storage.js.map +1 -0
- package/dist/deckgl/shapes/display-shape-layer/constants.d.ts +44 -0
- package/dist/deckgl/shapes/display-shape-layer/constants.js +61 -0
- package/dist/deckgl/shapes/display-shape-layer/constants.js.map +1 -0
- package/dist/deckgl/shapes/display-shape-layer/fiber.d.ts +25 -0
- package/dist/deckgl/shapes/display-shape-layer/fiber.js +21 -0
- package/dist/deckgl/shapes/display-shape-layer/fiber.js.map +1 -0
- package/dist/deckgl/shapes/display-shape-layer/index.d.ts +206 -0
- package/dist/deckgl/shapes/display-shape-layer/index.js +416 -0
- package/dist/deckgl/shapes/display-shape-layer/index.js.map +1 -0
- package/dist/deckgl/shapes/display-shape-layer/shape-label-layer.d.ts +66 -0
- package/dist/deckgl/shapes/display-shape-layer/shape-label-layer.js +116 -0
- package/dist/deckgl/shapes/display-shape-layer/shape-label-layer.js.map +1 -0
- package/dist/deckgl/shapes/display-shape-layer/store.d.ts +87 -0
- package/dist/deckgl/shapes/display-shape-layer/store.js +316 -0
- package/dist/deckgl/shapes/display-shape-layer/store.js.map +1 -0
- package/dist/deckgl/shapes/display-shape-layer/types.d.ts +115 -0
- package/dist/deckgl/shapes/display-shape-layer/types.js +12 -0
- package/dist/deckgl/shapes/display-shape-layer/use-shape-selection.d.ts +89 -0
- package/dist/deckgl/shapes/display-shape-layer/use-shape-selection.js +88 -0
- package/dist/deckgl/shapes/display-shape-layer/use-shape-selection.js.map +1 -0
- package/dist/deckgl/shapes/display-shape-layer/utils/display-style.d.ts +61 -0
- package/dist/deckgl/shapes/display-shape-layer/utils/display-style.js +111 -0
- package/dist/deckgl/shapes/display-shape-layer/utils/display-style.js.map +1 -0
- package/dist/deckgl/shapes/display-shape-layer/utils/labels.d.ts +196 -0
- package/dist/deckgl/shapes/display-shape-layer/utils/labels.js +368 -0
- package/dist/deckgl/shapes/display-shape-layer/utils/labels.js.map +1 -0
- package/dist/deckgl/shapes/index.d.ts +20 -0
- package/dist/deckgl/shapes/index.js +20 -0
- package/dist/deckgl/shapes/shared/constants.d.ts +78 -0
- package/dist/deckgl/shapes/shared/constants.js +109 -0
- package/dist/deckgl/shapes/shared/constants.js.map +1 -0
- package/dist/deckgl/shapes/shared/events.d.ts +73 -0
- package/dist/deckgl/shapes/shared/events.js +58 -0
- package/dist/deckgl/shapes/shared/events.js.map +1 -0
- package/dist/deckgl/shapes/shared/types.d.ts +158 -0
- package/dist/{decorators/deckgl.js → deckgl/shapes/shared/types.js} +12 -15
- package/dist/deckgl/shapes/shared/types.js.map +1 -0
- package/dist/deckgl/symbol-layer/index.d.ts +1 -1
- package/dist/maplibre/hooks/use-maplibre.d.ts +2 -2
- package/dist/maplibre/hooks/use-maplibre.js +2 -2
- package/dist/maplibre/hooks/use-maplibre.js.map +1 -1
- package/dist/viewport/viewport-size.d.ts +2 -2
- package/package.json +50 -23
- package/dist/decorators/deckgl.js.map +0 -1
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
|
|
3
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
* of the License at https://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
*
|
|
7
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
* governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
'use client';
|
|
15
|
+
|
|
16
|
+
import { getOrCreateClearSelection, getOrCreateServerSnapshot, getOrCreateSetSelectedId, getOrCreateSnapshot, getOrCreateSubscription } from "./store.js";
|
|
17
|
+
import { useSyncExternalStore } from "react";
|
|
18
|
+
|
|
19
|
+
//#region src/deckgl/shapes/display-shape-layer/use-shape-selection.ts
|
|
20
|
+
/**
|
|
21
|
+
* Hook to manage shape selection state with automatic deselection
|
|
22
|
+
*
|
|
23
|
+
* This hook encapsulates the common pattern of:
|
|
24
|
+
* 1. Listening to `shapes:selected` events and updating state
|
|
25
|
+
* 2. Listening to `shapes:deselected` events and clearing state
|
|
26
|
+
* 3. Listening to map clicks on empty space and emitting `shapes:deselected`
|
|
27
|
+
*
|
|
28
|
+
* Uses a store pattern with `useSyncExternalStore` for proper listener cleanup
|
|
29
|
+
* during HMR (Hot Module Replacement) in development. The store ensures only
|
|
30
|
+
* one bus listener exists per map instance, regardless of how many React
|
|
31
|
+
* components subscribe.
|
|
32
|
+
*
|
|
33
|
+
* @param mapId - The map instance ID for event filtering
|
|
34
|
+
* @returns Selection state and control functions
|
|
35
|
+
*
|
|
36
|
+
* @example Basic usage
|
|
37
|
+
* ```tsx
|
|
38
|
+
* import { useShapeSelection } from '@accelint/map-toolkit/deckgl/shapes';
|
|
39
|
+
*
|
|
40
|
+
* function MapWithShapes() {
|
|
41
|
+
* const { selectedId } = useShapeSelection(MAP_ID);
|
|
42
|
+
*
|
|
43
|
+
* return (
|
|
44
|
+
* <BaseMap id={MAP_ID}>
|
|
45
|
+
* <displayShapeLayer
|
|
46
|
+
* id="shapes"
|
|
47
|
+
* mapId={MAP_ID}
|
|
48
|
+
* data={shapes}
|
|
49
|
+
* selectedShapeId={selectedId}
|
|
50
|
+
* />
|
|
51
|
+
* </BaseMap>
|
|
52
|
+
* );
|
|
53
|
+
* }
|
|
54
|
+
* ```
|
|
55
|
+
*
|
|
56
|
+
* @example With programmatic selection control
|
|
57
|
+
* ```tsx
|
|
58
|
+
* function MapWithShapes() {
|
|
59
|
+
* const { selectedId, setSelectedId, clearSelection } = useShapeSelection(MAP_ID);
|
|
60
|
+
*
|
|
61
|
+
* return (
|
|
62
|
+
* <>
|
|
63
|
+
* <button onClick={() => setSelectedId(shapes[0].id)}>Select First Shape</button>
|
|
64
|
+
* <button onClick={clearSelection}>Clear Selection</button>
|
|
65
|
+
* <BaseMap id={MAP_ID}>
|
|
66
|
+
* <displayShapeLayer
|
|
67
|
+
* id="shapes"
|
|
68
|
+
* mapId={MAP_ID}
|
|
69
|
+
* data={shapes}
|
|
70
|
+
* selectedShapeId={selectedId}
|
|
71
|
+
* />
|
|
72
|
+
* </BaseMap>
|
|
73
|
+
* </>
|
|
74
|
+
* );
|
|
75
|
+
* }
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
78
|
+
function useShapeSelection(mapId) {
|
|
79
|
+
return {
|
|
80
|
+
selectedId: useSyncExternalStore(getOrCreateSubscription(mapId), getOrCreateSnapshot(mapId), getOrCreateServerSnapshot(mapId)),
|
|
81
|
+
setSelectedId: getOrCreateSetSelectedId(mapId),
|
|
82
|
+
clearSelection: getOrCreateClearSelection(mapId)
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
//#endregion
|
|
87
|
+
export { useShapeSelection };
|
|
88
|
+
//# sourceMappingURL=use-shape-selection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-shape-selection.js","names":[],"sources":["../../../../src/deckgl/shapes/display-shape-layer/use-shape-selection.ts"],"sourcesContent":["/*\n * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\n'use client';\n\nimport { useSyncExternalStore } from 'react';\nimport {\n getOrCreateClearSelection,\n getOrCreateServerSnapshot,\n getOrCreateSetSelectedId,\n getOrCreateSnapshot,\n getOrCreateSubscription,\n} from './store';\nimport type { UniqueId } from '@accelint/core';\nimport type { ShapeId } from '../shared/types';\n\n/**\n * Return type for useShapeSelection hook\n */\nexport interface UseShapeSelectionReturn {\n /** Currently selected shape ID, or undefined if nothing selected */\n selectedId: ShapeId | undefined;\n /** Manually set the selected shape ID (useful for programmatic selection) */\n setSelectedId: (id: ShapeId | undefined) => void;\n /** Manually clear the selection */\n clearSelection: () => void;\n}\n\n/**\n * Hook to manage shape selection state with automatic deselection\n *\n * This hook encapsulates the common pattern of:\n * 1. Listening to `shapes:selected` events and updating state\n * 2. Listening to `shapes:deselected` events and clearing state\n * 3. Listening to map clicks on empty space and emitting `shapes:deselected`\n *\n * Uses a store pattern with `useSyncExternalStore` for proper listener cleanup\n * during HMR (Hot Module Replacement) in development. The store ensures only\n * one bus listener exists per map instance, regardless of how many React\n * components subscribe.\n *\n * @param mapId - The map instance ID for event filtering\n * @returns Selection state and control functions\n *\n * @example Basic usage\n * ```tsx\n * import { useShapeSelection } from '@accelint/map-toolkit/deckgl/shapes';\n *\n * function MapWithShapes() {\n * const { selectedId } = useShapeSelection(MAP_ID);\n *\n * return (\n * <BaseMap id={MAP_ID}>\n * <displayShapeLayer\n * id=\"shapes\"\n * mapId={MAP_ID}\n * data={shapes}\n * selectedShapeId={selectedId}\n * />\n * </BaseMap>\n * );\n * }\n * ```\n *\n * @example With programmatic selection control\n * ```tsx\n * function MapWithShapes() {\n * const { selectedId, setSelectedId, clearSelection } = useShapeSelection(MAP_ID);\n *\n * return (\n * <>\n * <button onClick={() => setSelectedId(shapes[0].id)}>Select First Shape</button>\n * <button onClick={clearSelection}>Clear Selection</button>\n * <BaseMap id={MAP_ID}>\n * <displayShapeLayer\n * id=\"shapes\"\n * mapId={MAP_ID}\n * data={shapes}\n * selectedShapeId={selectedId}\n * />\n * </BaseMap>\n * </>\n * );\n * }\n * ```\n */\nexport function useShapeSelection(mapId: UniqueId): UseShapeSelectionReturn {\n // Get cached functions for this mapId (maintains referential stability)\n const subscribe = getOrCreateSubscription(mapId);\n const getSnapshot = getOrCreateSnapshot(mapId);\n const getServerSnapshot = getOrCreateServerSnapshot(mapId);\n\n // Subscribe to store changes using React's built-in external store hook\n const selectedId = useSyncExternalStore(\n subscribe,\n getSnapshot,\n getServerSnapshot,\n );\n\n // Get cached action functions (maintains referential stability)\n const setSelectedId = getOrCreateSetSelectedId(mapId);\n const clearSelection = getOrCreateClearSelection(mapId);\n\n return {\n selectedId,\n setSelectedId,\n clearSelection,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+FA,SAAgB,kBAAkB,OAA0C;AAiB1E,QAAO;EACL,YAXiB,qBALD,wBAAwB,MAAM,EAC5B,oBAAoB,MAAM,EACpB,0BAA0B,MAAM,CAOzD;EAQC,eALoB,yBAAyB,MAAM;EAMnD,gBALqB,0BAA0B,MAAM;EAMtD"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
|
|
3
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
* of the License at https://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
*
|
|
7
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
* governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { StyledFeature } from "../../shared/types.js";
|
|
14
|
+
import { Color } from "@deck.gl/core";
|
|
15
|
+
|
|
16
|
+
//#region src/deckgl/shapes/display-shape-layer/utils/display-style.d.ts
|
|
17
|
+
/**
|
|
18
|
+
* Get fill color for a feature
|
|
19
|
+
* Colors are passed through as-is unless applyBaseOpacity is true
|
|
20
|
+
*
|
|
21
|
+
* @param feature - The styled feature
|
|
22
|
+
* @param applyBaseOpacity - When true, multiplies alpha by BASE_FILL_OPACITY (0.6)
|
|
23
|
+
* @returns RGBA color array
|
|
24
|
+
*/
|
|
25
|
+
declare function getFillColor(feature: StyledFeature, applyBaseOpacity?: boolean): Color;
|
|
26
|
+
/**
|
|
27
|
+
* Get stroke color for a feature
|
|
28
|
+
* Strokes are always rendered at their literal alpha value
|
|
29
|
+
*
|
|
30
|
+
* @param feature - The styled feature
|
|
31
|
+
* @returns RGBA color array
|
|
32
|
+
*/
|
|
33
|
+
declare function getStrokeColor(feature: StyledFeature): Color;
|
|
34
|
+
/**
|
|
35
|
+
* Get line width for a feature
|
|
36
|
+
*/
|
|
37
|
+
declare function getLineWidth(feature: StyledFeature): number;
|
|
38
|
+
/**
|
|
39
|
+
* Alias for getLineWidth (for compatibility)
|
|
40
|
+
*/
|
|
41
|
+
declare const getStrokeWidth: typeof getLineWidth;
|
|
42
|
+
/**
|
|
43
|
+
* Get dash array for stroke pattern
|
|
44
|
+
*/
|
|
45
|
+
declare function getDashArray(feature: StyledFeature): [number, number] | null;
|
|
46
|
+
/**
|
|
47
|
+
* Get hover-enhanced line width
|
|
48
|
+
*/
|
|
49
|
+
declare function getHoverLineWidth(feature: StyledFeature, isHovered: boolean): number;
|
|
50
|
+
/**
|
|
51
|
+
* Get selection highlight color
|
|
52
|
+
* Returns the default highlight color or allows custom opacity override
|
|
53
|
+
*/
|
|
54
|
+
declare function getHighlightColor(opacity?: number): [number, number, number, number];
|
|
55
|
+
/**
|
|
56
|
+
* Get highlight line width (base width + increase)
|
|
57
|
+
*/
|
|
58
|
+
declare function getHighlightLineWidth(feature: StyledFeature): number;
|
|
59
|
+
//#endregion
|
|
60
|
+
export { getDashArray, getFillColor, getHighlightColor, getHighlightLineWidth, getHoverLineWidth, getLineWidth, getStrokeColor, getStrokeWidth };
|
|
61
|
+
//# sourceMappingURL=display-style.d.ts.map
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
|
|
3
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
* of the License at https://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
*
|
|
7
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
* governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
'use client';
|
|
15
|
+
|
|
16
|
+
import { BASE_FILL_OPACITY, DASH_ARRAYS, DEFAULT_COLORS, DEFAULT_STROKE_WIDTH, HIGHLIGHT_WIDTH_INCREASE, HOVER_WIDTH_INCREASE } from "../../shared/constants.js";
|
|
17
|
+
|
|
18
|
+
//#region src/deckgl/shapes/display-shape-layer/utils/display-style.ts
|
|
19
|
+
/**
|
|
20
|
+
* Get fill color for a feature
|
|
21
|
+
* Colors are passed through as-is unless applyBaseOpacity is true
|
|
22
|
+
*
|
|
23
|
+
* @param feature - The styled feature
|
|
24
|
+
* @param applyBaseOpacity - When true, multiplies alpha by BASE_FILL_OPACITY (0.6)
|
|
25
|
+
* @returns RGBA color array
|
|
26
|
+
*/
|
|
27
|
+
function getFillColor(feature, applyBaseOpacity = false) {
|
|
28
|
+
const rgba = normalizeColor((feature.properties?.styleProperties)?.fillColor ?? DEFAULT_COLORS.fill);
|
|
29
|
+
if (applyBaseOpacity) return [
|
|
30
|
+
rgba[0],
|
|
31
|
+
rgba[1],
|
|
32
|
+
rgba[2],
|
|
33
|
+
Math.round(rgba[3] * BASE_FILL_OPACITY)
|
|
34
|
+
];
|
|
35
|
+
return rgba;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Get stroke color for a feature
|
|
39
|
+
* Strokes are always rendered at their literal alpha value
|
|
40
|
+
*
|
|
41
|
+
* @param feature - The styled feature
|
|
42
|
+
* @returns RGBA color array
|
|
43
|
+
*/
|
|
44
|
+
function getStrokeColor(feature) {
|
|
45
|
+
return normalizeColor((feature.properties?.styleProperties)?.strokeColor ?? DEFAULT_COLORS.stroke);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Normalize a Color to a 4-element RGBA array
|
|
49
|
+
* Handles RGB arrays (adds alpha 255), RGBA arrays, and typed arrays
|
|
50
|
+
*/
|
|
51
|
+
function normalizeColor(color) {
|
|
52
|
+
if (color instanceof Uint8Array || color instanceof Uint8ClampedArray) return [
|
|
53
|
+
color[0] ?? 0,
|
|
54
|
+
color[1] ?? 0,
|
|
55
|
+
color[2] ?? 0,
|
|
56
|
+
color[3] ?? 255
|
|
57
|
+
];
|
|
58
|
+
return [
|
|
59
|
+
color[0],
|
|
60
|
+
color[1],
|
|
61
|
+
color[2],
|
|
62
|
+
color[3] ?? 255
|
|
63
|
+
];
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Get line width for a feature
|
|
67
|
+
*/
|
|
68
|
+
function getLineWidth(feature) {
|
|
69
|
+
return (feature.properties?.styleProperties)?.strokeWidth ?? DEFAULT_STROKE_WIDTH;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Alias for getLineWidth (for compatibility)
|
|
73
|
+
*/
|
|
74
|
+
const getStrokeWidth = getLineWidth;
|
|
75
|
+
/**
|
|
76
|
+
* Get dash array for stroke pattern
|
|
77
|
+
*/
|
|
78
|
+
function getDashArray(feature) {
|
|
79
|
+
return DASH_ARRAYS[(feature.properties?.styleProperties)?.strokePattern ?? "solid"] || null;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Get hover-enhanced line width
|
|
83
|
+
*/
|
|
84
|
+
function getHoverLineWidth(feature, isHovered) {
|
|
85
|
+
const baseWidth = getLineWidth(feature);
|
|
86
|
+
return isHovered ? baseWidth + HOVER_WIDTH_INCREASE : baseWidth;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Get selection highlight color
|
|
90
|
+
* Returns the default highlight color or allows custom opacity override
|
|
91
|
+
*/
|
|
92
|
+
function getHighlightColor(opacity) {
|
|
93
|
+
const rgba = normalizeColor(DEFAULT_COLORS.highlight);
|
|
94
|
+
if (opacity !== void 0) return [
|
|
95
|
+
rgba[0],
|
|
96
|
+
rgba[1],
|
|
97
|
+
rgba[2],
|
|
98
|
+
Math.round(opacity * 255)
|
|
99
|
+
];
|
|
100
|
+
return rgba;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Get highlight line width (base width + increase)
|
|
104
|
+
*/
|
|
105
|
+
function getHighlightLineWidth(feature) {
|
|
106
|
+
return getLineWidth(feature) + HIGHLIGHT_WIDTH_INCREASE;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
//#endregion
|
|
110
|
+
export { getDashArray, getFillColor, getHighlightColor, getHighlightLineWidth, getHoverLineWidth, getLineWidth, getStrokeColor, getStrokeWidth };
|
|
111
|
+
//# sourceMappingURL=display-style.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"display-style.js","names":[],"sources":["../../../../../src/deckgl/shapes/display-shape-layer/utils/display-style.ts"],"sourcesContent":["/*\n * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\n'use client';\n\nimport {\n BASE_FILL_OPACITY,\n DASH_ARRAYS,\n DEFAULT_COLORS,\n DEFAULT_STROKE_WIDTH,\n HIGHLIGHT_WIDTH_INCREASE,\n HOVER_WIDTH_INCREASE,\n} from '../../shared/constants';\nimport type { Color } from '@deck.gl/core';\nimport type { StyledFeature } from '../../shared/types';\n\n/**\n * Get fill color for a feature\n * Colors are passed through as-is unless applyBaseOpacity is true\n *\n * @param feature - The styled feature\n * @param applyBaseOpacity - When true, multiplies alpha by BASE_FILL_OPACITY (0.6)\n * @returns RGBA color array\n */\nexport function getFillColor(\n feature: StyledFeature,\n applyBaseOpacity = false,\n): Color {\n const styleProps = feature.properties?.styleProperties;\n const color = styleProps?.fillColor ?? DEFAULT_COLORS.fill;\n\n // Normalize to 4-element array\n const rgba = normalizeColor(color);\n\n if (applyBaseOpacity) {\n // Apply base opacity multiplier to alpha channel\n return [rgba[0], rgba[1], rgba[2], Math.round(rgba[3] * BASE_FILL_OPACITY)];\n }\n\n return rgba;\n}\n\n/**\n * Get stroke color for a feature\n * Strokes are always rendered at their literal alpha value\n *\n * @param feature - The styled feature\n * @returns RGBA color array\n */\nexport function getStrokeColor(feature: StyledFeature): Color {\n const styleProps = feature.properties?.styleProperties;\n const color = styleProps?.strokeColor ?? DEFAULT_COLORS.stroke;\n\n return normalizeColor(color);\n}\n\n/**\n * Normalize a Color to a 4-element RGBA array\n * Handles RGB arrays (adds alpha 255), RGBA arrays, and typed arrays\n */\nfunction normalizeColor(color: Color): [number, number, number, number] {\n if (color instanceof Uint8Array || color instanceof Uint8ClampedArray) {\n return [color[0] ?? 0, color[1] ?? 0, color[2] ?? 0, color[3] ?? 255];\n }\n\n // Handle RGB (3-element) or RGBA (4-element) arrays\n return [color[0], color[1], color[2], color[3] ?? 255];\n}\n\n/**\n * Get line width for a feature\n */\nexport function getLineWidth(feature: StyledFeature): number {\n const styleProps = feature.properties?.styleProperties;\n return styleProps?.strokeWidth ?? DEFAULT_STROKE_WIDTH;\n}\n\n/**\n * Alias for getLineWidth (for compatibility)\n */\nexport const getStrokeWidth = getLineWidth;\n\n/**\n * Get dash array for stroke pattern\n */\nexport function getDashArray(feature: StyledFeature): [number, number] | null {\n const styleProps = feature.properties?.styleProperties;\n const pattern = styleProps?.strokePattern ?? 'solid';\n\n return DASH_ARRAYS[pattern] || null;\n}\n\n/**\n * Get hover-enhanced line width\n */\nexport function getHoverLineWidth(\n feature: StyledFeature,\n isHovered: boolean,\n): number {\n const baseWidth = getLineWidth(feature);\n return isHovered ? baseWidth + HOVER_WIDTH_INCREASE : baseWidth;\n}\n\n/**\n * Get selection highlight color\n * Returns the default highlight color or allows custom opacity override\n */\nexport function getHighlightColor(\n opacity?: number,\n): [number, number, number, number] {\n const rgba = normalizeColor(DEFAULT_COLORS.highlight);\n\n if (opacity !== undefined) {\n return [rgba[0], rgba[1], rgba[2], Math.round(opacity * 255)];\n }\n\n return rgba;\n}\n\n/**\n * Get highlight line width (base width + increase)\n */\nexport function getHighlightLineWidth(feature: StyledFeature): number {\n const baseWidth = getLineWidth(feature);\n return baseWidth + HIGHLIGHT_WIDTH_INCREASE;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAiCA,SAAgB,aACd,SACA,mBAAmB,OACZ;CAKP,MAAM,OAAO,gBAJM,QAAQ,YAAY,kBACb,aAAa,eAAe,KAGpB;AAElC,KAAI,iBAEF,QAAO;EAAC,KAAK;EAAI,KAAK;EAAI,KAAK;EAAI,KAAK,MAAM,KAAK,KAAK,kBAAkB;EAAC;AAG7E,QAAO;;;;;;;;;AAUT,SAAgB,eAAe,SAA+B;AAI5D,QAAO,gBAHY,QAAQ,YAAY,kBACb,eAAe,eAAe,OAE5B;;;;;;AAO9B,SAAS,eAAe,OAAgD;AACtE,KAAI,iBAAiB,cAAc,iBAAiB,kBAClD,QAAO;EAAC,MAAM,MAAM;EAAG,MAAM,MAAM;EAAG,MAAM,MAAM;EAAG,MAAM,MAAM;EAAI;AAIvE,QAAO;EAAC,MAAM;EAAI,MAAM;EAAI,MAAM;EAAI,MAAM,MAAM;EAAI;;;;;AAMxD,SAAgB,aAAa,SAAgC;AAE3D,SADmB,QAAQ,YAAY,kBACpB,eAAe;;;;;AAMpC,MAAa,iBAAiB;;;;AAK9B,SAAgB,aAAa,SAAiD;AAI5E,QAAO,aAHY,QAAQ,YAAY,kBACX,iBAAiB,YAEd;;;;;AAMjC,SAAgB,kBACd,SACA,WACQ;CACR,MAAM,YAAY,aAAa,QAAQ;AACvC,QAAO,YAAY,YAAY,uBAAuB;;;;;;AAOxD,SAAgB,kBACd,SACkC;CAClC,MAAM,OAAO,eAAe,eAAe,UAAU;AAErD,KAAI,YAAY,OACd,QAAO;EAAC,KAAK;EAAI,KAAK;EAAI,KAAK;EAAI,KAAK,MAAM,UAAU,IAAI;EAAC;AAG/D,QAAO;;;;;AAMT,SAAgB,sBAAsB,SAAgC;AAEpE,QADkB,aAAa,QAAQ,GACpB"}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
|
|
3
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
* of the License at https://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
*
|
|
7
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
* governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { EditableShape } from "../../shared/types.js";
|
|
14
|
+
|
|
15
|
+
//#region src/deckgl/shapes/display-shape-layer/utils/labels.d.ts
|
|
16
|
+
/**
|
|
17
|
+
* Label positioning information including coordinates and screen-space offsets
|
|
18
|
+
*/
|
|
19
|
+
interface LabelPosition2d {
|
|
20
|
+
/** Geographic coordinates [longitude, latitude] */
|
|
21
|
+
coordinates: [number, number];
|
|
22
|
+
/** Horizontal text anchor point */
|
|
23
|
+
textAnchor: 'start' | 'middle' | 'end';
|
|
24
|
+
/** Vertical text alignment */
|
|
25
|
+
alignmentBaseline: 'top' | 'center' | 'bottom';
|
|
26
|
+
/** Pixel offset from coordinates [x, y] */
|
|
27
|
+
pixelOffset: [number, number];
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Calculate a point along a line segment
|
|
31
|
+
* @param start - Start coordinate [lon, lat]
|
|
32
|
+
* @param end - End coordinate [lon, lat]
|
|
33
|
+
* @param ratio - Position along segment (0 = start, 0.5 = middle, 1 = end)
|
|
34
|
+
* @returns Interpolated coordinate [lon, lat]
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* // Get a point 25% along a line segment
|
|
38
|
+
* const start: [number, number] = [-122.4, 37.8];
|
|
39
|
+
* const end: [number, number] = [-122.3, 37.9];
|
|
40
|
+
* const point = interpolatePoint(start, end, 0.25);
|
|
41
|
+
*/
|
|
42
|
+
declare function interpolatePoint(start: [number, number], end: [number, number], ratio: number): [number, number];
|
|
43
|
+
/**
|
|
44
|
+
* Get the midpoint of a LineString
|
|
45
|
+
* @param coordinates - LineString coordinates array
|
|
46
|
+
* @returns Midpoint coordinate [lon, lat]
|
|
47
|
+
*/
|
|
48
|
+
declare function getLineStringMidpoint(coordinates: [number, number][]): [number, number];
|
|
49
|
+
/**
|
|
50
|
+
* Get the end point of a LineString
|
|
51
|
+
* @param coordinates - LineString coordinates array
|
|
52
|
+
* @returns End coordinate [lon, lat]
|
|
53
|
+
*/
|
|
54
|
+
declare function getLineStringEndpoint(coordinates: [number, number][]): [number, number];
|
|
55
|
+
/**
|
|
56
|
+
* Get the midpoint of a Polygon's outer ring
|
|
57
|
+
* @param coordinates - Polygon coordinates array (rings)
|
|
58
|
+
* @returns Midpoint of outer ring [lon, lat]
|
|
59
|
+
*/
|
|
60
|
+
declare function getPolygonMidpoint(coordinates: [number, number][][]): [number, number];
|
|
61
|
+
/**
|
|
62
|
+
* Vertical label position relative to anchor point
|
|
63
|
+
*/
|
|
64
|
+
type LabelVerticalPosition = 'top' | 'middle' | 'bottom';
|
|
65
|
+
/**
|
|
66
|
+
* Horizontal label position relative to anchor point
|
|
67
|
+
*/
|
|
68
|
+
type LabelHorizontalPosition = 'left' | 'center' | 'right';
|
|
69
|
+
/**
|
|
70
|
+
* Cardinal direction anchor for positioning labels on geometry edges
|
|
71
|
+
* Uses edge positions relative to the geometry's bounding box
|
|
72
|
+
* Works for LineString, Polygon, and Circle geometries
|
|
73
|
+
* - 'center': centroid/midpoint of the geometry
|
|
74
|
+
* - 'top'/'right'/'bottom'/'left': edge positions
|
|
75
|
+
*/
|
|
76
|
+
type CardinalLabelCoordinateAnchor = 'center' | 'top' | 'right' | 'bottom' | 'left';
|
|
77
|
+
/**
|
|
78
|
+
* Global label positioning options for DisplayShapeLayer
|
|
79
|
+
*
|
|
80
|
+
* ## Priority System
|
|
81
|
+
* Label positioning follows a three-tier priority system:
|
|
82
|
+
* 1. **Per-shape properties** in `styleProperties` (highest priority)
|
|
83
|
+
* 2. **Global options** via this interface
|
|
84
|
+
* 3. **Default values** (geometry-specific fallbacks)
|
|
85
|
+
*
|
|
86
|
+
* ## Label Appearance
|
|
87
|
+
*
|
|
88
|
+
* Labels use a clean text-only style:
|
|
89
|
+
* - **Text**: White uppercase, bold Roboto Mono, 10px
|
|
90
|
+
* - **Outline**: Black 2px outline for contrast
|
|
91
|
+
* - **No background or border**
|
|
92
|
+
*
|
|
93
|
+
* Text height ≈ 10px
|
|
94
|
+
*
|
|
95
|
+
* ## Positioning Concepts
|
|
96
|
+
*
|
|
97
|
+
* ### Coordinate Anchor
|
|
98
|
+
* Determines *where* on the geometry to place the label:
|
|
99
|
+
* - **Point**: Label is always at the point coordinate
|
|
100
|
+
* - **LineString/Polygon**: 'start', 'middle', or 'end' along the geometry
|
|
101
|
+
* - **Circle**: 'top', 'right', 'bottom', or 'left' on the perimeter
|
|
102
|
+
*
|
|
103
|
+
* ### Vertical/Horizontal Anchor
|
|
104
|
+
* Determines how the label aligns *relative to* the anchor point:
|
|
105
|
+
* - **Vertical**: 'top' (label text below point), 'middle' (centered), 'bottom' (label text above point)
|
|
106
|
+
* - **Horizontal**: 'left' (label text right of point), 'center' (centered), 'right' (label text left of point)
|
|
107
|
+
*
|
|
108
|
+
* ### Pixel Offset
|
|
109
|
+
* Fine-tune label position with [x, y] pixel offsets:
|
|
110
|
+
* - Positive x moves right, negative moves left
|
|
111
|
+
* - Positive y moves down, negative moves up
|
|
112
|
+
*
|
|
113
|
+
* @example Position circle labels at the top with 5px clearance
|
|
114
|
+
* ```tsx
|
|
115
|
+
* const labelOptions: LabelPositionOptions = {
|
|
116
|
+
* circleLabelCoordinateAnchor: 'top',
|
|
117
|
+
* circleLabelVerticalAnchor: 'bottom', // Label above the top point
|
|
118
|
+
* circleLabelOffset: [0, -15], // -(10px text height + 5px clearance)
|
|
119
|
+
* };
|
|
120
|
+
* ```
|
|
121
|
+
*
|
|
122
|
+
* @example Position line labels at middle with offset to the right
|
|
123
|
+
* ```tsx
|
|
124
|
+
* const labelOptions: LabelPositionOptions = {
|
|
125
|
+
* lineStringLabelCoordinateAnchor: 'middle',
|
|
126
|
+
* lineStringLabelHorizontalAnchor: 'left',
|
|
127
|
+
* lineStringLabelOffset: [10, 0], // 10px to the right
|
|
128
|
+
* };
|
|
129
|
+
* ```
|
|
130
|
+
*/
|
|
131
|
+
interface LabelPositionOptions {
|
|
132
|
+
/** Vertical anchor for Point labels @default 'top' */
|
|
133
|
+
pointLabelVerticalAnchor?: LabelVerticalPosition;
|
|
134
|
+
/** Horizontal anchor for Point labels @default 'center' */
|
|
135
|
+
pointLabelHorizontalAnchor?: LabelHorizontalPosition;
|
|
136
|
+
/** Pixel offset for Point labels [x, y] @default [0, 10] */
|
|
137
|
+
pointLabelOffset?: [number, number];
|
|
138
|
+
/** Position on LineString edge (top/right/bottom/left) @default 'bottom' */
|
|
139
|
+
lineStringLabelCoordinateAnchor?: CardinalLabelCoordinateAnchor;
|
|
140
|
+
/** Vertical anchor for LineString labels @default 'top' */
|
|
141
|
+
lineStringLabelVerticalAnchor?: LabelVerticalPosition;
|
|
142
|
+
/** Horizontal anchor for LineString labels @default 'center' */
|
|
143
|
+
lineStringLabelHorizontalAnchor?: LabelHorizontalPosition;
|
|
144
|
+
/** Pixel offset for LineString labels [x, y] @default [0, 10] */
|
|
145
|
+
lineStringLabelOffset?: [number, number];
|
|
146
|
+
/** Position on Polygon edge (top/right/bottom/left) @default 'bottom' */
|
|
147
|
+
polygonLabelCoordinateAnchor?: CardinalLabelCoordinateAnchor;
|
|
148
|
+
/** Vertical anchor for Polygon labels @default 'top' */
|
|
149
|
+
polygonLabelVerticalAnchor?: LabelVerticalPosition;
|
|
150
|
+
/** Horizontal anchor for Polygon labels @default 'center' */
|
|
151
|
+
polygonLabelHorizontalAnchor?: LabelHorizontalPosition;
|
|
152
|
+
/** Pixel offset for Polygon labels [x, y] @default [0, 10] */
|
|
153
|
+
polygonLabelOffset?: [number, number];
|
|
154
|
+
/** Position on Circle perimeter (top/right/bottom/left) @default 'bottom' */
|
|
155
|
+
circleLabelCoordinateAnchor?: CardinalLabelCoordinateAnchor;
|
|
156
|
+
/** Vertical anchor for Circle labels @default 'top' */
|
|
157
|
+
circleLabelVerticalAnchor?: LabelVerticalPosition;
|
|
158
|
+
/** Horizontal anchor for Circle labels @default 'center' */
|
|
159
|
+
circleLabelHorizontalAnchor?: LabelHorizontalPosition;
|
|
160
|
+
/** Pixel offset for Circle labels [x, y] @default [0, 10] */
|
|
161
|
+
circleLabelOffset?: [number, number];
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Get 2D position for label based on geometry type
|
|
165
|
+
* Uses pixel-based offsets for consistent positioning at all zoom levels
|
|
166
|
+
*
|
|
167
|
+
* Priority for positioning:
|
|
168
|
+
* 1. Per-shape properties in styleProperties (highest)
|
|
169
|
+
* 2. Global labelOptions from layer props
|
|
170
|
+
* 3. Default values (fallback)
|
|
171
|
+
*
|
|
172
|
+
* Returns null if no valid coordinates can be determined
|
|
173
|
+
*/
|
|
174
|
+
declare function getLabelPosition2d(shape: EditableShape, options?: LabelPositionOptions): LabelPosition2d | null;
|
|
175
|
+
/**
|
|
176
|
+
* Get label text for a shape
|
|
177
|
+
*
|
|
178
|
+
* Returns the display label for the shape on the map in uppercase.
|
|
179
|
+
* - `label`: Optional short display name shown on the map (e.g., "NYC")
|
|
180
|
+
* - `name`: Full shape name used internally (e.g., "New York City Office")
|
|
181
|
+
*
|
|
182
|
+
* If `label` is not provided, falls back to using `name`.
|
|
183
|
+
* Text is automatically converted to uppercase for display.
|
|
184
|
+
*/
|
|
185
|
+
declare function getLabelText(shape: EditableShape): string;
|
|
186
|
+
/**
|
|
187
|
+
* Get label background color (uses RGB from shape fill color with fixed label opacity)
|
|
188
|
+
*/
|
|
189
|
+
declare function getLabelFillColor(shape: EditableShape): [number, number, number, number];
|
|
190
|
+
/**
|
|
191
|
+
* Get label border color (uses RGB from shape stroke color with full opacity)
|
|
192
|
+
*/
|
|
193
|
+
declare function getLabelBorderColor(shape: EditableShape): [number, number, number, number];
|
|
194
|
+
//#endregion
|
|
195
|
+
export { CardinalLabelCoordinateAnchor, LabelHorizontalPosition, LabelPosition2d, LabelPositionOptions, LabelVerticalPosition, getLabelBorderColor, getLabelFillColor, getLabelPosition2d, getLabelText, getLineStringEndpoint, getLineStringMidpoint, getPolygonMidpoint, interpolatePoint };
|
|
196
|
+
//# sourceMappingURL=labels.d.ts.map
|