@sqlrooms/deck 0.29.0-rc.11 → 0.29.0-rc.13

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 (154) hide show
  1. package/README.md +193 -35
  2. package/dist/BlockMapSettings.d.ts.map +1 -1
  3. package/dist/BlockMapSettings.js +4 -16
  4. package/dist/BlockMapSettings.js.map +1 -1
  5. package/dist/DashboardMapSettings.d.ts.map +1 -1
  6. package/dist/DashboardMapSettings.js +7 -10
  7. package/dist/DashboardMapSettings.js.map +1 -1
  8. package/dist/DeckJsonMap.d.ts.map +1 -1
  9. package/dist/DeckJsonMap.js +75 -23
  10. package/dist/DeckJsonMap.js.map +1 -1
  11. package/dist/DeckJsonMapSpec.d.ts +41 -0
  12. package/dist/DeckJsonMapSpec.d.ts.map +1 -1
  13. package/dist/DeckJsonMapSpec.js +2 -0
  14. package/dist/DeckJsonMapSpec.js.map +1 -1
  15. package/dist/DeckMapBasemapSelect.d.ts +9 -0
  16. package/dist/DeckMapBasemapSelect.d.ts.map +1 -0
  17. package/dist/DeckMapBasemapSelect.js +20 -0
  18. package/dist/DeckMapBasemapSelect.js.map +1 -0
  19. package/dist/DeckMapDefaultStylesProvider.d.ts +13 -19
  20. package/dist/DeckMapDefaultStylesProvider.d.ts.map +1 -1
  21. package/dist/DeckMapDefaultStylesProvider.js +11 -18
  22. package/dist/DeckMapDefaultStylesProvider.js.map +1 -1
  23. package/dist/DeckMapSurface.d.ts +1 -1
  24. package/dist/DeckMapSurface.js +1 -1
  25. package/dist/DeckMapSurface.js.map +1 -1
  26. package/dist/DeckMapsSlice.d.ts +5 -0
  27. package/dist/DeckMapsSlice.d.ts.map +1 -1
  28. package/dist/DeckMapsSlice.js +6 -3
  29. package/dist/DeckMapsSlice.js.map +1 -1
  30. package/dist/MapSettings.d.ts +14 -0
  31. package/dist/MapSettings.d.ts.map +1 -1
  32. package/dist/MapSettings.js +548 -192
  33. package/dist/MapSettings.js.map +1 -1
  34. package/dist/MapSettingsControls.d.ts +8 -1
  35. package/dist/MapSettingsControls.d.ts.map +1 -1
  36. package/dist/MapSettingsControls.js +24 -2
  37. package/dist/MapSettingsControls.js.map +1 -1
  38. package/dist/ai.d.ts.map +1 -1
  39. package/dist/ai.js +20 -12
  40. package/dist/ai.js.map +1 -1
  41. package/dist/aiNormalize.d.ts.map +1 -1
  42. package/dist/aiNormalize.js +2 -1
  43. package/dist/aiNormalize.js.map +1 -1
  44. package/dist/basemap.d.ts +23 -0
  45. package/dist/basemap.d.ts.map +1 -0
  46. package/dist/basemap.js +23 -0
  47. package/dist/basemap.js.map +1 -0
  48. package/dist/block.d.ts +1 -1
  49. package/dist/block.d.ts.map +1 -1
  50. package/dist/block.js +13 -9
  51. package/dist/block.js.map +1 -1
  52. package/dist/createOrUpdateDeckMapResource.d.ts +6 -2
  53. package/dist/createOrUpdateDeckMapResource.d.ts.map +1 -1
  54. package/dist/createOrUpdateDeckMapResource.js +57 -4
  55. package/dist/createOrUpdateDeckMapResource.js.map +1 -1
  56. package/dist/datasets/PreparedDatasetStore.d.ts +3 -4
  57. package/dist/datasets/PreparedDatasetStore.d.ts.map +1 -1
  58. package/dist/datasets/PreparedDatasetStore.js +4 -8
  59. package/dist/datasets/PreparedDatasetStore.js.map +1 -1
  60. package/dist/datasets/helpers.d.ts +39 -2
  61. package/dist/datasets/helpers.d.ts.map +1 -1
  62. package/dist/datasets/helpers.js +86 -3
  63. package/dist/datasets/helpers.js.map +1 -1
  64. package/dist/datasets/usePreparedDatasetStates.d.ts.map +1 -1
  65. package/dist/datasets/usePreparedDatasetStates.js +12 -8
  66. package/dist/datasets/usePreparedDatasetStates.js.map +1 -1
  67. package/dist/index.d.ts +6 -3
  68. package/dist/index.d.ts.map +1 -1
  69. package/dist/index.js +5 -2
  70. package/dist/index.js.map +1 -1
  71. package/dist/json/colorScaleFunction.d.ts +12 -4
  72. package/dist/json/colorScaleFunction.d.ts.map +1 -1
  73. package/dist/json/colorScaleFunction.js.map +1 -1
  74. package/dist/json/compileColorScale.d.ts +3 -2
  75. package/dist/json/compileColorScale.d.ts.map +1 -1
  76. package/dist/json/compileColorScale.js +16 -1
  77. package/dist/json/compileColorScale.js.map +1 -1
  78. package/dist/json/createDeckJsonConfiguration.d.ts.map +1 -1
  79. package/dist/json/createDeckJsonConfiguration.js +235 -175
  80. package/dist/json/createDeckJsonConfiguration.js.map +1 -1
  81. package/dist/json/defaultClasses.d.ts.map +1 -1
  82. package/dist/json/defaultClasses.js +3 -3
  83. package/dist/json/defaultClasses.js.map +1 -1
  84. package/dist/json/extractColorScaleLegends.d.ts.map +1 -1
  85. package/dist/json/extractColorScaleLegends.js +41 -26
  86. package/dist/json/extractColorScaleLegends.js.map +1 -1
  87. package/dist/json/heatmapDefaults.d.ts +17 -7
  88. package/dist/json/heatmapDefaults.d.ts.map +1 -1
  89. package/dist/json/heatmapDefaults.js +54 -12
  90. package/dist/json/heatmapDefaults.js.map +1 -1
  91. package/dist/json/layers/DeckHeatmapLayer.d.ts +32 -0
  92. package/dist/json/layers/DeckHeatmapLayer.d.ts.map +1 -0
  93. package/dist/json/layers/DeckHeatmapLayer.js +69 -0
  94. package/dist/json/layers/DeckHeatmapLayer.js.map +1 -0
  95. package/dist/json/layers/index.d.ts +1 -0
  96. package/dist/json/layers/index.d.ts.map +1 -1
  97. package/dist/json/layers/index.js +1 -0
  98. package/dist/json/layers/index.js.map +1 -1
  99. package/dist/json/rewriteGeoArrowAccessors.d.ts.map +1 -1
  100. package/dist/json/rewriteGeoArrowAccessors.js +13 -5
  101. package/dist/json/rewriteGeoArrowAccessors.js.map +1 -1
  102. package/dist/json/scaleFunction.d.ts +5 -8
  103. package/dist/json/scaleFunction.d.ts.map +1 -1
  104. package/dist/json/scaleFunction.js +30 -5
  105. package/dist/json/scaleFunction.js.map +1 -1
  106. package/dist/mapAiConfig.d.ts +6 -0
  107. package/dist/mapAiConfig.d.ts.map +1 -1
  108. package/dist/mapAiConfig.js +7 -0
  109. package/dist/mapAiConfig.js.map +1 -1
  110. package/dist/mapAiSharedInstructions.d.ts +1 -1
  111. package/dist/mapAiSharedInstructions.d.ts.map +1 -1
  112. package/dist/mapAiSharedInstructions.js +4 -3
  113. package/dist/mapAiSharedInstructions.js.map +1 -1
  114. package/dist/mapConfig.d.ts +6 -1
  115. package/dist/mapConfig.d.ts.map +1 -1
  116. package/dist/mapConfig.js +28 -3
  117. package/dist/mapConfig.js.map +1 -1
  118. package/dist/mapConfigUtils.d.ts +22 -0
  119. package/dist/mapConfigUtils.d.ts.map +1 -1
  120. package/dist/mapConfigUtils.js +152 -5
  121. package/dist/mapConfigUtils.js.map +1 -1
  122. package/dist/mapLayerConfigUtils.d.ts +55 -0
  123. package/dist/mapLayerConfigUtils.d.ts.map +1 -1
  124. package/dist/mapLayerConfigUtils.js +222 -11
  125. package/dist/mapLayerConfigUtils.js.map +1 -1
  126. package/dist/mapResourceAuthoring.d.ts +1 -1
  127. package/dist/mapResourceAuthoring.d.ts.map +1 -1
  128. package/dist/mapResourceAuthoring.js +14 -7
  129. package/dist/mapResourceAuthoring.js.map +1 -1
  130. package/dist/mapStyles.d.ts +16 -0
  131. package/dist/mapStyles.d.ts.map +1 -0
  132. package/dist/mapStyles.js +32 -0
  133. package/dist/mapStyles.js.map +1 -0
  134. package/dist/prepare/prepareDeckDataset.d.ts.map +1 -1
  135. package/dist/prepare/prepareDeckDataset.js +1 -0
  136. package/dist/prepare/prepareDeckDataset.js.map +1 -1
  137. package/dist/prepare/types.d.ts +3 -0
  138. package/dist/prepare/types.d.ts.map +1 -1
  139. package/dist/prepare/types.js.map +1 -1
  140. package/dist/prepare/wkbDecoder.d.ts.map +1 -1
  141. package/dist/prepare/wkbDecoder.js +62 -16
  142. package/dist/prepare/wkbDecoder.js.map +1 -1
  143. package/dist/prepare/wkbParser.d.ts +2 -0
  144. package/dist/prepare/wkbParser.d.ts.map +1 -1
  145. package/dist/prepare/wkbParser.js +1 -0
  146. package/dist/prepare/wkbParser.js.map +1 -1
  147. package/dist/protomapsStyles.d.ts +18 -0
  148. package/dist/protomapsStyles.d.ts.map +1 -0
  149. package/dist/protomapsStyles.js +38 -0
  150. package/dist/protomapsStyles.js.map +1 -0
  151. package/dist/types.d.ts +13 -0
  152. package/dist/types.d.ts.map +1 -1
  153. package/dist/types.js.map +1 -1
  154. package/package.json +11 -9
@@ -1,13 +1,13 @@
1
1
  import { COORDINATE_SYSTEM, FirstPersonView, MapView, OrbitView, OrthographicView, } from '@deck.gl/core';
2
2
  import { GeoJsonLayer } from '@deck.gl/layers';
3
- import { GeoArrowArcLayer, GeoArrowHeatmapLayer, GeoArrowPathLayer, GeoArrowPolygonLayer, GeoArrowScatterplotLayer, GeoArrowSolidPolygonLayer, } from '@geoarrow/deck.gl-geoarrow';
3
+ import { GeoArrowArcLayer, GeoArrowPathLayer, GeoArrowPolygonLayer, GeoArrowScatterplotLayer, GeoArrowSolidPolygonLayer, } from '@geoarrow/deck.gl-geoarrow';
4
4
  import { createTableToRecordBatchAdapter } from './layers/createTableToRecordBatchAdapter';
5
- import { DeckColumnLayer, DeckH3HexagonLayer, DeckTripsLayer } from './layers';
5
+ import { DeckColumnLayer, DeckH3HexagonLayer, DeckHeatmapLayer, DeckTripsLayer, } from './layers';
6
6
  // The 0.4.x GeoArrow layers expect `data: RecordBatch` + geometry as `Data`,
7
7
  // but our JSON pipeline passes `data: Table` + geometry as `Vector`.
8
8
  // These adapters bridge the gap by splitting Table batches into sublayers.
9
9
  const AdaptedScatterplotLayer = createTableToRecordBatchAdapter(GeoArrowScatterplotLayer, 'GeoArrowScatterplotLayer');
10
- const AdaptedHeatmapLayer = createTableToRecordBatchAdapter(GeoArrowHeatmapLayer, 'GeoArrowHeatmapLayer');
10
+ const AdaptedHeatmapLayer = createTableToRecordBatchAdapter(DeckHeatmapLayer, 'GeoArrowHeatmapLayer');
11
11
  const AdaptedPathLayer = createTableToRecordBatchAdapter(GeoArrowPathLayer, 'GeoArrowPathLayer');
12
12
  const AdaptedPolygonLayer = createTableToRecordBatchAdapter(GeoArrowPolygonLayer, 'GeoArrowPolygonLayer');
13
13
  const AdaptedSolidPolygonLayer = createTableToRecordBatchAdapter(GeoArrowSolidPolygonLayer, 'GeoArrowSolidPolygonLayer');
@@ -1 +1 @@
1
- {"version":3,"file":"defaultClasses.js","sourceRoot":"","sources":["../../src/json/defaultClasses.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,OAAO,EACP,SAAS,EACT,gBAAgB,GACjB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAC,YAAY,EAAC,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACpB,iBAAiB,EACjB,oBAAoB,EACpB,wBAAwB,EACxB,yBAAyB,GAC1B,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAC,+BAA+B,EAAC,MAAM,0CAA0C,CAAC;AACzF,OAAO,EAAC,eAAe,EAAE,kBAAkB,EAAE,cAAc,EAAC,MAAM,UAAU,CAAC;AAE7E,6EAA6E;AAC7E,qEAAqE;AACrE,2EAA2E;AAC3E,MAAM,uBAAuB,GAAG,+BAA+B,CAC7D,wBAA+B,EAC/B,0BAA0B,CAC3B,CAAC;AACF,MAAM,mBAAmB,GAAG,+BAA+B,CACzD,oBAA2B,EAC3B,sBAAsB,CACvB,CAAC;AACF,MAAM,gBAAgB,GAAG,+BAA+B,CACtD,iBAAwB,EACxB,mBAAmB,CACpB,CAAC;AACF,MAAM,mBAAmB,GAAG,+BAA+B,CACzD,oBAA2B,EAC3B,sBAAsB,CACvB,CAAC;AACF,MAAM,wBAAwB,GAAG,+BAA+B,CAC9D,yBAAgC,EAChC,2BAA2B,CAC5B,CAAC;AACF,MAAM,eAAe,GAAG,+BAA+B,CACrD,gBAAuB,EACvB,kBAAkB,CACnB,CAAC;AAEF,MAAM,CAAC,MAAM,yBAAyB,GAGlC;IACF,OAAO;IACP,eAAe;IACf,SAAS;IACT,gBAAgB;IAChB,YAAY;IACZ,wBAAwB,EAAE,uBAAuB;IACjD,oBAAoB,EAAE,mBAAmB;IACzC,mBAAmB,EAAE,eAAe;IACpC,iBAAiB,EAAE,gBAAgB;IACnC,oBAAoB,EAAE,mBAAmB;IACzC,yBAAyB,EAAE,wBAAwB;IACnD,gBAAgB,EAAE,eAAe;IACjC,kBAAkB,EAAE,cAAc;IAClC,sBAAsB,EAAE,kBAAkB;CAC3C,CAAC;AAEF,MAAM,CAAC,MAAM,8BAA8B,GAAG;IAC5C,iBAAiB;CAClB,CAAC;AAEF,MAAM,CAAC,MAAM,2BAA2B,GAAG,EAAE,CAAC","sourcesContent":["import {\n COORDINATE_SYSTEM,\n FirstPersonView,\n MapView,\n OrbitView,\n OrthographicView,\n} from '@deck.gl/core';\nimport {GeoJsonLayer} from '@deck.gl/layers';\nimport {\n GeoArrowArcLayer,\n GeoArrowHeatmapLayer,\n GeoArrowPathLayer,\n GeoArrowPolygonLayer,\n GeoArrowScatterplotLayer,\n GeoArrowSolidPolygonLayer,\n} from '@geoarrow/deck.gl-geoarrow';\nimport {createTableToRecordBatchAdapter} from './layers/createTableToRecordBatchAdapter';\nimport {DeckColumnLayer, DeckH3HexagonLayer, DeckTripsLayer} from './layers';\n\n// The 0.4.x GeoArrow layers expect `data: RecordBatch` + geometry as `Data`,\n// but our JSON pipeline passes `data: Table` + geometry as `Vector`.\n// These adapters bridge the gap by splitting Table batches into sublayers.\nconst AdaptedScatterplotLayer = createTableToRecordBatchAdapter(\n GeoArrowScatterplotLayer as any,\n 'GeoArrowScatterplotLayer',\n);\nconst AdaptedHeatmapLayer = createTableToRecordBatchAdapter(\n GeoArrowHeatmapLayer as any,\n 'GeoArrowHeatmapLayer',\n);\nconst AdaptedPathLayer = createTableToRecordBatchAdapter(\n GeoArrowPathLayer as any,\n 'GeoArrowPathLayer',\n);\nconst AdaptedPolygonLayer = createTableToRecordBatchAdapter(\n GeoArrowPolygonLayer as any,\n 'GeoArrowPolygonLayer',\n);\nconst AdaptedSolidPolygonLayer = createTableToRecordBatchAdapter(\n GeoArrowSolidPolygonLayer as any,\n 'GeoArrowSolidPolygonLayer',\n);\nconst AdaptedArcLayer = createTableToRecordBatchAdapter(\n GeoArrowArcLayer as any,\n 'GeoArrowArcLayer',\n);\n\nexport const DEFAULT_DECK_JSON_CLASSES: Record<\n string,\n new (props: Record<string, unknown>) => unknown\n> = {\n MapView,\n FirstPersonView,\n OrbitView,\n OrthographicView,\n GeoJsonLayer,\n GeoArrowScatterplotLayer: AdaptedScatterplotLayer,\n GeoArrowHeatmapLayer: AdaptedHeatmapLayer,\n GeoArrowColumnLayer: DeckColumnLayer,\n GeoArrowPathLayer: AdaptedPathLayer,\n GeoArrowPolygonLayer: AdaptedPolygonLayer,\n GeoArrowSolidPolygonLayer: AdaptedSolidPolygonLayer,\n GeoArrowArcLayer: AdaptedArcLayer,\n GeoArrowTripsLayer: DeckTripsLayer,\n GeoArrowH3HexagonLayer: DeckH3HexagonLayer,\n};\n\nexport const DEFAULT_DECK_JSON_ENUMERATIONS = {\n COORDINATE_SYSTEM,\n};\n\nexport const DEFAULT_DECK_JSON_CONSTANTS = {};\n"]}
1
+ {"version":3,"file":"defaultClasses.js","sourceRoot":"","sources":["../../src/json/defaultClasses.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,OAAO,EACP,SAAS,EACT,gBAAgB,GACjB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAC,YAAY,EAAC,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,oBAAoB,EACpB,wBAAwB,EACxB,yBAAyB,GAC1B,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAC,+BAA+B,EAAC,MAAM,0CAA0C,CAAC;AACzF,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EAChB,cAAc,GACf,MAAM,UAAU,CAAC;AAElB,6EAA6E;AAC7E,qEAAqE;AACrE,2EAA2E;AAC3E,MAAM,uBAAuB,GAAG,+BAA+B,CAC7D,wBAA+B,EAC/B,0BAA0B,CAC3B,CAAC;AACF,MAAM,mBAAmB,GAAG,+BAA+B,CACzD,gBAAuB,EACvB,sBAAsB,CACvB,CAAC;AACF,MAAM,gBAAgB,GAAG,+BAA+B,CACtD,iBAAwB,EACxB,mBAAmB,CACpB,CAAC;AACF,MAAM,mBAAmB,GAAG,+BAA+B,CACzD,oBAA2B,EAC3B,sBAAsB,CACvB,CAAC;AACF,MAAM,wBAAwB,GAAG,+BAA+B,CAC9D,yBAAgC,EAChC,2BAA2B,CAC5B,CAAC;AACF,MAAM,eAAe,GAAG,+BAA+B,CACrD,gBAAuB,EACvB,kBAAkB,CACnB,CAAC;AAEF,MAAM,CAAC,MAAM,yBAAyB,GAGlC;IACF,OAAO;IACP,eAAe;IACf,SAAS;IACT,gBAAgB;IAChB,YAAY;IACZ,wBAAwB,EAAE,uBAAuB;IACjD,oBAAoB,EAAE,mBAAmB;IACzC,mBAAmB,EAAE,eAAe;IACpC,iBAAiB,EAAE,gBAAgB;IACnC,oBAAoB,EAAE,mBAAmB;IACzC,yBAAyB,EAAE,wBAAwB;IACnD,gBAAgB,EAAE,eAAe;IACjC,kBAAkB,EAAE,cAAc;IAClC,sBAAsB,EAAE,kBAAkB;CAC3C,CAAC;AAEF,MAAM,CAAC,MAAM,8BAA8B,GAAG;IAC5C,iBAAiB;CAClB,CAAC;AAEF,MAAM,CAAC,MAAM,2BAA2B,GAAG,EAAE,CAAC","sourcesContent":["import {\n COORDINATE_SYSTEM,\n FirstPersonView,\n MapView,\n OrbitView,\n OrthographicView,\n} from '@deck.gl/core';\nimport {GeoJsonLayer} from '@deck.gl/layers';\nimport {\n GeoArrowArcLayer,\n GeoArrowPathLayer,\n GeoArrowPolygonLayer,\n GeoArrowScatterplotLayer,\n GeoArrowSolidPolygonLayer,\n} from '@geoarrow/deck.gl-geoarrow';\nimport {createTableToRecordBatchAdapter} from './layers/createTableToRecordBatchAdapter';\nimport {\n DeckColumnLayer,\n DeckH3HexagonLayer,\n DeckHeatmapLayer,\n DeckTripsLayer,\n} from './layers';\n\n// The 0.4.x GeoArrow layers expect `data: RecordBatch` + geometry as `Data`,\n// but our JSON pipeline passes `data: Table` + geometry as `Vector`.\n// These adapters bridge the gap by splitting Table batches into sublayers.\nconst AdaptedScatterplotLayer = createTableToRecordBatchAdapter(\n GeoArrowScatterplotLayer as any,\n 'GeoArrowScatterplotLayer',\n);\nconst AdaptedHeatmapLayer = createTableToRecordBatchAdapter(\n DeckHeatmapLayer as any,\n 'GeoArrowHeatmapLayer',\n);\nconst AdaptedPathLayer = createTableToRecordBatchAdapter(\n GeoArrowPathLayer as any,\n 'GeoArrowPathLayer',\n);\nconst AdaptedPolygonLayer = createTableToRecordBatchAdapter(\n GeoArrowPolygonLayer as any,\n 'GeoArrowPolygonLayer',\n);\nconst AdaptedSolidPolygonLayer = createTableToRecordBatchAdapter(\n GeoArrowSolidPolygonLayer as any,\n 'GeoArrowSolidPolygonLayer',\n);\nconst AdaptedArcLayer = createTableToRecordBatchAdapter(\n GeoArrowArcLayer as any,\n 'GeoArrowArcLayer',\n);\n\nexport const DEFAULT_DECK_JSON_CLASSES: Record<\n string,\n new (props: Record<string, unknown>) => unknown\n> = {\n MapView,\n FirstPersonView,\n OrbitView,\n OrthographicView,\n GeoJsonLayer,\n GeoArrowScatterplotLayer: AdaptedScatterplotLayer,\n GeoArrowHeatmapLayer: AdaptedHeatmapLayer,\n GeoArrowColumnLayer: DeckColumnLayer,\n GeoArrowPathLayer: AdaptedPathLayer,\n GeoArrowPolygonLayer: AdaptedPolygonLayer,\n GeoArrowSolidPolygonLayer: AdaptedSolidPolygonLayer,\n GeoArrowArcLayer: AdaptedArcLayer,\n GeoArrowTripsLayer: DeckTripsLayer,\n GeoArrowH3HexagonLayer: DeckH3HexagonLayer,\n};\n\nexport const DEFAULT_DECK_JSON_ENUMERATIONS = {\n COORDINATE_SYSTEM,\n};\n\nexport const DEFAULT_DECK_JSON_CONSTANTS = {};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"extractColorScaleLegends.d.ts","sourceRoot":"","sources":["../../src/json/extractColorScaleLegends.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,wBAAwB,CAAC;AAChE,OAAO,KAAK,EAAC,wBAAwB,EAAC,MAAM,UAAU,CAAC;AAoDvD,wBAAgB,wBAAwB,CAAC,OAAO,EAAE;IAChD,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACrC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAC;CACzD,yBA+EA"}
1
+ {"version":3,"file":"extractColorScaleLegends.d.ts","sourceRoot":"","sources":["../../src/json/extractColorScaleLegends.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,wBAAwB,CAAC;AAChE,OAAO,KAAK,EAAC,wBAAwB,EAAC,MAAM,UAAU,CAAC;AAoDvD,wBAAgB,wBAAwB,CAAC,OAAO,EAAE;IAChD,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACrC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAC;CACzD,yBAkGA"}
@@ -64,35 +64,50 @@ export function extractColorScaleLegends(options) {
64
64
  if (!datasetState || datasetState.status !== 'ready') {
65
65
  continue;
66
66
  }
67
- // Show a legend for each distinct color-scale accessor on the layer
68
- // (fill + stroke, or arc source/target). Skip duplicates that resolve to
69
- // the same title/type/scheme/field.
67
+ // Prefer fill legend; show stroke only when fill has no color scale.
68
+ const hasFillColorScale = resolvedColorScales.some((entry) => entry.propName === 'getFillColor');
69
+ const primaryScales = hasFillColorScale
70
+ ? resolvedColorScales.filter((entry) => entry.propName !== 'getLineColor')
71
+ : resolvedColorScales;
72
+ const strokeFallbackScales = hasFillColorScale
73
+ ? resolvedColorScales.filter((entry) => entry.propName === 'getLineColor')
74
+ : [];
70
75
  const seenLegendKeys = new Set();
71
- for (const { propName, colorScale } of resolvedColorScales) {
72
- try {
73
- const title = resolveLegendTitle(layerProps, propName, colorScale.field);
74
- const key = [
75
- title,
76
- colorScale.type,
77
- String(colorScale.scheme ?? ''),
78
- colorScale.field,
79
- JSON.stringify(colorScale),
80
- ].join('\0');
81
- if (seenLegendKeys.has(key))
82
- continue;
83
- const resolvedLegend = buildColorScaleLegend({
84
- table: datasetState.prepared.table,
85
- colorScale,
86
- title,
87
- });
88
- if (resolvedLegend) {
89
- seenLegendKeys.add(key);
90
- legends.push(resolvedLegend);
76
+ const pushLegendsFrom = (scales) => {
77
+ let added = 0;
78
+ for (const { propName, colorScale } of scales) {
79
+ try {
80
+ const title = resolveLegendTitle(layerProps, propName, colorScale.field);
81
+ const key = [
82
+ title,
83
+ colorScale.type,
84
+ String(colorScale.scheme ?? ''),
85
+ colorScale.field,
86
+ JSON.stringify(colorScale),
87
+ ].join('\0');
88
+ if (seenLegendKeys.has(key))
89
+ continue;
90
+ const resolvedLegend = buildColorScaleLegend({
91
+ table: datasetState.prepared.table,
92
+ colorScale,
93
+ title,
94
+ });
95
+ if (resolvedLegend) {
96
+ seenLegendKeys.add(key);
97
+ legends.push(resolvedLegend);
98
+ added += 1;
99
+ }
100
+ }
101
+ catch {
102
+ // skip failed accessor
91
103
  }
92
104
  }
93
- catch {
94
- // try next accessor
95
- }
105
+ return added;
106
+ };
107
+ const added = pushLegendsFrom(primaryScales);
108
+ // Fill scale failed to resolve → fall back to stroke.
109
+ if (added === 0 && strokeFallbackScales.length > 0) {
110
+ pushLegendsFrom(strokeFallbackScales);
96
111
  }
97
112
  }
98
113
  return legends;
@@ -1 +1 @@
1
- {"version":3,"file":"extractColorScaleLegends.js","sourceRoot":"","sources":["../../src/json/extractColorScaleLegends.ts"],"names":[],"mappings":"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","sourcesContent":["import type {ResolvedColorLegend} from '@sqlrooms/color-scales';\nimport type {PreparedDeckDatasetState} from '../types';\nimport {getAllColorScales} from './colorScaleFunction';\nimport {buildColorScaleLegend} from './compileColorScale';\nimport {DEFAULT_HEATMAP_COLOR_RANGE} from './heatmapDefaults';\nimport {resolveColorLegend, resolveDatasetId} from './layerConfig';\n\nimport type {ColorScalePropName} from './colorScaleFunction';\n\nfunction resolveLegendTitle(\n layerProps: Record<string, unknown>,\n propName: ColorScalePropName,\n fallbackField: string,\n) {\n const legend = resolveColorLegend(layerProps, propName);\n if (\n legend &&\n typeof legend === 'object' &&\n typeof legend.title === 'string'\n ) {\n return legend.title;\n }\n\n return fallbackField;\n}\n\nfunction buildHeatmapLegend(\n layerProps: Record<string, unknown>,\n): ResolvedColorLegend | null {\n const rawRange = layerProps.colorRange as\n | Array<[number, number, number, number]>\n | undefined;\n const colorRange =\n Array.isArray(rawRange) && rawRange.length >= 2\n ? rawRange\n : DEFAULT_HEATMAP_COLOR_RANGE;\n\n const stops = colorRange.map((c, i) => {\n const pct = (i / (colorRange.length - 1)) * 100;\n return `rgba(${c[0]},${c[1]},${c[2]},${(c[3] ?? 255) / 255}) ${pct.toFixed(1)}%`;\n });\n\n return {\n type: 'continuous',\n title: 'Density',\n gradient: `linear-gradient(to right, ${stops.join(', ')})`,\n ticks: [\n {label: 'Low', offset: 0},\n {label: 'High', offset: 100},\n ],\n };\n}\n\nexport function extractColorScaleLegends(options: {\n spec: Record<string, unknown> | null;\n datasetIds: string[];\n datasetStates: Record<string, PreparedDeckDatasetState>;\n}) {\n const {spec, datasetIds, datasetStates} = options;\n if (!spec || !Array.isArray(spec.layers)) {\n return [] as ResolvedColorLegend[];\n }\n\n const legends: ResolvedColorLegend[] = [];\n\n for (const layer of spec.layers) {\n if (!layer || typeof layer !== 'object') {\n continue;\n }\n\n const layerProps = layer as Record<string, unknown>;\n\n if (layerProps.visible === false) {\n continue;\n }\n\n const layerType = layerProps['@@type'];\n if (layerType === 'GeoArrowHeatmapLayer') {\n const heatmapLegend = buildHeatmapLegend(layerProps);\n if (heatmapLegend) {\n legends.push(heatmapLegend);\n }\n continue;\n }\n\n const resolvedColorScales = getAllColorScales(layerProps);\n if (resolvedColorScales.length === 0) {\n continue;\n }\n\n const datasetId = resolveDatasetId(layerProps, datasetIds);\n if (!datasetId) {\n continue;\n }\n\n const datasetState = datasetStates[datasetId];\n if (!datasetState || datasetState.status !== 'ready') {\n continue;\n }\n\n // Show a legend for each distinct color-scale accessor on the layer\n // (fill + stroke, or arc source/target). Skip duplicates that resolve to\n // the same title/type/scheme/field.\n const seenLegendKeys = new Set<string>();\n for (const {propName, colorScale} of resolvedColorScales) {\n try {\n const title = resolveLegendTitle(\n layerProps,\n propName,\n colorScale.field,\n );\n const key = [\n title,\n colorScale.type,\n String(colorScale.scheme ?? ''),\n colorScale.field,\n JSON.stringify(colorScale),\n ].join('\\0');\n if (seenLegendKeys.has(key)) continue;\n\n const resolvedLegend = buildColorScaleLegend({\n table: datasetState.prepared.table,\n colorScale,\n title,\n });\n if (resolvedLegend) {\n seenLegendKeys.add(key);\n legends.push(resolvedLegend);\n }\n } catch {\n // try next accessor\n }\n }\n }\n\n return legends;\n}\n"]}
1
+ {"version":3,"file":"extractColorScaleLegends.js","sourceRoot":"","sources":["../../src/json/extractColorScaleLegends.ts"],"names":[],"mappings":"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","sourcesContent":["import type {ResolvedColorLegend} from '@sqlrooms/color-scales';\nimport type {PreparedDeckDatasetState} from '../types';\nimport {getAllColorScales} from './colorScaleFunction';\nimport {buildColorScaleLegend} from './compileColorScale';\nimport {DEFAULT_HEATMAP_COLOR_RANGE} from './heatmapDefaults';\nimport {resolveColorLegend, resolveDatasetId} from './layerConfig';\n\nimport type {ColorScalePropName} from './colorScaleFunction';\n\nfunction resolveLegendTitle(\n layerProps: Record<string, unknown>,\n propName: ColorScalePropName,\n fallbackField: string,\n) {\n const legend = resolveColorLegend(layerProps, propName);\n if (\n legend &&\n typeof legend === 'object' &&\n typeof legend.title === 'string'\n ) {\n return legend.title;\n }\n\n return fallbackField;\n}\n\nfunction buildHeatmapLegend(\n layerProps: Record<string, unknown>,\n): ResolvedColorLegend | null {\n const rawRange = layerProps.colorRange as\n | Array<[number, number, number, number]>\n | undefined;\n const colorRange =\n Array.isArray(rawRange) && rawRange.length >= 2\n ? rawRange\n : DEFAULT_HEATMAP_COLOR_RANGE;\n\n const stops = colorRange.map((c, i) => {\n const pct = (i / (colorRange.length - 1)) * 100;\n return `rgba(${c[0]},${c[1]},${c[2]},${(c[3] ?? 255) / 255}) ${pct.toFixed(1)}%`;\n });\n\n return {\n type: 'continuous',\n title: 'Density',\n gradient: `linear-gradient(to right, ${stops.join(', ')})`,\n ticks: [\n {label: 'Low', offset: 0},\n {label: 'High', offset: 100},\n ],\n };\n}\n\nexport function extractColorScaleLegends(options: {\n spec: Record<string, unknown> | null;\n datasetIds: string[];\n datasetStates: Record<string, PreparedDeckDatasetState>;\n}) {\n const {spec, datasetIds, datasetStates} = options;\n if (!spec || !Array.isArray(spec.layers)) {\n return [] as ResolvedColorLegend[];\n }\n\n const legends: ResolvedColorLegend[] = [];\n\n for (const layer of spec.layers) {\n if (!layer || typeof layer !== 'object') {\n continue;\n }\n\n const layerProps = layer as Record<string, unknown>;\n\n if (layerProps.visible === false) {\n continue;\n }\n\n const layerType = layerProps['@@type'];\n if (layerType === 'GeoArrowHeatmapLayer') {\n const heatmapLegend = buildHeatmapLegend(layerProps);\n if (heatmapLegend) {\n legends.push(heatmapLegend);\n }\n continue;\n }\n\n const resolvedColorScales = getAllColorScales(layerProps);\n if (resolvedColorScales.length === 0) {\n continue;\n }\n\n const datasetId = resolveDatasetId(layerProps, datasetIds);\n if (!datasetId) {\n continue;\n }\n\n const datasetState = datasetStates[datasetId];\n if (!datasetState || datasetState.status !== 'ready') {\n continue;\n }\n\n // Prefer fill legend; show stroke only when fill has no color scale.\n const hasFillColorScale = resolvedColorScales.some(\n (entry) => entry.propName === 'getFillColor',\n );\n const primaryScales = hasFillColorScale\n ? resolvedColorScales.filter((entry) => entry.propName !== 'getLineColor')\n : resolvedColorScales;\n const strokeFallbackScales = hasFillColorScale\n ? resolvedColorScales.filter((entry) => entry.propName === 'getLineColor')\n : [];\n\n const seenLegendKeys = new Set<string>();\n const pushLegendsFrom = (scales: typeof resolvedColorScales): number => {\n let added = 0;\n for (const {propName, colorScale} of scales) {\n try {\n const title = resolveLegendTitle(\n layerProps,\n propName,\n colorScale.field,\n );\n const key = [\n title,\n colorScale.type,\n String(colorScale.scheme ?? ''),\n colorScale.field,\n JSON.stringify(colorScale),\n ].join('\\0');\n if (seenLegendKeys.has(key)) continue;\n\n const resolvedLegend = buildColorScaleLegend({\n table: datasetState.prepared.table,\n colorScale,\n title,\n });\n if (resolvedLegend) {\n seenLegendKeys.add(key);\n legends.push(resolvedLegend);\n added += 1;\n }\n } catch {\n // skip failed accessor\n }\n }\n return added;\n };\n\n const added = pushLegendsFrom(primaryScales);\n // Fill scale failed to resolve → fall back to stroke.\n if (added === 0 && strokeFallbackScales.length > 0) {\n pushLegendsFrom(strokeFallbackScales);\n }\n }\n\n return legends;\n}\n"]}
@@ -1,8 +1,18 @@
1
- /** Default color range for heatmap layers (YlOrRd, matching deck.gl's built-in default). */
2
- export declare const DEFAULT_HEATMAP_COLOR_RANGE: Array<[
3
- number,
4
- number,
5
- number,
6
- number
7
- ]>;
1
+ import { type ContinuousSequentialScheme, type ResolvedRGBA } from '@sqlrooms/color-scales';
2
+ /**
3
+ * Heatmap GPU weights-texture size.
4
+ */
5
+ export declare const DEFAULT_HEATMAP_WEIGHTS_TEXTURE_SIZE = 512;
6
+ /** Default heatmap scheme (YlOrRd, matching deck.gl's built-in default). */
7
+ export declare const DEFAULT_HEATMAP_SCHEME: ContinuousSequentialScheme;
8
+ /** Sample a sequential scheme into a heatmap `colorRange`. */
9
+ export declare function heatmapSchemeToColorRange(scheme: string): ResolvedRGBA[];
10
+ /**
11
+ * Named scheme for a heatmap `colorRange`. Missing or unrecognized ranges
12
+ * fall back to {@link DEFAULT_HEATMAP_SCHEME} so the settings picker matches
13
+ * the renderer default.
14
+ */
15
+ export declare function detectHeatmapScheme(colorRange: unknown): string;
16
+ /** Default color range for heatmap layers. */
17
+ export declare const DEFAULT_HEATMAP_COLOR_RANGE: ResolvedRGBA[];
8
18
  //# sourceMappingURL=heatmapDefaults.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"heatmapDefaults.d.ts","sourceRoot":"","sources":["../../src/json/heatmapDefaults.ts"],"names":[],"mappings":"AAOA,4FAA4F;AAC5F,eAAO,MAAM,2BAA2B,EAAE,KAAK,CAC7C;IAAC,MAAM;IAAE,MAAM;IAAE,MAAM;IAAE,MAAM;CAAC,CAc7B,CAAC"}
1
+ {"version":3,"file":"heatmapDefaults.d.ts","sourceRoot":"","sources":["../../src/json/heatmapDefaults.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,0BAA0B,EAC/B,KAAK,YAAY,EAClB,MAAM,wBAAwB,CAAC;AAIhC;;GAEG;AACH,eAAO,MAAM,oCAAoC,MAAM,CAAC;AAExD,4EAA4E;AAC5E,eAAO,MAAM,sBAAsB,EAAE,0BAAqC,CAAC;AAmB3E,8DAA8D;AAC9D,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,EAAE,CASxE;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,OAAO,GAAG,MAAM,CAmB/D;AAED,8CAA8C;AAC9C,eAAO,MAAM,2BAA2B,EAAE,YAAY,EACH,CAAC"}
@@ -1,14 +1,56 @@
1
- import { continuousSequentialInterpolators, parseColorString, } from '@sqlrooms/color-scales';
1
+ import { continuousSequentialInterpolators, continuousSequentialSchemes, parseColorString, } from '@sqlrooms/color-scales';
2
2
  const HEATMAP_COLOR_STEPS = 6;
3
- /** Default color range for heatmap layers (YlOrRd, matching deck.gl's built-in default). */
4
- export const DEFAULT_HEATMAP_COLOR_RANGE = continuousSequentialInterpolators.YlOrRd
5
- ? Array.from({ length: HEATMAP_COLOR_STEPS }, (_, i) => parseColorString(continuousSequentialInterpolators.YlOrRd(i / (HEATMAP_COLOR_STEPS - 1))))
6
- : [
7
- [255, 255, 178, 255],
8
- [254, 178, 76, 255],
9
- [253, 141, 60, 255],
10
- [240, 59, 32, 255],
11
- [189, 0, 38, 255],
12
- [128, 0, 38, 255],
13
- ];
3
+ /**
4
+ * Heatmap GPU weights-texture size.
5
+ */
6
+ export const DEFAULT_HEATMAP_WEIGHTS_TEXTURE_SIZE = 512;
7
+ /** Default heatmap scheme (YlOrRd, matching deck.gl's built-in default). */
8
+ export const DEFAULT_HEATMAP_SCHEME = 'YlOrRd';
9
+ const FALLBACK_YLORRD = [
10
+ [255, 255, 178, 255],
11
+ [254, 178, 76, 255],
12
+ [253, 141, 60, 255],
13
+ [240, 59, 32, 255],
14
+ [189, 0, 38, 255],
15
+ [128, 0, 38, 255],
16
+ ];
17
+ function sampleInterpolator(interpolator) {
18
+ return Array.from({ length: HEATMAP_COLOR_STEPS }, (_, i) => parseColorString(interpolator(i / (HEATMAP_COLOR_STEPS - 1))));
19
+ }
20
+ /** Sample a sequential scheme into a heatmap `colorRange`. */
21
+ export function heatmapSchemeToColorRange(scheme) {
22
+ const interpolator = continuousSequentialInterpolators[scheme] ?? continuousSequentialInterpolators[DEFAULT_HEATMAP_SCHEME];
23
+ if (!interpolator) {
24
+ return FALLBACK_YLORRD.map((color) => [...color]);
25
+ }
26
+ return sampleInterpolator(interpolator);
27
+ }
28
+ /**
29
+ * Named scheme for a heatmap `colorRange`. Missing or unrecognized ranges
30
+ * fall back to {@link DEFAULT_HEATMAP_SCHEME} so the settings picker matches
31
+ * the renderer default.
32
+ */
33
+ export function detectHeatmapScheme(colorRange) {
34
+ if (!Array.isArray(colorRange) || colorRange.length === 0) {
35
+ return DEFAULT_HEATMAP_SCHEME;
36
+ }
37
+ for (const scheme of continuousSequentialSchemes) {
38
+ const sampled = heatmapSchemeToColorRange(scheme);
39
+ if (sampled.length !== colorRange.length)
40
+ continue;
41
+ const matches = sampled.every((color, idx) => {
42
+ const actual = colorRange[idx];
43
+ if (!Array.isArray(actual))
44
+ return false;
45
+ return (Math.abs(color[0] - actual[0]) < 2 &&
46
+ Math.abs(color[1] - actual[1]) < 2 &&
47
+ Math.abs(color[2] - actual[2]) < 2);
48
+ });
49
+ if (matches)
50
+ return scheme;
51
+ }
52
+ return DEFAULT_HEATMAP_SCHEME;
53
+ }
54
+ /** Default color range for heatmap layers. */
55
+ export const DEFAULT_HEATMAP_COLOR_RANGE = heatmapSchemeToColorRange(DEFAULT_HEATMAP_SCHEME);
14
56
  //# sourceMappingURL=heatmapDefaults.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"heatmapDefaults.js","sourceRoot":"","sources":["../../src/json/heatmapDefaults.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iCAAiC,EACjC,gBAAgB,GACjB,MAAM,wBAAwB,CAAC;AAEhC,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAE9B,4FAA4F;AAC5F,MAAM,CAAC,MAAM,2BAA2B,GAEpC,iCAAiC,CAAC,MAAM;IAC1C,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAC,MAAM,EAAE,mBAAmB,EAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CACjD,gBAAgB,CACd,iCAAiC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,mBAAmB,GAAG,CAAC,CAAC,CAAC,CACxE,CACF;IACH,CAAC,CAAC;QACE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;QACpB,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,CAAC;QACnB,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,CAAC;QACnB,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC;QAClB,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC;QACjB,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC;KAClB,CAAC","sourcesContent":["import {\n continuousSequentialInterpolators,\n parseColorString,\n} from '@sqlrooms/color-scales';\n\nconst HEATMAP_COLOR_STEPS = 6;\n\n/** Default color range for heatmap layers (YlOrRd, matching deck.gl's built-in default). */\nexport const DEFAULT_HEATMAP_COLOR_RANGE: Array<\n [number, number, number, number]\n> = continuousSequentialInterpolators.YlOrRd\n ? Array.from({length: HEATMAP_COLOR_STEPS}, (_, i) =>\n parseColorString(\n continuousSequentialInterpolators.YlOrRd(i / (HEATMAP_COLOR_STEPS - 1)),\n ),\n )\n : [\n [255, 255, 178, 255],\n [254, 178, 76, 255],\n [253, 141, 60, 255],\n [240, 59, 32, 255],\n [189, 0, 38, 255],\n [128, 0, 38, 255],\n ];\n"]}
1
+ {"version":3,"file":"heatmapDefaults.js","sourceRoot":"","sources":["../../src/json/heatmapDefaults.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n continuousSequentialInterpolators,\n continuousSequentialSchemes,\n parseColorString,\n type ContinuousSequentialScheme,\n type ResolvedRGBA,\n} from '@sqlrooms/color-scales';\n\nconst HEATMAP_COLOR_STEPS = 6;\n\n/**\n * Heatmap GPU weights-texture size.\n */\nexport const DEFAULT_HEATMAP_WEIGHTS_TEXTURE_SIZE = 512;\n\n/** Default heatmap scheme (YlOrRd, matching deck.gl's built-in default). */\nexport const DEFAULT_HEATMAP_SCHEME: ContinuousSequentialScheme = 'YlOrRd';\n\nconst FALLBACK_YLORRD: ResolvedRGBA[] = [\n [255, 255, 178, 255],\n [254, 178, 76, 255],\n [253, 141, 60, 255],\n [240, 59, 32, 255],\n [189, 0, 38, 255],\n [128, 0, 38, 255],\n];\n\nfunction sampleInterpolator(\n interpolator: (t: number) => string,\n): ResolvedRGBA[] {\n return Array.from({length: HEATMAP_COLOR_STEPS}, (_, i) =>\n parseColorString(interpolator(i / (HEATMAP_COLOR_STEPS - 1))),\n );\n}\n\n/** Sample a sequential scheme into a heatmap `colorRange`. */\nexport function heatmapSchemeToColorRange(scheme: string): ResolvedRGBA[] {\n const interpolator =\n continuousSequentialInterpolators[\n scheme as keyof typeof continuousSequentialInterpolators\n ] ?? continuousSequentialInterpolators[DEFAULT_HEATMAP_SCHEME];\n if (!interpolator) {\n return FALLBACK_YLORRD.map((color) => [...color] as ResolvedRGBA);\n }\n return sampleInterpolator(interpolator);\n}\n\n/**\n * Named scheme for a heatmap `colorRange`. Missing or unrecognized ranges\n * fall back to {@link DEFAULT_HEATMAP_SCHEME} so the settings picker matches\n * the renderer default.\n */\nexport function detectHeatmapScheme(colorRange: unknown): string {\n if (!Array.isArray(colorRange) || colorRange.length === 0) {\n return DEFAULT_HEATMAP_SCHEME;\n }\n for (const scheme of continuousSequentialSchemes) {\n const sampled = heatmapSchemeToColorRange(scheme);\n if (sampled.length !== colorRange.length) continue;\n const matches = sampled.every((color, idx) => {\n const actual = colorRange[idx];\n if (!Array.isArray(actual)) return false;\n return (\n Math.abs(color[0] - actual[0]) < 2 &&\n Math.abs(color[1] - actual[1]) < 2 &&\n Math.abs(color[2] - actual[2]) < 2\n );\n });\n if (matches) return scheme;\n }\n return DEFAULT_HEATMAP_SCHEME;\n}\n\n/** Default color range for heatmap layers. */\nexport const DEFAULT_HEATMAP_COLOR_RANGE: ResolvedRGBA[] =\n heatmapSchemeToColorRange(DEFAULT_HEATMAP_SCHEME);\n"]}
@@ -0,0 +1,32 @@
1
+ import type { Layer, LayersList } from '@deck.gl/core';
2
+ import { GeoArrowHeatmapLayer } from '@geoarrow/deck.gl-geoarrow';
3
+ type HeatmapDataCache = {
4
+ sourceData: unknown;
5
+ sourcePosition: unknown;
6
+ weightKey: unknown;
7
+ data: unknown;
8
+ };
9
+ /**
10
+ * GeoArrow heatmap that reuses the inner binary `data` wrapper when only style
11
+ * props change. JSONConverter builds a new layer each time; a new wrapper looks
12
+ * like a data change and rebuilds aggregation.
13
+ */
14
+ export declare class DeckHeatmapLayer extends GeoArrowHeatmapLayer {
15
+ static layerName: string;
16
+ static defaultProps: {
17
+ weightsTextureSize: {
18
+ type: "number";
19
+ min: number;
20
+ max: number;
21
+ value: number;
22
+ };
23
+ };
24
+ state: {
25
+ heatmapDataCache?: HeatmapDataCache;
26
+ };
27
+ renderLayers(): Layer | LayersList | null;
28
+ }
29
+ /** Return the previous inner heatmap `data` object when Arrow inputs match. */
30
+ export declare function reuseCachedHeatmapData(cache: HeatmapDataCache | undefined, props: Record<string, unknown>, nextData: unknown): HeatmapDataCache;
31
+ export {};
32
+ //# sourceMappingURL=DeckHeatmapLayer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DeckHeatmapLayer.d.ts","sourceRoot":"","sources":["../../../src/json/layers/DeckHeatmapLayer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,KAAK,EAAE,UAAU,EAAC,MAAM,eAAe,CAAC;AACrD,OAAO,EAAC,oBAAoB,EAAC,MAAM,4BAA4B,CAAC;AAGhE,KAAK,gBAAgB,GAAG;IACtB,UAAU,EAAE,OAAO,CAAC;IACpB,cAAc,EAAE,OAAO,CAAC;IACxB,SAAS,EAAE,OAAO,CAAC;IACnB,IAAI,EAAE,OAAO,CAAC;CACf,CAAC;AAIF;;;;GAIG;AACH,qBAAa,gBAAiB,SAAQ,oBAAoB;IACxD,MAAM,CAAC,SAAS,SAA0B;IAC1C,MAAM,CAAC,YAAY;;;;;;;MAOjB;IAEM,KAAK,EAAE;QAAC,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;KAAC,CAAC;IAErD,YAAY,IAAI,KAAK,GAAG,UAAU,GAAG,IAAI;CAyB1C;AAED,+EAA+E;AAC/E,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,gBAAgB,GAAG,SAAS,EACnC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,QAAQ,EAAE,OAAO,GAChB,gBAAgB,CAalB"}
@@ -0,0 +1,69 @@
1
+ import { GeoArrowHeatmapLayer } from '@geoarrow/deck.gl-geoarrow';
2
+ import { DEFAULT_HEATMAP_WEIGHTS_TEXTURE_SIZE } from '../heatmapDefaults';
3
+ /**
4
+ * GeoArrow heatmap that reuses the inner binary `data` wrapper when only style
5
+ * props change. JSONConverter builds a new layer each time; a new wrapper looks
6
+ * like a data change and rebuilds aggregation.
7
+ */
8
+ export class DeckHeatmapLayer extends GeoArrowHeatmapLayer {
9
+ static layerName = 'GeoArrowHeatmapLayer';
10
+ static defaultProps = {
11
+ weightsTextureSize: {
12
+ type: 'number',
13
+ min: 128,
14
+ max: 2048,
15
+ value: DEFAULT_HEATMAP_WEIGHTS_TEXTURE_SIZE,
16
+ },
17
+ };
18
+ renderLayers() {
19
+ const rendered = super.renderLayers();
20
+ const heatmap = unwrapSingleLayer(rendered);
21
+ if (!heatmap)
22
+ return rendered;
23
+ const cache = reuseCachedHeatmapData(this.state?.heatmapDataCache, this.props, heatmap.props.data);
24
+ if (this.state) {
25
+ this.state.heatmapDataCache = cache;
26
+ }
27
+ if (cache.data === heatmap.props.data) {
28
+ return heatmap;
29
+ }
30
+ const HeatmapClass = heatmap.constructor;
31
+ return new HeatmapClass({
32
+ ...heatmap.props,
33
+ data: cache.data,
34
+ });
35
+ }
36
+ }
37
+ /** Return the previous inner heatmap `data` object when Arrow inputs match. */
38
+ export function reuseCachedHeatmapData(cache, props, nextData) {
39
+ const sourceData = props.data;
40
+ const sourcePosition = props.getPosition;
41
+ const weightKey = getHeatmapWeightKey(props);
42
+ if (cache &&
43
+ cache.sourceData === sourceData &&
44
+ cache.sourcePosition === sourcePosition &&
45
+ cache.weightKey === weightKey) {
46
+ return cache;
47
+ }
48
+ return { sourceData, sourcePosition, weightKey, data: nextData };
49
+ }
50
+ function getHeatmapWeightKey(props) {
51
+ const getWeight = props.getWeight;
52
+ const triggers = props.updateTriggers;
53
+ if (triggers && typeof triggers === 'object' && 'getWeight' in triggers) {
54
+ return triggers.getWeight;
55
+ }
56
+ if (typeof getWeight === 'number' || getWeight == null) {
57
+ return getWeight ?? 1;
58
+ }
59
+ return getWeight;
60
+ }
61
+ function unwrapSingleLayer(rendered) {
62
+ const layers = Array.isArray(rendered) ? rendered : [rendered];
63
+ const layer = layers[0];
64
+ if (layer && typeof layer === 'object' && 'props' in layer) {
65
+ return layer;
66
+ }
67
+ return null;
68
+ }
69
+ //# sourceMappingURL=DeckHeatmapLayer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DeckHeatmapLayer.js","sourceRoot":"","sources":["../../../src/json/layers/DeckHeatmapLayer.ts"],"names":[],"mappings":"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","sourcesContent":["import type {Layer, LayersList} from '@deck.gl/core';\nimport {GeoArrowHeatmapLayer} from '@geoarrow/deck.gl-geoarrow';\nimport {DEFAULT_HEATMAP_WEIGHTS_TEXTURE_SIZE} from '../heatmapDefaults';\n\ntype HeatmapDataCache = {\n sourceData: unknown;\n sourcePosition: unknown;\n weightKey: unknown;\n data: unknown;\n};\n\ntype LayerWithData = Layer & {props: {data?: unknown}};\n\n/**\n * GeoArrow heatmap that reuses the inner binary `data` wrapper when only style\n * props change. JSONConverter builds a new layer each time; a new wrapper looks\n * like a data change and rebuilds aggregation.\n */\nexport class DeckHeatmapLayer extends GeoArrowHeatmapLayer {\n static layerName = 'GeoArrowHeatmapLayer';\n static defaultProps = {\n weightsTextureSize: {\n type: 'number' as const,\n min: 128,\n max: 2048,\n value: DEFAULT_HEATMAP_WEIGHTS_TEXTURE_SIZE,\n },\n };\n\n declare state: {heatmapDataCache?: HeatmapDataCache};\n\n renderLayers(): Layer | LayersList | null {\n const rendered = super.renderLayers();\n const heatmap = unwrapSingleLayer(rendered);\n if (!heatmap) return rendered;\n\n const cache = reuseCachedHeatmapData(\n this.state?.heatmapDataCache,\n this.props as Record<string, unknown>,\n heatmap.props.data,\n );\n if (this.state) {\n this.state.heatmapDataCache = cache;\n }\n if (cache.data === heatmap.props.data) {\n return heatmap;\n }\n\n const HeatmapClass = heatmap.constructor as new (\n props: Record<string, unknown>,\n ) => Layer;\n return new HeatmapClass({\n ...heatmap.props,\n data: cache.data,\n });\n }\n}\n\n/** Return the previous inner heatmap `data` object when Arrow inputs match. */\nexport function reuseCachedHeatmapData(\n cache: HeatmapDataCache | undefined,\n props: Record<string, unknown>,\n nextData: unknown,\n): HeatmapDataCache {\n const sourceData = props.data;\n const sourcePosition = props.getPosition;\n const weightKey = getHeatmapWeightKey(props);\n if (\n cache &&\n cache.sourceData === sourceData &&\n cache.sourcePosition === sourcePosition &&\n cache.weightKey === weightKey\n ) {\n return cache;\n }\n return {sourceData, sourcePosition, weightKey, data: nextData};\n}\n\nfunction getHeatmapWeightKey(props: Record<string, unknown>): unknown {\n const getWeight = props.getWeight;\n const triggers = props.updateTriggers;\n if (triggers && typeof triggers === 'object' && 'getWeight' in triggers) {\n return (triggers as Record<string, unknown>).getWeight;\n }\n if (typeof getWeight === 'number' || getWeight == null) {\n return getWeight ?? 1;\n }\n return getWeight;\n}\n\nfunction unwrapSingleLayer(rendered: unknown): LayerWithData | null {\n const layers = Array.isArray(rendered) ? rendered : [rendered];\n const layer = layers[0];\n if (layer && typeof layer === 'object' && 'props' in layer) {\n return layer as LayerWithData;\n }\n return null;\n}\n"]}
@@ -1,6 +1,7 @@
1
1
  export { createTableToRecordBatchAdapter } from './createTableToRecordBatchAdapter';
2
2
  export { DeckColumnLayer } from './DeckColumnLayer';
3
3
  export { DeckH3HexagonLayer } from './DeckH3HexagonLayer';
4
+ export { DeckHeatmapLayer } from './DeckHeatmapLayer';
4
5
  export { formatH3IndexForDeck } from './h3IndexFormat';
5
6
  export { DeckTripsLayer } from './DeckTripsLayer';
6
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/json/layers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,+BAA+B,EAAC,MAAM,mCAAmC,CAAC;AAClF,OAAO,EAAC,eAAe,EAAC,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAC,kBAAkB,EAAC,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAC,oBAAoB,EAAC,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAC,cAAc,EAAC,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/json/layers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,+BAA+B,EAAC,MAAM,mCAAmC,CAAC;AAClF,OAAO,EAAC,eAAe,EAAC,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAC,kBAAkB,EAAC,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAC,gBAAgB,EAAC,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAC,oBAAoB,EAAC,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAC,cAAc,EAAC,MAAM,kBAAkB,CAAC"}
@@ -1,6 +1,7 @@
1
1
  export { createTableToRecordBatchAdapter } from './createTableToRecordBatchAdapter';
2
2
  export { DeckColumnLayer } from './DeckColumnLayer';
3
3
  export { DeckH3HexagonLayer } from './DeckH3HexagonLayer';
4
+ export { DeckHeatmapLayer } from './DeckHeatmapLayer';
4
5
  export { formatH3IndexForDeck } from './h3IndexFormat';
5
6
  export { DeckTripsLayer } from './DeckTripsLayer';
6
7
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/json/layers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,+BAA+B,EAAC,MAAM,mCAAmC,CAAC;AAClF,OAAO,EAAC,eAAe,EAAC,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAC,kBAAkB,EAAC,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAC,oBAAoB,EAAC,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAC,cAAc,EAAC,MAAM,kBAAkB,CAAC","sourcesContent":["export {createTableToRecordBatchAdapter} from './createTableToRecordBatchAdapter';\nexport {DeckColumnLayer} from './DeckColumnLayer';\nexport {DeckH3HexagonLayer} from './DeckH3HexagonLayer';\nexport {formatH3IndexForDeck} from './h3IndexFormat';\nexport {DeckTripsLayer} from './DeckTripsLayer';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/json/layers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,+BAA+B,EAAC,MAAM,mCAAmC,CAAC;AAClF,OAAO,EAAC,eAAe,EAAC,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAC,kBAAkB,EAAC,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAC,gBAAgB,EAAC,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAC,oBAAoB,EAAC,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAC,cAAc,EAAC,MAAM,kBAAkB,CAAC","sourcesContent":["export {createTableToRecordBatchAdapter} from './createTableToRecordBatchAdapter';\nexport {DeckColumnLayer} from './DeckColumnLayer';\nexport {DeckH3HexagonLayer} from './DeckH3HexagonLayer';\nexport {DeckHeatmapLayer} from './DeckHeatmapLayer';\nexport {formatH3IndexForDeck} from './h3IndexFormat';\nexport {DeckTripsLayer} from './DeckTripsLayer';\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"rewriteGeoArrowAccessors.d.ts","sourceRoot":"","sources":["../../src/json/rewriteGeoArrowAccessors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAqCtC,wBAAgB,wBAAwB,CAAC,OAAO,EAAE;IAChD,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB,2BA4CA"}
1
+ {"version":3,"file":"rewriteGeoArrowAccessors.d.ts","sourceRoot":"","sources":["../../src/json/rewriteGeoArrowAccessors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AA8CtC,wBAAgB,wBAAwB,CAAC,OAAO,EAAE;IAChD,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB,2BA4CA"}
@@ -14,6 +14,18 @@ function canUseDirectVectorAccessor(propName, vector) {
14
14
  // DuckDB UBIGINT often arrives as Int(true, 64), not instanceof Int64.
15
15
  (arrow.DataType.isInt(type) && type.bitWidth === 64));
16
16
  }
17
+ const firstChunk = vector.data[0];
18
+ if (!firstChunk) {
19
+ return false;
20
+ }
21
+ // Heatmap weights are a scalar column. Passing a float Vector through lets
22
+ // GeoArrow put them in binary attributes instead of a new function on every
23
+ // JSON convert (which would look like a data change). Integer columns stay
24
+ // on the function accessor: GeoArrow only uploads float weights, and Int64
25
+ // values are bigint / BigInt64Array which deck.gl cannot use as GPU data.
26
+ if (propName === 'getWeight') {
27
+ return arrow.DataType.isFloat(firstChunk.type);
28
+ }
17
29
  // Direct numeric vectors (for example `getRadius`) currently end up in deck's
18
30
  // binary attribute path and trigger `Float64Array` initialization failures in the
19
31
  // GeoArrow scatterplot wrapper. Re-test which direct vector accessors are safe
@@ -21,11 +33,7 @@ function canUseDirectVectorAccessor(propName, vector) {
21
33
  if (!propName.endsWith('Color')) {
22
34
  return false;
23
35
  }
24
- const firstChunk = vector.data[0];
25
- if (!firstChunk || !arrow.DataType.isFixedSizeList(firstChunk.type)) {
26
- return false;
27
- }
28
- return true;
36
+ return arrow.DataType.isFixedSizeList(firstChunk.type);
29
37
  }
30
38
  export function rewriteGeoArrowAccessors(options) {
31
39
  const { props, table, layerName } = options;
@@ -1 +1 @@
1
- {"version":3,"file":"rewriteGeoArrowAccessors.js","sourceRoot":"","sources":["../../src/json/rewriteGeoArrowAccessors.ts"],"names":[],"mappings":"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","sourcesContent":["import * as arrow from 'apache-arrow';\nimport {compileGeoArrowAccessor} from './compileGeoArrowAccessor';\nimport {getLayerCompatibility} from './layerCompatibility';\n\nfunction isSimpleColumnReference(expression: string) {\n return /^[A-Za-z_$][\\w$]*$/.test(expression.trim());\n}\n\nfunction canUseDirectVectorAccessor(propName: string, vector: arrow.Vector) {\n // H3 index columns are safe as Vectors — DeckH3HexagonLayer reads them\n // directly and converts BigInt → hex string when needed.\n if (propName === 'getHexagon') {\n const type = vector.type;\n return (\n arrow.DataType.isUtf8(type) ||\n arrow.DataType.isLargeUtf8(type) ||\n // DuckDB UBIGINT often arrives as Int(true, 64), not instanceof Int64.\n (arrow.DataType.isInt(type) && type.bitWidth === 64)\n );\n }\n\n // Direct numeric vectors (for example `getRadius`) currently end up in deck's\n // binary attribute path and trigger `Float64Array` initialization failures in the\n // GeoArrow scatterplot wrapper. Re-test which direct vector accessors are safe\n // after verifying the 0.4.x runtime contract handles them correctly.\n if (!propName.endsWith('Color')) {\n return false;\n }\n\n const firstChunk = vector.data[0];\n if (!firstChunk || !arrow.DataType.isFixedSizeList(firstChunk.type)) {\n return false;\n }\n\n return true;\n}\n\nexport function rewriteGeoArrowAccessors(options: {\n props: Record<string, unknown>;\n table: arrow.Table;\n layerName: string;\n}) {\n const {props, table, layerName} = options;\n const compatibility = getLayerCompatibility(layerName);\n if (!compatibility || compatibility.representation !== 'geoarrow') {\n return props;\n }\n\n const nextProps = {...props};\n\n for (const [propName, propValue] of Object.entries(nextProps)) {\n if (\n typeof propValue !== 'string' ||\n !propValue.startsWith('@@=') ||\n !propName.startsWith('get')\n ) {\n continue;\n }\n\n const expression = propValue.slice(3);\n if (\n compatibility.vectorAccessorProps.includes(propName) &&\n isSimpleColumnReference(expression)\n ) {\n const vector = table.getChild(expression.trim());\n if (vector && canUseDirectVectorAccessor(propName, vector)) {\n nextProps[propName] = vector;\n continue;\n }\n if (!vector) {\n // Column not found — fall through to compileGeoArrowAccessor which\n // handles missing bindings gracefully (returns undefined per row).\n console.warn(\n `Column \"${expression.trim()}\" not found in dataset for accessor \"${propName}\".`,\n );\n }\n }\n\n // This custom compiler handles GeoArrow batch-oriented callbacks. The 0.4.x\n // layers call function accessors with {index, data: {data: batch}, target},\n // which this compiler produces.\n nextProps[propName] = compileGeoArrowAccessor(expression, table);\n }\n\n return nextProps;\n}\n"]}
1
+ {"version":3,"file":"rewriteGeoArrowAccessors.js","sourceRoot":"","sources":["../../src/json/rewriteGeoArrowAccessors.ts"],"names":[],"mappings":"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","sourcesContent":["import * as arrow from 'apache-arrow';\nimport {compileGeoArrowAccessor} from './compileGeoArrowAccessor';\nimport {getLayerCompatibility} from './layerCompatibility';\n\nfunction isSimpleColumnReference(expression: string) {\n return /^[A-Za-z_$][\\w$]*$/.test(expression.trim());\n}\n\nfunction canUseDirectVectorAccessor(propName: string, vector: arrow.Vector) {\n // H3 index columns are safe as Vectors — DeckH3HexagonLayer reads them\n // directly and converts BigInt → hex string when needed.\n if (propName === 'getHexagon') {\n const type = vector.type;\n return (\n arrow.DataType.isUtf8(type) ||\n arrow.DataType.isLargeUtf8(type) ||\n // DuckDB UBIGINT often arrives as Int(true, 64), not instanceof Int64.\n (arrow.DataType.isInt(type) && type.bitWidth === 64)\n );\n }\n\n const firstChunk = vector.data[0];\n if (!firstChunk) {\n return false;\n }\n\n // Heatmap weights are a scalar column. Passing a float Vector through lets\n // GeoArrow put them in binary attributes instead of a new function on every\n // JSON convert (which would look like a data change). Integer columns stay\n // on the function accessor: GeoArrow only uploads float weights, and Int64\n // values are bigint / BigInt64Array which deck.gl cannot use as GPU data.\n if (propName === 'getWeight') {\n return arrow.DataType.isFloat(firstChunk.type);\n }\n\n // Direct numeric vectors (for example `getRadius`) currently end up in deck's\n // binary attribute path and trigger `Float64Array` initialization failures in the\n // GeoArrow scatterplot wrapper. Re-test which direct vector accessors are safe\n // after verifying the 0.4.x runtime contract handles them correctly.\n if (!propName.endsWith('Color')) {\n return false;\n }\n\n return arrow.DataType.isFixedSizeList(firstChunk.type);\n}\n\nexport function rewriteGeoArrowAccessors(options: {\n props: Record<string, unknown>;\n table: arrow.Table;\n layerName: string;\n}) {\n const {props, table, layerName} = options;\n const compatibility = getLayerCompatibility(layerName);\n if (!compatibility || compatibility.representation !== 'geoarrow') {\n return props;\n }\n\n const nextProps = {...props};\n\n for (const [propName, propValue] of Object.entries(nextProps)) {\n if (\n typeof propValue !== 'string' ||\n !propValue.startsWith('@@=') ||\n !propName.startsWith('get')\n ) {\n continue;\n }\n\n const expression = propValue.slice(3);\n if (\n compatibility.vectorAccessorProps.includes(propName) &&\n isSimpleColumnReference(expression)\n ) {\n const vector = table.getChild(expression.trim());\n if (vector && canUseDirectVectorAccessor(propName, vector)) {\n nextProps[propName] = vector;\n continue;\n }\n if (!vector) {\n // Column not found — fall through to compileGeoArrowAccessor which\n // handles missing bindings gracefully (returns undefined per row).\n console.warn(\n `Column \"${expression.trim()}\" not found in dataset for accessor \"${propName}\".`,\n );\n }\n }\n\n // This custom compiler handles GeoArrow batch-oriented callbacks. The 0.4.x\n // layers call function accessors with {index, data: {data: batch}, target},\n // which this compiler produces.\n nextProps[propName] = compileGeoArrowAccessor(expression, table);\n }\n\n return nextProps;\n}\n"]}
@@ -18,13 +18,10 @@ export declare function isScaleMarker(value: unknown): value is ScaleMarker;
18
18
  * {@link compileLinearScaleAccessor}.
19
19
  */
20
20
  export declare function compileLinearScaleExpression(table: arrow.Table, scale: LinearScaleConfig): string | undefined;
21
- /** Elevation accessor for any Arrow column name (incl. non-identifiers). */
22
- export declare function compileLinearScaleAccessor(table: arrow.Table, scale: LinearScaleConfig): ((info: {
23
- index: number;
24
- data: {
25
- data: unknown;
26
- };
27
- target: number[];
28
- }) => number) | undefined;
21
+ /**
22
+ * Elevation accessor for any Arrow column name (incl. non-identifiers).
23
+ * Reads GeoArrow `{index, data}` callbacks or GeoJSON `{properties}` features.
24
+ */
25
+ export declare function compileLinearScaleAccessor(table: arrow.Table, scale: LinearScaleConfig): ((value: unknown) => number) | undefined;
29
26
  export {};
30
27
  //# sourceMappingURL=scaleFunction.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"scaleFunction.d.ts","sourceRoot":"","sources":["../../src/json/scaleFunction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAC;AAG3C,QAAA,MAAM,qBAAqB,eAA8C,CAAC;AAE1E,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,kFAAkF;IAClF,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,iBAAiB,GAAG;IAC5C,CAAC,qBAAqB,CAAC,EAAE,IAAI,CAAC;CAC/B,CAAC;AAEF,oFAAoF;AACpF,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,WAAW,GAAG,SAAS,CA6BzB;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,WAAW,CAMlE;AAqBD;;;GAGG;AACH,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,KAAK,CAAC,KAAK,EAClB,KAAK,EAAE,iBAAiB,GACvB,MAAM,GAAG,SAAS,CA8BpB;AAED,4EAA4E;AAC5E,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,KAAK,CAAC,KAAK,EAClB,KAAK,EAAE,iBAAiB,GAEtB,CAAC,CAAC,IAAI,EAAE;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE;QAAC,IAAI,EAAE,OAAO,CAAA;KAAC,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAC,KAAK,MAAM,CAAC,GAC5E,SAAS,CAmCZ"}
1
+ {"version":3,"file":"scaleFunction.d.ts","sourceRoot":"","sources":["../../src/json/scaleFunction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAC;AAG3C,QAAA,MAAM,qBAAqB,eAA8C,CAAC;AAE1E,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,kFAAkF;IAClF,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,iBAAiB,GAAG;IAC5C,CAAC,qBAAqB,CAAC,EAAE,IAAI,CAAC;CAC/B,CAAC;AAEF,oFAAoF;AACpF,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,WAAW,GAAG,SAAS,CA6BzB;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,WAAW,CAMlE;AAqBD;;;GAGG;AACH,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,KAAK,CAAC,KAAK,EAClB,KAAK,EAAE,iBAAiB,GACvB,MAAM,GAAG,SAAS,CA8BpB;AAsCD;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,KAAK,CAAC,KAAK,EAClB,KAAK,EAAE,iBAAiB,GACvB,CAAC,CAAC,KAAK,EAAE,OAAO,KAAK,MAAM,CAAC,GAAG,SAAS,CAiC1C"}
@@ -87,7 +87,34 @@ export function compileLinearScaleExpression(table, scale) {
87
87
  // Clamp after linear map (bigint coercion lives in compileGeoArrowAccessor).
88
88
  return `@@=Math.max(${lo}, Math.min(${hi}, ${r0} + (${field} - ${d0}) / ${span} * ${r1 - r0}))`;
89
89
  }
90
- /** Elevation accessor for any Arrow column name (incl. non-identifiers). */
90
+ function readLinearScaleRawValue(value, field, vector) {
91
+ if (!value || typeof value !== 'object')
92
+ return undefined;
93
+ const object = value;
94
+ if (typeof object.index === 'number') {
95
+ const batch = object.data?.data;
96
+ if (batch?.getChild) {
97
+ return batch.getChild(field)?.get(object.index);
98
+ }
99
+ if (batch) {
100
+ // Batch-local index (GeoArrow) without this field — do not fall back to
101
+ // the table-level vector.
102
+ return undefined;
103
+ }
104
+ return vector.get(object.index);
105
+ }
106
+ const sources = [object.properties, object];
107
+ for (const source of sources) {
108
+ if (source && typeof source === 'object' && field in source) {
109
+ return source[field];
110
+ }
111
+ }
112
+ return undefined;
113
+ }
114
+ /**
115
+ * Elevation accessor for any Arrow column name (incl. non-identifiers).
116
+ * Reads GeoArrow `{index, data}` callbacks or GeoJSON `{properties}` features.
117
+ */
91
118
  export function compileLinearScaleAccessor(table, scale) {
92
119
  const field = scale.field.trim();
93
120
  if (!field)
@@ -102,10 +129,8 @@ export function compileLinearScaleAccessor(table, scale) {
102
129
  return undefined;
103
130
  const [d0, d1] = domain;
104
131
  const range = scale.range;
105
- return ({ index, data }) => {
106
- const batch = data.data;
107
- const child = batch.getChild?.(field) ?? vector;
108
- const raw = child?.get(index);
132
+ return (value) => {
133
+ const raw = readLinearScaleRawValue(value, field, vector);
109
134
  if (raw == null)
110
135
  return 0;
111
136
  const v = Number(raw);