@sqlrooms/deck 0.29.0-rc.8 → 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.
Files changed (107) hide show
  1. package/README.md +31 -6
  2. package/dist/DeckJsonMap.d.ts +2 -2
  3. package/dist/DeckJsonMap.d.ts.map +1 -1
  4. package/dist/DeckJsonMap.js +202 -19
  5. package/dist/DeckJsonMap.js.map +1 -1
  6. package/dist/DeckJsonMapSpec.d.ts +36 -36
  7. package/dist/DeckJsonMapSpec.d.ts.map +1 -1
  8. package/dist/DeckJsonMapSpec.js +1 -0
  9. package/dist/DeckJsonMapSpec.js.map +1 -1
  10. package/dist/MapSettings.d.ts.map +1 -1
  11. package/dist/MapSettings.js +202 -25
  12. package/dist/MapSettings.js.map +1 -1
  13. package/dist/ai.d.ts +55 -8
  14. package/dist/ai.d.ts.map +1 -1
  15. package/dist/ai.js +190 -41
  16. package/dist/ai.js.map +1 -1
  17. package/dist/block.d.ts +20 -0
  18. package/dist/block.d.ts.map +1 -0
  19. package/dist/block.js +119 -0
  20. package/dist/block.js.map +1 -0
  21. package/dist/dashboard.d.ts +2 -8
  22. package/dist/dashboard.d.ts.map +1 -1
  23. package/dist/dashboard.js +194 -289
  24. package/dist/dashboard.js.map +1 -1
  25. package/dist/dashboardConfig.d.ts +11 -3
  26. package/dist/dashboardConfig.d.ts.map +1 -1
  27. package/dist/dashboardConfig.js +82 -7
  28. package/dist/dashboardConfig.js.map +1 -1
  29. package/dist/index.d.ts +4 -3
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +3 -2
  32. package/dist/index.js.map +1 -1
  33. package/dist/json/aggregateWaypoints.d.ts +14 -0
  34. package/dist/json/aggregateWaypoints.d.ts.map +1 -0
  35. package/dist/json/aggregateWaypoints.js +190 -0
  36. package/dist/json/aggregateWaypoints.js.map +1 -0
  37. package/dist/json/compileColorScale.d.ts +1 -1
  38. package/dist/json/compileColorScale.d.ts.map +1 -1
  39. package/dist/json/compileColorScale.js +42 -20
  40. package/dist/json/compileColorScale.js.map +1 -1
  41. package/dist/json/createDeckJsonConfiguration.d.ts.map +1 -1
  42. package/dist/json/createDeckJsonConfiguration.js +106 -8
  43. package/dist/json/createDeckJsonConfiguration.js.map +1 -1
  44. package/dist/json/defaultClasses.d.ts +5 -4
  45. package/dist/json/defaultClasses.d.ts.map +1 -1
  46. package/dist/json/defaultClasses.js +9 -4
  47. package/dist/json/defaultClasses.js.map +1 -1
  48. package/dist/json/extractColorScaleLegends.d.ts.map +1 -1
  49. package/dist/json/extractColorScaleLegends.js +43 -5
  50. package/dist/json/extractColorScaleLegends.js.map +1 -1
  51. package/dist/json/heatmapDefaults.d.ts +8 -0
  52. package/dist/json/heatmapDefaults.d.ts.map +1 -0
  53. package/dist/json/heatmapDefaults.js +14 -0
  54. package/dist/json/heatmapDefaults.js.map +1 -0
  55. package/dist/json/layerCompatibility.d.ts.map +1 -1
  56. package/dist/json/layerCompatibility.js +5 -1
  57. package/dist/json/layerCompatibility.js.map +1 -1
  58. package/dist/json/layers/DeckColumnLayer.d.ts +12 -0
  59. package/dist/json/layers/DeckColumnLayer.d.ts.map +1 -0
  60. package/dist/json/layers/DeckColumnLayer.js +26 -0
  61. package/dist/json/layers/DeckColumnLayer.js.map +1 -0
  62. package/dist/json/layers/DeckH3HexagonLayer.d.ts +37 -0
  63. package/dist/json/layers/DeckH3HexagonLayer.d.ts.map +1 -0
  64. package/dist/json/layers/DeckH3HexagonLayer.js +96 -0
  65. package/dist/json/layers/DeckH3HexagonLayer.js.map +1 -0
  66. package/dist/json/layers/DeckTripsLayer.d.ts +45 -0
  67. package/dist/json/layers/DeckTripsLayer.d.ts.map +1 -0
  68. package/dist/json/layers/DeckTripsLayer.js +169 -0
  69. package/dist/json/layers/DeckTripsLayer.js.map +1 -0
  70. package/dist/json/layers/index.d.ts +4 -0
  71. package/dist/json/layers/index.d.ts.map +1 -0
  72. package/dist/json/layers/index.js +4 -0
  73. package/dist/json/layers/index.js.map +1 -0
  74. package/dist/json/rewriteGeoArrowAccessors.d.ts.map +1 -1
  75. package/dist/json/rewriteGeoArrowAccessors.js +5 -0
  76. package/dist/json/rewriteGeoArrowAccessors.js.map +1 -1
  77. package/dist/mapConfigUtils.d.ts +102 -1
  78. package/dist/mapConfigUtils.d.ts.map +1 -1
  79. package/dist/mapConfigUtils.js +21 -3
  80. package/dist/mapConfigUtils.js.map +1 -1
  81. package/dist/mapLayerConfigUtils.d.ts +15 -0
  82. package/dist/mapLayerConfigUtils.d.ts.map +1 -1
  83. package/dist/mapLayerConfigUtils.js +109 -7
  84. package/dist/mapLayerConfigUtils.js.map +1 -1
  85. package/dist/prepare/detectGeometryColumn.d.ts +10 -1
  86. package/dist/prepare/detectGeometryColumn.d.ts.map +1 -1
  87. package/dist/prepare/detectGeometryColumn.js +48 -6
  88. package/dist/prepare/detectGeometryColumn.js.map +1 -1
  89. package/dist/prepare/wkbDecoder.d.ts.map +1 -1
  90. package/dist/prepare/wkbDecoder.js +88 -1
  91. package/dist/prepare/wkbDecoder.js.map +1 -1
  92. package/dist/prepare/wkbParser.d.ts +5 -0
  93. package/dist/prepare/wkbParser.d.ts.map +1 -1
  94. package/dist/prepare/wkbParser.js +24 -0
  95. package/dist/prepare/wkbParser.js.map +1 -1
  96. package/dist/types.d.ts +14 -4
  97. package/dist/types.d.ts.map +1 -1
  98. package/dist/types.js.map +1 -1
  99. package/dist/useDeckMapDatasets.d.ts +17 -0
  100. package/dist/useDeckMapDatasets.d.ts.map +1 -0
  101. package/dist/useDeckMapDatasets.js +69 -0
  102. package/dist/useDeckMapDatasets.js.map +1 -0
  103. package/dist/useDeckMapFitToBounds.d.ts +29 -0
  104. package/dist/useDeckMapFitToBounds.d.ts.map +1 -0
  105. package/dist/useDeckMapFitToBounds.js +333 -0
  106. package/dist/useDeckMapFitToBounds.js.map +1 -0
  107. 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,IAQS,OAAO,OAAO,mDAEvB;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,CAiB7B"}
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
- const { fieldName, vector } = getColumn(table, colorScale.field);
73
- const mapper = createColorScaleMapper({
74
- colorScale,
75
- values: getColumnValues(vector),
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
- const { vector } = getColumn(table, colorScale.field);
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":"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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 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\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\nexport function compileColorScale(options: {\n table: arrow.Table;\n colorScale: ColorScaleConfig;\n}) {\n const {table, colorScale} = options;\n const {fieldName, vector} = getColumn(table, colorScale.field);\n const mapper = createColorScaleMapper({\n colorScale,\n values: getColumnValues(vector),\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 const {vector} = getColumn(table, colorScale.field);\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
+ {"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;AAGhD,OAAO,KAAK,EAAoB,wBAAwB,EAAC,MAAM,UAAU,CAAC;AAkB1E,KAAK,kCAAkC,GAAG;IACxC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAC;IACxD,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB,CAAC;AAsHF,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,kCAAkC,qBA2G5C"}
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
- const resolvedGeometry = prepared.resolveGeometry(columnName);
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 (table !== prepared.table && table !== layerData.table) {
59
- throw new Error(`Layer "${layerName}" cannot combine promoted geometry columns from different prepared tables.`);
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
- return rewriteGeoArrowAccessors({
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"]}