@accelint/map-toolkit 2.0.0 → 3.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/CHANGELOG.md +50 -0
- package/README.md +8 -1
- package/catalog-info.yaml +9 -6
- package/dist/deckgl/base-map/index.d.ts +2 -2
- package/dist/deckgl/base-map/provider.d.ts +2 -2
- package/dist/deckgl/extensions/coffin-corner/coffin-corner-extension.d.ts +144 -0
- package/dist/deckgl/extensions/coffin-corner/coffin-corner-extension.js +535 -0
- package/dist/deckgl/extensions/coffin-corner/coffin-corner-extension.js.map +1 -0
- package/dist/deckgl/extensions/coffin-corner/index.d.ts +17 -0
- package/dist/deckgl/extensions/coffin-corner/index.js +19 -0
- package/dist/deckgl/extensions/coffin-corner/store.d.ts +96 -0
- package/dist/deckgl/extensions/coffin-corner/store.js +173 -0
- package/dist/deckgl/extensions/coffin-corner/store.js.map +1 -0
- package/dist/deckgl/extensions/coffin-corner/types.d.ts +76 -0
- package/dist/deckgl/extensions/coffin-corner/types.js +27 -0
- package/dist/deckgl/extensions/coffin-corner/types.js.map +1 -0
- package/dist/deckgl/extensions/coffin-corner/use-coffin-corner.d.ts +81 -0
- package/dist/deckgl/extensions/coffin-corner/use-coffin-corner.js +75 -0
- package/dist/deckgl/extensions/coffin-corner/use-coffin-corner.js.map +1 -0
- package/dist/deckgl/extensions/index.d.ts +15 -0
- package/dist/deckgl/extensions/index.js +16 -0
- package/dist/deckgl/index.d.ts +6 -1
- package/dist/deckgl/index.js +5 -1
- package/dist/deckgl/shapes/display-shape-layer/constants.js +6 -15
- package/dist/deckgl/shapes/display-shape-layer/constants.js.map +1 -1
- package/dist/deckgl/shapes/display-shape-layer/index.d.ts +31 -15
- package/dist/deckgl/shapes/display-shape-layer/index.js +97 -78
- package/dist/deckgl/shapes/display-shape-layer/index.js.map +1 -1
- package/dist/deckgl/shapes/display-shape-layer/types.d.ts +8 -0
- package/dist/deckgl/shapes/display-shape-layer/utils/icon-config.js +3 -48
- package/dist/deckgl/shapes/display-shape-layer/utils/icon-config.js.map +1 -1
- package/dist/deckgl/shapes/display-shape-layer/utils/radius-label.js +53 -0
- package/dist/deckgl/shapes/display-shape-layer/utils/radius-label.js.map +1 -0
- package/dist/deckgl/shapes/draw-shape-layer/index.d.ts +7 -3
- package/dist/deckgl/shapes/draw-shape-layer/index.js +7 -3
- package/dist/deckgl/shapes/draw-shape-layer/index.js.map +1 -1
- package/dist/deckgl/shapes/draw-shape-layer/modes/draw-circle-mode-with-tooltip.js +4 -2
- package/dist/deckgl/shapes/draw-shape-layer/modes/draw-circle-mode-with-tooltip.js.map +1 -1
- package/dist/deckgl/shapes/draw-shape-layer/modes/draw-ellipse-mode-with-tooltip.js +3 -2
- package/dist/deckgl/shapes/draw-shape-layer/modes/draw-ellipse-mode-with-tooltip.js.map +1 -1
- package/dist/deckgl/shapes/draw-shape-layer/modes/draw-line-string-mode-with-tooltip.js +5 -2
- package/dist/deckgl/shapes/draw-shape-layer/modes/draw-line-string-mode-with-tooltip.js.map +1 -1
- package/dist/deckgl/shapes/draw-shape-layer/modes/draw-polygon-mode-with-tooltip.js +5 -2
- package/dist/deckgl/shapes/draw-shape-layer/modes/draw-polygon-mode-with-tooltip.js.map +1 -1
- package/dist/deckgl/shapes/draw-shape-layer/modes/draw-rectangle-mode-with-tooltip.js +7 -2
- package/dist/deckgl/shapes/draw-shape-layer/modes/draw-rectangle-mode-with-tooltip.js.map +1 -1
- package/dist/deckgl/shapes/draw-shape-layer/types.d.ts +2 -2
- package/dist/deckgl/shapes/edit-shape-layer/index.d.ts +7 -4
- package/dist/deckgl/shapes/edit-shape-layer/index.js +22 -8
- package/dist/deckgl/shapes/edit-shape-layer/index.js.map +1 -1
- package/dist/deckgl/shapes/edit-shape-layer/modes/bounding-transform-mode.js +3 -2
- package/dist/deckgl/shapes/edit-shape-layer/modes/bounding-transform-mode.js.map +1 -1
- package/dist/deckgl/shapes/edit-shape-layer/modes/circle-transform-mode.js +4 -2
- package/dist/deckgl/shapes/edit-shape-layer/modes/circle-transform-mode.js.map +1 -1
- package/dist/deckgl/shapes/edit-shape-layer/store.js +15 -4
- package/dist/deckgl/shapes/edit-shape-layer/store.js.map +1 -1
- package/dist/deckgl/shapes/edit-shape-layer/types.d.ts +4 -2
- package/dist/deckgl/shapes/edit-shape-layer/use-edit-shape.d.ts +1 -1
- package/dist/deckgl/shapes/edit-shape-layer/use-edit-shape.js +7 -3
- package/dist/deckgl/shapes/edit-shape-layer/use-edit-shape.js.map +1 -1
- package/dist/deckgl/shapes/index.d.ts +3 -2
- package/dist/deckgl/shapes/index.js +2 -1
- package/dist/deckgl/shapes/shared/constants.js +1 -1
- package/dist/deckgl/shapes/shared/types.d.ts +11 -4
- package/dist/deckgl/shapes/shared/types.js.map +1 -1
- package/dist/deckgl/shapes/shared/utils/duplicate-shape.d.ts +56 -0
- package/dist/deckgl/shapes/shared/utils/duplicate-shape.js +131 -0
- package/dist/deckgl/shapes/shared/utils/duplicate-shape.js.map +1 -0
- package/dist/deckgl/shapes/shared/utils/geometry-measurements.js.map +1 -1
- package/dist/deckgl/shapes/shared/utils/layer-config.js +10 -7
- package/dist/deckgl/shapes/shared/utils/layer-config.js.map +1 -1
- package/dist/deckgl/symbol-layer/fiber.d.ts +3 -1
- package/dist/deckgl/symbol-layer/fiber.js.map +1 -1
- package/dist/shared/units.d.ts +15 -56
- package/dist/shared/units.js +1 -52
- package/dist/shared/units.js.map +1 -1
- package/dist/viewport/index.d.ts +2 -3
- package/dist/viewport/index.js +1 -2
- package/dist/viewport/types.d.ts +8 -4
- package/dist/viewport/utils.d.ts +3 -3
- package/dist/viewport/utils.js +16 -8
- package/dist/viewport/utils.js.map +1 -1
- package/dist/viewport/viewport-size.d.ts +4 -3
- package/dist/viewport/viewport-size.js +2 -2
- package/dist/viewport/viewport-size.js.map +1 -1
- package/package.json +13 -6
- package/dist/deckgl/shapes/display-shape-layer/utils/interaction.js +0 -50
- package/dist/deckgl/shapes/display-shape-layer/utils/interaction.js.map +0 -1
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
'use client';
|
|
15
15
|
|
|
16
16
|
import { DEFAULT_COLORS } from "../shared/constants.js";
|
|
17
|
+
import { CoffinCornerExtension } from "../../extensions/coffin-corner/coffin-corner-extension.js";
|
|
17
18
|
import { PathStyleExtension } from "@deck.gl/extensions";
|
|
18
19
|
|
|
19
20
|
//#region src/deckgl/shapes/display-shape-layer/constants.ts
|
|
@@ -29,19 +30,6 @@ const MAP_INTERACTION = {
|
|
|
29
30
|
ICON_HOVER_SIZE_INCREASE: 5
|
|
30
31
|
};
|
|
31
32
|
/**
|
|
32
|
-
* Coffin corners configuration for Point selection/hover feedback.
|
|
33
|
-
*
|
|
34
|
-
* Coffin corners are bracket-like corners that appear around Point shapes
|
|
35
|
-
* with icons to indicate hover and selection states. They provide visual
|
|
36
|
-
* feedback without obscuring the icon itself.
|
|
37
|
-
*/
|
|
38
|
-
const COFFIN_CORNERS = {
|
|
39
|
-
HOVER_ICON: "coffin-corners-hover",
|
|
40
|
-
SELECTED_ICON: "coffin-corners-selected",
|
|
41
|
-
SELECTED_HOVER_ICON: "coffin-corners-selected-hover",
|
|
42
|
-
SIZE: 38
|
|
43
|
-
};
|
|
44
|
-
/**
|
|
45
33
|
* Default props for DisplayShapeLayer.
|
|
46
34
|
*
|
|
47
35
|
* Provides sensible defaults for interactive shape display with labels,
|
|
@@ -109,7 +97,10 @@ const BRIGHTNESS_FACTOR = {
|
|
|
109
97
|
*/
|
|
110
98
|
const OVERLAY_FILL_OPACITY = .25;
|
|
111
99
|
/** Reusable deck.gl PathStyleExtension enabling dash patterns on GeoJsonLayer lines. */
|
|
112
|
-
const DASH_EXTENSION =
|
|
100
|
+
const DASH_EXTENSION = new PathStyleExtension({ dash: true });
|
|
101
|
+
const COFFIN_CORNER_EXTENSION = new CoffinCornerExtension();
|
|
102
|
+
/** Stable extensions array for GeoJsonLayer — avoids new reference per render triggering getShaders() re-evaluation. */
|
|
103
|
+
const DISPLAY_EXTENSIONS = [DASH_EXTENSION, COFFIN_CORNER_EXTENSION];
|
|
113
104
|
/** Readonly [r, g, b, a] tuple of DEFAULT_COLORS.highlight, pre-spread at module load for hot-path usage. */
|
|
114
105
|
const HIGHLIGHT_COLOR_TUPLE = [
|
|
115
106
|
DEFAULT_COLORS.highlight[0],
|
|
@@ -119,5 +110,5 @@ const HIGHLIGHT_COLOR_TUPLE = [
|
|
|
119
110
|
];
|
|
120
111
|
|
|
121
112
|
//#endregion
|
|
122
|
-
export { BRIGHTNESS_FACTOR,
|
|
113
|
+
export { BRIGHTNESS_FACTOR, DEFAULT_DISPLAY_PROPS, DISPLAY_EXTENSIONS, HIGHLIGHT_COLOR_TUPLE, MAP_INTERACTION, MATERIAL_SETTINGS, OVERLAY_FILL_OPACITY };
|
|
123
114
|
//# sourceMappingURL=constants.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","names":["HIGHLIGHT_COLOR_TUPLE: Rgba255Tuple"],"sources":["../../../../src/deckgl/shapes/display-shape-layer/constants.ts"],"sourcesContent":["/*\n * Copyright 2026 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';\nimport { PathStyleExtension } from '@deck.gl/extensions';\nimport { DEFAULT_COLORS } from '../shared/constants';\nimport type { Rgba255Tuple } from '@accelint/predicates';\n\n/**\n * Map interaction constants.\n *\n * Values derived from ngc2 for consistency with existing UI patterns.\n * Controls sizing and interaction feedback for shape rendering.\n */\nexport const MAP_INTERACTION = {\n LINE_WIDTH_MIN_PIXELS: 1
|
|
1
|
+
{"version":3,"file":"constants.js","names":["HIGHLIGHT_COLOR_TUPLE: Rgba255Tuple"],"sources":["../../../../src/deckgl/shapes/display-shape-layer/constants.ts"],"sourcesContent":["/*\n * Copyright 2026 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';\nimport { PathStyleExtension } from '@deck.gl/extensions';\nimport { CoffinCornerExtension } from '../../extensions/coffin-corner/coffin-corner-extension';\nimport { DEFAULT_COLORS } from '../shared/constants';\nimport type { Rgba255Tuple } from '@accelint/predicates';\n\n/**\n * Map interaction constants.\n *\n * Values derived from ngc2 for consistency with existing UI patterns.\n * Controls sizing and interaction feedback for shape rendering.\n */\nexport const MAP_INTERACTION = {\n LINE_WIDTH_MIN_PIXELS: 1,\n ICON_SIZE: 38,\n ICON_HOVER_SIZE_INCREASE: 5,\n} as const;\n\n/**\n * Default props for DisplayShapeLayer.\n *\n * Provides sensible defaults for interactive shape display with labels,\n * standard opacity handling, and minimal visual feedback. These can be\n * overridden via layer props.\n */\nexport const DEFAULT_DISPLAY_PROPS = {\n pickable: true,\n showLabels: 'always' as const,\n showHighlight: false,\n applyBaseOpacity: true,\n highlightColor: DEFAULT_COLORS.highlight,\n};\n\n/**\n * Material settings for lighting effects on polygon shapes.\n * Controls fill brightness for hover and selection overlay layers.\n * Keys mirror BRIGHTNESS_FACTOR for consistency.\n */\nexport const MATERIAL_SETTINGS = {\n // Normal state - standard lighting\n NORMAL: {\n ambient: 0.35,\n diffuse: 0.6,\n shininess: 32,\n specularColor: [255, 255, 255] as [number, number, number],\n },\n // Hovered or selected (single active state)\n HOVER_OR_SELECT: {\n ambient: 0.6,\n diffuse: 0.8,\n shininess: 64,\n specularColor: [255, 255, 255] as [number, number, number],\n },\n // Hovered and selected simultaneously - brighter\n HOVER_AND_SELECT: {\n ambient: 0.75,\n diffuse: 0.95,\n shininess: 80,\n specularColor: [255, 255, 255] as [number, number, number],\n },\n} as const;\n\n/**\n * Brightness multipliers for interaction state feedback.\n * Applied via brightenColor() to line colors, curtains, and elevation indicators.\n * - HOVER_OR_SELECT: shape is hovered or selected (single active state)\n * - HOVER_AND_SELECT: shape is both hovered and selected simultaneously\n */\nexport const BRIGHTNESS_FACTOR = {\n HOVER_OR_SELECT: 1.4,\n HOVER_AND_SELECT: 1.7,\n} as const;\n\n/**\n * Opacity multiplier for interaction overlay layers (hover, select).\n * Applied to the shape's fill alpha — sits between the base opacity (0.2)\n * and full opacity (1.0) so the overlay reads clearly without being too solid.\n */\nexport const OVERLAY_FILL_OPACITY = 0.25;\n\n/** Reusable deck.gl PathStyleExtension enabling dash patterns on GeoJsonLayer lines. */\nexport const DASH_EXTENSION = new PathStyleExtension({ dash: true });\n\nexport const COFFIN_CORNER_EXTENSION = new CoffinCornerExtension();\n\n/** Stable extensions array for GeoJsonLayer — avoids new reference per render triggering getShaders() re-evaluation. */\nexport const DISPLAY_EXTENSIONS = [DASH_EXTENSION, COFFIN_CORNER_EXTENSION];\n\n/** Readonly [r, g, b, a] tuple of DEFAULT_COLORS.highlight, pre-spread at module load for hot-path usage. */\nexport const HIGHLIGHT_COLOR_TUPLE: Rgba255Tuple = [\n DEFAULT_COLORS.highlight[0],\n DEFAULT_COLORS.highlight[1],\n DEFAULT_COLORS.highlight[2],\n DEFAULT_COLORS.highlight[3] ?? 255,\n];\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAwBA,MAAa,kBAAkB;CAC7B,uBAAuB;CACvB,WAAW;CACX,0BAA0B;CAC3B;;;;;;;;AASD,MAAa,wBAAwB;CACnC,UAAU;CACV,YAAY;CACZ,eAAe;CACf,kBAAkB;CAClB,gBAAgB,eAAe;CAChC;;;;;;AAOD,MAAa,oBAAoB;CAE/B,QAAQ;EACN,SAAS;EACT,SAAS;EACT,WAAW;EACX,eAAe;GAAC;GAAK;GAAK;GAAI;EAC/B;CAED,iBAAiB;EACf,SAAS;EACT,SAAS;EACT,WAAW;EACX,eAAe;GAAC;GAAK;GAAK;GAAI;EAC/B;CAED,kBAAkB;EAChB,SAAS;EACT,SAAS;EACT,WAAW;EACX,eAAe;GAAC;GAAK;GAAK;GAAI;EAC/B;CACF;;;;;;;AAQD,MAAa,oBAAoB;CAC/B,iBAAiB;CACjB,kBAAkB;CACnB;;;;;;AAOD,MAAa,uBAAuB;;AAGpC,MAAa,iBAAiB,IAAI,mBAAmB,EAAE,MAAM,MAAM,CAAC;AAEpE,MAAa,0BAA0B,IAAI,uBAAuB;;AAGlE,MAAa,qBAAqB,CAAC,gBAAgB,wBAAwB;;AAG3E,MAAaA,wBAAsC;CACjD,eAAe,UAAU;CACzB,eAAe,UAAU;CACzB,eAAe,UAAU;CACzB,eAAe,UAAU,MAAM;CAChC"}
|
|
@@ -25,7 +25,7 @@ import { CompositeLayer, Layer, PickingInfo } from "@deck.gl/core";
|
|
|
25
25
|
* ## Features
|
|
26
26
|
* - **Multiple geometry types**: Point, LineString, Polygon, and Circle
|
|
27
27
|
* - **Icon support**: Custom icons for Point geometries via icon atlases
|
|
28
|
-
* - **Interactive selection**: Click handling with brightness overlay on polygon select, optional highlight
|
|
28
|
+
* - **Interactive selection**: Click handling with brightness overlay on polygon select, optional highlight outline for non-Point shapes (if showHighlight=true). Point geometries use coffin corner brackets instead.
|
|
29
29
|
* - **Hover effects**: Polygon fills brighten via material lighting; outline width increases by 2px on hover
|
|
30
30
|
* - **Customizable labels**: Flexible label positioning with per-shape or global options
|
|
31
31
|
* - **Style properties**: Full control over colors, border/outline patterns, and opacity
|
|
@@ -38,13 +38,14 @@ import { CompositeLayer, Layer, PickingInfo } from "@deck.gl/core";
|
|
|
38
38
|
* and material-based brightness — the base shape is never altered.
|
|
39
39
|
*
|
|
40
40
|
* ## Layer Structure
|
|
41
|
-
* Renders
|
|
42
|
-
* 1. **
|
|
43
|
-
* 2. **
|
|
44
|
-
* 3. **
|
|
41
|
+
* Renders sublayers in this order (bottom to top):
|
|
42
|
+
* 1. **Highlight layer**: Selection outline for non-polygon, non-Point shapes (when showHighlight enabled)
|
|
43
|
+
* 2. **Select layer**: Selection brightness overlay for polygon shapes
|
|
44
|
+
* 3. **Hover layer**: Hover brightness overlay for polygon shapes
|
|
45
45
|
* 4. **Elevation visualization**: Curtains (LineStrings) or wireframes (polygons) — elevation only
|
|
46
46
|
* 5. **Elevation indicators**: Vertical strut lines for elevated non-polygon shapes — elevation only
|
|
47
|
-
* 6. **Main GeoJsonLayer**: Shape geometries with styling and interaction
|
|
47
|
+
* 6. **Main GeoJsonLayer**: Shape geometries with styling and interaction; includes CoffinCornerExtension
|
|
48
|
+
* which propagates to the icon/scatterplot sublayer for Point hover/select bracket feedback
|
|
48
49
|
* 7. **Label layer**: Text labels (if showLabels enabled)
|
|
49
50
|
*
|
|
50
51
|
* ## Icon Atlas Constraint
|
|
@@ -111,6 +112,8 @@ declare class DisplayShapeLayer extends CompositeLayer<DisplayShapeLayerProps> {
|
|
|
111
112
|
private elevationCache;
|
|
112
113
|
/** Cache for elevation indicator line segments */
|
|
113
114
|
private indicatorCache;
|
|
115
|
+
/** Cached coffin corner color tuple — avoids new array reference per render when highlight hasn't changed. */
|
|
116
|
+
private coffinCornerColorCache;
|
|
114
117
|
static layerName: string;
|
|
115
118
|
static defaultProps: {
|
|
116
119
|
pickable: boolean;
|
|
@@ -127,6 +130,11 @@ declare class DisplayShapeLayer extends CompositeLayer<DisplayShapeLayerProps> {
|
|
|
127
130
|
* Resolved highlight color — uses prop if provided, falls back to default.
|
|
128
131
|
*/
|
|
129
132
|
private get resolvedHighlight();
|
|
133
|
+
/**
|
|
134
|
+
* Coffin corner bracket color derived from resolvedHighlight with forced full opacity.
|
|
135
|
+
* Cached to avoid a new array reference per render triggering deck.gl prop-change detection.
|
|
136
|
+
*/
|
|
137
|
+
private get coffinCornerColor();
|
|
130
138
|
/**
|
|
131
139
|
* Handle picking events from the main shapes layer
|
|
132
140
|
*/
|
|
@@ -173,11 +181,13 @@ declare class DisplayShapeLayer extends CompositeLayer<DisplayShapeLayerProps> {
|
|
|
173
181
|
*/
|
|
174
182
|
private getShapeById;
|
|
175
183
|
/**
|
|
176
|
-
* Handle shape click
|
|
184
|
+
* Handle shape click — emits `shapes:selected` via bus and calls `onShapeClick` callback.
|
|
185
|
+
* @param info - deck.gl picking info from the clicked sublayer.
|
|
177
186
|
*/
|
|
178
187
|
private handleShapeClick;
|
|
179
188
|
/**
|
|
180
|
-
* Handle shape hover
|
|
189
|
+
* Handle shape hover — emits `shapes:hovered` via bus (deduplicated by shapeId) and calls `onShapeHover` callback.
|
|
190
|
+
* @param info - deck.gl picking info from the hovered sublayer.
|
|
181
191
|
*/
|
|
182
192
|
private handleShapeHover;
|
|
183
193
|
/**
|
|
@@ -187,7 +197,8 @@ declare class DisplayShapeLayer extends CompositeLayer<DisplayShapeLayerProps> {
|
|
|
187
197
|
private getElevationData;
|
|
188
198
|
/**
|
|
189
199
|
* Render highlight sublayer (underneath main layer).
|
|
190
|
-
*
|
|
200
|
+
* Point geometries skip this layer — they use coffin corner brackets
|
|
201
|
+
* via CoffinCornerExtension on the main layer's icon/scatterplot sublayer instead.
|
|
191
202
|
*/
|
|
192
203
|
private renderHighlightLayer;
|
|
193
204
|
/**
|
|
@@ -202,11 +213,6 @@ declare class DisplayShapeLayer extends CompositeLayer<DisplayShapeLayerProps> {
|
|
|
202
213
|
* Stacks with other interaction layers (e.g. selection highlight underneath).
|
|
203
214
|
*/
|
|
204
215
|
private renderHoverLayer;
|
|
205
|
-
/**
|
|
206
|
-
* Render coffin corners layer for Point geometries that have icons on hover/select
|
|
207
|
-
* Coffin corners provide visual feedback for points instead of select layer
|
|
208
|
-
*/
|
|
209
|
-
private renderCoffinCornersLayer;
|
|
210
216
|
/**
|
|
211
217
|
* Render main shapes layer
|
|
212
218
|
*/
|
|
@@ -219,6 +225,15 @@ declare class DisplayShapeLayer extends CompositeLayer<DisplayShapeLayerProps> {
|
|
|
219
225
|
* - 'never': No labels
|
|
220
226
|
*/
|
|
221
227
|
private renderLabelsLayer;
|
|
228
|
+
/**
|
|
229
|
+
* Render radius label layer for hovered circle shapes.
|
|
230
|
+
* Shows the circle's radius value converted to the configured display unit.
|
|
231
|
+
*
|
|
232
|
+
* Positioning relative to the shape's label:
|
|
233
|
+
* - When showLabels is 'always' or 'hover': appears below the label
|
|
234
|
+
* - When showLabels is 'never': appears in the label's position
|
|
235
|
+
*/
|
|
236
|
+
private renderRadiusLabelLayer;
|
|
222
237
|
/**
|
|
223
238
|
* Render vertical elevation indicator lines for non-polygon shapes.
|
|
224
239
|
* Creates vertical "strut" lines from ground level to elevated features.
|
|
@@ -240,7 +255,8 @@ declare class DisplayShapeLayer extends CompositeLayer<DisplayShapeLayerProps> {
|
|
|
240
255
|
*/
|
|
241
256
|
private renderElevationVisualizationLayer;
|
|
242
257
|
/**
|
|
243
|
-
* Render all sublayers
|
|
258
|
+
* Render all sublayers.
|
|
259
|
+
* @returns Ordered array of sublayers (highlight, select, hover, elevation, main, labels) from bottom to top.
|
|
244
260
|
*/
|
|
245
261
|
renderLayers(): Layer[];
|
|
246
262
|
}
|
|
@@ -13,23 +13,23 @@
|
|
|
13
13
|
|
|
14
14
|
'use client';
|
|
15
15
|
|
|
16
|
-
import { createLoggerDomain } from "../../../shared/logger.js";
|
|
17
16
|
import { ShapeEvents } from "../shared/events.js";
|
|
18
|
-
import { isLineGeometry, isPointType, isPolygonGeometry } from "../shared/types.js";
|
|
17
|
+
import { isCircleShape, isLineGeometry, isPointType, isPolygonGeometry } from "../shared/types.js";
|
|
18
|
+
import { DEFAULT_TEXT_SIZE, DEFAULT_TEXT_STYLE } from "../../text-settings.js";
|
|
19
19
|
import { SHAPE_LAYER_IDS } from "../shared/constants.js";
|
|
20
20
|
import { getDashArray, getFillColor, getLineColor } from "../shared/utils/style-utils.js";
|
|
21
|
-
import { BRIGHTNESS_FACTOR,
|
|
21
|
+
import { BRIGHTNESS_FACTOR, DEFAULT_DISPLAY_PROPS, DISPLAY_EXTENSIONS, HIGHLIGHT_COLOR_TUPLE, MAP_INTERACTION, MATERIAL_SETTINGS } from "./constants.js";
|
|
22
|
+
import { getLabelPosition2d } from "./utils/labels.js";
|
|
22
23
|
import { createShapeLabelLayer } from "./shape-label-layer.js";
|
|
23
24
|
import { applyOverlayOpacity, brightenColor, getHighlightLineWidth, getHoverLineWidth, getOverlayFillColor } from "./utils/display-style.js";
|
|
24
25
|
import { buildIndicatorLineData, classifyElevatedFeatures, createCurtainPolygonFeatures, flattenFeatureTo2D, getFeatureElevation, partitionCurtains } from "./utils/elevation.js";
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
26
|
+
import { getIconConfig, getIconLayerProps, getIconUpdateTriggers } from "./utils/icon-config.js";
|
|
27
|
+
import { getRadiusLabelText } from "./utils/radius-label.js";
|
|
27
28
|
import { Broadcast } from "@accelint/bus";
|
|
28
29
|
import { CompositeLayer } from "@deck.gl/core";
|
|
29
|
-
import { GeoJsonLayer,
|
|
30
|
+
import { GeoJsonLayer, LineLayer, TextLayer } from "@deck.gl/layers";
|
|
30
31
|
|
|
31
32
|
//#region src/deckgl/shapes/display-shape-layer/index.ts
|
|
32
|
-
const logger = createLoggerDomain("[DisplayShapeLayer]");
|
|
33
33
|
/**
|
|
34
34
|
* Typed event bus instance for shape events.
|
|
35
35
|
* Provides type-safe event emission for shape interactions.
|
|
@@ -44,7 +44,7 @@ const shapeBus = Broadcast.getInstance();
|
|
|
44
44
|
* ## Features
|
|
45
45
|
* - **Multiple geometry types**: Point, LineString, Polygon, and Circle
|
|
46
46
|
* - **Icon support**: Custom icons for Point geometries via icon atlases
|
|
47
|
-
* - **Interactive selection**: Click handling with brightness overlay on polygon select, optional highlight
|
|
47
|
+
* - **Interactive selection**: Click handling with brightness overlay on polygon select, optional highlight outline for non-Point shapes (if showHighlight=true). Point geometries use coffin corner brackets instead.
|
|
48
48
|
* - **Hover effects**: Polygon fills brighten via material lighting; outline width increases by 2px on hover
|
|
49
49
|
* - **Customizable labels**: Flexible label positioning with per-shape or global options
|
|
50
50
|
* - **Style properties**: Full control over colors, border/outline patterns, and opacity
|
|
@@ -57,13 +57,14 @@ const shapeBus = Broadcast.getInstance();
|
|
|
57
57
|
* and material-based brightness — the base shape is never altered.
|
|
58
58
|
*
|
|
59
59
|
* ## Layer Structure
|
|
60
|
-
* Renders
|
|
61
|
-
* 1. **
|
|
62
|
-
* 2. **
|
|
63
|
-
* 3. **
|
|
60
|
+
* Renders sublayers in this order (bottom to top):
|
|
61
|
+
* 1. **Highlight layer**: Selection outline for non-polygon, non-Point shapes (when showHighlight enabled)
|
|
62
|
+
* 2. **Select layer**: Selection brightness overlay for polygon shapes
|
|
63
|
+
* 3. **Hover layer**: Hover brightness overlay for polygon shapes
|
|
64
64
|
* 4. **Elevation visualization**: Curtains (LineStrings) or wireframes (polygons) — elevation only
|
|
65
65
|
* 5. **Elevation indicators**: Vertical strut lines for elevated non-polygon shapes — elevation only
|
|
66
|
-
* 6. **Main GeoJsonLayer**: Shape geometries with styling and interaction
|
|
66
|
+
* 6. **Main GeoJsonLayer**: Shape geometries with styling and interaction; includes CoffinCornerExtension
|
|
67
|
+
* which propagates to the icon/scatterplot sublayer for Point hover/select bracket feedback
|
|
67
68
|
* 7. **Label layer**: Text labels (if showLabels enabled)
|
|
68
69
|
*
|
|
69
70
|
* ## Icon Atlas Constraint
|
|
@@ -129,6 +130,8 @@ var DisplayShapeLayer = class extends CompositeLayer {
|
|
|
129
130
|
elevationCache = null;
|
|
130
131
|
/** Cache for elevation indicator line segments */
|
|
131
132
|
indicatorCache = null;
|
|
133
|
+
/** Cached coffin corner color tuple — avoids new array reference per render when highlight hasn't changed. */
|
|
134
|
+
coffinCornerColorCache = null;
|
|
132
135
|
static layerName = "DisplayShapeLayer";
|
|
133
136
|
static defaultProps = { ...DEFAULT_DISPLAY_PROPS };
|
|
134
137
|
/**
|
|
@@ -142,6 +145,7 @@ var DisplayShapeLayer = class extends CompositeLayer {
|
|
|
142
145
|
this.featuresCache = null;
|
|
143
146
|
this.elevationCache = null;
|
|
144
147
|
this.indicatorCache = null;
|
|
148
|
+
this.coffinCornerColorCache = null;
|
|
145
149
|
}
|
|
146
150
|
/**
|
|
147
151
|
* Resolved highlight color — uses prop if provided, falls back to default.
|
|
@@ -150,6 +154,23 @@ var DisplayShapeLayer = class extends CompositeLayer {
|
|
|
150
154
|
return this.props.highlightColor ?? HIGHLIGHT_COLOR_TUPLE;
|
|
151
155
|
}
|
|
152
156
|
/**
|
|
157
|
+
* Coffin corner bracket color derived from resolvedHighlight with forced full opacity.
|
|
158
|
+
* Cached to avoid a new array reference per render triggering deck.gl prop-change detection.
|
|
159
|
+
*/
|
|
160
|
+
get coffinCornerColor() {
|
|
161
|
+
const highlight = this.resolvedHighlight;
|
|
162
|
+
if (this.coffinCornerColorCache?.source !== highlight) this.coffinCornerColorCache = {
|
|
163
|
+
source: highlight,
|
|
164
|
+
color: [
|
|
165
|
+
highlight[0],
|
|
166
|
+
highlight[1],
|
|
167
|
+
highlight[2],
|
|
168
|
+
255
|
|
169
|
+
]
|
|
170
|
+
};
|
|
171
|
+
return this.coffinCornerColorCache.color;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
153
174
|
* Handle picking events from the main shapes layer
|
|
154
175
|
*/
|
|
155
176
|
handleMainLayerPick(info, mode) {
|
|
@@ -241,7 +262,8 @@ var DisplayShapeLayer = class extends CompositeLayer {
|
|
|
241
262
|
return index !== void 0 ? this.props.data[index] : void 0;
|
|
242
263
|
}
|
|
243
264
|
/**
|
|
244
|
-
* Handle shape click
|
|
265
|
+
* Handle shape click — emits `shapes:selected` via bus and calls `onShapeClick` callback.
|
|
266
|
+
* @param info - deck.gl picking info from the clicked sublayer.
|
|
245
267
|
*/
|
|
246
268
|
handleShapeClick = (info) => {
|
|
247
269
|
const { onShapeClick, mapId } = this.props;
|
|
@@ -257,7 +279,8 @@ var DisplayShapeLayer = class extends CompositeLayer {
|
|
|
257
279
|
if (onShapeClick) onShapeClick(shape);
|
|
258
280
|
};
|
|
259
281
|
/**
|
|
260
|
-
* Handle shape hover
|
|
282
|
+
* Handle shape hover — emits `shapes:hovered` via bus (deduplicated by shapeId) and calls `onShapeHover` callback.
|
|
283
|
+
* @param info - deck.gl picking info from the hovered sublayer.
|
|
261
284
|
*/
|
|
262
285
|
handleShapeHover = (info) => {
|
|
263
286
|
const { onShapeHover, mapId } = this.props;
|
|
@@ -293,7 +316,8 @@ var DisplayShapeLayer = class extends CompositeLayer {
|
|
|
293
316
|
}
|
|
294
317
|
/**
|
|
295
318
|
* Render highlight sublayer (underneath main layer).
|
|
296
|
-
*
|
|
319
|
+
* Point geometries skip this layer — they use coffin corner brackets
|
|
320
|
+
* via CoffinCornerExtension on the main layer's icon/scatterplot sublayer instead.
|
|
297
321
|
*/
|
|
298
322
|
renderHighlightLayer(features) {
|
|
299
323
|
const { selectedShapeId, showHighlight } = this.props;
|
|
@@ -301,9 +325,7 @@ var DisplayShapeLayer = class extends CompositeLayer {
|
|
|
301
325
|
const featureIndex = this.featuresCache?.shapeIdToIndex.get(selectedShapeId);
|
|
302
326
|
const selectedFeature = featureIndex !== void 0 ? features[featureIndex] : void 0;
|
|
303
327
|
if (!selectedFeature) return [];
|
|
304
|
-
if (isPointType(selectedFeature.geometry))
|
|
305
|
-
if (!!selectedFeature.properties?.styleProperties?.icon) return [];
|
|
306
|
-
}
|
|
328
|
+
if (isPointType(selectedFeature.geometry)) return [];
|
|
307
329
|
const highlightFeature = flattenFeatureTo2D(selectedFeature);
|
|
308
330
|
const lineColor = this.resolvedHighlight;
|
|
309
331
|
return [new GeoJsonLayer({
|
|
@@ -383,66 +405,13 @@ var DisplayShapeLayer = class extends CompositeLayer {
|
|
|
383
405
|
})];
|
|
384
406
|
}
|
|
385
407
|
/**
|
|
386
|
-
* Render coffin corners layer for Point geometries that have icons on hover/select
|
|
387
|
-
* Coffin corners provide visual feedback for points instead of select layer
|
|
388
|
-
*/
|
|
389
|
-
renderCoffinCornersLayer(features) {
|
|
390
|
-
const { selectedShapeId } = this.props;
|
|
391
|
-
const hoverIndex = this.state?.hoverIndex;
|
|
392
|
-
const shapeIdToIndex = this.featuresCache?.shapeIdToIndex;
|
|
393
|
-
if (!shapeIdToIndex) return [];
|
|
394
|
-
const pointFeatures = [];
|
|
395
|
-
for (const f of features) {
|
|
396
|
-
if (f.geometry.type !== "Point") continue;
|
|
397
|
-
if (!f.properties?.styleProperties?.icon) continue;
|
|
398
|
-
const { isSelected, isHovered } = getPointInteractionState(f, selectedShapeId, hoverIndex, shapeIdToIndex);
|
|
399
|
-
if (isSelected || isHovered) pointFeatures.push(f);
|
|
400
|
-
}
|
|
401
|
-
if (pointFeatures.length === 0) return [];
|
|
402
|
-
const firstPointIcon = pointFeatures[0]?.properties?.styleProperties?.icon;
|
|
403
|
-
const iconAtlas = firstPointIcon?.atlas;
|
|
404
|
-
const iconMapping = firstPointIcon?.mapping;
|
|
405
|
-
if (!(iconAtlas && iconMapping)) {
|
|
406
|
-
logger.warn("Point shape has icon style but missing iconAtlas or iconMapping - coffin corners will not render");
|
|
407
|
-
return [];
|
|
408
|
-
}
|
|
409
|
-
const extendedMapping = extendMappingWithCoffinCorners(iconMapping);
|
|
410
|
-
return [new IconLayer({
|
|
411
|
-
id: `${this.props.id}-${SHAPE_LAYER_IDS.DISPLAY}-coffin-corners`,
|
|
412
|
-
data: pointFeatures,
|
|
413
|
-
iconAtlas,
|
|
414
|
-
iconMapping: extendedMapping,
|
|
415
|
-
getIcon: (d) => {
|
|
416
|
-
const { isSelected, isHovered } = getPointInteractionState(d, selectedShapeId, hoverIndex, shapeIdToIndex);
|
|
417
|
-
if (isSelected && isHovered) return COFFIN_CORNERS.SELECTED_HOVER_ICON;
|
|
418
|
-
if (isSelected) return COFFIN_CORNERS.SELECTED_ICON;
|
|
419
|
-
return COFFIN_CORNERS.HOVER_ICON;
|
|
420
|
-
},
|
|
421
|
-
getSize: COFFIN_CORNERS.SIZE,
|
|
422
|
-
getPosition: (d) => {
|
|
423
|
-
return isPointType(d.geometry) ? d.geometry.coordinates : [0, 0];
|
|
424
|
-
},
|
|
425
|
-
getPixelOffset: (d) => {
|
|
426
|
-
return [-1, -(d.properties?.styleProperties?.icon?.size ?? MAP_INTERACTION.ICON_SIZE) / 2];
|
|
427
|
-
},
|
|
428
|
-
billboard: false,
|
|
429
|
-
pickable: false,
|
|
430
|
-
updateTriggers: {
|
|
431
|
-
getIcon: [selectedShapeId, this.state?.hoverIndex],
|
|
432
|
-
data: [
|
|
433
|
-
features,
|
|
434
|
-
selectedShapeId,
|
|
435
|
-
this.state?.hoverIndex
|
|
436
|
-
]
|
|
437
|
-
}
|
|
438
|
-
})];
|
|
439
|
-
}
|
|
440
|
-
/**
|
|
441
408
|
* Render main shapes layer
|
|
442
409
|
*/
|
|
443
410
|
renderMainLayer(features) {
|
|
444
411
|
const { pickable, applyBaseOpacity, selectedShapeId } = this.props;
|
|
445
412
|
const { hasIcons, atlas: iconAtlas, mapping: iconMapping } = getIconConfig(features);
|
|
413
|
+
const hoveredFeature = this.state?.hoverIndex !== void 0 ? features[this.state.hoverIndex] : void 0;
|
|
414
|
+
const hoveredEntityId = hoveredFeature?.geometry.type === "Point" ? hoveredFeature.properties?.shapeId : void 0;
|
|
446
415
|
return new GeoJsonLayer({
|
|
447
416
|
id: `${this.props.id}-${SHAPE_LAYER_IDS.DISPLAY}`,
|
|
448
417
|
data: features,
|
|
@@ -473,7 +442,11 @@ var DisplayShapeLayer = class extends CompositeLayer {
|
|
|
473
442
|
},
|
|
474
443
|
pointRadiusUnits: "pixels",
|
|
475
444
|
...getIconLayerProps(hasIcons, iconAtlas, iconMapping),
|
|
476
|
-
|
|
445
|
+
selectedEntityId: selectedShapeId,
|
|
446
|
+
hoveredEntityId,
|
|
447
|
+
getEntityId: (d) => d.properties?.shapeId,
|
|
448
|
+
selectedCoffinCornerColor: this.coffinCornerColor,
|
|
449
|
+
extensions: DISPLAY_EXTENSIONS,
|
|
477
450
|
getDashArray,
|
|
478
451
|
pickable,
|
|
479
452
|
autoHighlight: false,
|
|
@@ -520,6 +493,51 @@ var DisplayShapeLayer = class extends CompositeLayer {
|
|
|
520
493
|
})];
|
|
521
494
|
}
|
|
522
495
|
/**
|
|
496
|
+
* Render radius label layer for hovered circle shapes.
|
|
497
|
+
* Shows the circle's radius value converted to the configured display unit.
|
|
498
|
+
*
|
|
499
|
+
* Positioning relative to the shape's label:
|
|
500
|
+
* - When showLabels is 'always' or 'hover': appears below the label
|
|
501
|
+
* - When showLabels is 'never': appears in the label's position
|
|
502
|
+
*/
|
|
503
|
+
renderRadiusLabelLayer() {
|
|
504
|
+
const { data, unit, showLabels, labelOptions } = this.props;
|
|
505
|
+
const hoverIndex = this.state?.hoverIndex;
|
|
506
|
+
const hoveredShape = hoverIndex !== void 0 ? data[hoverIndex] : void 0;
|
|
507
|
+
const radiusText = hoveredShape && isCircleShape(hoveredShape) ? getRadiusLabelText(hoveredShape, unit) : void 0;
|
|
508
|
+
const labelPosition = radiusText && hoveredShape ? getLabelPosition2d(hoveredShape, labelOptions) : void 0;
|
|
509
|
+
if (!labelPosition) return [];
|
|
510
|
+
const pixelOffset = showLabels !== "never" ? [labelPosition.pixelOffset[0], labelPosition.pixelOffset[1] + DEFAULT_TEXT_SIZE + 2] : labelPosition.pixelOffset;
|
|
511
|
+
return [new TextLayer({
|
|
512
|
+
id: `${this.props.id}-${SHAPE_LAYER_IDS.DISPLAY}-radius-label`,
|
|
513
|
+
data: [{
|
|
514
|
+
text: radiusText,
|
|
515
|
+
position: labelPosition.coordinates
|
|
516
|
+
}],
|
|
517
|
+
getText: (d) => d.text,
|
|
518
|
+
getPosition: (d) => d.position,
|
|
519
|
+
getPixelOffset: pixelOffset,
|
|
520
|
+
getTextAnchor: labelPosition.textAnchor,
|
|
521
|
+
getAlignmentBaseline: labelPosition.alignmentBaseline,
|
|
522
|
+
...DEFAULT_TEXT_STYLE,
|
|
523
|
+
getAngle: 0,
|
|
524
|
+
background: false,
|
|
525
|
+
fontFamily: "Roboto MonoVariable, monospace",
|
|
526
|
+
pickable: false,
|
|
527
|
+
updateTriggers: {
|
|
528
|
+
getText: [hoverIndex, unit],
|
|
529
|
+
getPosition: [hoverIndex, labelOptions],
|
|
530
|
+
getPixelOffset: [
|
|
531
|
+
hoverIndex,
|
|
532
|
+
labelOptions,
|
|
533
|
+
showLabels
|
|
534
|
+
],
|
|
535
|
+
getTextAnchor: [hoverIndex, labelOptions],
|
|
536
|
+
getAlignmentBaseline: [hoverIndex, labelOptions]
|
|
537
|
+
}
|
|
538
|
+
})];
|
|
539
|
+
}
|
|
540
|
+
/**
|
|
523
541
|
* Render vertical elevation indicator lines for non-polygon shapes.
|
|
524
542
|
* Creates vertical "strut" lines from ground level to elevated features.
|
|
525
543
|
* For LineStrings, creates a "curtain" effect with vertical lines at each coordinate.
|
|
@@ -648,7 +666,8 @@ var DisplayShapeLayer = class extends CompositeLayer {
|
|
|
648
666
|
return layers;
|
|
649
667
|
}
|
|
650
668
|
/**
|
|
651
|
-
* Render all sublayers
|
|
669
|
+
* Render all sublayers.
|
|
670
|
+
* @returns Ordered array of sublayers (highlight, select, hover, elevation, main, labels) from bottom to top.
|
|
652
671
|
*/
|
|
653
672
|
renderLayers() {
|
|
654
673
|
const features = this.getFeaturesWithId();
|
|
@@ -656,8 +675,7 @@ var DisplayShapeLayer = class extends CompositeLayer {
|
|
|
656
675
|
const layers = [
|
|
657
676
|
...this.renderHighlightLayer(features),
|
|
658
677
|
...this.renderSelectLayer(features),
|
|
659
|
-
...this.renderHoverLayer(features)
|
|
660
|
-
...this.renderCoffinCornersLayer(features)
|
|
678
|
+
...this.renderHoverLayer(features)
|
|
661
679
|
];
|
|
662
680
|
if (enableElevation) {
|
|
663
681
|
const { classification, curtainFeatures } = this.getElevationData(features, this.props.applyBaseOpacity);
|
|
@@ -667,6 +685,7 @@ var DisplayShapeLayer = class extends CompositeLayer {
|
|
|
667
685
|
}
|
|
668
686
|
layers.push(this.renderMainLayer(features));
|
|
669
687
|
layers.push(...this.renderLabelsLayer());
|
|
688
|
+
layers.push(...this.renderRadiusLabelLayer());
|
|
670
689
|
return layers;
|
|
671
690
|
}
|
|
672
691
|
};
|