@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.
Files changed (108) hide show
  1. package/LICENSE.md +2 -1
  2. package/README.md +31 -6
  3. package/dist/DeckJsonMap.d.ts +2 -2
  4. package/dist/DeckJsonMap.d.ts.map +1 -1
  5. package/dist/DeckJsonMap.js +204 -17
  6. package/dist/DeckJsonMap.js.map +1 -1
  7. package/dist/DeckJsonMapSpec.d.ts +36 -36
  8. package/dist/DeckJsonMapSpec.d.ts.map +1 -1
  9. package/dist/DeckJsonMapSpec.js +1 -0
  10. package/dist/DeckJsonMapSpec.js.map +1 -1
  11. package/dist/MapSettings.d.ts.map +1 -1
  12. package/dist/MapSettings.js +203 -25
  13. package/dist/MapSettings.js.map +1 -1
  14. package/dist/ai.d.ts +55 -8
  15. package/dist/ai.d.ts.map +1 -1
  16. package/dist/ai.js +190 -41
  17. package/dist/ai.js.map +1 -1
  18. package/dist/block.d.ts +20 -0
  19. package/dist/block.d.ts.map +1 -0
  20. package/dist/block.js +119 -0
  21. package/dist/block.js.map +1 -0
  22. package/dist/dashboard.d.ts +2 -0
  23. package/dist/dashboard.d.ts.map +1 -1
  24. package/dist/dashboard.js +194 -285
  25. package/dist/dashboard.js.map +1 -1
  26. package/dist/dashboardConfig.d.ts +11 -3
  27. package/dist/dashboardConfig.d.ts.map +1 -1
  28. package/dist/dashboardConfig.js +82 -7
  29. package/dist/dashboardConfig.js.map +1 -1
  30. package/dist/index.d.ts +4 -3
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +3 -2
  33. package/dist/index.js.map +1 -1
  34. package/dist/json/aggregateWaypoints.d.ts +14 -0
  35. package/dist/json/aggregateWaypoints.d.ts.map +1 -0
  36. package/dist/json/aggregateWaypoints.js +190 -0
  37. package/dist/json/aggregateWaypoints.js.map +1 -0
  38. package/dist/json/compileColorScale.d.ts +1 -1
  39. package/dist/json/compileColorScale.d.ts.map +1 -1
  40. package/dist/json/compileColorScale.js +42 -20
  41. package/dist/json/compileColorScale.js.map +1 -1
  42. package/dist/json/createDeckJsonConfiguration.d.ts.map +1 -1
  43. package/dist/json/createDeckJsonConfiguration.js +106 -8
  44. package/dist/json/createDeckJsonConfiguration.js.map +1 -1
  45. package/dist/json/defaultClasses.d.ts +5 -4
  46. package/dist/json/defaultClasses.d.ts.map +1 -1
  47. package/dist/json/defaultClasses.js +9 -4
  48. package/dist/json/defaultClasses.js.map +1 -1
  49. package/dist/json/extractColorScaleLegends.d.ts.map +1 -1
  50. package/dist/json/extractColorScaleLegends.js +43 -5
  51. package/dist/json/extractColorScaleLegends.js.map +1 -1
  52. package/dist/json/heatmapDefaults.d.ts +8 -0
  53. package/dist/json/heatmapDefaults.d.ts.map +1 -0
  54. package/dist/json/heatmapDefaults.js +14 -0
  55. package/dist/json/heatmapDefaults.js.map +1 -0
  56. package/dist/json/layerCompatibility.d.ts.map +1 -1
  57. package/dist/json/layerCompatibility.js +5 -1
  58. package/dist/json/layerCompatibility.js.map +1 -1
  59. package/dist/json/layers/DeckColumnLayer.d.ts +12 -0
  60. package/dist/json/layers/DeckColumnLayer.d.ts.map +1 -0
  61. package/dist/json/layers/DeckColumnLayer.js +26 -0
  62. package/dist/json/layers/DeckColumnLayer.js.map +1 -0
  63. package/dist/json/layers/DeckH3HexagonLayer.d.ts +37 -0
  64. package/dist/json/layers/DeckH3HexagonLayer.d.ts.map +1 -0
  65. package/dist/json/layers/DeckH3HexagonLayer.js +96 -0
  66. package/dist/json/layers/DeckH3HexagonLayer.js.map +1 -0
  67. package/dist/json/layers/DeckTripsLayer.d.ts +45 -0
  68. package/dist/json/layers/DeckTripsLayer.d.ts.map +1 -0
  69. package/dist/json/layers/DeckTripsLayer.js +169 -0
  70. package/dist/json/layers/DeckTripsLayer.js.map +1 -0
  71. package/dist/json/layers/index.d.ts +4 -0
  72. package/dist/json/layers/index.d.ts.map +1 -0
  73. package/dist/json/layers/index.js +4 -0
  74. package/dist/json/layers/index.js.map +1 -0
  75. package/dist/json/rewriteGeoArrowAccessors.d.ts.map +1 -1
  76. package/dist/json/rewriteGeoArrowAccessors.js +5 -0
  77. package/dist/json/rewriteGeoArrowAccessors.js.map +1 -1
  78. package/dist/mapConfigUtils.d.ts +102 -1
  79. package/dist/mapConfigUtils.d.ts.map +1 -1
  80. package/dist/mapConfigUtils.js +21 -3
  81. package/dist/mapConfigUtils.js.map +1 -1
  82. package/dist/mapLayerConfigUtils.d.ts +15 -0
  83. package/dist/mapLayerConfigUtils.d.ts.map +1 -1
  84. package/dist/mapLayerConfigUtils.js +109 -7
  85. package/dist/mapLayerConfigUtils.js.map +1 -1
  86. package/dist/prepare/detectGeometryColumn.d.ts +10 -1
  87. package/dist/prepare/detectGeometryColumn.d.ts.map +1 -1
  88. package/dist/prepare/detectGeometryColumn.js +48 -6
  89. package/dist/prepare/detectGeometryColumn.js.map +1 -1
  90. package/dist/prepare/wkbDecoder.d.ts.map +1 -1
  91. package/dist/prepare/wkbDecoder.js +88 -1
  92. package/dist/prepare/wkbDecoder.js.map +1 -1
  93. package/dist/prepare/wkbParser.d.ts +5 -0
  94. package/dist/prepare/wkbParser.d.ts.map +1 -1
  95. package/dist/prepare/wkbParser.js +24 -0
  96. package/dist/prepare/wkbParser.js.map +1 -1
  97. package/dist/types.d.ts +14 -4
  98. package/dist/types.d.ts.map +1 -1
  99. package/dist/types.js.map +1 -1
  100. package/dist/useDeckMapDatasets.d.ts +17 -0
  101. package/dist/useDeckMapDatasets.d.ts.map +1 -0
  102. package/dist/useDeckMapDatasets.js +69 -0
  103. package/dist/useDeckMapDatasets.js.map +1 -0
  104. package/dist/useDeckMapFitToBounds.d.ts +29 -0
  105. package/dist/useDeckMapFitToBounds.d.ts.map +1 -0
  106. package/dist/useDeckMapFitToBounds.js +333 -0
  107. package/dist/useDeckMapFitToBounds.js.map +1 -0
  108. package/package.json +7 -6
@@ -1,6 +1,6 @@
1
1
  import { isColorScaleFunction } from './json/layerConfig';
2
2
  export const DECK_MAP_LAYER_TYPE_OPTIONS = [
3
- { value: 'GeoArrowScatterplotLayer', label: 'Scatterplot' },
3
+ { value: 'GeoArrowScatterplotLayer', label: 'Point' },
4
4
  { value: 'GeoArrowHeatmapLayer', label: 'Heatmap' },
5
5
  { value: 'GeoArrowColumnLayer', label: 'Column' },
6
6
  { value: 'GeoArrowPathLayer', label: 'Path' },
@@ -28,6 +28,8 @@ export const DECK_MAP_COLOR_SCALE_TYPE_OPTIONS = [
28
28
  const GEOMETRY_COLUMN_LAYER_TYPES = new Set([
29
29
  'geoarrowpolygonlayer',
30
30
  'geoarrowsolidpolygonlayer',
31
+ 'geoarrowpathlayer',
32
+ 'geoarrowtripslayer',
31
33
  'geojsonlayer',
32
34
  'polygonlayer',
33
35
  'solidpolygonlayer',
@@ -35,6 +37,31 @@ const GEOMETRY_COLUMN_LAYER_TYPES = new Set([
35
37
  'polygon',
36
38
  'solid polygon',
37
39
  ]);
40
+ const H3_LAYER_TYPES = new Set(['geoarrowh3hexagonlayer', 'h3hexagonlayer']);
41
+ const ARC_LAYER_TYPES = new Set(['geoarrowarclayer', 'arclayer']);
42
+ const TRIPS_LAYER_TYPES = new Set([
43
+ 'geoarrowtripslayer',
44
+ 'decktripslayer',
45
+ 'tripslayer',
46
+ ]);
47
+ const RADIUS_LAYER_TYPES = new Set([
48
+ 'geoarrowscatterplotlayer',
49
+ 'scatterplotlayer',
50
+ ]);
51
+ const COLUMN_RADIUS_LAYER_TYPES = new Set([
52
+ 'geoarrowcolumnlayer',
53
+ 'columnlayer',
54
+ ]);
55
+ const EXTRUDABLE_LAYER_TYPES = new Set([
56
+ 'geoarrowh3hexagonlayer',
57
+ 'h3hexagonlayer',
58
+ 'geoarrowcolumnlayer',
59
+ 'columnlayer',
60
+ 'geoarrowpolygonlayer',
61
+ 'polygonlayer',
62
+ 'geoarrowsolidpolygonlayer',
63
+ 'solidpolygonlayer',
64
+ ]);
38
65
  function isRecord(value) {
39
66
  return Boolean(value && typeof value === 'object' && !Array.isArray(value));
40
67
  }
@@ -55,6 +82,29 @@ export function usesGeometryColumnSetting(layerType) {
55
82
  return (typeof layerType === 'string' &&
56
83
  GEOMETRY_COLUMN_LAYER_TYPES.has(layerType.toLowerCase()));
57
84
  }
85
+ export function usesH3ColumnSetting(layerType) {
86
+ return (typeof layerType === 'string' && H3_LAYER_TYPES.has(layerType.toLowerCase()));
87
+ }
88
+ export function usesArcColumnSetting(layerType) {
89
+ return (typeof layerType === 'string' &&
90
+ ARC_LAYER_TYPES.has(layerType.toLowerCase()));
91
+ }
92
+ export function usesRadiusSetting(layerType) {
93
+ return (typeof layerType === 'string' &&
94
+ RADIUS_LAYER_TYPES.has(layerType.toLowerCase()));
95
+ }
96
+ export function usesColumnRadiusSetting(layerType) {
97
+ return (typeof layerType === 'string' &&
98
+ COLUMN_RADIUS_LAYER_TYPES.has(layerType.toLowerCase()));
99
+ }
100
+ export function usesTripsSettings(layerType) {
101
+ return (typeof layerType === 'string' &&
102
+ TRIPS_LAYER_TYPES.has(layerType.toLowerCase()));
103
+ }
104
+ export function usesExtrusionSettings(layerType) {
105
+ return (typeof layerType === 'string' &&
106
+ EXTRUDABLE_LAYER_TYPES.has(layerType.toLowerCase()));
107
+ }
58
108
  export function getDeckMapColorAccessorOptions(layerType) {
59
109
  if (layerType === 'GeoArrowPathLayer' || layerType === 'GeoArrowTripsLayer') {
60
110
  return DECK_MAP_COLOR_ACCESSOR_OPTIONS.filter((option) => option.value === 'getColor');
@@ -85,10 +135,20 @@ export function updateDeckMapLayer(config, layerIndex, updater) {
85
135
  };
86
136
  }
87
137
  export function setDeckMapLayerType(config, layerIndex, layerType) {
88
- return updateDeckMapLayer(config, layerIndex, (layer) => ({
89
- ...layer,
90
- '@@type': layerType,
91
- }));
138
+ return updateDeckMapLayer(config, layerIndex, (layer) => {
139
+ const nextLayer = {
140
+ ...layer,
141
+ '@@type': layerType,
142
+ };
143
+ const lt = layerType.toLowerCase();
144
+ if (lt === 'geoarrowcolumnlayer' ||
145
+ lt === 'columnlayer' ||
146
+ lt === 'deckcolumnlayer') {
147
+ nextLayer.radius ??= 3;
148
+ nextLayer.elevationScale ??= 1;
149
+ }
150
+ return nextLayer;
151
+ });
92
152
  }
93
153
  export function setDeckMapLayerGeometryColumn(config, layerIndex, geometryColumn) {
94
154
  const layer = getDeckMapLayerRecords(config)[layerIndex];
@@ -96,7 +156,7 @@ export function setDeckMapLayerGeometryColumn(config, layerIndex, geometryColumn
96
156
  if (!datasetId || !config.datasets?.[datasetId]) {
97
157
  return config;
98
158
  }
99
- return {
159
+ const updatedConfig = {
100
160
  ...config,
101
161
  datasets: {
102
162
  ...config.datasets,
@@ -105,7 +165,41 @@ export function setDeckMapLayerGeometryColumn(config, layerIndex, geometryColumn
105
165
  geometryColumn,
106
166
  },
107
167
  },
168
+ fitToData: config.fitToData &&
169
+ config.fitToData.dataset === datasetId &&
170
+ 'geometryColumn' in config.fitToData
171
+ ? {
172
+ ...config.fitToData,
173
+ geometryColumn,
174
+ }
175
+ : config.fitToData,
108
176
  };
177
+ return updateDeckMapLayer(updatedConfig, layerIndex, (l) => ({
178
+ ...l,
179
+ _sqlroomsBinding: {
180
+ ...l._sqlroomsBinding,
181
+ geometryColumn,
182
+ },
183
+ }));
184
+ }
185
+ export function setDeckMapLayerHexagonColumn(config, layerIndex, hexagonColumn) {
186
+ return updateDeckMapLayer(config, layerIndex, (layer) => ({
187
+ ...layer,
188
+ getHexagon: `@@=${hexagonColumn}`,
189
+ _sqlroomsBinding: {
190
+ ...(isRecord(layer._sqlroomsBinding) ? layer._sqlroomsBinding : {}),
191
+ hexagonColumn,
192
+ },
193
+ }));
194
+ }
195
+ export function setDeckMapLayerArcColumns(config, layerIndex, columns) {
196
+ return updateDeckMapLayer(config, layerIndex, (layer) => ({
197
+ ...layer,
198
+ _sqlroomsBinding: {
199
+ ...(isRecord(layer._sqlroomsBinding) ? layer._sqlroomsBinding : {}),
200
+ ...columns,
201
+ },
202
+ }));
109
203
  }
110
204
  export function getDeckMapLayerColorScale(layer, accessor) {
111
205
  const value = layer?.[accessor];
@@ -119,10 +213,18 @@ export function setDeckMapLayerColorScale(config, layerIndex, accessor, colorSca
119
213
  [accessor]: colorScale,
120
214
  }));
121
215
  }
216
+ const DEFAULT_LAYER_FILL_COLOR = [
217
+ 56, 189, 248, 180,
218
+ ];
122
219
  export function clearDeckMapLayerColorScale(config, layerIndex, accessor) {
123
220
  return updateDeckMapLayer(config, layerIndex, (layer) => {
124
221
  const nextLayer = { ...layer };
125
- delete nextLayer[accessor];
222
+ if (accessor === 'getFillColor') {
223
+ nextLayer[accessor] = [...DEFAULT_LAYER_FILL_COLOR];
224
+ }
225
+ else {
226
+ delete nextLayer[accessor];
227
+ }
126
228
  return nextLayer;
127
229
  });
128
230
  }
@@ -1 +1 @@
1
- {"version":3,"file":"mapLayerConfigUtils.js","sourceRoot":"","sources":["../src/mapLayerConfigUtils.ts"],"names":[],"mappings":"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","sourcesContent":["import type {ColorScaleConfig, ColorScaleScheme} from '@sqlrooms/color-scales';\nimport type {DeckMapDashboardPanelConfig} from './dashboardConfig';\nimport type {DeckAutoLayerType} from './types';\nimport {isColorScaleFunction} from './json/layerConfig';\n\nexport type DeckMapLayerRecord = Record<string, unknown>;\n\nexport type DeckMapLayerColorScaleFunction = ColorScaleConfig & {\n '@@function': 'colorScale';\n};\n\nexport type DeckMapLayerColorAccessor =\n | 'getFillColor'\n | 'getLineColor'\n | 'getColor'\n | 'getSourceColor'\n | 'getTargetColor';\n\nexport const DECK_MAP_LAYER_TYPE_OPTIONS: ReadonlyArray<{\n value: DeckAutoLayerType | 'GeoArrowSolidPolygonLayer';\n label: string;\n}> = [\n {value: 'GeoArrowScatterplotLayer', label: 'Scatterplot'},\n {value: 'GeoArrowHeatmapLayer', label: 'Heatmap'},\n {value: 'GeoArrowColumnLayer', label: 'Column'},\n {value: 'GeoArrowPathLayer', label: 'Path'},\n {value: 'GeoArrowPolygonLayer', label: 'Polygon'},\n {value: 'GeoArrowSolidPolygonLayer', label: 'Solid polygon'},\n {value: 'GeoArrowArcLayer', label: 'Arc'},\n {value: 'GeoArrowTripsLayer', label: 'Trips'},\n {value: 'GeoArrowH3HexagonLayer', label: 'H3 hexagon'},\n {value: 'GeoJsonLayer', label: 'GeoJSON'},\n];\n\nexport const DECK_MAP_COLOR_ACCESSOR_OPTIONS: ReadonlyArray<{\n value: DeckMapLayerColorAccessor;\n label: string;\n}> = [\n {value: 'getFillColor', label: 'Fill color'},\n {value: 'getLineColor', label: 'Line color'},\n {value: 'getColor', label: 'Color'},\n {value: 'getSourceColor', label: 'Source color'},\n {value: 'getTargetColor', label: 'Target color'},\n];\n\nexport const DECK_MAP_COLOR_SCALE_TYPE_OPTIONS: ReadonlyArray<{\n value: ColorScaleConfig['type'];\n label: string;\n defaultScheme: ColorScaleScheme;\n}> = [\n {value: 'sequential', label: 'Sequential', defaultScheme: 'Viridis'},\n {value: 'diverging', label: 'Diverging', defaultScheme: 'RdBu'},\n {value: 'quantize', label: 'Quantize', defaultScheme: 'YlOrRd'},\n {value: 'quantile', label: 'Quantile', defaultScheme: 'YlOrRd'},\n {value: 'categorical', label: 'Categorical', defaultScheme: 'Tableau10'},\n];\n\nconst GEOMETRY_COLUMN_LAYER_TYPES = new Set([\n 'geoarrowpolygonlayer',\n 'geoarrowsolidpolygonlayer',\n 'geojsonlayer',\n 'polygonlayer',\n 'solidpolygonlayer',\n 'geojson',\n 'polygon',\n 'solid polygon',\n]);\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value && typeof value === 'object' && !Array.isArray(value));\n}\n\nfunction getObjectSpec(\n config: DeckMapDashboardPanelConfig,\n): Record<string, unknown> | undefined {\n return isRecord(config.spec) ? config.spec : undefined;\n}\n\nexport function getDeckMapLayerRecords(\n config: DeckMapDashboardPanelConfig,\n): DeckMapLayerRecord[] {\n const layers = getObjectSpec(config)?.layers;\n return Array.isArray(layers) ? layers.filter(isRecord) : [];\n}\n\nexport function getDeckMapLayerDatasetId(\n layer: DeckMapLayerRecord | undefined,\n): string | undefined {\n const binding = layer?._sqlroomsBinding;\n if (!isRecord(binding)) return undefined;\n return typeof binding.dataset === 'string' ? binding.dataset : undefined;\n}\n\nexport function usesGeometryColumnSetting(layerType: unknown) {\n return (\n typeof layerType === 'string' &&\n GEOMETRY_COLUMN_LAYER_TYPES.has(layerType.toLowerCase())\n );\n}\n\nexport function getDeckMapColorAccessorOptions(\n layerType: unknown,\n): typeof DECK_MAP_COLOR_ACCESSOR_OPTIONS {\n if (layerType === 'GeoArrowPathLayer' || layerType === 'GeoArrowTripsLayer') {\n return DECK_MAP_COLOR_ACCESSOR_OPTIONS.filter(\n (option) => option.value === 'getColor',\n );\n }\n\n if (layerType === 'GeoArrowArcLayer') {\n return DECK_MAP_COLOR_ACCESSOR_OPTIONS.filter(\n (option) =>\n option.value === 'getSourceColor' || option.value === 'getTargetColor',\n );\n }\n\n if (layerType === 'GeoArrowHeatmapLayer') {\n return [];\n }\n\n return DECK_MAP_COLOR_ACCESSOR_OPTIONS.filter(\n (option) =>\n option.value === 'getFillColor' || option.value === 'getLineColor',\n );\n}\n\nexport function updateDeckMapLayer(\n config: DeckMapDashboardPanelConfig,\n layerIndex: number,\n updater: (layer: DeckMapLayerRecord) => DeckMapLayerRecord,\n): DeckMapDashboardPanelConfig {\n const spec = getObjectSpec(config);\n if (!spec || !Array.isArray(spec.layers)) {\n return config;\n }\n\n const layer = spec.layers[layerIndex];\n if (!isRecord(layer)) {\n return config;\n }\n\n return {\n ...config,\n spec: {\n ...spec,\n layers: spec.layers.map((candidate, index) =>\n index === layerIndex ? updater({...layer}) : candidate,\n ),\n },\n };\n}\n\nexport function setDeckMapLayerType(\n config: DeckMapDashboardPanelConfig,\n layerIndex: number,\n layerType: string,\n): DeckMapDashboardPanelConfig {\n return updateDeckMapLayer(config, layerIndex, (layer) => ({\n ...layer,\n '@@type': layerType,\n }));\n}\n\nexport function setDeckMapLayerGeometryColumn(\n config: DeckMapDashboardPanelConfig,\n layerIndex: number,\n geometryColumn: string,\n): DeckMapDashboardPanelConfig {\n const layer = getDeckMapLayerRecords(config)[layerIndex];\n const datasetId = getDeckMapLayerDatasetId(layer);\n if (!datasetId || !config.datasets?.[datasetId]) {\n return config;\n }\n\n return {\n ...config,\n datasets: {\n ...config.datasets,\n [datasetId]: {\n ...config.datasets[datasetId],\n geometryColumn,\n },\n },\n };\n}\n\nexport function getDeckMapLayerColorScale(\n layer: DeckMapLayerRecord | undefined,\n accessor: DeckMapLayerColorAccessor,\n): DeckMapLayerColorScaleFunction | undefined {\n const value = layer?.[accessor];\n return isColorScaleFunction(value)\n ? (value as DeckMapLayerColorScaleFunction)\n : undefined;\n}\n\nexport function setDeckMapLayerColorScale(\n config: DeckMapDashboardPanelConfig,\n layerIndex: number,\n accessor: DeckMapLayerColorAccessor,\n colorScale: DeckMapLayerColorScaleFunction,\n): DeckMapDashboardPanelConfig {\n return updateDeckMapLayer(config, layerIndex, (layer) => ({\n ...layer,\n [accessor]: colorScale,\n }));\n}\n\nexport function clearDeckMapLayerColorScale(\n config: DeckMapDashboardPanelConfig,\n layerIndex: number,\n accessor: DeckMapLayerColorAccessor,\n): DeckMapDashboardPanelConfig {\n return updateDeckMapLayer(config, layerIndex, (layer) => {\n const nextLayer = {...layer};\n delete nextLayer[accessor];\n return nextLayer;\n });\n}\n\nexport function createDeckMapLayerColorScale(options: {\n field: string;\n type?: ColorScaleConfig['type'];\n scheme?: ColorScaleScheme;\n title?: string;\n}): DeckMapLayerColorScaleFunction {\n const type = options.type ?? 'sequential';\n const scheme =\n options.scheme ??\n DECK_MAP_COLOR_SCALE_TYPE_OPTIONS.find((option) => option.value === type)\n ?.defaultScheme ??\n 'Viridis';\n const base = {\n '@@function': 'colorScale' as const,\n field: options.field,\n legend: {title: options.title ?? options.field},\n };\n\n if (type === 'categorical') {\n return {\n ...base,\n type,\n scheme: scheme as Extract<\n ColorScaleConfig,\n {type: 'categorical'}\n >['scheme'],\n };\n }\n\n if (type === 'diverging') {\n return {\n ...base,\n type,\n scheme: scheme as Extract<\n ColorScaleConfig,\n {type: 'diverging'}\n >['scheme'],\n domain: 'auto',\n };\n }\n\n if (type === 'quantize') {\n return {\n ...base,\n type,\n scheme: scheme as Extract<ColorScaleConfig, {type: 'quantize'}>['scheme'],\n domain: 'auto',\n };\n }\n\n if (type === 'quantile') {\n return {\n ...base,\n type,\n scheme: scheme as Extract<ColorScaleConfig, {type: 'quantile'}>['scheme'],\n };\n }\n\n if (type === 'threshold') {\n return {\n ...base,\n type,\n scheme: scheme as Extract<\n ColorScaleConfig,\n {type: 'threshold'}\n >['scheme'],\n thresholds: [],\n };\n }\n\n return {\n ...base,\n type: 'sequential',\n scheme: scheme as Extract<ColorScaleConfig, {type: 'sequential'}>['scheme'],\n domain: 'auto',\n };\n}\n"]}
1
+ {"version":3,"file":"mapLayerConfigUtils.js","sourceRoot":"","sources":["../src/mapLayerConfigUtils.ts"],"names":[],"mappings":"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","sourcesContent":["import type {ColorScaleConfig, ColorScaleScheme} from '@sqlrooms/color-scales';\nimport type {DeckMapDashboardPanelConfig} from './dashboardConfig';\nimport type {DeckAutoLayerType} from './types';\nimport {isColorScaleFunction} from './json/layerConfig';\n\nexport type DeckMapLayerRecord = Record<string, unknown>;\n\nexport type DeckMapLayerColorScaleFunction = ColorScaleConfig & {\n '@@function': 'colorScale';\n};\n\nexport type DeckMapLayerColorAccessor =\n | 'getFillColor'\n | 'getLineColor'\n | 'getColor'\n | 'getSourceColor'\n | 'getTargetColor';\n\nexport const DECK_MAP_LAYER_TYPE_OPTIONS: ReadonlyArray<{\n value: DeckAutoLayerType | 'GeoArrowSolidPolygonLayer';\n label: string;\n}> = [\n {value: 'GeoArrowScatterplotLayer', label: 'Point'},\n {value: 'GeoArrowHeatmapLayer', label: 'Heatmap'},\n {value: 'GeoArrowColumnLayer', label: 'Column'},\n {value: 'GeoArrowPathLayer', label: 'Path'},\n {value: 'GeoArrowPolygonLayer', label: 'Polygon'},\n {value: 'GeoArrowSolidPolygonLayer', label: 'Solid polygon'},\n {value: 'GeoArrowArcLayer', label: 'Arc'},\n {value: 'GeoArrowTripsLayer', label: 'Trips'},\n {value: 'GeoArrowH3HexagonLayer', label: 'H3 hexagon'},\n {value: 'GeoJsonLayer', label: 'GeoJSON'},\n];\n\nexport const DECK_MAP_COLOR_ACCESSOR_OPTIONS: ReadonlyArray<{\n value: DeckMapLayerColorAccessor;\n label: string;\n}> = [\n {value: 'getFillColor', label: 'Fill color'},\n {value: 'getLineColor', label: 'Line color'},\n {value: 'getColor', label: 'Color'},\n {value: 'getSourceColor', label: 'Source color'},\n {value: 'getTargetColor', label: 'Target color'},\n];\n\nexport const DECK_MAP_COLOR_SCALE_TYPE_OPTIONS: ReadonlyArray<{\n value: ColorScaleConfig['type'];\n label: string;\n defaultScheme: ColorScaleScheme;\n}> = [\n {value: 'sequential', label: 'Sequential', defaultScheme: 'Viridis'},\n {value: 'diverging', label: 'Diverging', defaultScheme: 'RdBu'},\n {value: 'quantize', label: 'Quantize', defaultScheme: 'YlOrRd'},\n {value: 'quantile', label: 'Quantile', defaultScheme: 'YlOrRd'},\n {value: 'categorical', label: 'Categorical', defaultScheme: 'Tableau10'},\n];\n\nconst GEOMETRY_COLUMN_LAYER_TYPES = new Set([\n 'geoarrowpolygonlayer',\n 'geoarrowsolidpolygonlayer',\n 'geoarrowpathlayer',\n 'geoarrowtripslayer',\n 'geojsonlayer',\n 'polygonlayer',\n 'solidpolygonlayer',\n 'geojson',\n 'polygon',\n 'solid polygon',\n]);\n\nconst H3_LAYER_TYPES = new Set(['geoarrowh3hexagonlayer', 'h3hexagonlayer']);\n\nconst ARC_LAYER_TYPES = new Set(['geoarrowarclayer', 'arclayer']);\n\nconst TRIPS_LAYER_TYPES = new Set([\n 'geoarrowtripslayer',\n 'decktripslayer',\n 'tripslayer',\n]);\n\nconst RADIUS_LAYER_TYPES = new Set([\n 'geoarrowscatterplotlayer',\n 'scatterplotlayer',\n]);\n\nconst COLUMN_RADIUS_LAYER_TYPES = new Set([\n 'geoarrowcolumnlayer',\n 'columnlayer',\n]);\n\nconst EXTRUDABLE_LAYER_TYPES = new Set([\n 'geoarrowh3hexagonlayer',\n 'h3hexagonlayer',\n 'geoarrowcolumnlayer',\n 'columnlayer',\n 'geoarrowpolygonlayer',\n 'polygonlayer',\n 'geoarrowsolidpolygonlayer',\n 'solidpolygonlayer',\n]);\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value && typeof value === 'object' && !Array.isArray(value));\n}\n\nfunction getObjectSpec(\n config: DeckMapDashboardPanelConfig,\n): Record<string, unknown> | undefined {\n return isRecord(config.spec) ? config.spec : undefined;\n}\n\nexport function getDeckMapLayerRecords(\n config: DeckMapDashboardPanelConfig,\n): DeckMapLayerRecord[] {\n const layers = getObjectSpec(config)?.layers;\n return Array.isArray(layers) ? layers.filter(isRecord) : [];\n}\n\nexport function getDeckMapLayerDatasetId(\n layer: DeckMapLayerRecord | undefined,\n): string | undefined {\n const binding = layer?._sqlroomsBinding;\n if (!isRecord(binding)) return undefined;\n return typeof binding.dataset === 'string' ? binding.dataset : undefined;\n}\n\nexport function usesGeometryColumnSetting(layerType: unknown) {\n return (\n typeof layerType === 'string' &&\n GEOMETRY_COLUMN_LAYER_TYPES.has(layerType.toLowerCase())\n );\n}\n\nexport function usesH3ColumnSetting(layerType: unknown) {\n return (\n typeof layerType === 'string' && H3_LAYER_TYPES.has(layerType.toLowerCase())\n );\n}\n\nexport function usesArcColumnSetting(layerType: unknown) {\n return (\n typeof layerType === 'string' &&\n ARC_LAYER_TYPES.has(layerType.toLowerCase())\n );\n}\n\nexport function usesRadiusSetting(layerType: unknown) {\n return (\n typeof layerType === 'string' &&\n RADIUS_LAYER_TYPES.has(layerType.toLowerCase())\n );\n}\n\nexport function usesColumnRadiusSetting(layerType: unknown) {\n return (\n typeof layerType === 'string' &&\n COLUMN_RADIUS_LAYER_TYPES.has(layerType.toLowerCase())\n );\n}\n\nexport function usesTripsSettings(layerType: unknown) {\n return (\n typeof layerType === 'string' &&\n TRIPS_LAYER_TYPES.has(layerType.toLowerCase())\n );\n}\n\nexport function usesExtrusionSettings(layerType: unknown) {\n return (\n typeof layerType === 'string' &&\n EXTRUDABLE_LAYER_TYPES.has(layerType.toLowerCase())\n );\n}\n\nexport function getDeckMapColorAccessorOptions(\n layerType: unknown,\n): typeof DECK_MAP_COLOR_ACCESSOR_OPTIONS {\n if (layerType === 'GeoArrowPathLayer' || layerType === 'GeoArrowTripsLayer') {\n return DECK_MAP_COLOR_ACCESSOR_OPTIONS.filter(\n (option) => option.value === 'getColor',\n );\n }\n\n if (layerType === 'GeoArrowArcLayer') {\n return DECK_MAP_COLOR_ACCESSOR_OPTIONS.filter(\n (option) =>\n option.value === 'getSourceColor' || option.value === 'getTargetColor',\n );\n }\n\n if (layerType === 'GeoArrowHeatmapLayer') {\n return [];\n }\n\n return DECK_MAP_COLOR_ACCESSOR_OPTIONS.filter(\n (option) =>\n option.value === 'getFillColor' || option.value === 'getLineColor',\n );\n}\n\nexport function updateDeckMapLayer(\n config: DeckMapDashboardPanelConfig,\n layerIndex: number,\n updater: (layer: DeckMapLayerRecord) => DeckMapLayerRecord,\n): DeckMapDashboardPanelConfig {\n const spec = getObjectSpec(config);\n if (!spec || !Array.isArray(spec.layers)) {\n return config;\n }\n\n const layer = spec.layers[layerIndex];\n if (!isRecord(layer)) {\n return config;\n }\n\n return {\n ...config,\n spec: {\n ...spec,\n layers: spec.layers.map((candidate, index) =>\n index === layerIndex ? updater({...layer}) : candidate,\n ),\n },\n };\n}\n\nexport function setDeckMapLayerType(\n config: DeckMapDashboardPanelConfig,\n layerIndex: number,\n layerType: string,\n): DeckMapDashboardPanelConfig {\n return updateDeckMapLayer(config, layerIndex, (layer) => {\n const nextLayer: DeckMapLayerRecord = {\n ...layer,\n '@@type': layerType,\n };\n const lt = layerType.toLowerCase();\n if (\n lt === 'geoarrowcolumnlayer' ||\n lt === 'columnlayer' ||\n lt === 'deckcolumnlayer'\n ) {\n nextLayer.radius ??= 3;\n nextLayer.elevationScale ??= 1;\n }\n return nextLayer;\n });\n}\n\nexport function setDeckMapLayerGeometryColumn(\n config: DeckMapDashboardPanelConfig,\n layerIndex: number,\n geometryColumn: string,\n): DeckMapDashboardPanelConfig {\n const layer = getDeckMapLayerRecords(config)[layerIndex];\n const datasetId = getDeckMapLayerDatasetId(layer);\n if (!datasetId || !config.datasets?.[datasetId]) {\n return config;\n }\n\n const updatedConfig = {\n ...config,\n datasets: {\n ...config.datasets,\n [datasetId]: {\n ...config.datasets[datasetId],\n geometryColumn,\n },\n },\n fitToData:\n config.fitToData &&\n config.fitToData.dataset === datasetId &&\n 'geometryColumn' in config.fitToData\n ? {\n ...config.fitToData,\n geometryColumn,\n }\n : config.fitToData,\n };\n\n return updateDeckMapLayer(updatedConfig, layerIndex, (l) => ({\n ...l,\n _sqlroomsBinding: {\n ...(l._sqlroomsBinding as Record<string, unknown>),\n geometryColumn,\n },\n }));\n}\n\nexport function setDeckMapLayerHexagonColumn(\n config: DeckMapDashboardPanelConfig,\n layerIndex: number,\n hexagonColumn: string,\n): DeckMapDashboardPanelConfig {\n return updateDeckMapLayer(config, layerIndex, (layer) => ({\n ...layer,\n getHexagon: `@@=${hexagonColumn}`,\n _sqlroomsBinding: {\n ...(isRecord(layer._sqlroomsBinding) ? layer._sqlroomsBinding : {}),\n hexagonColumn,\n },\n }));\n}\n\nexport function setDeckMapLayerArcColumns(\n config: DeckMapDashboardPanelConfig,\n layerIndex: number,\n columns: {\n sourceGeometryColumn?: string;\n targetGeometryColumn?: string;\n sourceLatitudeColumn?: string;\n sourceLongitudeColumn?: string;\n targetLatitudeColumn?: string;\n targetLongitudeColumn?: string;\n },\n): DeckMapDashboardPanelConfig {\n return updateDeckMapLayer(config, layerIndex, (layer) => ({\n ...layer,\n _sqlroomsBinding: {\n ...(isRecord(layer._sqlroomsBinding) ? layer._sqlroomsBinding : {}),\n ...columns,\n },\n }));\n}\n\nexport function getDeckMapLayerColorScale(\n layer: DeckMapLayerRecord | undefined,\n accessor: DeckMapLayerColorAccessor,\n): DeckMapLayerColorScaleFunction | undefined {\n const value = layer?.[accessor];\n return isColorScaleFunction(value)\n ? (value as DeckMapLayerColorScaleFunction)\n : undefined;\n}\n\nexport function setDeckMapLayerColorScale(\n config: DeckMapDashboardPanelConfig,\n layerIndex: number,\n accessor: DeckMapLayerColorAccessor,\n colorScale: DeckMapLayerColorScaleFunction,\n): DeckMapDashboardPanelConfig {\n return updateDeckMapLayer(config, layerIndex, (layer) => ({\n ...layer,\n [accessor]: colorScale,\n }));\n}\n\nconst DEFAULT_LAYER_FILL_COLOR: [number, number, number, number] = [\n 56, 189, 248, 180,\n];\n\nexport function clearDeckMapLayerColorScale(\n config: DeckMapDashboardPanelConfig,\n layerIndex: number,\n accessor: DeckMapLayerColorAccessor,\n): DeckMapDashboardPanelConfig {\n return updateDeckMapLayer(config, layerIndex, (layer) => {\n const nextLayer = {...layer};\n if (accessor === 'getFillColor') {\n nextLayer[accessor] = [...DEFAULT_LAYER_FILL_COLOR];\n } else {\n delete nextLayer[accessor];\n }\n return nextLayer;\n });\n}\n\nexport function createDeckMapLayerColorScale(options: {\n field: string;\n type?: ColorScaleConfig['type'];\n scheme?: ColorScaleScheme;\n title?: string;\n}): DeckMapLayerColorScaleFunction {\n const type = options.type ?? 'sequential';\n const scheme =\n options.scheme ??\n DECK_MAP_COLOR_SCALE_TYPE_OPTIONS.find((option) => option.value === type)\n ?.defaultScheme ??\n 'Viridis';\n const base = {\n '@@function': 'colorScale' as const,\n field: options.field,\n legend: {title: options.title ?? options.field},\n };\n\n if (type === 'categorical') {\n return {\n ...base,\n type,\n scheme: scheme as Extract<\n ColorScaleConfig,\n {type: 'categorical'}\n >['scheme'],\n };\n }\n\n if (type === 'diverging') {\n return {\n ...base,\n type,\n scheme: scheme as Extract<\n ColorScaleConfig,\n {type: 'diverging'}\n >['scheme'],\n domain: 'auto',\n };\n }\n\n if (type === 'quantize') {\n return {\n ...base,\n type,\n scheme: scheme as Extract<ColorScaleConfig, {type: 'quantize'}>['scheme'],\n domain: 'auto',\n };\n }\n\n if (type === 'quantile') {\n return {\n ...base,\n type,\n scheme: scheme as Extract<ColorScaleConfig, {type: 'quantile'}>['scheme'],\n };\n }\n\n if (type === 'threshold') {\n return {\n ...base,\n type,\n scheme: scheme as Extract<\n ColorScaleConfig,\n {type: 'threshold'}\n >['scheme'],\n thresholds: [],\n };\n }\n\n return {\n ...base,\n type: 'sequential',\n scheme: scheme as Extract<ColorScaleConfig, {type: 'sequential'}>['scheme'],\n domain: 'auto',\n };\n}\n"]}
@@ -1,10 +1,19 @@
1
- import type * as arrow from 'apache-arrow';
1
+ import * as arrow from 'apache-arrow';
2
2
  import type { GeometryEncodingHint, ResolvedGeometryColumn } from './types';
3
3
  type DetectGeometryColumnOptions = {
4
4
  table: arrow.Table;
5
5
  geometryColumn?: string;
6
6
  geometryEncodingHint?: GeometryEncodingHint;
7
7
  };
8
+ /**
9
+ * Detects longitude/latitude columns in an Arrow table by matching
10
+ * field names against known patterns (case-insensitive).
11
+ * Returns the original field names if found, or null.
12
+ */
13
+ export declare function findCoordinateColumns(table: arrow.Table): {
14
+ lonField: string;
15
+ latField: string;
16
+ } | null;
8
17
  export declare function detectGeometryColumn(options: DetectGeometryColumnOptions): ResolvedGeometryColumn;
9
18
  export {};
10
19
  //# sourceMappingURL=detectGeometryColumn.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"detectGeometryColumn.d.ts","sourceRoot":"","sources":["../../src/prepare/detectGeometryColumn.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAC;AAE3C,OAAO,KAAK,EACV,oBAAoB,EACpB,sBAAsB,EAEvB,MAAM,SAAS,CAAC;AAEjB,KAAK,2BAA2B,GAAG;IACjC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;CAC7C,CAAC;AAmEF,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,2BAA2B,GACnC,sBAAsB,CA0CxB"}
1
+ {"version":3,"file":"detectGeometryColumn.d.ts","sourceRoot":"","sources":["../../src/prepare/detectGeometryColumn.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAEtC,OAAO,KAAK,EACV,oBAAoB,EACpB,sBAAsB,EAEvB,MAAM,SAAS,CAAC;AAEjB,KAAK,2BAA2B,GAAG;IACjC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;CAC7C,CAAC;AAgBF;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,KAAK,CAAC,KAAK,GACjB;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAC,GAAG,IAAI,CAU7C;AAgFD,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,2BAA2B,GACnC,sBAAsB,CA2CxB"}
@@ -1,14 +1,56 @@
1
1
  import { getGeoMetadata, getGeometryColumnsFromSchema, } from '@loaders.gl/geoarrow';
2
2
  import { isDirectGeoArrowEncoding } from './geoarrow';
3
+ const LON_NAMES = new Set([
4
+ 'longitude',
5
+ 'lon',
6
+ 'lng',
7
+ 'long',
8
+ 'source_lon',
9
+ 'target_lon',
10
+ ]);
11
+ const LAT_NAMES = new Set(['latitude', 'lat', 'source_lat', 'target_lat']);
3
12
  function getFieldNames(table) {
4
13
  return table.schema.fields.map((field) => field.name);
5
14
  }
15
+ /**
16
+ * Detects longitude/latitude columns in an Arrow table by matching
17
+ * field names against known patterns (case-insensitive).
18
+ * Returns the original field names if found, or null.
19
+ */
20
+ export function findCoordinateColumns(table) {
21
+ const fields = table.schema.fields;
22
+ let lonField;
23
+ let latField;
24
+ for (const field of fields) {
25
+ const lower = field.name.toLowerCase();
26
+ if (!lonField && LON_NAMES.has(lower))
27
+ lonField = field.name;
28
+ if (!latField && LAT_NAMES.has(lower))
29
+ latField = field.name;
30
+ }
31
+ return lonField && latField ? { lonField, latField } : null;
32
+ }
33
+ const KNOWN_GEOM_NAMES = ['geometry', 'geom', 'wkb_geometry', 'the_geom'];
6
34
  function getFieldVector(table, fieldName) {
7
35
  const vector = table.getChild(fieldName);
8
- if (!vector) {
9
- throw new Error(`Geometry column "${fieldName}" was not found in the Arrow table.`);
36
+ if (vector) {
37
+ return { vector };
38
+ }
39
+ // Fallback: if the requested geometry column doesn't exist, try other common names
40
+ if (KNOWN_GEOM_NAMES.includes(fieldName.toLowerCase())) {
41
+ for (const altName of KNOWN_GEOM_NAMES) {
42
+ if (altName.toLowerCase() === fieldName.toLowerCase())
43
+ continue;
44
+ const altVector = table.getChild(altName);
45
+ if (altVector) {
46
+ return { vector: altVector };
47
+ }
48
+ }
10
49
  }
11
- return vector;
50
+ const available = table.schema.fields.map((f) => f.name).join(', ');
51
+ throw new Error(`Geometry column "${fieldName}" was not found in the Arrow table. Available columns: ${available}. ` +
52
+ `If the data has longitude/latitude columns, the dataset source SQL should create the geometry column ` +
53
+ `(e.g. ST_AsWKB(ST_Point(longitude, latitude)) AS "${fieldName}").`);
12
54
  }
13
55
  function normalizeEncoding(encoding) {
14
56
  if (!encoding) {
@@ -68,15 +110,15 @@ export function detectGeometryColumn(options) {
68
110
  if (!detectedGeometryColumn) {
69
111
  throw new Error(`Could not detect a geometry column. Available columns: ${fieldNames.join(', ')}`);
70
112
  }
71
- const vector = getFieldVector(table, detectedGeometryColumn);
113
+ const fieldResult = getFieldVector(table, detectedGeometryColumn);
72
114
  const metadataEncoding = normalizeEncoding(fieldMetadata[detectedGeometryColumn]?.encoding) ??
73
115
  normalizeEncoding(geoMetadata?.columns?.[detectedGeometryColumn]?.encoding);
74
116
  const encoding = inferEncodingFromHint(geometryEncodingHint) ??
75
117
  metadataEncoding ??
76
- inferEncodingFromVector(vector);
118
+ inferEncodingFromVector(fieldResult.vector);
77
119
  return {
78
120
  columnName: detectedGeometryColumn,
79
- vector,
121
+ vector: fieldResult.vector,
80
122
  encoding,
81
123
  nativeGeoArrow: isDirectGeoArrowEncoding(encoding),
82
124
  };
@@ -1 +1 @@
1
- {"version":3,"file":"detectGeometryColumn.js","sourceRoot":"","sources":["../../src/prepare/detectGeometryColumn.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n getGeoMetadata,\n getGeometryColumnsFromSchema,\n} from '@loaders.gl/geoarrow';\nimport type * as arrow from 'apache-arrow';\nimport {isDirectGeoArrowEncoding} from './geoarrow';\nimport type {\n GeometryEncodingHint,\n ResolvedGeometryColumn,\n ResolvedGeometryEncoding,\n} from './types';\n\ntype DetectGeometryColumnOptions = {\n table: arrow.Table;\n geometryColumn?: string;\n geometryEncodingHint?: GeometryEncodingHint;\n};\n\nfunction getFieldNames(table: arrow.Table) {\n return table.schema.fields.map((field) => field.name);\n}\n\nfunction getFieldVector(table: arrow.Table, fieldName: string) {\n const vector = table.getChild(fieldName);\n if (!vector) {\n throw new Error(\n `Geometry column \"${fieldName}\" was not found in the Arrow table.`,\n );\n }\n return vector;\n}\n\nfunction normalizeEncoding(\n encoding: string | undefined,\n): ResolvedGeometryEncoding | undefined {\n if (!encoding) {\n return undefined;\n }\n\n const normalized = encoding.toLowerCase() as ResolvedGeometryEncoding;\n switch (normalized) {\n case 'geoarrow.point':\n case 'geoarrow.multipoint':\n case 'geoarrow.linestring':\n case 'geoarrow.multilinestring':\n case 'geoarrow.polygon':\n case 'geoarrow.multipolygon':\n case 'geoarrow.wkb':\n case 'geoarrow.wkt':\n case 'wkb':\n case 'wkt':\n return normalized;\n default:\n return undefined;\n }\n}\n\nfunction inferEncodingFromHint(\n hint: GeometryEncodingHint | undefined,\n): ResolvedGeometryEncoding | undefined {\n switch (hint) {\n case 'wkb':\n return 'wkb';\n case 'wkt':\n return 'wkt';\n default:\n return undefined;\n }\n}\n\nfunction inferEncodingFromVector(\n vector: arrow.Vector,\n): ResolvedGeometryEncoding {\n const typeName = String(vector.type).toLowerCase();\n if (typeName.includes('utf')) {\n return 'wkt';\n }\n if (typeName.includes('binary')) {\n return 'wkb';\n }\n return 'unknown';\n}\n\nexport function detectGeometryColumn(\n options: DetectGeometryColumnOptions,\n): ResolvedGeometryColumn {\n const {table, geometryColumn, geometryEncodingHint} = options;\n const fieldNames = getFieldNames(table);\n const fieldMetadata = getGeometryColumnsFromSchema(table.schema as never);\n const geoMetadata = getGeoMetadata(table.schema as never);\n const metadataCandidates = new Set<string>([\n ...Object.keys(fieldMetadata),\n ...Object.keys(geoMetadata?.columns ?? {}),\n ]);\n\n const namedCandidates = fieldNames.filter((fieldName) =>\n /^(geom|geometry)$/i.test(fieldName),\n );\n\n const explicitGeometryColumn = geometryColumn;\n const detectedGeometryColumn =\n explicitGeometryColumn ??\n (metadataCandidates.size === 1 ? [...metadataCandidates][0] : undefined) ??\n (namedCandidates.length === 1 ? namedCandidates[0] : undefined);\n\n if (!detectedGeometryColumn) {\n throw new Error(\n `Could not detect a geometry column. Available columns: ${fieldNames.join(', ')}`,\n );\n }\n\n const vector = getFieldVector(table, detectedGeometryColumn);\n const metadataEncoding =\n normalizeEncoding(fieldMetadata[detectedGeometryColumn]?.encoding) ??\n normalizeEncoding(geoMetadata?.columns?.[detectedGeometryColumn]?.encoding);\n\n const encoding =\n inferEncodingFromHint(geometryEncodingHint) ??\n metadataEncoding ??\n inferEncodingFromVector(vector);\n\n return {\n columnName: detectedGeometryColumn,\n vector,\n encoding,\n nativeGeoArrow: isDirectGeoArrowEncoding(encoding),\n };\n}\n"]}
1
+ {"version":3,"file":"detectGeometryColumn.js","sourceRoot":"","sources":["../../src/prepare/detectGeometryColumn.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n getGeoMetadata,\n getGeometryColumnsFromSchema,\n} from '@loaders.gl/geoarrow';\nimport * as arrow from 'apache-arrow';\nimport {isDirectGeoArrowEncoding} from './geoarrow';\nimport type {\n GeometryEncodingHint,\n ResolvedGeometryColumn,\n ResolvedGeometryEncoding,\n} from './types';\n\ntype DetectGeometryColumnOptions = {\n table: arrow.Table;\n geometryColumn?: string;\n geometryEncodingHint?: GeometryEncodingHint;\n};\n\nconst LON_NAMES = new Set([\n 'longitude',\n 'lon',\n 'lng',\n 'long',\n 'source_lon',\n 'target_lon',\n]);\nconst LAT_NAMES = new Set(['latitude', 'lat', 'source_lat', 'target_lat']);\n\nfunction getFieldNames(table: arrow.Table) {\n return table.schema.fields.map((field) => field.name);\n}\n\n/**\n * Detects longitude/latitude columns in an Arrow table by matching\n * field names against known patterns (case-insensitive).\n * Returns the original field names if found, or null.\n */\nexport function findCoordinateColumns(\n table: arrow.Table,\n): {lonField: string; latField: string} | null {\n const fields = table.schema.fields;\n let lonField: string | undefined;\n let latField: string | undefined;\n for (const field of fields) {\n const lower = field.name.toLowerCase();\n if (!lonField && LON_NAMES.has(lower)) lonField = field.name;\n if (!latField && LAT_NAMES.has(lower)) latField = field.name;\n }\n return lonField && latField ? {lonField, latField} : null;\n}\n\nconst KNOWN_GEOM_NAMES = ['geometry', 'geom', 'wkb_geometry', 'the_geom'];\n\nfunction getFieldVector(table: arrow.Table, fieldName: string) {\n const vector = table.getChild(fieldName);\n if (vector) {\n return {vector};\n }\n\n // Fallback: if the requested geometry column doesn't exist, try other common names\n if (KNOWN_GEOM_NAMES.includes(fieldName.toLowerCase())) {\n for (const altName of KNOWN_GEOM_NAMES) {\n if (altName.toLowerCase() === fieldName.toLowerCase()) continue;\n const altVector = table.getChild(altName);\n if (altVector) {\n return {vector: altVector};\n }\n }\n }\n\n const available = table.schema.fields.map((f) => f.name).join(', ');\n throw new Error(\n `Geometry column \"${fieldName}\" was not found in the Arrow table. Available columns: ${available}. ` +\n `If the data has longitude/latitude columns, the dataset source SQL should create the geometry column ` +\n `(e.g. ST_AsWKB(ST_Point(longitude, latitude)) AS \"${fieldName}\").`,\n );\n}\n\nfunction normalizeEncoding(\n encoding: string | undefined,\n): ResolvedGeometryEncoding | undefined {\n if (!encoding) {\n return undefined;\n }\n\n const normalized = encoding.toLowerCase() as ResolvedGeometryEncoding;\n switch (normalized) {\n case 'geoarrow.point':\n case 'geoarrow.multipoint':\n case 'geoarrow.linestring':\n case 'geoarrow.multilinestring':\n case 'geoarrow.polygon':\n case 'geoarrow.multipolygon':\n case 'geoarrow.wkb':\n case 'geoarrow.wkt':\n case 'wkb':\n case 'wkt':\n return normalized;\n default:\n return undefined;\n }\n}\n\nfunction inferEncodingFromHint(\n hint: GeometryEncodingHint | undefined,\n): ResolvedGeometryEncoding | undefined {\n switch (hint) {\n case 'wkb':\n return 'wkb';\n case 'wkt':\n return 'wkt';\n default:\n return undefined;\n }\n}\n\nfunction inferEncodingFromVector(\n vector: arrow.Vector,\n): ResolvedGeometryEncoding {\n const typeName = String(vector.type).toLowerCase();\n if (typeName.includes('utf')) {\n return 'wkt';\n }\n if (typeName.includes('binary')) {\n return 'wkb';\n }\n return 'unknown';\n}\n\nexport function detectGeometryColumn(\n options: DetectGeometryColumnOptions,\n): ResolvedGeometryColumn {\n const {table, geometryColumn, geometryEncodingHint} = options;\n const fieldNames = getFieldNames(table);\n const fieldMetadata = getGeometryColumnsFromSchema(table.schema as never);\n const geoMetadata = getGeoMetadata(table.schema as never);\n const metadataCandidates = new Set<string>([\n ...Object.keys(fieldMetadata),\n ...Object.keys(geoMetadata?.columns ?? {}),\n ]);\n\n const namedCandidates = fieldNames.filter((fieldName) =>\n /^(geom|geometry)$/i.test(fieldName),\n );\n\n const explicitGeometryColumn = geometryColumn;\n const detectedGeometryColumn =\n explicitGeometryColumn ??\n (metadataCandidates.size === 1 ? [...metadataCandidates][0] : undefined) ??\n (namedCandidates.length === 1 ? namedCandidates[0] : undefined);\n\n if (!detectedGeometryColumn) {\n throw new Error(\n `Could not detect a geometry column. Available columns: ${fieldNames.join(', ')}`,\n );\n }\n\n const fieldResult = getFieldVector(table, detectedGeometryColumn);\n\n const metadataEncoding =\n normalizeEncoding(fieldMetadata[detectedGeometryColumn]?.encoding) ??\n normalizeEncoding(geoMetadata?.columns?.[detectedGeometryColumn]?.encoding);\n\n const encoding =\n inferEncodingFromHint(geometryEncodingHint) ??\n metadataEncoding ??\n inferEncodingFromVector(fieldResult.vector);\n\n return {\n columnName: detectedGeometryColumn,\n vector: fieldResult.vector,\n encoding,\n nativeGeoArrow: isDirectGeoArrowEncoding(encoding),\n };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"wkbDecoder.d.ts","sourceRoot":"","sources":["../../src/prepare/wkbDecoder.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,mBAAmB,CAAC;AAmYvD,eAAO,MAAM,kBAAkB,EAAE,eAsEhC,CAAC"}
1
+ {"version":3,"file":"wkbDecoder.d.ts","sourceRoot":"","sources":["../../src/prepare/wkbDecoder.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,mBAAmB,CAAC;AAsevD,eAAO,MAAM,kBAAkB,EAAE,eAmFhC,CAAC"}
@@ -1,7 +1,7 @@
1
1
  import { WKBLoader, WKTLoader } from '@loaders.gl/wkt';
2
2
  import { Field, FixedSizeList, Float64, List, makeData, Table, Vector, } from 'apache-arrow';
3
3
  import { buildBinaryGeoJsonData } from './toGeoJsonBinary';
4
- import { parseWKBHeader, readWKBPointXY, visitWKBMultiPolygonCoordinates, visitWKBPolygonCoordinates, WKB_MULTIPOLYGON, WKB_POINT, WKB_POLYGON, } from './wkbParser';
4
+ import { parseWKBHeader, readWKBLineStringXY, readWKBPointXY, visitWKBMultiPolygonCoordinates, visitWKBPolygonCoordinates, WKB_LINESTRING, WKB_MULTIPOLYGON, WKB_POINT, WKB_POLYGON, } from './wkbParser';
5
5
  const COORD_FIELD = new Field('xy', new Float64(), false);
6
6
  const VERTEX_TYPE = new FixedSizeList(2, COORD_FIELD);
7
7
  const VERTEX_FIELD = new Field('', VERTEX_TYPE, true);
@@ -291,11 +291,92 @@ const POINT_LAYERS = new Set([
291
291
  'GeoArrowScatterplotLayer',
292
292
  'GeoArrowHeatmapLayer',
293
293
  'GeoArrowColumnLayer',
294
+ 'GeoArrowArcLayer',
294
295
  ]);
295
296
  const POLYGON_LAYERS = new Set([
296
297
  'GeoArrowPolygonLayer',
297
298
  'GeoArrowSolidPolygonLayer',
298
299
  ]);
300
+ const PATH_LAYERS = new Set(['GeoArrowPathLayer', 'GeoArrowTripsLayer']);
301
+ /**
302
+ * Promotes WKB/WKT LineString geometries to a native GeoArrow LineString vector
303
+ * (List<FixedSizeList<2, Float64>>). Returns null if any geometry is not a LineString.
304
+ */
305
+ function tryPromoteLineStringTable(table, columnName, encoding) {
306
+ const vector = table.getChild(columnName);
307
+ if (!vector)
308
+ return null;
309
+ const n = table.numRows;
310
+ const allCoords = [];
311
+ const offsets = new Int32Array(n + 1);
312
+ const isNull = new Uint8Array(n);
313
+ let nullCount = 0;
314
+ let totalPoints = 0;
315
+ for (let i = 0; i < n; i++) {
316
+ offsets[i] = totalPoints;
317
+ const raw = vector.get(i);
318
+ if (raw == null) {
319
+ isNull[i] = 1;
320
+ nullCount++;
321
+ continue;
322
+ }
323
+ let coords = null;
324
+ if (isWKTEncoding(encoding, raw)) {
325
+ const geom = parseGeometryValue(raw, encoding);
326
+ if (!geom) {
327
+ isNull[i] = 1;
328
+ nullCount++;
329
+ continue;
330
+ }
331
+ if (geom.type !== 'LineString')
332
+ return null;
333
+ coords = geom.coordinates.map((c) => [c[0], c[1]]);
334
+ }
335
+ else {
336
+ const buf = toArrayBuffer(raw);
337
+ const hdr = parseWKBHeader(buf);
338
+ if (!hdr)
339
+ return null;
340
+ coords = readWKBLineStringXY(buf, hdr);
341
+ if (!coords)
342
+ return null;
343
+ }
344
+ const flat = new Float64Array(coords.length * 2);
345
+ for (let j = 0; j < coords.length; j++) {
346
+ flat[j * 2] = coords[j][0];
347
+ flat[j * 2 + 1] = coords[j][1];
348
+ }
349
+ allCoords.push(flat);
350
+ totalPoints += coords.length;
351
+ }
352
+ offsets[n] = totalPoints;
353
+ const flatValues = new Float64Array(totalPoints * 2);
354
+ let writeOffset = 0;
355
+ for (const chunk of allCoords) {
356
+ flatValues.set(chunk, writeOffset);
357
+ writeOffset += chunk.length;
358
+ }
359
+ const floatData = makeData({
360
+ type: new Float64(),
361
+ length: totalPoints * 2,
362
+ data: flatValues,
363
+ });
364
+ const vertexData = makeData({
365
+ type: VERTEX_TYPE,
366
+ length: totalPoints,
367
+ child: floatData,
368
+ });
369
+ const lineStringType = new List(VERTEX_FIELD);
370
+ const lineData = makeData({
371
+ type: lineStringType,
372
+ length: n,
373
+ nullCount,
374
+ nullBitmap: buildNullBitmap(n, isNull, nullCount),
375
+ valueOffsets: offsets,
376
+ child: vertexData,
377
+ });
378
+ return buildPromotedResult(table, columnName, new Vector([lineData]), 'geoarrow.linestring');
379
+ }
299
380
  export const wkbGeometryDecoder = {
300
381
  supportsGeoArrowPromotion(layerType, encoding, table, columnName) {
301
382
  if (!['wkb', 'geoarrow.wkb', 'wkt', 'geoarrow.wkt', 'unknown'].includes(encoding)) {
@@ -307,12 +388,18 @@ export const wkbGeometryDecoder = {
307
388
  if (POLYGON_LAYERS.has(layerType)) {
308
389
  return sampledGeometriesMatch(table, columnName, encoding, (geometryType) => geometryType === 'Polygon' || geometryType === 'MultiPolygon', (geometryType) => geometryType === WKB_POLYGON || geometryType === WKB_MULTIPOLYGON);
309
390
  }
391
+ if (PATH_LAYERS.has(layerType)) {
392
+ return sampledGeometriesMatch(table, columnName, encoding, (geometryType) => geometryType === 'LineString', (geometryType) => geometryType === WKB_LINESTRING);
393
+ }
310
394
  return false;
311
395
  },
312
396
  toGeoArrowLike(table, columnName, encoding) {
313
397
  const pointResult = tryPromotePointTable(table, columnName, encoding);
314
398
  if (pointResult)
315
399
  return pointResult;
400
+ const lineResult = tryPromoteLineStringTable(table, columnName, encoding);
401
+ if (lineResult)
402
+ return lineResult;
316
403
  const result = tryPromotePolygonTable(table, columnName, encoding);
317
404
  if (result)
318
405
  return result;