Skip to content

feat: PostGIS import UX improvements and tile_source routing refactor#260

Merged
sharkAndshark merged 18 commits into
mainfrom
fix/postgis-modal-click
May 25, 2026
Merged

feat: PostGIS import UX improvements and tile_source routing refactor#260
sharkAndshark merged 18 commits into
mainfrom
fix/postgis-modal-click

Conversation

@sharkAndshark
Copy link
Copy Markdown
Owner

Summary

PostGIS connection and import workflow improvements, plus a tile routing architecture refactor.

PostGIS Import Improvements

  • One-click import: Removed FID column selector and import popover. Import button directly registers PostGIS source without requiring FID selection.
  • FID optional: fid_column is now Option throughout the backend. PostGIS sources work without FID.
  • Row count display: PostGIS sources show row count (e.g., '2 rows') instead of '0 B'. Backend queries COUNT(*) on registration and pg_class.reltuples for discovery.
  • Connection reuse: Same database imported multiple times shares one postgis_connections record.
  • Re-import support: Re-importing the same schema.table auto-cleans old registration.
  • Connect API: New POST /api/postgis/connections/connect that combines test + version check + object discovery in one request.

Tile Source Routing Refactor

  • tile_source as sole routing discriminator: All tile endpoints (get_tile, get_file_schema, get_feature_properties, get_public_tile) now use match tile_source.as_str() instead of checking tile_format first.
  • MBTiles explicit type: MBTiles import sets tile_source='mbtiles' (was implicit via tile_format IS NOT NULL).
  • PostGIS no tile_format: PostGIS sources no longer set tile_format='mvt'. This was causing PostGIS to be routed to the MBTiles code path.
  • PreviewMeta returns tileSource: Frontend can now distinguish source types for click behavior.
  • Defensive migration: Existing MBTiles records with tile_source='duckdb' are migrated to tile_source='mbtiles'.

Frontend Changes

  • Feature click logic uses tileSource === 'postgis' instead of tileFormat === 'mvt' for MVT branch.
  • File list and detail panel show row count for PostGIS sources.
  • Discovery list shows estimated row count per table.

Test Data

  • Imported Monaco OSM data into test PostGIS database (3979 roads, 4147 POIs, 2190 buildings).

Verification

  • 258 backend tests pass
  • Frontend builds cleanly
  • Smoke test: PostGIS import -> preview -> tile rendering -> click properties all work

@sharkAndshark sharkAndshark force-pushed the fix/postgis-modal-click branch from 928604e to ed6d5a3 Compare May 22, 2026 08:50
Phase 1 & 2 of the map editor feature:

Backend:
- maps table + CRUD API (list/create/get/update/delete)
- preview-sources endpoint listing ready data sources
- field-values endpoint for classification (distinct values + min/max stats)

Frontend:
- MapsPanel: map list with create/delete/edit entry
- MapEditor: three-panel layout (layers / OL map / symbolization)
- ClassificationWizard: single color, unique value, graduated color
- ColorRamp: categorical + sequential ramps with interpolation
- styleJsonToOl: Mapbox Style JSON -> OL Style conversion with
  expression support (case/get/==/<=/interpolate/match)
- Layer visibility toggle and reordering (up/down)
- Auto-fit to data bounds on source add
- Debounced auto-save of style JSON
- i18n (en/zh) for all map editor UI

Homepage tabs: [数据] [资源] [地图]
…dmap

Reference QGIS symbology capabilities to prioritize next features:
labeling, layer opacity, scale visibility, filter, rule-based renderer,
proportional symbols, point clustering, heatmap as high priority.
- Replace overlay button with div to avoid capturing click events
- Add stopPropagation on modal-content to prevent event bubbling
- Add keyboard handlers for accessibility
Backend:
- Add 3 new API endpoints for discovering schemas, tables, and columns
- Add data structures for discovery requests/responses

Frontend:
- Add API functions for schema/table/column discovery
- Refactor PostGIS form to use cascade selection:
  - Test connection → load schemas
  - Select schema → load tables
  - Select table → load geometry columns and FID candidates
- Add i18n translations for new UI elements
- Fix object field being cleared by race condition in loadPostgisTables:
  move reset logic to handleSchemaChange (synchronous, before async load)
- Remove connectionName field: auto-generate from host:port if not provided
- Remove displayName field: backend defaults to table name
- Add frontend validation: object must be selected before register
Redesign the PostGIS workflow to separate connection from selection:
- New discover-objects API scans all tables with geometry columns
- Simplified modal: only connection info (host/port/db/user/pass)
- On connect, automatically scan and close modal
- Discovered objects appear in data list as collapsible group
- Each object shows schema.table, type, geometry info
- One-click import button per object (uses first geometry/fid column)
- Remove connectionName/displayName/schema/table/column selectors
- Remove port spinner buttons
…rlap

The PostGIS section was placed as a direct child of panel-body (flex row),
causing it to be squeezed between list-area and detail-area. Moved it inside
list-area with maxHeight:260px and overflow-y:auto for proper scrolling.
PostGIS code was incorrectly placed inside DetailSidebar component
(which has no access to App state). Moved to the correct location:
inside list-area, between file list and list-area closing div.
- Backend: discover-objects now returns pkColumns (integer columns with
  single-column PK/UNIQUE constraint) alongside fidCandidates
- Frontend: clicking 'Import' opens inline popover with FID dropdown
  - PK columns annotated with (PK), others with (no unique constraint)
  - Geometry column shown as read-only (or dropdown if multiple)
  - User must confirm before import
- Prevents import failures from blindly selecting non-unique FID columns
Tables require single-column PK/UNIQUE for FID (backend enforced).
Now the frontend only shows valid FID options:
- Tables: only pkColumns (columns with PK/UNIQUE constraint)
- Views: all fidCandidates (views skip index check)
Tables without any PK/UNIQUE column show 'No valid FID column' and
cannot be imported.
- tile_source is now the only routing criterion for all tile endpoints
- tile_format is only used for MBTiles content-type, not for routing
- MBTiles sets tile_source='mbtiles' on import (was implicit via tile_format)
- PostGIS no longer sets tile_format='mvt' (was causing MBTiles routing bug)
- PreviewMeta now returns tileSource for frontend to distinguish source types
- Frontend Preview.jsx uses tileSource for click behavior (MVT vs DuckDB)
- get_tile/get_file_schema/get_feature_properties/get_public_tile all use
  match tile_source instead of if-else cascade
- db.rs defensive migration: existing MBTiles records get tile_source='mbtiles'
- PostGIS row count: COUNT(*) for files.size, pg_class.reltuples for discovery
- Frontend shows 'N rows' instead of '0 B' for PostGIS sources
…e clamping

- handleToggleVisibility: fix inverted logic (was never toggling)
- evalExpr: use === and !== instead of == and != for ==/!=/in operators
- interpolate: clamp to first stop value when input is below first stop
- db.rs: log warnings on migration failure instead of silently discarding
- styleJsonToOl.js: remove dead code colorProp variable
- MapEditor.jsx: cleanup saveTimeoutRef on unmount to prevent stale setState
@sharkAndshark sharkAndshark force-pushed the fix/postgis-modal-click branch from 6d31130 to 1fdfd71 Compare May 25, 2026 02:33
@sharkAndshark sharkAndshark merged commit 828e69b into main May 25, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant