Repository navigation
feat: add geometry column settings in map settings - #815
dmitriy-kostianetskiy wants to merge 1 commit into
Conversation
📝 WalkthroughWalkthroughChangesMap geometry configuration
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant MapSettings
participant MapGeometrySettings
participant mapConfigUtils
MapSettings->>MapGeometrySettings: render geometry configuration
MapGeometrySettings->>mapConfigUtils: update geometry bindings
mapConfigUtils-->>MapGeometrySettings: return updated DeckMapConfig
MapGeometrySettings-->>MapSettings: emit onConfigChange
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e14cc4ebe4
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| if (!column.type) return false; | ||
| if (kind === 'numeric') return isColumnNumeric(column.type); | ||
| if (kind === 'quantitative') return isColumnQuantitative(column.type); | ||
| if (kind === 'geometry') return isColumnGeometry(column.type); |
There was a problem hiding this comment.
Allow WKB columns in geometry selectors
When the dataset schema is inspected from ST_AsWKB(...)/generated point transforms, the geometry output column is reported as BLOB (and ST_AsText(...) as VARCHAR), not GEOMETRY. Filtering the new Geometry selector to only isColumnGeometry therefore hides the valid geom, __sqlrooms_geom, source_geom, and target_geom columns that existing WKB map configs rely on; before this change those selectors used the unfiltered column list, so users could select or repair these bindings.
Useful? React with 👍 / 👎.
| (value: string) => { | ||
| if (value === 'wkb') { | ||
| // Switch to WKB mode - regenerate config with geometry column | ||
| const geometryColumn = activeLayerDataset?.geometryColumn ?? 'geom'; |
There was a problem hiding this comment.
Do not reuse generated lon/lat geometry for WKB mode
For a lon/lat-generated point map, activeLayerDataset.geometryColumn is the generated __sqlrooms_geom created by the transform, but this WKB-mode branch also replaces the dataset source with a bare table source below, so that generated column no longer exists. On tables that have both lon/lat and a real WKB geometry column, toggling to “Geometry Column (WKB)” leaves the map and fit config pointing at a missing generated column instead of the native geometry column until the user manually fixes it.
Useful? React with 👍 / 👎.
| geometryEncodingHint: 'wkb', | ||
| source: { | ||
| tableName: | ||
| sourceDataTable.tableName ?? | ||
| getTableIdentity(sourceDataTable.table), |
There was a problem hiding this comment.
Convert DuckDB GEOMETRY before marking it as WKB
When the selected column is a DuckDB GEOMETRY column (the type this new Geometry selector allows), this branch stores the raw table as the source while forcing geometryEncodingHint: 'wkb'. DuckDB spatial GEOMETRY values are not standard WKB—the existing decoder path tells callers to use ST_AsWKB/ST_AsText first—so switching to this mode for a native geometry table makes dataset preparation fail unless the source includes a conversion transform.
Useful? React with 👍 / 👎.
| sourceDataTable.tableName ?? | ||
| getTableIdentity(sourceDataTable.table), |
There was a problem hiding this comment.
Preserve qualified table identity in WKB mode
In this branch sourceDataTable.tableName is always used because that deprecated field is required, so the getTableIdentity(sourceDataTable.table) fallback is effectively unreachable. For a selected table outside the default schema/catalog (or when duplicate table names exist), switching to WKB mode rewrites the dataset source to an unqualified table name and can query the wrong relation or fail, unlike the regenerate path that preserves the qualified table reference.
Useful? React with 👍 / 👎.
| ...mapConfig, | ||
| datasets: { | ||
| ...mapConfig.datasets, | ||
| [activeLayerDatasetId ?? '']: { |
There was a problem hiding this comment.
Avoid creating an empty dataset id without an active layer
When the settings panel is open for an empty map that still has a selected table, activeLayerDatasetId is undefined but this control is still rendered. Choosing “Geometry Column (WKB)” then writes a dataset under the empty-string key and fitToData.dataset: '' without creating any layer, leaving the map in an invalid/unrenderable state instead of seeding a normal dataset-backed layer like the lat/long regenerate path does.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
packages/deck/src/MapGeometrySettings.tsx (2)
21-33: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd tsdoc for new exported API.
MapGeometrySettingsPropsandMapGeometrySettingsare new public exports inpackages/deckwithout tsdoc.As per coding guidelines, "Add tsdoc to exported types and functions in
@sqlrooms/*packages."🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/deck/src/MapGeometrySettings.tsx` around lines 21 - 33, Add TSDoc comments to the exported MapGeometrySettingsProps interface and MapGeometrySettings component, documenting their purpose and public usage without changing their APIs or behavior.Source: Coding guidelines
1-198: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy liftNo tests for new geometry-mode-switching logic.
This file introduces non-trivial config-mutation logic (mode switching, geometry/lat-long updates) with no accompanying tests.
As per coding guidelines, "Add or update tests when changing behavior or public API, when practical."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/deck/src/MapGeometrySettings.tsx` around lines 1 - 198, Add tests covering MapGeometrySettings geometry-mode switching and column updates. Verify switching to WKB preserves relevant fit-to-data options and configures the dataset geometry fields, switching to latitude/longitude regenerates the config, and the latitude, longitude, and geometry change handlers update the expected columns.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/deck/src/MapGeometrySettings.tsx`:
- Around line 52-82: Harden handleGeometryModeChange when switching to WKB:
return without updating config if activeLayerDatasetId is missing, and resolve
the geometry column from sourceDataTable using isColumnGeometry instead of
defaulting to “geom”. Preserve the existing activeLayerDataset.source fields,
including transformSql, while updating only tableName and geometry-related
settings; keep datasets and fitToData keyed by the validated dataset ID.
---
Nitpick comments:
In `@packages/deck/src/MapGeometrySettings.tsx`:
- Around line 21-33: Add TSDoc comments to the exported MapGeometrySettingsProps
interface and MapGeometrySettings component, documenting their purpose and
public usage without changing their APIs or behavior.
- Around line 1-198: Add tests covering MapGeometrySettings geometry-mode
switching and column updates. Verify switching to WKB preserves relevant
fit-to-data options and configures the dataset geometry fields, switching to
latitude/longitude regenerates the config, and the latitude, longitude, and
geometry change handlers update the expected columns.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: ecdb81f1-829b-46db-a9e4-ee12872237bd
📒 Files selected for processing (7)
packages/deck/src/MapGeometrySettings.tsxpackages/deck/src/MapSettings.tsxpackages/deck/src/MapSettingsControls.tsxpackages/deck/src/mapConfigUtils.tspackages/duckdb-core/src/index.tspackages/duckdb-core/src/schema-tree/typeCategories.tspackages/duckdb/src/index.ts
| const handleGeometryModeChange = useCallback( | ||
| (value: string) => { | ||
| if (value === 'wkb') { | ||
| // Switch to WKB mode - regenerate config with geometry column | ||
| const geometryColumn = activeLayerDataset?.geometryColumn ?? 'geom'; | ||
| onConfigChange({ | ||
| ...mapConfig, | ||
| datasets: { | ||
| ...mapConfig.datasets, | ||
| [activeLayerDatasetId ?? '']: { | ||
| ...activeLayerDataset, | ||
| geometryColumn, | ||
| geometryEncodingHint: 'wkb', | ||
| source: { | ||
| tableName: | ||
| sourceDataTable.tableName ?? | ||
| getTableIdentity(sourceDataTable.table), | ||
| }, | ||
| }, | ||
| }, | ||
| fitToData: { | ||
| dataset: activeLayerDatasetId ?? '', | ||
| geometryColumn, | ||
| ...(mapConfig.fitToData?.padding !== undefined && { | ||
| padding: mapConfig.fitToData.padding, | ||
| }), | ||
| ...(mapConfig.fitToData?.maxZoom !== undefined && { | ||
| maxZoom: mapConfig.fitToData.maxZoom, | ||
| }), | ||
| }, | ||
| }); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Fragile 'wkb' config construction: unsafe dataset key, hardcoded fallback column, dropped transformSql.
Several issues in the hand-rolled config update when switching to WKB mode:
- Line 61/73:
activeLayerDatasetId ?? ''silently writes todatasets['']/fitToData.dataset: ''when there's no active dataset (e.g., no layer yet), producing an orphaned config entry instead of failing safely. - Line 56: falls back to the literal
'geom'column name with no check that such a column exists, unlikeregenerateMapConfigForTable/createDeckMapConfigForTable, which resolve real columns from the table. - Lines 65-69:
source: {tableName: ...}replaces the wholesourceobject, dropping any existingtransformSqlonactiveLayerDataset.source.
🐛 Proposed fix
if (value === 'wkb') {
+ if (!activeLayerDatasetId) return;
// Switch to WKB mode - regenerate config with geometry column
- const geometryColumn = activeLayerDataset?.geometryColumn ?? 'geom';
+ const geometryColumn =
+ activeLayerDataset?.geometryColumn ??
+ sourceDataTable.columns.find((c) => isColumnGeometry(c.type))?.name ??
+ 'geom';
onConfigChange({
...mapConfig,
datasets: {
...mapConfig.datasets,
- [activeLayerDatasetId ?? '']: {
+ [activeLayerDatasetId]: {
...activeLayerDataset,
geometryColumn,
geometryEncodingHint: 'wkb',
source: {
+ ...(activeLayerDataset?.source as Record<string, unknown> | undefined),
tableName:
sourceDataTable.tableName ??
getTableIdentity(sourceDataTable.table),
},
},
},
fitToData: {
- dataset: activeLayerDatasetId ?? '',
+ dataset: activeLayerDatasetId,
geometryColumn,(requires importing isColumnGeometry from @sqlrooms/duckdb)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/deck/src/MapGeometrySettings.tsx` around lines 52 - 82, Harden
handleGeometryModeChange when switching to WKB: return without updating config
if activeLayerDatasetId is missing, and resolve the geometry column from
sourceDataTable using isColumnGeometry instead of defaulting to “geom”. Preserve
the existing activeLayerDataset.source fields, including transformSql, while
updating only tableName and geometry-related settings; keep datasets and
fitToData keyed by the validated dataset ID.
Screen.Recording.2026-07-15.at.10.51.14.mov
Summary by CodeRabbit
New Features
Bug Fixes