@sqlrooms/deck 0.29.0-rc.10 → 0.29.0-rc.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +88 -16
- package/dist/BlockMapSettings.d.ts.map +1 -1
- package/dist/BlockMapSettings.js +4 -16
- package/dist/BlockMapSettings.js.map +1 -1
- package/dist/DashboardMapSettings.d.ts.map +1 -1
- package/dist/DashboardMapSettings.js +7 -10
- package/dist/DashboardMapSettings.js.map +1 -1
- package/dist/DeckJsonMap.d.ts.map +1 -1
- package/dist/DeckJsonMap.js +20 -18
- package/dist/DeckJsonMap.js.map +1 -1
- package/dist/DeckJsonMapSpec.d.ts +916 -53
- package/dist/DeckJsonMapSpec.d.ts.map +1 -1
- package/dist/DeckJsonMapSpec.js +9 -0
- package/dist/DeckJsonMapSpec.js.map +1 -1
- package/dist/DeckMapDefaultStylesProvider.d.ts +3 -4
- package/dist/DeckMapDefaultStylesProvider.d.ts.map +1 -1
- package/dist/DeckMapDefaultStylesProvider.js +13 -7
- package/dist/DeckMapDefaultStylesProvider.js.map +1 -1
- package/dist/DeckMapSurface.d.ts +1 -1
- package/dist/DeckMapSurface.js +1 -1
- package/dist/DeckMapSurface.js.map +1 -1
- package/dist/MapSettings.d.ts +14 -0
- package/dist/MapSettings.d.ts.map +1 -1
- package/dist/MapSettings.js +555 -186
- package/dist/MapSettings.js.map +1 -1
- package/dist/MapSettingsControls.d.ts +8 -1
- package/dist/MapSettingsControls.d.ts.map +1 -1
- package/dist/MapSettingsControls.js +24 -2
- package/dist/MapSettingsControls.js.map +1 -1
- package/dist/ai.d.ts +19 -5
- package/dist/ai.d.ts.map +1 -1
- package/dist/ai.js +63 -112
- package/dist/ai.js.map +1 -1
- package/dist/aiNormalize.d.ts +31 -0
- package/dist/aiNormalize.d.ts.map +1 -0
- package/dist/aiNormalize.js +630 -0
- package/dist/aiNormalize.js.map +1 -0
- package/dist/block.d.ts +1 -1
- package/dist/block.d.ts.map +1 -1
- package/dist/block.js +1 -1
- package/dist/block.js.map +1 -1
- package/dist/createOrUpdateDeckMapResource.d.ts +6 -2
- package/dist/createOrUpdateDeckMapResource.d.ts.map +1 -1
- package/dist/createOrUpdateDeckMapResource.js +57 -4
- package/dist/createOrUpdateDeckMapResource.js.map +1 -1
- package/dist/dashboard.d.ts.map +1 -1
- package/dist/dashboard.js +72 -8
- package/dist/dashboard.js.map +1 -1
- package/dist/dashboardConfig.d.ts +10 -1
- package/dist/dashboardConfig.d.ts.map +1 -1
- package/dist/dashboardConfig.js +55 -22
- package/dist/dashboardConfig.js.map +1 -1
- package/dist/datasets/PreparedDatasetStore.d.ts +3 -4
- package/dist/datasets/PreparedDatasetStore.d.ts.map +1 -1
- package/dist/datasets/PreparedDatasetStore.js +35 -10
- package/dist/datasets/PreparedDatasetStore.js.map +1 -1
- package/dist/datasets/helpers.d.ts +39 -2
- package/dist/datasets/helpers.d.ts.map +1 -1
- package/dist/datasets/helpers.js +86 -3
- package/dist/datasets/helpers.js.map +1 -1
- package/dist/datasets/usePreparedDatasetStates.d.ts.map +1 -1
- package/dist/datasets/usePreparedDatasetStates.js +12 -8
- package/dist/datasets/usePreparedDatasetStates.js.map +1 -1
- package/dist/datasets/wrapGeometryAsWkb.d.ts +20 -0
- package/dist/datasets/wrapGeometryAsWkb.d.ts.map +1 -0
- package/dist/datasets/wrapGeometryAsWkb.js +65 -0
- package/dist/datasets/wrapGeometryAsWkb.js.map +1 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/json/colorScaleFunction.d.ts +12 -4
- package/dist/json/colorScaleFunction.d.ts.map +1 -1
- package/dist/json/colorScaleFunction.js.map +1 -1
- package/dist/json/compileColorScale.d.ts +3 -2
- package/dist/json/compileColorScale.d.ts.map +1 -1
- package/dist/json/compileColorScale.js +16 -1
- package/dist/json/compileColorScale.js.map +1 -1
- package/dist/json/compileGeoArrowAccessor.d.ts +5 -0
- package/dist/json/compileGeoArrowAccessor.d.ts.map +1 -1
- package/dist/json/compileGeoArrowAccessor.js +17 -3
- package/dist/json/compileGeoArrowAccessor.js.map +1 -1
- package/dist/json/createDeckJsonConfiguration.d.ts.map +1 -1
- package/dist/json/createDeckJsonConfiguration.js +278 -151
- package/dist/json/createDeckJsonConfiguration.js.map +1 -1
- package/dist/json/defaultClasses.d.ts.map +1 -1
- package/dist/json/defaultClasses.js +3 -3
- package/dist/json/defaultClasses.js.map +1 -1
- package/dist/json/extractColorScaleLegends.d.ts.map +1 -1
- package/dist/json/extractColorScaleLegends.js +43 -14
- package/dist/json/extractColorScaleLegends.js.map +1 -1
- package/dist/json/heatmapDefaults.d.ts +17 -7
- package/dist/json/heatmapDefaults.d.ts.map +1 -1
- package/dist/json/heatmapDefaults.js +54 -12
- package/dist/json/heatmapDefaults.js.map +1 -1
- package/dist/json/layers/DeckH3HexagonLayer.d.ts.map +1 -1
- package/dist/json/layers/DeckH3HexagonLayer.js +9 -14
- package/dist/json/layers/DeckH3HexagonLayer.js.map +1 -1
- package/dist/json/layers/DeckHeatmapLayer.d.ts +32 -0
- package/dist/json/layers/DeckHeatmapLayer.d.ts.map +1 -0
- package/dist/json/layers/DeckHeatmapLayer.js +69 -0
- package/dist/json/layers/DeckHeatmapLayer.js.map +1 -0
- package/dist/json/layers/h3IndexFormat.d.ts +6 -0
- package/dist/json/layers/h3IndexFormat.d.ts.map +1 -0
- package/dist/json/layers/h3IndexFormat.js +17 -0
- package/dist/json/layers/h3IndexFormat.js.map +1 -0
- package/dist/json/layers/index.d.ts +2 -0
- package/dist/json/layers/index.d.ts.map +1 -1
- package/dist/json/layers/index.js +2 -0
- package/dist/json/layers/index.js.map +1 -1
- package/dist/json/rewriteGeoArrowAccessors.d.ts.map +1 -1
- package/dist/json/rewriteGeoArrowAccessors.js +22 -5
- package/dist/json/rewriteGeoArrowAccessors.js.map +1 -1
- package/dist/json/scaleFunction.d.ts +27 -0
- package/dist/json/scaleFunction.d.ts.map +1 -0
- package/dist/json/scaleFunction.js +151 -0
- package/dist/json/scaleFunction.js.map +1 -0
- package/dist/mapAiConfig.d.ts +8 -0
- package/dist/mapAiConfig.d.ts.map +1 -1
- package/dist/mapAiConfig.js +9 -1
- package/dist/mapAiConfig.js.map +1 -1
- package/dist/mapAiSharedInstructions.d.ts +3 -0
- package/dist/mapAiSharedInstructions.d.ts.map +1 -0
- package/dist/mapAiSharedInstructions.js +16 -0
- package/dist/mapAiSharedInstructions.js.map +1 -0
- package/dist/mapConfig.d.ts +7 -1
- package/dist/mapConfig.d.ts.map +1 -1
- package/dist/mapConfig.js.map +1 -1
- package/dist/mapConfigUtils.d.ts +22 -0
- package/dist/mapConfigUtils.d.ts.map +1 -1
- package/dist/mapConfigUtils.js +147 -3
- package/dist/mapConfigUtils.js.map +1 -1
- package/dist/mapFit.d.ts +16 -0
- package/dist/mapFit.d.ts.map +1 -1
- package/dist/mapFit.js +208 -30
- package/dist/mapFit.js.map +1 -1
- package/dist/mapLayerConfigUtils.d.ts +64 -1
- package/dist/mapLayerConfigUtils.d.ts.map +1 -1
- package/dist/mapLayerConfigUtils.js +277 -16
- package/dist/mapLayerConfigUtils.js.map +1 -1
- package/dist/mapResourceAuthoring.d.ts +3 -1
- package/dist/mapResourceAuthoring.d.ts.map +1 -1
- package/dist/mapResourceAuthoring.js +413 -20
- package/dist/mapResourceAuthoring.js.map +1 -1
- package/dist/mosaic.d.ts +1 -1
- package/dist/mosaic.d.ts.map +1 -1
- package/dist/mosaic.js.map +1 -1
- package/dist/prepare/geoarrow.js.map +1 -1
- package/dist/prepare/prepareDeckDataset.d.ts.map +1 -1
- package/dist/prepare/prepareDeckDataset.js +1 -0
- package/dist/prepare/prepareDeckDataset.js.map +1 -1
- package/dist/prepare/types.d.ts +3 -0
- package/dist/prepare/types.d.ts.map +1 -1
- package/dist/prepare/types.js.map +1 -1
- package/dist/prepare/wkbDecoder.d.ts +10 -0
- package/dist/prepare/wkbDecoder.d.ts.map +1 -1
- package/dist/prepare/wkbDecoder.js +141 -20
- package/dist/prepare/wkbDecoder.js.map +1 -1
- package/dist/prepare/wkbParser.d.ts +9 -0
- package/dist/prepare/wkbParser.d.ts.map +1 -1
- package/dist/prepare/wkbParser.js +22 -0
- package/dist/prepare/wkbParser.js.map +1 -1
- package/dist/selectStarAsWkbCollision.d.ts +3 -0
- package/dist/selectStarAsWkbCollision.d.ts.map +1 -0
- package/dist/selectStarAsWkbCollision.js +78 -0
- package/dist/selectStarAsWkbCollision.js.map +1 -0
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/useDeckMapFitToBounds.d.ts.map +1 -1
- package/dist/useDeckMapFitToBounds.js +1 -1
- package/dist/useDeckMapFitToBounds.js.map +1 -1
- package/package.json +15 -15
|
@@ -1,17 +1,28 @@
|
|
|
1
1
|
import { JSONConfiguration } from '@deck.gl/json';
|
|
2
|
-
import { wkbGeometryDecoder } from '../prepare/wkbDecoder';
|
|
2
|
+
import { isPointPositionLayer, promoteToPointPositions, wkbGeometryDecoder, describeGeoArrowPromotionFailure, } from '../prepare/wkbDecoder';
|
|
3
3
|
import { tryAggregateWaypointsToLineStrings } from './aggregateWaypoints';
|
|
4
4
|
import { createColorScaleMarker, getAllColorScales, COLOR_SCALE_PROP_NAMES, } from './colorScaleFunction';
|
|
5
5
|
import { compileColorScale } from './compileColorScale';
|
|
6
6
|
import { DEFAULT_DECK_JSON_CLASSES, DEFAULT_DECK_JSON_CONSTANTS, DEFAULT_DECK_JSON_ENUMERATIONS, } from './defaultClasses';
|
|
7
|
-
import { DEFAULT_HEATMAP_COLOR_RANGE } from './heatmapDefaults';
|
|
7
|
+
import { DEFAULT_HEATMAP_COLOR_RANGE, DEFAULT_HEATMAP_WEIGHTS_TEXTURE_SIZE, } from './heatmapDefaults';
|
|
8
8
|
import { getLayerCompatibility } from './layerCompatibility';
|
|
9
9
|
import { isManagedLayer, resolveConfiguredColumn, resolveDatasetId, resolveGeometryColumn, stripLayerExtensionProps, } from './layerConfig';
|
|
10
10
|
import { rewriteGeoArrowAccessors } from './rewriteGeoArrowAccessors';
|
|
11
|
+
import { isBindableGeoArrowFieldIdentifier } from './compileGeoArrowAccessor';
|
|
12
|
+
import { compileLinearScaleAccessor, compileLinearScaleExpression, createScaleMarker, isScaleMarker, } from './scaleFunction';
|
|
11
13
|
function getLayerName(Class) {
|
|
12
14
|
const maybeClass = Class;
|
|
13
15
|
return maybeClass.layerName ?? maybeClass.name ?? 'UnknownLayer';
|
|
14
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* Deck.gl matches layers by id. Each JSON convert would otherwise create a new
|
|
19
|
+
* GPU layer. Dataset id alone collides when two layers share a dataset.
|
|
20
|
+
*/
|
|
21
|
+
function assignStableLayerId(props, datasetId, layerName, index) {
|
|
22
|
+
if (typeof props.id === 'string' && props.id !== '')
|
|
23
|
+
return;
|
|
24
|
+
props.id = `${datasetId}:${layerName}:${index}`;
|
|
25
|
+
}
|
|
15
26
|
function applyColorScale(options) {
|
|
16
27
|
const { props, table } = options;
|
|
17
28
|
const allScales = getAllColorScales(props);
|
|
@@ -44,16 +55,110 @@ function applyColorScale(options) {
|
|
|
44
55
|
}
|
|
45
56
|
return result;
|
|
46
57
|
}
|
|
58
|
+
function getElevationTrigger(rawElev) {
|
|
59
|
+
if (rawElev === undefined)
|
|
60
|
+
return 'none';
|
|
61
|
+
if (typeof rawElev === 'string' || typeof rawElev === 'number') {
|
|
62
|
+
return String(rawElev);
|
|
63
|
+
}
|
|
64
|
+
try {
|
|
65
|
+
return JSON.stringify(rawElev);
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
return String(rawElev);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
function mergeGetElevationTrigger(props, rawElev) {
|
|
72
|
+
const existing = props.updateTriggers &&
|
|
73
|
+
typeof props.updateTriggers === 'object' &&
|
|
74
|
+
!Array.isArray(props.updateTriggers)
|
|
75
|
+
? props.updateTriggers
|
|
76
|
+
: {};
|
|
77
|
+
return {
|
|
78
|
+
...props,
|
|
79
|
+
updateTriggers: {
|
|
80
|
+
...existing,
|
|
81
|
+
getElevation: getElevationTrigger(rawElev),
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
/** Compile `getElevation` scale / `@@=` column accessors against the Arrow table. */
|
|
86
|
+
function compileGetElevation(options) {
|
|
87
|
+
const { table, layerName, datasetId, requireFunctionAccessor } = options;
|
|
88
|
+
const nextProps = { ...options.props };
|
|
89
|
+
const rawElev = nextProps.getElevation;
|
|
90
|
+
if (isScaleMarker(rawElev)) {
|
|
91
|
+
const expression = requireFunctionAccessor
|
|
92
|
+
? undefined
|
|
93
|
+
: compileLinearScaleExpression(table, rawElev);
|
|
94
|
+
if (expression) {
|
|
95
|
+
nextProps.getElevation = expression;
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
const accessor = compileLinearScaleAccessor(table, rawElev);
|
|
99
|
+
if (accessor) {
|
|
100
|
+
nextProps.getElevation = accessor;
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
const field = typeof rawElev.field === 'string' ? rawElev.field : '';
|
|
104
|
+
throw new Error(`Layer "${layerName}" getElevation scale field "${field || '(missing)'}" was not found in dataset "${datasetId}".`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
else if (typeof rawElev === 'string' && rawElev.startsWith('@@=')) {
|
|
109
|
+
const elevField = rawElev.slice(3).trim();
|
|
110
|
+
const elevVector = table.getChild(elevField);
|
|
111
|
+
if (elevVector) {
|
|
112
|
+
let min = Infinity;
|
|
113
|
+
for (let i = 0; i < elevVector.length; i++) {
|
|
114
|
+
if (typeof elevVector.isValid === 'function' &&
|
|
115
|
+
!elevVector.isValid(i)) {
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
const raw = elevVector.get(i);
|
|
119
|
+
if (raw == null)
|
|
120
|
+
continue;
|
|
121
|
+
const v = Number(raw);
|
|
122
|
+
if (Number.isFinite(v) && v < min)
|
|
123
|
+
min = v;
|
|
124
|
+
}
|
|
125
|
+
if (Number.isFinite(min)) {
|
|
126
|
+
if (!requireFunctionAccessor &&
|
|
127
|
+
isBindableGeoArrowFieldIdentifier(elevField)) {
|
|
128
|
+
if (min !== 0) {
|
|
129
|
+
nextProps.getElevation = `@@=Math.max(0, ${elevField} - ${min})`;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
const accessor = compileLinearScaleAccessor(table, {
|
|
134
|
+
field: elevField,
|
|
135
|
+
domain: [min, min],
|
|
136
|
+
});
|
|
137
|
+
if (accessor)
|
|
138
|
+
nextProps.getElevation = accessor;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return nextProps;
|
|
144
|
+
}
|
|
47
145
|
function resolveGeoArrowBindings(options) {
|
|
48
146
|
const { layerName, compatibility, layerProps, prepared, props } = options;
|
|
49
147
|
let table = prepared.table;
|
|
50
148
|
const boundProps = {};
|
|
51
149
|
for (const binding of compatibility.bindings) {
|
|
52
|
-
|
|
150
|
+
const existing = props[binding.prop];
|
|
151
|
+
// Prefer Arrow Vector over `@@=column` (avoids empty H3 / missing-column silence).
|
|
152
|
+
const existingIsSimpleAccessor = typeof existing === 'string' &&
|
|
153
|
+
/^@@=[A-Za-z_$][\w$]*$/.test(existing.trim());
|
|
154
|
+
if (existing !== undefined && !existingIsSimpleAccessor) {
|
|
53
155
|
continue;
|
|
54
156
|
}
|
|
55
157
|
if (binding.kind === 'geometry') {
|
|
56
|
-
const columnName = resolveConfiguredColumn(layerProps, binding.configKey)
|
|
158
|
+
const columnName = resolveConfiguredColumn(layerProps, binding.configKey) ??
|
|
159
|
+
(existingIsSimpleAccessor
|
|
160
|
+
? existing.trim().slice(3)
|
|
161
|
+
: undefined);
|
|
57
162
|
if (binding.required && !columnName) {
|
|
58
163
|
throw new Error(`Layer "${layerName}" requires _sqlroomsBinding.${binding.configKey}.`);
|
|
59
164
|
}
|
|
@@ -91,10 +196,33 @@ function resolveGeoArrowBindings(options) {
|
|
|
91
196
|
`but only point coordinates were found. Available columns: ${available}.`);
|
|
92
197
|
}
|
|
93
198
|
if (!resolvedGeometry.nativeGeoArrow) {
|
|
94
|
-
if (!compatibility.allowGeoArrowPromotion
|
|
95
|
-
!wkbGeometryDecoder.supportsGeoArrowPromotion(layerName, resolvedGeometry.encoding, prepared.table, resolvedGeometry.columnName)) {
|
|
199
|
+
if (!compatibility.allowGeoArrowPromotion) {
|
|
96
200
|
throw new Error(`Layer "${layerName}" cannot render geometry encoding "${resolvedGeometry.encoding}" for dataset "${prepared.datasetId}".`);
|
|
97
201
|
}
|
|
202
|
+
// Point layers: promote Points only — no silent polygon centroid.
|
|
203
|
+
if (isPointPositionLayer(layerName)) {
|
|
204
|
+
const promoted = promoteToPointPositions(prepared.table, resolvedGeometry.columnName, resolvedGeometry.encoding);
|
|
205
|
+
if (!promoted) {
|
|
206
|
+
throw new Error(`Layer "${layerName}" needs Point positions for dataset "${prepared.datasetId}" ` +
|
|
207
|
+
`(geometry encoding "${resolvedGeometry.encoding}"). ` +
|
|
208
|
+
`Use a point geometry column, or transformSql with ` +
|
|
209
|
+
`ST_AsWKB(ST_Centroid(geom)) / ST_PointOnSurface(geom). ` +
|
|
210
|
+
`For building footprints prefer GeoArrowPolygonLayer or GeoJsonLayer.`);
|
|
211
|
+
}
|
|
212
|
+
boundProps[binding.prop] = promoted.geometryColumn;
|
|
213
|
+
if (table === prepared.table) {
|
|
214
|
+
table = promoted.table;
|
|
215
|
+
}
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
if (!wkbGeometryDecoder.supportsGeoArrowPromotion(layerName, resolvedGeometry.encoding, prepared.table, resolvedGeometry.columnName)) {
|
|
219
|
+
const pathHint = layerName === 'GeoArrowPathLayer' ||
|
|
220
|
+
layerName === 'GeoArrowTripsLayer'
|
|
221
|
+
? ` GeoArrowPathLayer needs LineString WKB (or a single-part MultiLineString). Multi-part MultiLineString cannot be stitched into one path — explode/merge with ST_Dump / ST_LineMerge first, then ST_AsWKB.`
|
|
222
|
+
: '';
|
|
223
|
+
const mixedHint = describeGeoArrowPromotionFailure(layerName, resolvedGeometry.encoding, prepared.table, resolvedGeometry.columnName);
|
|
224
|
+
throw new Error(`Layer "${layerName}" cannot render geometry encoding "${resolvedGeometry.encoding}" for dataset "${prepared.datasetId}".${pathHint}${mixedHint}`);
|
|
225
|
+
}
|
|
98
226
|
}
|
|
99
227
|
const layerData = prepared.getGeoArrowLayerData(columnName);
|
|
100
228
|
if (layerData.source === 'promoted') {
|
|
@@ -112,7 +240,10 @@ function resolveGeoArrowBindings(options) {
|
|
|
112
240
|
}
|
|
113
241
|
continue;
|
|
114
242
|
}
|
|
115
|
-
const columnName = resolveConfiguredColumn(layerProps, binding.configKey)
|
|
243
|
+
const columnName = resolveConfiguredColumn(layerProps, binding.configKey) ??
|
|
244
|
+
(existingIsSimpleAccessor
|
|
245
|
+
? existing.trim().slice(3)
|
|
246
|
+
: undefined);
|
|
116
247
|
if (!columnName) {
|
|
117
248
|
if (binding.required) {
|
|
118
249
|
throw new Error(`Layer "${layerName}" requires _sqlroomsBinding.${binding.configKey}.`);
|
|
@@ -129,179 +260,175 @@ function resolveGeoArrowBindings(options) {
|
|
|
129
260
|
}
|
|
130
261
|
export function createDeckJsonConfiguration(options) {
|
|
131
262
|
const { datasetStates, datasetIds } = options;
|
|
263
|
+
let nextManagedLayerIndex = 0;
|
|
132
264
|
return new JSONConfiguration({
|
|
133
265
|
classes: DEFAULT_DECK_JSON_CLASSES,
|
|
134
266
|
enumerations: DEFAULT_DECK_JSON_ENUMERATIONS,
|
|
135
267
|
constants: DEFAULT_DECK_JSON_CONSTANTS,
|
|
136
268
|
functions: {
|
|
137
269
|
colorScale: (props) => createColorScaleMarker(props),
|
|
138
|
-
scale: (props) =>
|
|
139
|
-
const field = typeof props.field === 'string' ? props.field : undefined;
|
|
140
|
-
if (!field)
|
|
141
|
-
return undefined;
|
|
142
|
-
return `@@=${field}`;
|
|
143
|
-
},
|
|
270
|
+
scale: (props) => createScaleMarker(props),
|
|
144
271
|
},
|
|
145
272
|
// We preserve raw `@@=` strings here because `@deck.gl/json` would otherwise
|
|
146
273
|
// eagerly compile them into row-based accessors before `preProcessClassProps`
|
|
147
274
|
// can rewrite them for GeoArrow's batch-oriented callback contract.
|
|
148
275
|
convertFunction: ((expression) => `@@=${expression}`),
|
|
149
276
|
preProcessClassProps: (Class, props) => {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
if (!compatibility) {
|
|
153
|
-
return props;
|
|
154
|
-
}
|
|
155
|
-
const layerProps = props;
|
|
156
|
-
const extensionProps = layerProps;
|
|
157
|
-
const datasetId = resolveDatasetId(extensionProps, datasetIds);
|
|
158
|
-
const managed = isManagedLayer(extensionProps, datasetIds) ||
|
|
159
|
-
(datasetIds.length > 1 && layerProps.data === undefined);
|
|
160
|
-
if (!managed) {
|
|
161
|
-
return props;
|
|
162
|
-
}
|
|
163
|
-
if (!datasetId) {
|
|
164
|
-
throw new Error(`Layer "${layerName}" must declare _sqlroomsBinding.dataset when multiple datasets are available.`);
|
|
165
|
-
}
|
|
166
|
-
const datasetState = datasetStates[datasetId];
|
|
167
|
-
if (!datasetState) {
|
|
168
|
-
throw new Error(`Layer "${layerName}" references unknown dataset "${datasetId}".`);
|
|
277
|
+
try {
|
|
278
|
+
return preprocessManagedLayer();
|
|
169
279
|
}
|
|
170
|
-
|
|
171
|
-
|
|
280
|
+
catch (error) {
|
|
281
|
+
// JSONConverter skips postProcessConvertedJson when convert throws.
|
|
282
|
+
nextManagedLayerIndex = 0;
|
|
283
|
+
throw error;
|
|
172
284
|
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
285
|
+
function preprocessManagedLayer() {
|
|
286
|
+
const layerName = getLayerName(Class);
|
|
287
|
+
const compatibility = getLayerCompatibility(layerName);
|
|
288
|
+
if (!compatibility) {
|
|
289
|
+
return props;
|
|
290
|
+
}
|
|
291
|
+
const layerProps = props;
|
|
292
|
+
const extensionProps = layerProps;
|
|
293
|
+
const datasetId = resolveDatasetId(extensionProps, datasetIds);
|
|
294
|
+
const managed = isManagedLayer(extensionProps, datasetIds) ||
|
|
295
|
+
(datasetIds.length > 1 && layerProps.data === undefined);
|
|
296
|
+
if (!managed) {
|
|
297
|
+
return props;
|
|
298
|
+
}
|
|
299
|
+
if (!datasetId) {
|
|
300
|
+
throw new Error(`Layer "${layerName}" must declare _sqlroomsBinding.dataset when multiple datasets are available.`);
|
|
301
|
+
}
|
|
302
|
+
const datasetState = datasetStates[datasetId];
|
|
303
|
+
if (!datasetState) {
|
|
304
|
+
throw new Error(`Layer "${layerName}" references unknown dataset "${datasetId}".`);
|
|
305
|
+
}
|
|
306
|
+
if (datasetState.status !== 'ready') {
|
|
307
|
+
const pendingProps = stripLayerExtensionProps(layerProps);
|
|
308
|
+
assignStableLayerId(pendingProps, datasetId, layerName, nextManagedLayerIndex++);
|
|
309
|
+
return { ...pendingProps, data: [] };
|
|
310
|
+
}
|
|
311
|
+
const prepared = datasetState.prepared;
|
|
312
|
+
const geometryColumn = resolveGeometryColumn(extensionProps);
|
|
313
|
+
const strippedProps = stripLayerExtensionProps(layerProps);
|
|
314
|
+
assignStableLayerId(strippedProps, datasetId, layerName, nextManagedLayerIndex++);
|
|
315
|
+
if (compatibility.representation === 'geojson') {
|
|
316
|
+
const baseProps = applyColorScale({
|
|
317
|
+
props: strippedProps,
|
|
318
|
+
table: prepared.table,
|
|
319
|
+
});
|
|
320
|
+
const withElevation = compileGetElevation({
|
|
321
|
+
props: baseProps,
|
|
322
|
+
table: prepared.table,
|
|
323
|
+
layerName,
|
|
324
|
+
datasetId: prepared.datasetId,
|
|
325
|
+
requireFunctionAccessor: true,
|
|
326
|
+
});
|
|
327
|
+
return {
|
|
328
|
+
...mergeGetElevationTrigger(withElevation, baseProps.getElevation),
|
|
329
|
+
data: prepared.getGeoJsonBinaryData(geometryColumn),
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
const { table, boundProps } = resolveGeoArrowBindings({
|
|
333
|
+
layerName,
|
|
334
|
+
compatibility: compatibility,
|
|
335
|
+
layerProps: extensionProps,
|
|
336
|
+
prepared,
|
|
337
|
+
props: strippedProps,
|
|
338
|
+
});
|
|
177
339
|
const baseProps = applyColorScale({
|
|
178
340
|
props: strippedProps,
|
|
179
|
-
table
|
|
341
|
+
table,
|
|
180
342
|
});
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
const elevField = rawElev.slice(3).trim();
|
|
207
|
-
const elevVector = table.getChild(elevField);
|
|
208
|
-
if (elevVector) {
|
|
209
|
-
let min = Infinity;
|
|
210
|
-
for (let i = 0; i < elevVector.length; i++) {
|
|
211
|
-
const v = Number(elevVector.get(i));
|
|
212
|
-
if (Number.isFinite(v) && v < min)
|
|
213
|
-
min = v;
|
|
214
|
-
}
|
|
215
|
-
if (Number.isFinite(min) && min !== 0) {
|
|
216
|
-
nextProps.getElevation = `@@=Math.max(0, ${elevField} - ${min})`;
|
|
343
|
+
const nextProps = compileGetElevation({
|
|
344
|
+
props: {
|
|
345
|
+
...baseProps,
|
|
346
|
+
data: table,
|
|
347
|
+
...boundProps,
|
|
348
|
+
},
|
|
349
|
+
table,
|
|
350
|
+
layerName,
|
|
351
|
+
datasetId: prepared.datasetId,
|
|
352
|
+
});
|
|
353
|
+
const rewritten = rewriteGeoArrowAccessors({
|
|
354
|
+
props: nextProps,
|
|
355
|
+
table,
|
|
356
|
+
layerName,
|
|
357
|
+
});
|
|
358
|
+
// Set updateTriggers for @@= accessor props and getElevation
|
|
359
|
+
// so deck.gl re-evaluates them when references change or are cleared.
|
|
360
|
+
{
|
|
361
|
+
const accessorTriggers = {};
|
|
362
|
+
for (const [propName, propValue] of Object.entries(nextProps)) {
|
|
363
|
+
if (typeof propValue === 'string' &&
|
|
364
|
+
propValue.startsWith('@@=') &&
|
|
365
|
+
propName.startsWith('get')) {
|
|
366
|
+
accessorTriggers[propName] = propValue;
|
|
367
|
+
}
|
|
217
368
|
}
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
});
|
|
225
|
-
// Set updateTriggers for @@= accessor props and getElevation
|
|
226
|
-
// so deck.gl re-evaluates them when references change or are cleared.
|
|
227
|
-
{
|
|
228
|
-
const accessorTriggers = {};
|
|
229
|
-
for (const [propName, propValue] of Object.entries(nextProps)) {
|
|
230
|
-
if (typeof propValue === 'string' &&
|
|
231
|
-
propValue.startsWith('@@=') &&
|
|
232
|
-
propName.startsWith('get')) {
|
|
233
|
-
accessorTriggers[propName] = propValue;
|
|
369
|
+
// Always emit getElevation trigger so clearing the column invalidates
|
|
370
|
+
// stale heights from a previous column-based accessor.
|
|
371
|
+
if (!('getElevation' in accessorTriggers)) {
|
|
372
|
+
const elev = nextProps.getElevation;
|
|
373
|
+
accessorTriggers.getElevation =
|
|
374
|
+
elev !== undefined ? String(elev) : 'none';
|
|
234
375
|
}
|
|
376
|
+
const existingTriggers = rewritten.updateTriggers &&
|
|
377
|
+
typeof rewritten.updateTriggers === 'object' &&
|
|
378
|
+
!Array.isArray(rewritten.updateTriggers)
|
|
379
|
+
? rewritten.updateTriggers
|
|
380
|
+
: {};
|
|
381
|
+
rewritten.updateTriggers = {
|
|
382
|
+
...existingTriggers,
|
|
383
|
+
...accessorTriggers,
|
|
384
|
+
};
|
|
235
385
|
}
|
|
236
|
-
//
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
}
|
|
253
|
-
// For TripsLayer: compute max timestamp for animation and set defaults
|
|
254
|
-
if (layerName === 'GeoArrowTripsLayer' || layerName === 'TripsLayer') {
|
|
255
|
-
const tsVector = boundProps.getTimestamps;
|
|
256
|
-
if (tsVector) {
|
|
257
|
-
let maxTs = 0;
|
|
258
|
-
for (let i = 0; i < tsVector.length; i++) {
|
|
259
|
-
const listItem = tsVector.get(i);
|
|
260
|
-
if (listItem &&
|
|
261
|
-
typeof listItem === 'object' &&
|
|
262
|
-
'length' in listItem) {
|
|
263
|
-
const list = listItem;
|
|
264
|
-
for (let j = 0; j < list.length; j++) {
|
|
265
|
-
const v = Number(list.get(j)) || 0;
|
|
266
|
-
if (v > maxTs)
|
|
267
|
-
maxTs = v;
|
|
386
|
+
// For TripsLayer: compute max timestamp for animation and set defaults
|
|
387
|
+
if (layerName === 'GeoArrowTripsLayer' || layerName === 'TripsLayer') {
|
|
388
|
+
const tsVector = boundProps.getTimestamps;
|
|
389
|
+
if (tsVector) {
|
|
390
|
+
let maxTs = 0;
|
|
391
|
+
for (let i = 0; i < tsVector.length; i++) {
|
|
392
|
+
const listItem = tsVector.get(i);
|
|
393
|
+
if (listItem &&
|
|
394
|
+
typeof listItem === 'object' &&
|
|
395
|
+
'length' in listItem) {
|
|
396
|
+
const list = listItem;
|
|
397
|
+
for (let j = 0; j < list.length; j++) {
|
|
398
|
+
const v = Number(list.get(j)) || 0;
|
|
399
|
+
if (v > maxTs)
|
|
400
|
+
maxTs = v;
|
|
401
|
+
}
|
|
268
402
|
}
|
|
269
403
|
}
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
404
|
+
if (maxTs > 0) {
|
|
405
|
+
rewritten._tripsMaxTimestamp = maxTs;
|
|
406
|
+
if (!rewritten.trailLength) {
|
|
407
|
+
rewritten.trailLength = maxTs;
|
|
408
|
+
}
|
|
409
|
+
if (rewritten.currentTime === undefined ||
|
|
410
|
+
rewritten.currentTime === 0) {
|
|
411
|
+
rewritten.currentTime = maxTs;
|
|
412
|
+
}
|
|
279
413
|
}
|
|
280
414
|
}
|
|
281
415
|
}
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
416
|
+
// HeatmapLayer remaps colorRange in _updateColorTexture. Putting it in
|
|
417
|
+
// getWeight updateTriggers would mark aggregation dirty and rebuild the
|
|
418
|
+
// GPU weight texture when only the colormap changed.
|
|
419
|
+
if (layerName === 'GeoArrowHeatmapLayer') {
|
|
420
|
+
if (!rewritten.colorRange) {
|
|
421
|
+
rewritten.colorRange = DEFAULT_HEATMAP_COLOR_RANGE;
|
|
422
|
+
}
|
|
423
|
+
if (rewritten.weightsTextureSize === undefined) {
|
|
424
|
+
rewritten.weightsTextureSize = DEFAULT_HEATMAP_WEIGHTS_TEXTURE_SIZE;
|
|
425
|
+
}
|
|
288
426
|
}
|
|
289
|
-
|
|
290
|
-
typeof rewritten.updateTriggers === 'object' &&
|
|
291
|
-
!Array.isArray(rewritten.updateTriggers)
|
|
292
|
-
? rewritten.updateTriggers
|
|
293
|
-
: {};
|
|
294
|
-
const previousGetWeight = existingTriggers.getWeight;
|
|
295
|
-
rewritten.updateTriggers = {
|
|
296
|
-
...existingTriggers,
|
|
297
|
-
getWeight: previousGetWeight === undefined
|
|
298
|
-
? JSON.stringify(rewritten.colorRange)
|
|
299
|
-
: [previousGetWeight, JSON.stringify(rewritten.colorRange)],
|
|
300
|
-
};
|
|
427
|
+
return rewritten;
|
|
301
428
|
}
|
|
302
|
-
return rewritten;
|
|
303
429
|
},
|
|
304
430
|
postProcessConvertedJson: (json) => {
|
|
431
|
+
nextManagedLayerIndex = 0;
|
|
305
432
|
if (json &&
|
|
306
433
|
typeof json === 'object' &&
|
|
307
434
|
'layers' in json &&
|