@sqlrooms/deck 0.29.0-rc.7 → 0.29.0-rc.9
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/LICENSE.md +2 -1
- package/README.md +31 -6
- package/dist/DeckJsonMap.d.ts +2 -2
- package/dist/DeckJsonMap.d.ts.map +1 -1
- package/dist/DeckJsonMap.js +204 -17
- package/dist/DeckJsonMap.js.map +1 -1
- package/dist/DeckJsonMapSpec.d.ts +36 -36
- package/dist/DeckJsonMapSpec.d.ts.map +1 -1
- package/dist/DeckJsonMapSpec.js +1 -0
- package/dist/DeckJsonMapSpec.js.map +1 -1
- package/dist/MapSettings.d.ts.map +1 -1
- package/dist/MapSettings.js +203 -25
- package/dist/MapSettings.js.map +1 -1
- package/dist/ai.d.ts +55 -8
- package/dist/ai.d.ts.map +1 -1
- package/dist/ai.js +190 -41
- package/dist/ai.js.map +1 -1
- package/dist/block.d.ts +20 -0
- package/dist/block.d.ts.map +1 -0
- package/dist/block.js +119 -0
- package/dist/block.js.map +1 -0
- package/dist/dashboard.d.ts +2 -0
- package/dist/dashboard.d.ts.map +1 -1
- package/dist/dashboard.js +194 -285
- package/dist/dashboard.js.map +1 -1
- package/dist/dashboardConfig.d.ts +11 -3
- package/dist/dashboardConfig.d.ts.map +1 -1
- package/dist/dashboardConfig.js +82 -7
- package/dist/dashboardConfig.js.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/json/aggregateWaypoints.d.ts +14 -0
- package/dist/json/aggregateWaypoints.d.ts.map +1 -0
- package/dist/json/aggregateWaypoints.js +190 -0
- package/dist/json/aggregateWaypoints.js.map +1 -0
- package/dist/json/compileColorScale.d.ts +1 -1
- package/dist/json/compileColorScale.d.ts.map +1 -1
- package/dist/json/compileColorScale.js +42 -20
- package/dist/json/compileColorScale.js.map +1 -1
- package/dist/json/createDeckJsonConfiguration.d.ts.map +1 -1
- package/dist/json/createDeckJsonConfiguration.js +106 -8
- package/dist/json/createDeckJsonConfiguration.js.map +1 -1
- package/dist/json/defaultClasses.d.ts +5 -4
- package/dist/json/defaultClasses.d.ts.map +1 -1
- package/dist/json/defaultClasses.js +9 -4
- package/dist/json/defaultClasses.js.map +1 -1
- package/dist/json/extractColorScaleLegends.d.ts.map +1 -1
- package/dist/json/extractColorScaleLegends.js +43 -5
- package/dist/json/extractColorScaleLegends.js.map +1 -1
- package/dist/json/heatmapDefaults.d.ts +8 -0
- package/dist/json/heatmapDefaults.d.ts.map +1 -0
- package/dist/json/heatmapDefaults.js +14 -0
- package/dist/json/heatmapDefaults.js.map +1 -0
- package/dist/json/layerCompatibility.d.ts.map +1 -1
- package/dist/json/layerCompatibility.js +5 -1
- package/dist/json/layerCompatibility.js.map +1 -1
- package/dist/json/layers/DeckColumnLayer.d.ts +12 -0
- package/dist/json/layers/DeckColumnLayer.d.ts.map +1 -0
- package/dist/json/layers/DeckColumnLayer.js +26 -0
- package/dist/json/layers/DeckColumnLayer.js.map +1 -0
- package/dist/json/layers/DeckH3HexagonLayer.d.ts +37 -0
- package/dist/json/layers/DeckH3HexagonLayer.d.ts.map +1 -0
- package/dist/json/layers/DeckH3HexagonLayer.js +96 -0
- package/dist/json/layers/DeckH3HexagonLayer.js.map +1 -0
- package/dist/json/layers/DeckTripsLayer.d.ts +45 -0
- package/dist/json/layers/DeckTripsLayer.d.ts.map +1 -0
- package/dist/json/layers/DeckTripsLayer.js +169 -0
- package/dist/json/layers/DeckTripsLayer.js.map +1 -0
- package/dist/json/layers/index.d.ts +4 -0
- package/dist/json/layers/index.d.ts.map +1 -0
- package/dist/json/layers/index.js +4 -0
- package/dist/json/layers/index.js.map +1 -0
- package/dist/json/rewriteGeoArrowAccessors.d.ts.map +1 -1
- package/dist/json/rewriteGeoArrowAccessors.js +5 -0
- package/dist/json/rewriteGeoArrowAccessors.js.map +1 -1
- package/dist/mapConfigUtils.d.ts +102 -1
- package/dist/mapConfigUtils.d.ts.map +1 -1
- package/dist/mapConfigUtils.js +21 -3
- package/dist/mapConfigUtils.js.map +1 -1
- package/dist/mapLayerConfigUtils.d.ts +15 -0
- package/dist/mapLayerConfigUtils.d.ts.map +1 -1
- package/dist/mapLayerConfigUtils.js +109 -7
- package/dist/mapLayerConfigUtils.js.map +1 -1
- package/dist/prepare/detectGeometryColumn.d.ts +10 -1
- package/dist/prepare/detectGeometryColumn.d.ts.map +1 -1
- package/dist/prepare/detectGeometryColumn.js +48 -6
- package/dist/prepare/detectGeometryColumn.js.map +1 -1
- package/dist/prepare/wkbDecoder.d.ts.map +1 -1
- package/dist/prepare/wkbDecoder.js +88 -1
- package/dist/prepare/wkbDecoder.js.map +1 -1
- package/dist/prepare/wkbParser.d.ts +5 -0
- package/dist/prepare/wkbParser.d.ts.map +1 -1
- package/dist/prepare/wkbParser.js +24 -0
- package/dist/prepare/wkbParser.js.map +1 -1
- package/dist/types.d.ts +14 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/useDeckMapDatasets.d.ts +17 -0
- package/dist/useDeckMapDatasets.d.ts.map +1 -0
- package/dist/useDeckMapDatasets.js +69 -0
- package/dist/useDeckMapDatasets.js.map +1 -0
- package/dist/useDeckMapFitToBounds.d.ts +29 -0
- package/dist/useDeckMapFitToBounds.d.ts.map +1 -0
- package/dist/useDeckMapFitToBounds.js +333 -0
- package/dist/useDeckMapFitToBounds.js.map +1 -0
- package/package.json +7 -6
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import * as arrow from 'apache-arrow';
|
|
2
|
+
import { findCoordinateColumns } from '../prepare/detectGeometryColumn';
|
|
3
|
+
const GROUP_ID_PATTERNS = [
|
|
4
|
+
'path_id',
|
|
5
|
+
'route_id',
|
|
6
|
+
'trip_id',
|
|
7
|
+
'track_id',
|
|
8
|
+
'line_id',
|
|
9
|
+
'segment_id',
|
|
10
|
+
'id',
|
|
11
|
+
'path',
|
|
12
|
+
'route',
|
|
13
|
+
'trip',
|
|
14
|
+
'track',
|
|
15
|
+
];
|
|
16
|
+
const ORDER_PATTERNS = [
|
|
17
|
+
'waypoint_order',
|
|
18
|
+
'point_order',
|
|
19
|
+
'order',
|
|
20
|
+
'sequence',
|
|
21
|
+
'seq',
|
|
22
|
+
'waypoint',
|
|
23
|
+
'index',
|
|
24
|
+
'step',
|
|
25
|
+
'position',
|
|
26
|
+
'sort',
|
|
27
|
+
];
|
|
28
|
+
const TIMESTAMP_PATTERNS = [
|
|
29
|
+
'timestamp',
|
|
30
|
+
'timestamps',
|
|
31
|
+
'time',
|
|
32
|
+
't',
|
|
33
|
+
'elapsed',
|
|
34
|
+
'seconds',
|
|
35
|
+
'ms',
|
|
36
|
+
];
|
|
37
|
+
function findColumnByPatterns(fieldNames, patterns) {
|
|
38
|
+
const lower = fieldNames.map((n) => n.toLowerCase());
|
|
39
|
+
for (const pattern of patterns) {
|
|
40
|
+
const idx = lower.indexOf(pattern);
|
|
41
|
+
if (idx >= 0)
|
|
42
|
+
return fieldNames[idx];
|
|
43
|
+
}
|
|
44
|
+
return undefined;
|
|
45
|
+
}
|
|
46
|
+
function findLatLonColumns(table) {
|
|
47
|
+
const result = findCoordinateColumns(table);
|
|
48
|
+
if (!result)
|
|
49
|
+
return null;
|
|
50
|
+
return { lat: result.latField, lon: result.lonField };
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Auto-aggregates per-waypoint rows into LineString vectors for PathLayer.
|
|
54
|
+
* Detects group-by ID and order columns by naming patterns, groups rows,
|
|
55
|
+
* and builds a GeoArrow List<FixedSizeList<2, Float64>> linestring vector.
|
|
56
|
+
*
|
|
57
|
+
* Also builds a timestamps list column if a timestamp-like column is found,
|
|
58
|
+
* suitable for GeoArrowTripsLayer.
|
|
59
|
+
*/
|
|
60
|
+
export function tryAggregateWaypointsToLineStrings(table) {
|
|
61
|
+
const fieldNames = table.schema.fields.map((f) => f.name);
|
|
62
|
+
const groupCol = findColumnByPatterns(fieldNames, GROUP_ID_PATTERNS);
|
|
63
|
+
if (!groupCol)
|
|
64
|
+
return null;
|
|
65
|
+
const coords = findLatLonColumns(table);
|
|
66
|
+
if (!coords)
|
|
67
|
+
return null;
|
|
68
|
+
const orderCol = findColumnByPatterns(fieldNames, ORDER_PATTERNS);
|
|
69
|
+
const groupVector = table.getChild(groupCol);
|
|
70
|
+
const latVector = table.getChild(coords.lat);
|
|
71
|
+
const lonVector = table.getChild(coords.lon);
|
|
72
|
+
const orderVector = orderCol ? table.getChild(orderCol) : null;
|
|
73
|
+
// Collect rows per group
|
|
74
|
+
const groups = new Map();
|
|
75
|
+
const groupOrder = [];
|
|
76
|
+
for (let i = 0; i < table.numRows; i++) {
|
|
77
|
+
const key = String(groupVector.get(i) ?? '');
|
|
78
|
+
let group = groups.get(key);
|
|
79
|
+
if (!group) {
|
|
80
|
+
group = { indices: [] };
|
|
81
|
+
groups.set(key, group);
|
|
82
|
+
groupOrder.push(key);
|
|
83
|
+
}
|
|
84
|
+
group.indices.push(i);
|
|
85
|
+
}
|
|
86
|
+
// Sort indices within each group by order column
|
|
87
|
+
if (orderVector) {
|
|
88
|
+
for (const group of groups.values()) {
|
|
89
|
+
group.indices.sort((a, b) => {
|
|
90
|
+
const av = Number(orderVector.get(a)) || 0;
|
|
91
|
+
const bv = Number(orderVector.get(b)) || 0;
|
|
92
|
+
return av - bv;
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
const numPaths = groupOrder.length;
|
|
97
|
+
const offsets = new Int32Array(numPaths + 1);
|
|
98
|
+
let totalPoints = 0;
|
|
99
|
+
for (let g = 0; g < numPaths; g++) {
|
|
100
|
+
offsets[g] = totalPoints;
|
|
101
|
+
totalPoints += groups.get(groupOrder[g]).indices.length;
|
|
102
|
+
}
|
|
103
|
+
offsets[numPaths] = totalPoints;
|
|
104
|
+
const flatCoords = new Float64Array(totalPoints * 2);
|
|
105
|
+
let writeIdx = 0;
|
|
106
|
+
for (const key of groupOrder) {
|
|
107
|
+
for (const rowIdx of groups.get(key).indices) {
|
|
108
|
+
flatCoords[writeIdx++] = Number(lonVector.get(rowIdx)) || 0;
|
|
109
|
+
flatCoords[writeIdx++] = Number(latVector.get(rowIdx)) || 0;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
// Build GeoArrow LineString vector: List<FixedSizeList<2, Float64>>
|
|
113
|
+
const coordField = new arrow.Field('xy', new arrow.Float64(), false);
|
|
114
|
+
const vertexType = new arrow.FixedSizeList(2, coordField);
|
|
115
|
+
const vertexField = new arrow.Field('', vertexType, true);
|
|
116
|
+
const lineStringType = new arrow.List(vertexField);
|
|
117
|
+
const floatData = arrow.makeData({
|
|
118
|
+
type: new arrow.Float64(),
|
|
119
|
+
length: totalPoints * 2,
|
|
120
|
+
data: flatCoords,
|
|
121
|
+
});
|
|
122
|
+
const vertexData = arrow.makeData({
|
|
123
|
+
type: vertexType,
|
|
124
|
+
length: totalPoints,
|
|
125
|
+
child: floatData,
|
|
126
|
+
});
|
|
127
|
+
const lineData = arrow.makeData({
|
|
128
|
+
type: lineStringType,
|
|
129
|
+
length: numPaths,
|
|
130
|
+
valueOffsets: offsets,
|
|
131
|
+
child: vertexData,
|
|
132
|
+
});
|
|
133
|
+
const geometryVector = new arrow.Vector([lineData]);
|
|
134
|
+
// Build aggregated table with one row per path (first row's non-geom values)
|
|
135
|
+
const columns = {};
|
|
136
|
+
const timestampCol = findColumnByPatterns(fieldNames, TIMESTAMP_PATTERNS);
|
|
137
|
+
const excludeCols = new Set([coords.lat, coords.lon, orderCol, timestampCol].filter(Boolean));
|
|
138
|
+
for (const field of table.schema.fields) {
|
|
139
|
+
if (excludeCols.has(field.name))
|
|
140
|
+
continue;
|
|
141
|
+
const srcVector = table.getChild(field.name);
|
|
142
|
+
const values = [];
|
|
143
|
+
for (const key of groupOrder) {
|
|
144
|
+
const firstIdx = groups.get(key).indices[0];
|
|
145
|
+
values.push(srcVector.get(firstIdx));
|
|
146
|
+
}
|
|
147
|
+
columns[field.name] = arrow.vectorFromArray(values);
|
|
148
|
+
}
|
|
149
|
+
columns['__geom'] = geometryVector;
|
|
150
|
+
// Build timestamps list column if a timestamp column exists.
|
|
151
|
+
// Must be a proper Arrow List<Float64> vector for GeoArrowTripsLayer.
|
|
152
|
+
if (timestampCol) {
|
|
153
|
+
const tsVector = table.getChild(timestampCol);
|
|
154
|
+
const tsOffsets = new Int32Array(numPaths + 1);
|
|
155
|
+
let tsTotalValues = 0;
|
|
156
|
+
for (let g = 0; g < numPaths; g++) {
|
|
157
|
+
tsOffsets[g] = tsTotalValues;
|
|
158
|
+
tsTotalValues += groups.get(groupOrder[g]).indices.length;
|
|
159
|
+
}
|
|
160
|
+
tsOffsets[numPaths] = tsTotalValues;
|
|
161
|
+
const tsFlat = new Float64Array(tsTotalValues);
|
|
162
|
+
let tsWriteIdx = 0;
|
|
163
|
+
for (const key of groupOrder) {
|
|
164
|
+
for (const rowIdx of groups.get(key).indices) {
|
|
165
|
+
tsFlat[tsWriteIdx++] = Number(tsVector.get(rowIdx)) || 0;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
const tsValueField = new arrow.Field('', new arrow.Float64(), true);
|
|
169
|
+
const tsListType = new arrow.List(tsValueField);
|
|
170
|
+
const tsValuesData = arrow.makeData({
|
|
171
|
+
type: new arrow.Float64(),
|
|
172
|
+
length: tsTotalValues,
|
|
173
|
+
data: tsFlat,
|
|
174
|
+
});
|
|
175
|
+
const tsListData = arrow.makeData({
|
|
176
|
+
type: tsListType,
|
|
177
|
+
length: numPaths,
|
|
178
|
+
valueOffsets: tsOffsets,
|
|
179
|
+
child: tsValuesData,
|
|
180
|
+
});
|
|
181
|
+
const tsListVector = new arrow.Vector([tsListData]);
|
|
182
|
+
columns[timestampCol] = tsListVector;
|
|
183
|
+
if (timestampCol !== 'timestamps') {
|
|
184
|
+
columns['timestamps'] = tsListVector;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
const aggregatedTable = new arrow.Table(columns);
|
|
188
|
+
return { table: aggregatedTable, geometryVector };
|
|
189
|
+
}
|
|
190
|
+
//# sourceMappingURL=aggregateWaypoints.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aggregateWaypoints.js","sourceRoot":"","sources":["../../src/json/aggregateWaypoints.ts"],"names":[],"mappings":"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","sourcesContent":["import * as arrow from 'apache-arrow';\nimport {findCoordinateColumns} from '../prepare/detectGeometryColumn';\n\nconst GROUP_ID_PATTERNS = [\n 'path_id',\n 'route_id',\n 'trip_id',\n 'track_id',\n 'line_id',\n 'segment_id',\n 'id',\n 'path',\n 'route',\n 'trip',\n 'track',\n];\nconst ORDER_PATTERNS = [\n 'waypoint_order',\n 'point_order',\n 'order',\n 'sequence',\n 'seq',\n 'waypoint',\n 'index',\n 'step',\n 'position',\n 'sort',\n];\nconst TIMESTAMP_PATTERNS = [\n 'timestamp',\n 'timestamps',\n 'time',\n 't',\n 'elapsed',\n 'seconds',\n 'ms',\n];\n\nfunction findColumnByPatterns(\n fieldNames: string[],\n patterns: string[],\n): string | undefined {\n const lower = fieldNames.map((n) => n.toLowerCase());\n for (const pattern of patterns) {\n const idx = lower.indexOf(pattern);\n if (idx >= 0) return fieldNames[idx];\n }\n return undefined;\n}\n\nfunction findLatLonColumns(\n table: arrow.Table,\n): {lat: string; lon: string} | null {\n const result = findCoordinateColumns(table);\n if (!result) return null;\n return {lat: result.latField, lon: result.lonField};\n}\n\n/**\n * Auto-aggregates per-waypoint rows into LineString vectors for PathLayer.\n * Detects group-by ID and order columns by naming patterns, groups rows,\n * and builds a GeoArrow List<FixedSizeList<2, Float64>> linestring vector.\n *\n * Also builds a timestamps list column if a timestamp-like column is found,\n * suitable for GeoArrowTripsLayer.\n */\nexport function tryAggregateWaypointsToLineStrings(\n table: arrow.Table,\n): {table: arrow.Table; geometryVector: arrow.Vector} | null {\n const fieldNames = table.schema.fields.map((f) => f.name);\n const groupCol = findColumnByPatterns(fieldNames, GROUP_ID_PATTERNS);\n if (!groupCol) return null;\n\n const coords = findLatLonColumns(table);\n if (!coords) return null;\n\n const orderCol = findColumnByPatterns(fieldNames, ORDER_PATTERNS);\n\n const groupVector = table.getChild(groupCol)!;\n const latVector = table.getChild(coords.lat)!;\n const lonVector = table.getChild(coords.lon)!;\n const orderVector = orderCol ? table.getChild(orderCol) : null;\n\n // Collect rows per group\n const groups = new Map<string, {indices: number[]}>();\n const groupOrder: string[] = [];\n for (let i = 0; i < table.numRows; i++) {\n const key = String(groupVector.get(i) ?? '');\n let group = groups.get(key);\n if (!group) {\n group = {indices: []};\n groups.set(key, group);\n groupOrder.push(key);\n }\n group.indices.push(i);\n }\n\n // Sort indices within each group by order column\n if (orderVector) {\n for (const group of groups.values()) {\n group.indices.sort((a, b) => {\n const av = Number(orderVector.get(a)) || 0;\n const bv = Number(orderVector.get(b)) || 0;\n return av - bv;\n });\n }\n }\n\n const numPaths = groupOrder.length;\n const offsets = new Int32Array(numPaths + 1);\n let totalPoints = 0;\n\n for (let g = 0; g < numPaths; g++) {\n offsets[g] = totalPoints;\n totalPoints += groups.get(groupOrder[g]!)!.indices.length;\n }\n offsets[numPaths] = totalPoints;\n\n const flatCoords = new Float64Array(totalPoints * 2);\n let writeIdx = 0;\n for (const key of groupOrder) {\n for (const rowIdx of groups.get(key)!.indices) {\n flatCoords[writeIdx++] = Number(lonVector.get(rowIdx)) || 0;\n flatCoords[writeIdx++] = Number(latVector.get(rowIdx)) || 0;\n }\n }\n\n // Build GeoArrow LineString vector: List<FixedSizeList<2, Float64>>\n const coordField = new arrow.Field('xy', new arrow.Float64(), false);\n const vertexType = new arrow.FixedSizeList(2, coordField);\n const vertexField = new arrow.Field('', vertexType, true);\n const lineStringType = new arrow.List(vertexField);\n\n const floatData = arrow.makeData({\n type: new arrow.Float64(),\n length: totalPoints * 2,\n data: flatCoords,\n });\n const vertexData = arrow.makeData({\n type: vertexType,\n length: totalPoints,\n child: floatData,\n });\n const lineData = arrow.makeData({\n type: lineStringType,\n length: numPaths,\n valueOffsets: offsets,\n child: vertexData,\n });\n const geometryVector = new arrow.Vector([lineData]);\n\n // Build aggregated table with one row per path (first row's non-geom values)\n const columns: Record<string, arrow.Vector> = {};\n const timestampCol = findColumnByPatterns(fieldNames, TIMESTAMP_PATTERNS);\n const excludeCols = new Set(\n [coords.lat, coords.lon, orderCol, timestampCol].filter(Boolean),\n );\n\n for (const field of table.schema.fields) {\n if (excludeCols.has(field.name)) continue;\n const srcVector = table.getChild(field.name)!;\n const values: unknown[] = [];\n for (const key of groupOrder) {\n const firstIdx = groups.get(key)!.indices[0]!;\n values.push(srcVector.get(firstIdx));\n }\n columns[field.name] = arrow.vectorFromArray(values);\n }\n columns['__geom'] = geometryVector;\n\n // Build timestamps list column if a timestamp column exists.\n // Must be a proper Arrow List<Float64> vector for GeoArrowTripsLayer.\n if (timestampCol) {\n const tsVector = table.getChild(timestampCol)!;\n const tsOffsets = new Int32Array(numPaths + 1);\n let tsTotalValues = 0;\n for (let g = 0; g < numPaths; g++) {\n tsOffsets[g] = tsTotalValues;\n tsTotalValues += groups.get(groupOrder[g]!)!.indices.length;\n }\n tsOffsets[numPaths] = tsTotalValues;\n\n const tsFlat = new Float64Array(tsTotalValues);\n let tsWriteIdx = 0;\n for (const key of groupOrder) {\n for (const rowIdx of groups.get(key)!.indices) {\n tsFlat[tsWriteIdx++] = Number(tsVector.get(rowIdx)) || 0;\n }\n }\n\n const tsValueField = new arrow.Field('', new arrow.Float64(), true);\n const tsListType = new arrow.List(tsValueField);\n const tsValuesData = arrow.makeData({\n type: new arrow.Float64(),\n length: tsTotalValues,\n data: tsFlat,\n });\n const tsListData = arrow.makeData({\n type: tsListType,\n length: numPaths,\n valueOffsets: tsOffsets,\n child: tsValuesData,\n });\n const tsListVector = new arrow.Vector([tsListData]);\n columns[timestampCol] = tsListVector;\n if (timestampCol !== 'timestamps') {\n columns['timestamps'] = tsListVector;\n }\n }\n\n const aggregatedTable = new arrow.Table(columns);\n return {table: aggregatedTable, geometryVector};\n}\n"]}
|
|
@@ -3,7 +3,7 @@ import type * as arrow from 'apache-arrow';
|
|
|
3
3
|
export declare function compileColorScale(options: {
|
|
4
4
|
table: arrow.Table;
|
|
5
5
|
colorScale: ColorScaleConfig;
|
|
6
|
-
}): (value: unknown) => import("@sqlrooms/color-scales").ResolvedRGBA;
|
|
6
|
+
}): (() => null) | ((value: unknown) => import("@sqlrooms/color-scales").ResolvedRGBA);
|
|
7
7
|
export declare function buildColorScaleLegend(options: {
|
|
8
8
|
table: arrow.Table;
|
|
9
9
|
colorScale: ColorScaleConfig;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compileColorScale.d.ts","sourceRoot":"","sources":["../../src/json/compileColorScale.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACzB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAC;AA2G3C,wBAAgB,iBAAiB,CAAC,OAAO,EAAE;IACzC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC;IACnB,UAAU,EAAE,gBAAgB,CAAC;CAC9B,
|
|
1
|
+
{"version":3,"file":"compileColorScale.d.ts","sourceRoot":"","sources":["../../src/json/compileColorScale.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACzB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAC;AA2G3C,wBAAgB,iBAAiB,CAAC,OAAO,EAAE;IACzC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC;IACnB,UAAU,EAAE,gBAAgB,CAAC;CAC9B,2BA0BgB,OAAO,oDAEvB;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE;IAC7C,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC;IACnB,UAAU,EAAE,gBAAgB,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,mBAAmB,GAAG,IAAI,CAuB7B"}
|
|
@@ -12,20 +12,6 @@ function resolveFieldName(schemaOwner, requestedField) {
|
|
|
12
12
|
}
|
|
13
13
|
return undefined;
|
|
14
14
|
}
|
|
15
|
-
function getColumn(table, field) {
|
|
16
|
-
const resolvedFieldName = resolveFieldName(table, field);
|
|
17
|
-
if (!resolvedFieldName) {
|
|
18
|
-
throw new Error(`Unknown colorScale field "${field}".`);
|
|
19
|
-
}
|
|
20
|
-
const vector = table.getChild(resolvedFieldName);
|
|
21
|
-
if (!vector) {
|
|
22
|
-
throw new Error(`Unable to read colorScale field "${resolvedFieldName}".`);
|
|
23
|
-
}
|
|
24
|
-
return {
|
|
25
|
-
fieldName: resolvedFieldName,
|
|
26
|
-
vector,
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
15
|
function getRowValue(row, fieldName) {
|
|
30
16
|
if (!row || typeof row !== 'object') {
|
|
31
17
|
return undefined;
|
|
@@ -67,18 +53,54 @@ function getGeoArrowOrRowValue(options) {
|
|
|
67
53
|
function getColumnValues(vector) {
|
|
68
54
|
return Array.from({ length: vector.length }, (_, index) => vector.get(index));
|
|
69
55
|
}
|
|
56
|
+
function getColumn(table, field) {
|
|
57
|
+
const resolvedFieldName = resolveFieldName(table, field);
|
|
58
|
+
if (!resolvedFieldName) {
|
|
59
|
+
throw new Error(`Unknown colorScale field "${field}".`);
|
|
60
|
+
}
|
|
61
|
+
const vector = table.getChild(resolvedFieldName);
|
|
62
|
+
if (!vector) {
|
|
63
|
+
throw new Error(`Unable to read colorScale field "${resolvedFieldName}".`);
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
fieldName: resolvedFieldName,
|
|
67
|
+
vector,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
70
|
export function compileColorScale(options) {
|
|
71
71
|
const { table, colorScale } = options;
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
colorScale
|
|
75
|
-
|
|
76
|
-
|
|
72
|
+
let column;
|
|
73
|
+
try {
|
|
74
|
+
column = getColumn(table, colorScale.field);
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
console.warn(`[compileColorScale] Field "${colorScale.field}" not found in dataset. Color scale will use default colors.`);
|
|
78
|
+
return () => null;
|
|
79
|
+
}
|
|
80
|
+
const { fieldName, vector } = column;
|
|
81
|
+
let mapper;
|
|
82
|
+
try {
|
|
83
|
+
mapper = createColorScaleMapper({
|
|
84
|
+
colorScale,
|
|
85
|
+
values: getColumnValues(vector),
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
catch (err) {
|
|
89
|
+
console.warn(`[compileColorScale] Failed to create color scale for field "${colorScale.field}":`, err);
|
|
90
|
+
return () => null;
|
|
91
|
+
}
|
|
77
92
|
return (value) => mapper(getGeoArrowOrRowValue({ value, fieldName, vector }));
|
|
78
93
|
}
|
|
79
94
|
export function buildColorScaleLegend(options) {
|
|
80
95
|
const { table, colorScale } = options;
|
|
81
|
-
|
|
96
|
+
let column;
|
|
97
|
+
try {
|
|
98
|
+
column = getColumn(table, colorScale.field);
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
const { vector } = column;
|
|
82
104
|
const values = getColumnValues(vector);
|
|
83
105
|
if (colorScale.type !== 'categorical' &&
|
|
84
106
|
values.every((value) => coerceFiniteNumber(value) === undefined)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compileColorScale.js","sourceRoot":"","sources":["../../src/json/compileColorScale.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,IAAI,4BAA4B,EACrD,kBAAkB,EAClB,sBAAsB,GAGvB,MAAM,wBAAwB,CAAC;AAGhC,SAAS,gBAAgB,CACvB,WAA4C,EAC5C,cAAsB;IAEtB,MAAM,UAAU,GAAG,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAC/C,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,cAAc,CACzC,EAAE,IAAI,CAAC;IACR,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,MAAM,sBAAsB,GAAG,WAAW,CAAC,MAAM,CAAC,MAAM;SACrD,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC;SAC1B,MAAM,CACL,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,WAAW,EAAE,KAAK,cAAc,CAAC,WAAW,EAAE,CACxE,CAAC;IAEJ,IAAI,sBAAsB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxC,OAAO,sBAAsB,CAAC,CAAC,CAAE,CAAC;IACpC,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,
|
|
1
|
+
{"version":3,"file":"compileColorScale.js","sourceRoot":"","sources":["../../src/json/compileColorScale.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n buildColorScaleLegend as buildGenericColorScaleLegend,\n coerceFiniteNumber,\n createColorScaleMapper,\n type ColorScaleConfig,\n type ResolvedColorLegend,\n} from '@sqlrooms/color-scales';\nimport type * as arrow from 'apache-arrow';\n\nfunction resolveFieldName(\n schemaOwner: arrow.Table | arrow.RecordBatch,\n requestedField: string,\n) {\n const exactMatch = schemaOwner.schema.fields.find(\n (field) => field.name === requestedField,\n )?.name;\n if (exactMatch) {\n return exactMatch;\n }\n\n const caseInsensitiveMatches = schemaOwner.schema.fields\n .map((field) => field.name)\n .filter(\n (fieldName) => fieldName.toLowerCase() === requestedField.toLowerCase(),\n );\n\n if (caseInsensitiveMatches.length === 1) {\n return caseInsensitiveMatches[0]!;\n }\n\n return undefined;\n}\n\nfunction getRowValue(row: unknown, fieldName: string) {\n if (!row || typeof row !== 'object') {\n return undefined;\n }\n\n const object = row as Record<string, unknown>;\n const sources = [\n object,\n object.properties as Record<string, unknown> | undefined,\n ].filter((value): value is Record<string, unknown> =>\n Boolean(value && typeof value === 'object'),\n );\n\n for (const source of sources) {\n if (fieldName in source) {\n return source[fieldName];\n }\n\n const caseInsensitiveMatches = Object.keys(source).filter(\n (key) => key.toLowerCase() === fieldName.toLowerCase(),\n );\n if (caseInsensitiveMatches.length === 1) {\n return source[caseInsensitiveMatches[0]!] as unknown;\n }\n }\n\n return undefined;\n}\n\nfunction getGeoArrowOrRowValue(options: {\n value: unknown;\n fieldName: string;\n vector: arrow.Vector;\n}) {\n const {value, fieldName, vector} = options;\n if (\n value &&\n typeof value === 'object' &&\n 'index' in value &&\n typeof (value as {index?: unknown}).index === 'number'\n ) {\n const objectInfo = value as {\n index: number;\n data?: {data?: arrow.Table | arrow.RecordBatch};\n };\n const batch = objectInfo.data?.data;\n const batchFieldName = batch\n ? resolveFieldName(batch, fieldName)\n : undefined;\n\n if (batch && batchFieldName) {\n return batch.getChild(batchFieldName)?.get(objectInfo.index);\n }\n\n return vector.get(objectInfo.index);\n }\n\n return getRowValue(value, fieldName);\n}\n\nfunction getColumnValues(vector: arrow.Vector) {\n return Array.from({length: vector.length}, (_, index) => vector.get(index));\n}\n\nfunction getColumn(table: arrow.Table, field: string) {\n const resolvedFieldName = resolveFieldName(table, field);\n if (!resolvedFieldName) {\n throw new Error(`Unknown colorScale field \"${field}\".`);\n }\n\n const vector = table.getChild(resolvedFieldName);\n if (!vector) {\n throw new Error(`Unable to read colorScale field \"${resolvedFieldName}\".`);\n }\n\n return {\n fieldName: resolvedFieldName,\n vector,\n };\n}\n\nexport function compileColorScale(options: {\n table: arrow.Table;\n colorScale: ColorScaleConfig;\n}) {\n const {table, colorScale} = options;\n let column;\n try {\n column = getColumn(table, colorScale.field);\n } catch {\n console.warn(\n `[compileColorScale] Field \"${colorScale.field}\" not found in dataset. Color scale will use default colors.`,\n );\n return () => null;\n }\n const {fieldName, vector} = column;\n let mapper: ReturnType<typeof createColorScaleMapper>;\n try {\n mapper = createColorScaleMapper({\n colorScale,\n values: getColumnValues(vector),\n });\n } catch (err) {\n console.warn(\n `[compileColorScale] Failed to create color scale for field \"${colorScale.field}\":`,\n err,\n );\n return () => null;\n }\n\n return (value: unknown) =>\n mapper(getGeoArrowOrRowValue({value, fieldName, vector}));\n}\n\nexport function buildColorScaleLegend(options: {\n table: arrow.Table;\n colorScale: ColorScaleConfig;\n title?: string;\n}): ResolvedColorLegend | null {\n const {table, colorScale} = options;\n let column;\n try {\n column = getColumn(table, colorScale.field);\n } catch {\n return null;\n }\n const {vector} = column;\n const values = getColumnValues(vector);\n\n if (\n colorScale.type !== 'categorical' &&\n values.every((value) => coerceFiniteNumber(value) === undefined)\n ) {\n return null;\n }\n\n return buildGenericColorScaleLegend({\n colorScale,\n values,\n title: options.title,\n });\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createDeckJsonConfiguration.d.ts","sourceRoot":"","sources":["../../src/json/createDeckJsonConfiguration.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,iBAAiB,EAAC,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"createDeckJsonConfiguration.d.ts","sourceRoot":"","sources":["../../src/json/createDeckJsonConfiguration.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,iBAAiB,EAAC,MAAM,eAAe,CAAC;AAKhD,OAAO,KAAK,EAAoB,wBAAwB,EAAC,MAAM,UAAU,CAAC;AAmB1E,KAAK,kCAAkC,GAAG;IACxC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAC;IACxD,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB,CAAC;AAsKF,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,kCAAkC,qBA+K5C"}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { JSONConfiguration } from '@deck.gl/json';
|
|
2
2
|
import { wkbGeometryDecoder } from '../prepare/wkbDecoder';
|
|
3
|
+
import { tryAggregateWaypointsToLineStrings } from './aggregateWaypoints';
|
|
3
4
|
import { createColorScaleMarker, getColorScale } from './colorScaleFunction';
|
|
4
5
|
import { compileColorScale } from './compileColorScale';
|
|
5
6
|
import { DEFAULT_DECK_JSON_CLASSES, DEFAULT_DECK_JSON_CONSTANTS, DEFAULT_DECK_JSON_ENUMERATIONS, } from './defaultClasses';
|
|
7
|
+
import { DEFAULT_HEATMAP_COLOR_RANGE } from './heatmapDefaults';
|
|
6
8
|
import { getLayerCompatibility } from './layerCompatibility';
|
|
7
9
|
import { isManagedLayer, resolveConfiguredColumn, resolveDatasetId, resolveGeometryColumn, stripLayerExtensionProps, } from './layerConfig';
|
|
8
10
|
import { rewriteGeoArrowAccessors } from './rewriteGeoArrowAccessors';
|
|
@@ -47,7 +49,39 @@ function resolveGeoArrowBindings(options) {
|
|
|
47
49
|
if (binding.required && !columnName) {
|
|
48
50
|
throw new Error(`Layer "${layerName}" requires _sqlroomsBinding.${binding.configKey}.`);
|
|
49
51
|
}
|
|
50
|
-
|
|
52
|
+
let resolvedGeometry;
|
|
53
|
+
try {
|
|
54
|
+
resolvedGeometry = prepared.resolveGeometry(columnName);
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
throw new Error(`Geometry column "${columnName}" was not found in dataset "${prepared.datasetId}".`);
|
|
58
|
+
}
|
|
59
|
+
// Detect mismatch: synthesized points can't satisfy a LineString binding.
|
|
60
|
+
// For PathLayer, try auto-aggregating waypoint rows into linestrings.
|
|
61
|
+
if (resolvedGeometry.encoding === 'geoarrow.point' &&
|
|
62
|
+
binding.prop === 'getPath') {
|
|
63
|
+
const aggregated = tryAggregateWaypointsToLineStrings(prepared.table);
|
|
64
|
+
if (aggregated) {
|
|
65
|
+
table = aggregated.table;
|
|
66
|
+
boundProps[binding.prop] = aggregated.geometryVector;
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
const available = prepared.table.schema.fields
|
|
70
|
+
.map((f) => f.name)
|
|
71
|
+
.join(', ');
|
|
72
|
+
throw new Error(`Layer "${layerName}" requires LineString geometry for getPath, ` +
|
|
73
|
+
`but only point coordinates were found and auto-aggregation failed. ` +
|
|
74
|
+
`The dataset sqlQuery must aggregate rows into linestrings using ST_MakeLine. ` +
|
|
75
|
+
`Available columns: ${available}.`);
|
|
76
|
+
}
|
|
77
|
+
if (resolvedGeometry.encoding === 'geoarrow.point' &&
|
|
78
|
+
binding.prop === 'getPolygon') {
|
|
79
|
+
const available = prepared.table.schema.fields
|
|
80
|
+
.map((f) => f.name)
|
|
81
|
+
.join(', ');
|
|
82
|
+
throw new Error(`Layer "${layerName}" requires Polygon geometry for ${binding.prop}, ` +
|
|
83
|
+
`but only point coordinates were found. Available columns: ${available}.`);
|
|
84
|
+
}
|
|
51
85
|
if (!resolvedGeometry.nativeGeoArrow) {
|
|
52
86
|
if (!compatibility.allowGeoArrowPromotion ||
|
|
53
87
|
!wkbGeometryDecoder.supportsGeoArrowPromotion(layerName, resolvedGeometry.encoding, prepared.table, resolvedGeometry.columnName)) {
|
|
@@ -55,11 +89,19 @@ function resolveGeoArrowBindings(options) {
|
|
|
55
89
|
}
|
|
56
90
|
}
|
|
57
91
|
const layerData = prepared.getGeoArrowLayerData(columnName);
|
|
58
|
-
if (
|
|
59
|
-
|
|
92
|
+
if (layerData.source === 'promoted') {
|
|
93
|
+
boundProps[binding.prop] = layerData.geometryColumn;
|
|
94
|
+
if (table === prepared.table) {
|
|
95
|
+
table = layerData.table;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
if (table !== prepared.table && table !== layerData.table) {
|
|
100
|
+
throw new Error(`Layer "${layerName}" cannot combine promoted geometry columns from different prepared tables.`);
|
|
101
|
+
}
|
|
102
|
+
table = layerData.table;
|
|
103
|
+
boundProps[binding.prop] = layerData.geometryColumn;
|
|
60
104
|
}
|
|
61
|
-
table = layerData.table;
|
|
62
|
-
boundProps[binding.prop] = layerData.geometryColumn;
|
|
63
105
|
continue;
|
|
64
106
|
}
|
|
65
107
|
const columnName = resolveConfiguredColumn(layerProps, binding.configKey);
|
|
@@ -85,6 +127,12 @@ export function createDeckJsonConfiguration(options) {
|
|
|
85
127
|
constants: DEFAULT_DECK_JSON_CONSTANTS,
|
|
86
128
|
functions: {
|
|
87
129
|
colorScale: (props) => createColorScaleMarker(props),
|
|
130
|
+
scale: (props) => {
|
|
131
|
+
const field = typeof props.field === 'string' ? props.field : undefined;
|
|
132
|
+
if (!field)
|
|
133
|
+
return undefined;
|
|
134
|
+
return `@@=${field}`;
|
|
135
|
+
},
|
|
88
136
|
},
|
|
89
137
|
// TODO(geoarrow-upgrade): In 0.3.x we preserve raw `@@=` strings here because
|
|
90
138
|
// `@deck.gl/json` would otherwise eagerly compile them into row-based accessors
|
|
@@ -114,7 +162,7 @@ export function createDeckJsonConfiguration(options) {
|
|
|
114
162
|
throw new Error(`Layer "${layerName}" references unknown dataset "${datasetId}".`);
|
|
115
163
|
}
|
|
116
164
|
if (datasetState.status !== 'ready') {
|
|
117
|
-
return stripLayerExtensionProps(layerProps);
|
|
165
|
+
return { ...stripLayerExtensionProps(layerProps), data: [] };
|
|
118
166
|
}
|
|
119
167
|
const prepared = datasetState.prepared;
|
|
120
168
|
const geometryColumn = resolveGeometryColumn(extensionProps);
|
|
@@ -131,7 +179,7 @@ export function createDeckJsonConfiguration(options) {
|
|
|
131
179
|
}
|
|
132
180
|
const { table, boundProps } = resolveGeoArrowBindings({
|
|
133
181
|
layerName,
|
|
134
|
-
compatibility,
|
|
182
|
+
compatibility: compatibility,
|
|
135
183
|
layerProps: extensionProps,
|
|
136
184
|
prepared,
|
|
137
185
|
props: strippedProps,
|
|
@@ -145,11 +193,61 @@ export function createDeckJsonConfiguration(options) {
|
|
|
145
193
|
data: table,
|
|
146
194
|
...boundProps,
|
|
147
195
|
};
|
|
148
|
-
|
|
196
|
+
const rewritten = rewriteGeoArrowAccessors({
|
|
149
197
|
props: nextProps,
|
|
150
198
|
table,
|
|
151
199
|
layerName,
|
|
152
200
|
});
|
|
201
|
+
// For TripsLayer: compute max timestamp for animation and set defaults
|
|
202
|
+
if (layerName === 'GeoArrowTripsLayer' || layerName === 'TripsLayer') {
|
|
203
|
+
const tsVector = boundProps.getTimestamps;
|
|
204
|
+
if (tsVector) {
|
|
205
|
+
let maxTs = 0;
|
|
206
|
+
for (let i = 0; i < tsVector.length; i++) {
|
|
207
|
+
const listItem = tsVector.get(i);
|
|
208
|
+
if (listItem &&
|
|
209
|
+
typeof listItem === 'object' &&
|
|
210
|
+
'length' in listItem) {
|
|
211
|
+
const list = listItem;
|
|
212
|
+
for (let j = 0; j < list.length; j++) {
|
|
213
|
+
const v = Number(list.get(j)) || 0;
|
|
214
|
+
if (v > maxTs)
|
|
215
|
+
maxTs = v;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
if (maxTs > 0) {
|
|
220
|
+
rewritten._tripsMaxTimestamp = maxTs;
|
|
221
|
+
if (!rewritten.trailLength) {
|
|
222
|
+
rewritten.trailLength = maxTs;
|
|
223
|
+
}
|
|
224
|
+
if (rewritten.currentTime === undefined ||
|
|
225
|
+
rewritten.currentTime === 0) {
|
|
226
|
+
rewritten.currentTime = maxTs;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
// For HeatmapLayer: apply default colorRange (YlOrRd) when not explicitly set.
|
|
232
|
+
// Also set updateTriggers to force re-aggregation when colorRange changes.
|
|
233
|
+
if (layerName === 'GeoArrowHeatmapLayer') {
|
|
234
|
+
if (!rewritten.colorRange) {
|
|
235
|
+
rewritten.colorRange = DEFAULT_HEATMAP_COLOR_RANGE;
|
|
236
|
+
}
|
|
237
|
+
const existingTriggers = rewritten.updateTriggers &&
|
|
238
|
+
typeof rewritten.updateTriggers === 'object' &&
|
|
239
|
+
!Array.isArray(rewritten.updateTriggers)
|
|
240
|
+
? rewritten.updateTriggers
|
|
241
|
+
: {};
|
|
242
|
+
const previousGetWeight = existingTriggers.getWeight;
|
|
243
|
+
rewritten.updateTriggers = {
|
|
244
|
+
...existingTriggers,
|
|
245
|
+
getWeight: previousGetWeight === undefined
|
|
246
|
+
? JSON.stringify(rewritten.colorRange)
|
|
247
|
+
: [previousGetWeight, JSON.stringify(rewritten.colorRange)],
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
return rewritten;
|
|
153
251
|
},
|
|
154
252
|
postProcessConvertedJson: (json) => {
|
|
155
253
|
if (json &&
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createDeckJsonConfiguration.js","sourceRoot":"","sources":["../../src/json/createDeckJsonConfiguration.ts"],"names":[],"mappings":"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","sourcesContent":["import {JSONConfiguration} from '@deck.gl/json';\nimport type {ColorScaleConfig} from '@sqlrooms/color-scales';\nimport {wkbGeometryDecoder} from '../prepare/wkbDecoder';\nimport type {LayerBindingProps, PreparedDeckDatasetState} from '../types';\nimport {createColorScaleMarker, getColorScale} from './colorScaleFunction';\nimport {compileColorScale} from './compileColorScale';\nimport {\n DEFAULT_DECK_JSON_CLASSES,\n DEFAULT_DECK_JSON_CONSTANTS,\n DEFAULT_DECK_JSON_ENUMERATIONS,\n} from './defaultClasses';\nimport {getLayerCompatibility} from './layerCompatibility';\nimport {\n isManagedLayer,\n resolveConfiguredColumn,\n resolveDatasetId,\n resolveGeometryColumn,\n stripLayerExtensionProps,\n} from './layerConfig';\nimport {rewriteGeoArrowAccessors} from './rewriteGeoArrowAccessors';\n\ntype CreateDeckJsonConfigurationOptions = {\n datasetStates: Record<string, PreparedDeckDatasetState>;\n datasetIds: string[];\n};\n\nfunction getLayerName(Class: unknown) {\n const maybeClass = Class as {layerName?: string; name?: string};\n return maybeClass.layerName ?? maybeClass.name ?? 'UnknownLayer';\n}\n\nfunction applyColorScale(options: {\n props: Record<string, unknown>;\n table: import('apache-arrow').Table;\n}) {\n const {props, table} = options;\n const resolved = getColorScale(props);\n if (!resolved) {\n return props;\n }\n\n const {propName, colorScale} = resolved;\n\n const updateTriggers =\n props.updateTriggers &&\n typeof props.updateTriggers === 'object' &&\n !Array.isArray(props.updateTriggers)\n ? (props.updateTriggers as Record<string, unknown>)\n : {};\n\n return {\n ...props,\n [propName]: compileColorScale({\n table,\n colorScale,\n }),\n updateTriggers: {\n ...updateTriggers,\n [propName]: JSON.stringify(colorScale),\n },\n };\n}\n\nfunction resolveGeoArrowBindings(options: {\n layerName: string;\n compatibility: NonNullable<ReturnType<typeof getLayerCompatibility>> & {\n representation: 'geoarrow';\n };\n layerProps: LayerBindingProps & Record<string, unknown>;\n prepared: Extract<PreparedDeckDatasetState, {status: 'ready'}>['prepared'];\n props: Record<string, unknown>;\n}) {\n const {layerName, compatibility, layerProps, prepared, props} = options;\n let table = prepared.table;\n const boundProps: Record<string, unknown> = {};\n\n for (const binding of compatibility.bindings) {\n if (props[binding.prop] !== undefined) {\n continue;\n }\n\n if (binding.kind === 'geometry') {\n const columnName = resolveConfiguredColumn(layerProps, binding.configKey);\n if (binding.required && !columnName) {\n throw new Error(\n `Layer \"${layerName}\" requires _sqlroomsBinding.${binding.configKey}.`,\n );\n }\n\n const resolvedGeometry = prepared.resolveGeometry(columnName);\n if (!resolvedGeometry.nativeGeoArrow) {\n if (\n !compatibility.allowGeoArrowPromotion ||\n !wkbGeometryDecoder.supportsGeoArrowPromotion(\n layerName,\n resolvedGeometry.encoding,\n prepared.table,\n resolvedGeometry.columnName,\n )\n ) {\n throw new Error(\n `Layer \"${layerName}\" cannot render geometry encoding \"${resolvedGeometry.encoding}\" for dataset \"${prepared.datasetId}\".`,\n );\n }\n }\n\n const layerData = prepared.getGeoArrowLayerData(columnName);\n if (table !== prepared.table && table !== layerData.table) {\n throw new Error(\n `Layer \"${layerName}\" cannot combine promoted geometry columns from different prepared tables.`,\n );\n }\n\n table = layerData.table;\n boundProps[binding.prop] = layerData.geometryColumn;\n continue;\n }\n\n const columnName = resolveConfiguredColumn(layerProps, binding.configKey);\n if (!columnName) {\n if (binding.required) {\n throw new Error(\n `Layer \"${layerName}\" requires _sqlroomsBinding.${binding.configKey}.`,\n );\n }\n continue;\n }\n\n const vector =\n table.getChild(columnName) ?? prepared.table.getChild(columnName);\n if (!vector) {\n throw new Error(\n `Layer \"${layerName}\" references unknown column \"${columnName}\" for ${binding.prop}.`,\n );\n }\n\n boundProps[binding.prop] = vector;\n }\n\n return {table, boundProps};\n}\n\nexport function createDeckJsonConfiguration(\n options: CreateDeckJsonConfigurationOptions,\n) {\n const {datasetStates, datasetIds} = options;\n\n return new JSONConfiguration({\n classes: DEFAULT_DECK_JSON_CLASSES,\n enumerations: DEFAULT_DECK_JSON_ENUMERATIONS,\n constants: DEFAULT_DECK_JSON_CONSTANTS,\n functions: {\n colorScale: (props: ColorScaleConfig) => createColorScaleMarker(props),\n },\n // TODO(geoarrow-upgrade): In 0.3.x we preserve raw `@@=` strings here because\n // `@deck.gl/json` would otherwise eagerly compile them into row-based accessors\n // before `preProcessClassProps` can rewrite them for GeoArrow. If the next\n // GeoArrow version can consume deck.gl/json's converted accessors directly, or\n // exposes a cleaner injection seam, remove this shim.\n convertFunction: ((expression: string) => `@@=${expression}`) as never,\n preProcessClassProps: (Class: unknown, props: Record<string, unknown>) => {\n const layerName = getLayerName(Class);\n const compatibility = getLayerCompatibility(layerName);\n\n if (!compatibility) {\n return props;\n }\n\n const layerProps = props as Record<string, unknown>;\n const extensionProps = layerProps as typeof layerProps &\n LayerBindingProps;\n const datasetId = resolveDatasetId(extensionProps, datasetIds);\n const managed =\n isManagedLayer(extensionProps, datasetIds) ||\n (datasetIds.length > 1 && layerProps.data === undefined);\n\n if (!managed) {\n return props;\n }\n\n if (!datasetId) {\n throw new Error(\n `Layer \"${layerName}\" must declare _sqlroomsBinding.dataset when multiple datasets are available.`,\n );\n }\n\n const datasetState = datasetStates[datasetId];\n if (!datasetState) {\n throw new Error(\n `Layer \"${layerName}\" references unknown dataset \"${datasetId}\".`,\n );\n }\n\n if (datasetState.status !== 'ready') {\n return stripLayerExtensionProps(layerProps);\n }\n\n const prepared = datasetState.prepared;\n const geometryColumn = resolveGeometryColumn(extensionProps);\n const strippedProps = stripLayerExtensionProps(layerProps);\n\n if (compatibility.representation === 'geojson') {\n const baseProps = applyColorScale({\n props: strippedProps,\n table: prepared.table,\n });\n return {\n ...baseProps,\n data: prepared.getGeoJsonBinaryData(geometryColumn),\n };\n }\n\n const {table, boundProps} = resolveGeoArrowBindings({\n layerName,\n compatibility,\n layerProps: extensionProps,\n prepared,\n props: strippedProps,\n });\n const baseProps = applyColorScale({\n props: strippedProps,\n table,\n });\n const nextProps = {\n ...baseProps,\n data: table,\n ...boundProps,\n };\n\n return rewriteGeoArrowAccessors({\n props: nextProps,\n table,\n layerName,\n });\n },\n postProcessConvertedJson: (json: unknown) => {\n if (\n json &&\n typeof json === 'object' &&\n 'layers' in json &&\n Array.isArray((json as {layers?: unknown[]}).layers)\n ) {\n (json as {layers: unknown[]}).layers = (\n json as {layers: unknown[]}\n ).layers.filter(Boolean);\n }\n\n return json;\n },\n });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"createDeckJsonConfiguration.js","sourceRoot":"","sources":["../../src/json/createDeckJsonConfiguration.ts"],"names":[],"mappings":"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","sourcesContent":["import {JSONConfiguration} from '@deck.gl/json';\nimport * as arrow from 'apache-arrow';\nimport type {ColorScaleConfig} from '@sqlrooms/color-scales';\nimport {wkbGeometryDecoder} from '../prepare/wkbDecoder';\nimport {tryAggregateWaypointsToLineStrings} from './aggregateWaypoints';\nimport type {LayerBindingProps, PreparedDeckDatasetState} from '../types';\nimport {createColorScaleMarker, getColorScale} from './colorScaleFunction';\nimport {compileColorScale} from './compileColorScale';\nimport {\n DEFAULT_DECK_JSON_CLASSES,\n DEFAULT_DECK_JSON_CONSTANTS,\n DEFAULT_DECK_JSON_ENUMERATIONS,\n} from './defaultClasses';\nimport {DEFAULT_HEATMAP_COLOR_RANGE} from './heatmapDefaults';\nimport {getLayerCompatibility} from './layerCompatibility';\nimport {\n isManagedLayer,\n resolveConfiguredColumn,\n resolveDatasetId,\n resolveGeometryColumn,\n stripLayerExtensionProps,\n} from './layerConfig';\nimport {rewriteGeoArrowAccessors} from './rewriteGeoArrowAccessors';\n\ntype CreateDeckJsonConfigurationOptions = {\n datasetStates: Record<string, PreparedDeckDatasetState>;\n datasetIds: string[];\n};\n\nfunction getLayerName(Class: unknown) {\n const maybeClass = Class as {layerName?: string; name?: string};\n return maybeClass.layerName ?? maybeClass.name ?? 'UnknownLayer';\n}\n\nfunction applyColorScale(options: {\n props: Record<string, unknown>;\n table: import('apache-arrow').Table;\n}) {\n const {props, table} = options;\n const resolved = getColorScale(props);\n if (!resolved) {\n return props;\n }\n\n const {propName, colorScale} = resolved;\n\n const updateTriggers =\n props.updateTriggers &&\n typeof props.updateTriggers === 'object' &&\n !Array.isArray(props.updateTriggers)\n ? (props.updateTriggers as Record<string, unknown>)\n : {};\n\n return {\n ...props,\n [propName]: compileColorScale({\n table,\n colorScale,\n }),\n updateTriggers: {\n ...updateTriggers,\n [propName]: JSON.stringify(colorScale),\n },\n };\n}\n\nfunction resolveGeoArrowBindings(options: {\n layerName: string;\n compatibility: NonNullable<ReturnType<typeof getLayerCompatibility>> & {\n representation: 'geoarrow';\n };\n layerProps: LayerBindingProps & Record<string, unknown>;\n prepared: Extract<PreparedDeckDatasetState, {status: 'ready'}>['prepared'];\n props: Record<string, unknown>;\n}) {\n const {layerName, compatibility, layerProps, prepared, props} = options;\n let table = prepared.table;\n const boundProps: Record<string, unknown> = {};\n\n for (const binding of compatibility.bindings) {\n if (props[binding.prop] !== undefined) {\n continue;\n }\n\n if (binding.kind === 'geometry') {\n const columnName = resolveConfiguredColumn(layerProps, binding.configKey);\n if (binding.required && !columnName) {\n throw new Error(\n `Layer \"${layerName}\" requires _sqlroomsBinding.${binding.configKey}.`,\n );\n }\n\n let resolvedGeometry;\n try {\n resolvedGeometry = prepared.resolveGeometry(columnName);\n } catch {\n throw new Error(\n `Geometry column \"${columnName}\" was not found in dataset \"${prepared.datasetId}\".`,\n );\n }\n\n // Detect mismatch: synthesized points can't satisfy a LineString binding.\n // For PathLayer, try auto-aggregating waypoint rows into linestrings.\n if (\n resolvedGeometry.encoding === 'geoarrow.point' &&\n binding.prop === 'getPath'\n ) {\n const aggregated = tryAggregateWaypointsToLineStrings(prepared.table);\n if (aggregated) {\n table = aggregated.table;\n boundProps[binding.prop] = aggregated.geometryVector;\n continue;\n }\n const available = prepared.table.schema.fields\n .map((f) => f.name)\n .join(', ');\n throw new Error(\n `Layer \"${layerName}\" requires LineString geometry for getPath, ` +\n `but only point coordinates were found and auto-aggregation failed. ` +\n `The dataset sqlQuery must aggregate rows into linestrings using ST_MakeLine. ` +\n `Available columns: ${available}.`,\n );\n }\n if (\n resolvedGeometry.encoding === 'geoarrow.point' &&\n binding.prop === 'getPolygon'\n ) {\n const available = prepared.table.schema.fields\n .map((f) => f.name)\n .join(', ');\n throw new Error(\n `Layer \"${layerName}\" requires Polygon geometry for ${binding.prop}, ` +\n `but only point coordinates were found. Available columns: ${available}.`,\n );\n }\n if (!resolvedGeometry.nativeGeoArrow) {\n if (\n !compatibility.allowGeoArrowPromotion ||\n !wkbGeometryDecoder.supportsGeoArrowPromotion(\n layerName,\n resolvedGeometry.encoding,\n prepared.table,\n resolvedGeometry.columnName,\n )\n ) {\n throw new Error(\n `Layer \"${layerName}\" cannot render geometry encoding \"${resolvedGeometry.encoding}\" for dataset \"${prepared.datasetId}\".`,\n );\n }\n }\n\n const layerData = prepared.getGeoArrowLayerData(columnName);\n if (layerData.source === 'promoted') {\n boundProps[binding.prop] = layerData.geometryColumn;\n if (table === prepared.table) {\n table = layerData.table;\n }\n } else {\n if (table !== prepared.table && table !== layerData.table) {\n throw new Error(\n `Layer \"${layerName}\" cannot combine promoted geometry columns from different prepared tables.`,\n );\n }\n table = layerData.table;\n boundProps[binding.prop] = layerData.geometryColumn;\n }\n continue;\n }\n\n const columnName = resolveConfiguredColumn(layerProps, binding.configKey);\n if (!columnName) {\n if (binding.required) {\n throw new Error(\n `Layer \"${layerName}\" requires _sqlroomsBinding.${binding.configKey}.`,\n );\n }\n continue;\n }\n\n const vector =\n table.getChild(columnName) ?? prepared.table.getChild(columnName);\n if (!vector) {\n throw new Error(\n `Layer \"${layerName}\" references unknown column \"${columnName}\" for ${binding.prop}.`,\n );\n }\n\n boundProps[binding.prop] = vector;\n }\n\n return {table, boundProps};\n}\n\nexport function createDeckJsonConfiguration(\n options: CreateDeckJsonConfigurationOptions,\n) {\n const {datasetStates, datasetIds} = options;\n\n return new JSONConfiguration({\n classes: DEFAULT_DECK_JSON_CLASSES,\n enumerations: DEFAULT_DECK_JSON_ENUMERATIONS,\n constants: DEFAULT_DECK_JSON_CONSTANTS,\n functions: {\n colorScale: (props: ColorScaleConfig) => createColorScaleMarker(props),\n scale: (props: Record<string, unknown>) => {\n const field = typeof props.field === 'string' ? props.field : undefined;\n if (!field) return undefined;\n return `@@=${field}`;\n },\n },\n // TODO(geoarrow-upgrade): In 0.3.x we preserve raw `@@=` strings here because\n // `@deck.gl/json` would otherwise eagerly compile them into row-based accessors\n // before `preProcessClassProps` can rewrite them for GeoArrow. If the next\n // GeoArrow version can consume deck.gl/json's converted accessors directly, or\n // exposes a cleaner injection seam, remove this shim.\n convertFunction: ((expression: string) => `@@=${expression}`) as never,\n preProcessClassProps: (Class: unknown, props: Record<string, unknown>) => {\n const layerName = getLayerName(Class);\n const compatibility = getLayerCompatibility(layerName);\n\n if (!compatibility) {\n return props;\n }\n\n const layerProps = props as Record<string, unknown>;\n const extensionProps = layerProps as typeof layerProps &\n LayerBindingProps;\n const datasetId = resolveDatasetId(extensionProps, datasetIds);\n const managed =\n isManagedLayer(extensionProps, datasetIds) ||\n (datasetIds.length > 1 && layerProps.data === undefined);\n\n if (!managed) {\n return props;\n }\n\n if (!datasetId) {\n throw new Error(\n `Layer \"${layerName}\" must declare _sqlroomsBinding.dataset when multiple datasets are available.`,\n );\n }\n\n const datasetState = datasetStates[datasetId];\n if (!datasetState) {\n throw new Error(\n `Layer \"${layerName}\" references unknown dataset \"${datasetId}\".`,\n );\n }\n\n if (datasetState.status !== 'ready') {\n return {...stripLayerExtensionProps(layerProps), data: []};\n }\n\n const prepared = datasetState.prepared;\n const geometryColumn = resolveGeometryColumn(extensionProps);\n const strippedProps = stripLayerExtensionProps(layerProps);\n\n if (compatibility.representation === 'geojson') {\n const baseProps = applyColorScale({\n props: strippedProps,\n table: prepared.table,\n });\n return {\n ...baseProps,\n data: prepared.getGeoJsonBinaryData(geometryColumn),\n };\n }\n\n const {table, boundProps} = resolveGeoArrowBindings({\n layerName,\n compatibility: compatibility as NonNullable<\n ReturnType<typeof getLayerCompatibility>\n > & {representation: 'geoarrow'},\n layerProps: extensionProps,\n prepared,\n props: strippedProps,\n });\n const baseProps = applyColorScale({\n props: strippedProps,\n table,\n });\n const nextProps = {\n ...baseProps,\n data: table,\n ...boundProps,\n };\n\n const rewritten = rewriteGeoArrowAccessors({\n props: nextProps,\n table,\n layerName,\n });\n\n // For TripsLayer: compute max timestamp for animation and set defaults\n if (layerName === 'GeoArrowTripsLayer' || layerName === 'TripsLayer') {\n const tsVector = boundProps.getTimestamps as arrow.Vector | undefined;\n if (tsVector) {\n let maxTs = 0;\n for (let i = 0; i < tsVector.length; i++) {\n const listItem = tsVector.get(i);\n if (\n listItem &&\n typeof listItem === 'object' &&\n 'length' in listItem\n ) {\n const list = listItem as {\n length: number;\n get: (i: number) => unknown;\n };\n for (let j = 0; j < list.length; j++) {\n const v = Number(list.get(j)) || 0;\n if (v > maxTs) maxTs = v;\n }\n }\n }\n if (maxTs > 0) {\n rewritten._tripsMaxTimestamp = maxTs;\n if (!rewritten.trailLength) {\n rewritten.trailLength = maxTs;\n }\n if (\n rewritten.currentTime === undefined ||\n rewritten.currentTime === 0\n ) {\n rewritten.currentTime = maxTs;\n }\n }\n }\n }\n\n // For HeatmapLayer: apply default colorRange (YlOrRd) when not explicitly set.\n // Also set updateTriggers to force re-aggregation when colorRange changes.\n if (layerName === 'GeoArrowHeatmapLayer') {\n if (!rewritten.colorRange) {\n rewritten.colorRange = DEFAULT_HEATMAP_COLOR_RANGE;\n }\n const existingTriggers =\n rewritten.updateTriggers &&\n typeof rewritten.updateTriggers === 'object' &&\n !Array.isArray(rewritten.updateTriggers)\n ? (rewritten.updateTriggers as Record<string, unknown>)\n : {};\n const previousGetWeight = existingTriggers.getWeight;\n rewritten.updateTriggers = {\n ...existingTriggers,\n getWeight:\n previousGetWeight === undefined\n ? JSON.stringify(rewritten.colorRange)\n : [previousGetWeight, JSON.stringify(rewritten.colorRange)],\n };\n }\n\n return rewritten;\n },\n postProcessConvertedJson: (json: unknown) => {\n if (\n json &&\n typeof json === 'object' &&\n 'layers' in json &&\n Array.isArray((json as {layers?: unknown[]}).layers)\n ) {\n (json as {layers: unknown[]}).layers = (\n json as {layers: unknown[]}\n ).layers.filter(Boolean);\n }\n\n return json;\n },\n });\n}\n"]}
|