Commit Graph

368 Commits

Author SHA1 Message Date
AI Assistant ba71ca3ef5 feat(parcel-sync): fix click, color styling, UAT boundary cross-check
Click fix:
- Keep l-terenuri-fill visible but transparent (opacity 0) so it still
  catches click events for FeatureInfoPanel. Enrichment overlay renders
  underneath.

Color changes:
- No enrichment: amber/yellow fill (was light green)
- With enrichment: green fill
- Buildings: red fill = no legal docs, blue = legal, gray = unknown
- Parcel outline: red = building no legal, blue = building legal

Boundary cross-check (/api/geoportal/boundary-check?siruta=X):
- Finds "foreign" parcels: registered in other UATs but geometrically
  within this UAT boundary (orange dashed)
- Finds "edge" parcels: registered here but centroid outside boundary
  (purple dashed)
- Alert banner shows count, legend updated with mismatch indicators

Martin config: added gis_cladiri_status source with build_legal property.
Enrichment views: gis_cladiri_status now JOINs parent parcel's BUILD_LEGAL.

Requires: docker restart martin + POST /api/geoportal/setup-enrichment-views

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:05:12 +02:00
AI Assistant 2848868263 fix(parcel-sync): fitBounds zoom + Martin config for enrichment tiles
- Map tab now uses fitBounds (not flyTo with fixed zoom) to show entire
  UAT extent when selected. Bounds are fetched and applied after map ready.
- Added gis_terenuri_status to martin.yaml so Martin serves enrichment
  tiles (has_enrichment, has_building, build_legal properties).
- Removed center/zoom props from MapViewer — use fitBounds via handle.
- Requires `docker restart martin` on server for Martin to reload config.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 15:38:15 +02:00
AI Assistant 2b8d144924 fix(parcel-sync): replace Unicode escapes with actual Romanian diacritics
The \u0103, \u00ee etc. escape sequences were rendering literally in JSX
text nodes instead of displaying ă, î, ț, ș characters.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 15:24:11 +02:00
AI Assistant d48a2bbf5d refactor(parcel-sync): split 4800-line module into 9 files + Harta tab + enrichment views
Split parcel-sync-module.tsx (4800 lines) into modular files:
- Orchestrator (452 lines): shared state (session, UAT, sync) + tab routing
- Types + helpers, ConnectionPill, 6 tab components (search, layers, export, database, cf, map)

New ParcelSync Harta tab:
- UAT-scoped map: zoom to extent, filter parcels/buildings by siruta
- Data-driven styling via gis_terenuri_status enrichment overlay
  (green=no enrichment, dark green=enriched, blue outline=building, red=no legal docs)
- Reuses Geoportal components (MapViewer, SelectionToolbar, FeatureInfoPanel, BasemapSwitcher)
- Export DXF/GPKG for selection, legend

New PostGIS views (gis_terenuri_status, gis_cladiri_status):
- has_enrichment, has_building, build_legal columns from enrichment JSON
- Auto-created via /api/geoportal/setup-enrichment-views
- Does not modify existing Geoportal views

New API: /api/geoportal/uat-bounds (WGS84 bbox from PostGIS geometry)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 15:02:01 +02:00
AI Assistant 3fcf7e2a67 fix(geoportal): Google satellite, ESC/right-click exit, no UAT fill, ANCPI bbox fix
Basemaps: added Google Satellite option
ANCPI ortofoto: fixed bbox conversion (all 4 corners, not just SW/NE)
Selection: ESC key and right-click exit selection mode, tooltips updated
UAT layers: removed fill (only lines + labels), less visual clutter
Proprietari vechi: greyed out (opacity-50) so current owners stand out

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 14:19:02 +02:00
AI Assistant 1cc73a3033 fix(geoportal): enrichment now calls proven /api/eterra/search internally
Instead of reimplementing eTerra search logic (which missed most fields),
now calls the existing /api/eterra/search endpoint that already works
perfectly in ParcelSync. Same data, same format: proprietari, CF, CFvechi,
topo, intravilan, categorie, adresa, solicitant.

Per-parcel, 2-5 seconds, persists in DB.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 14:05:07 +02:00
AI Assistant 024ee0f21a fix(geoportal): layer toggle + enrichment update + refresh button
1. Layer toggle fix: removed isStyleLoaded() check that silently blocked
   visibility changes when OpenFreeMap style has pending sprite/font loads
2. Enrichment: "Actualizeaza" button always visible (re-fetch from eTerra)
   replaces "Enrichment" button when data already exists
3. Panel updates with returned enrichment data immediately

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 13:53:18 +02:00
AI Assistant 19bed6724b fix(geoportal): enrichment panel update + force-hide all layers + boundary filter
1. Enrichment: panel now updates immediately with returned data (was only showing message)
2. Layers: ALL data layers set to visibility:none immediately after creation,
   then only enabled ones are shown. Fixes cladiri appearing when only terenuri toggled.
3. OpenFreeMap boundaries: also filter by source-layer="boundary" (more reliable)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 13:45:29 +02:00
AI Assistant 48fe47d2c0 fix(geoportal): per-parcel enrichment via searchImmovableByIdentifier
Replaces background UAT-wide enrichment with instant per-parcel search.
Uses eTerra searchImmovableByIdentifier (cadastral number lookup) which
returns in 1-3 seconds instead of minutes.

Extracts: NR_CF, proprietari (with shares), intravilan, categorie,
adresa, has_building, build_legal. Persists in DB immediately.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 13:35:03 +02:00
AI Assistant 5ff7d4cdd7 fix(geoportal): hide oneway arrows from OpenFreeMap basemap
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 13:24:41 +02:00
AI Assistant 91034c41ee fix(geoportal): background enrichment using proven enrichFeatures()
Previous single-parcel enrichment wrote empty data (couldn't match in eTerra).
Now uses the original enrichFeatures() which properly fetches owners, CF, etc.

Changes:
- Enrichment runs in BACKGROUND (returns immediately with message)
- Clears bad enrichment data before re-running
- Tracks running enrichments to avoid duplicates
- GET /api/geoportal/enrich?siruta=... checks if enrichment is running
- Panel: hasRealEnrichment checks for CF/PROPRIETARI/CATEGORIE (not just NR_CAD)
- Enrichment button stays visible until real data exists
- Message: "Enrichment pornit in background. Datele vor aparea in 1-3 minute."

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 13:23:44 +02:00
AI Assistant d9c247fee2 fix(geoportal): force all layers hidden on map load (fixes terenuri/cladiri showing when toggled off)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 13:20:13 +02:00
AI Assistant 7ae23aebf4 fix(geoportal): hide OpenFreeMap built-in boundary layers on load
OpenFreeMap Liberty/Dark styles include admin boundary layers that show
even when our UAT toggle is off. Now hides all boundary/admin/border
layers from the basemap style on map load.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 13:18:44 +02:00
AI Assistant d2b69d5ec6 fix(geoportal): all layers OFF by default + full enrichment display
Layers:
- ALL layers OFF by default (just basemap on load)
- User activates what they need

Feature panel:
- Shows ALL enrichment fields: proprietari (full text, wrapping),
  CF vechi, nr topo, adresa, solicitant, intravilan, categorie
- Building info with icon (cu acte / fara acte warning)
- hasEnrichment check relaxed (any non-empty field counts)
- Panel scrollable (max-h 60vh) for long data
- WrapRow for multi-line text (proprietari, adresa)
- Enrichment button visible when no enrichment data
- Enrichment auto-updates panel on success

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 13:09:41 +02:00
AI Assistant dfa4815d75 fix(geoportal): layers off by default + bulk enrichment feedback
- UAT + Intravilan layers OFF by default (user activates when needed)
- Terenuri/Cladiri listed first in panel (most used)
- Bulk enrichment: per-feature with progress counter (3/10), success summary
- Progress text shown in toolbar during enrichment

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 12:58:24 +02:00
AI Assistant 903dc67ac4 fix: drop views before recreating slim versions (cannot drop columns from view)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 12:43:56 +02:00
AI Assistant 60919122d9 feat(geoportal): one-click optimize-tiles + unified setup banner
New endpoint POST /api/geoportal/optimize-tiles:
- Slims gis_features view (drops attributes, enrichment, timestamps)
- Cascades to gis_terenuri, gis_cladiri, gis_administrativ, gis_documentatii
- Makes vector tiles dramatically smaller

Setup banner now checks 3 optimizations:
1. UAT zoom views (gis_uats_z0/z5/z8/z12)
2. Pre-computed geometry (geom_z0/z5/z8 columns)
3. Slim tile views (no JSON columns)

One "Aplica toate" button runs all pending steps sequentially.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 12:26:08 +02:00
AI Assistant 32d3f30f9d fix(geoportal): auto-refresh panel after enrichment + Comanda CF always visible
- After enrichment: panel updates immediately with returned data (no reload needed)
- "Comanda CF" button visible on any parcel with cadastral ref (not just enriched ones)
- "Descarca CF" shown when CF extract already exists in DB

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 12:11:59 +02:00
AI Assistant 8ead985c7e perf(geoportal): single-parcel enrichment instead of full UAT
Previous enrichment tried to enrich ALL parcels in a UAT (minutes).
Now enriches just the clicked parcel (seconds):
1. Finds the GisFeature by ID or objectId+siruta
2. Fetches immovable data from eTerra for that specific parcel
3. Persists enrichment in DB
4. Skips if enriched < 7 days ago

Auto-uses env credentials (ETERRA_USERNAME/PASSWORD) — no manual login needed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 11:56:04 +02:00
AI Assistant 566d7c4bb1 fix(geoportal): better enrichment error messages + login retry
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 11:25:55 +02:00
AI Assistant 3ffb617970 fix(geoportal): font 404s + slim tile views for performance
- Labels: add text-font ["Noto Sans Regular"] (OpenFreeMap compatible)
- Optimize views: gis_features/terenuri/cladiri/administrativ now exclude
  attributes, enrichment, timestamps (huge JSON columns that made tiles slow)
- Views only include: id, layer_id, siruta, object_id, cadastral_ref,
  area_value, is_active, geom

Run optimize-views again after deploy to apply slimmer views.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 11:23:05 +02:00
AI Assistant 8362e3fd84 fix(geoportal): drop views before adding columns (fixes geometry type conflict)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 11:01:11 +02:00
AI Assistant 53c241c20f perf(geoportal): materialize simplified UAT geometries (fixes 90% CPU on PostgreSQL)
ST_SimplifyPreserveTopology in views runs on every Martin tile request,
causing constant CPU load. Fix: pre-compute simplified geometries into
dedicated columns (geom_z0, geom_z5, geom_z8) on the GisUat table.

POST /api/geoportal/optimize-views:
1. Adds geom_z0/z5/z8 columns to GisUat
2. Backfills with pre-computed simplifications (one-time cost)
3. Creates GiST spatial indexes on each
4. Replaces views to use pre-computed columns (zero CPU reads)
5. Updates trigger to auto-compute on INSERT/UPDATE

Setup banner: now checks optimization status and shows "Optimizeaza"
button if needed. One-click, then docker restart martin.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 10:51:17 +02:00
AI Assistant c4122cea01 feat(geoportal): enrichment API + CF download + bulk enrichment
New API endpoints:
- POST /api/geoportal/enrich — enriches all parcels for a SIRUTA,
  skips already-enriched, persists in GisFeature.enrichment column
- GET /api/geoportal/cf-status?nrCad=... — checks if CF extract exists,
  returns download URL if available

Feature panel:
- No enrichment: "Enrichment" button (triggers eTerra sync for UAT)
- Has enrichment + CF available: "Descarca CF" button (direct download)
- Has enrichment + no CF: "Comanda CF" button (link to ePay tab)
- Copy button always visible
- After enrichment completes, panel auto-reloads data

Selection toolbar:
- Bulk "Enrichment" button for selected parcels (per unique SIRUTA)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 10:48:08 +02:00
AI Assistant 800c45916e feat(geoportal): rectangle + freehand polygon selection drawing on map
Rectangle mode (Dreptunghi):
- Mousedown starts drawing, mousemove shows amber overlay, mouseup selects
- All terenuri features in the drawn bbox are added to selection
- Map panning disabled during draw, re-enabled after
- Minimum 5px size to prevent accidental micro-selections

Freehand mode (Desen):
- Each click adds a point, polygon drawn with GeoJSON source
- Double-click closes polygon, selects features whose centroid is inside
- Ray-casting point-in-polygon algorithm for spatial filtering
- Double-click zoom disabled during freehand mode

Draw state clears when switching selection modes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 08:19:20 +02:00
AI Assistant 3a2262edd0 feat(geoportal): feature panel with Enrichment + Extras CF buttons
- Parcele fara enrichment: buton "Enrichment" (sync magic de la eTerra)
- Parcele cu enrichment: date complete + buton "Extras CF" (link ePay)
- Buton "Copiaza" (clipboard cu NR_CAD, CF, suprafata, proprietari)
- ExportFormat: removed geojson (only dxf + gpkg)
- Tooltips pe fiecare buton

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 08:17:15 +02:00
AI Assistant 836d60b72f feat(geoportal): one-time setup banner for PostGIS views
- GET /api/geoportal/setup-views checks if zoom views exist
- POST creates them (idempotent)
- SetupBanner component: auto-checks on mount, shows amber banner if
  views missing, button to create them, success message with docker
  restart reminder, auto-hides when everything is ready

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 08:05:22 +02:00
AI Assistant 7d2fe4ade0 feat(geoportal): selection modes (click/rectangle/freehand) + export DXF/GPKG only
- Selection toolbar: 3 modes — Click (individual), Dreptunghi (area), Desen (freehand)
- Each mode has tooltip explaining usage
- Export: removed GeoJSON, only DXF + GPKG. GPKG labeled "cu metadata"
- DXF export fix: -s_srs + -t_srs (was -a_srs + -t_srs)

Note: rectangle and freehand drawing on map not yet implemented (UI ready,
map interaction coming next session).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 07:57:34 +02:00
AI Assistant 78625d6415 fix(geoportal): simplified info panel, preserve basemap zoom, DXF export, intravilan outline
- Feature panel: simplified (NR_CAD/NR_CF/SIRUTA/Suprafata/Proprietari),
  aligned top-right under basemap switcher, click empty space to close
- Basemap switch: preserves zoom+center via viewStateRef + moveend listener
- DXF export: use -s_srs + -t_srs (not -a_srs + -t_srs which ogr2ogr rejects)
- Intravilan: double line (black outer + orange inner), z13+, no fill
- Parcel labels: cadastral_ref shown at z16+
- UAT z12: original geometry (no simplification)
- Removed MapLibre popup (only side panel)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 07:43:11 +02:00
AI Assistant b38916229e fix(martin): add --default-srid=3844 (ST_Simplify views lose SRID metadata)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 22:05:19 +02:00
AI Assistant 1b679098ab fix(martin): revert to auto-discovery (Docker bind mount creates directories on Portainer)
Views already select only needed columns, so Martin auto-discovery
serves the same result without needing a config file.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 21:55:59 +02:00
AI Assistant ba3edc3321 fix(martin): mount config as /martin-config.yaml (Docker created /config/martin.yaml as directory)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 21:34:28 +02:00
AI Assistant 0af3e16a2b feat(geoportal): add /api/geoportal/setup-views endpoint for creating UAT zoom views
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 21:08:14 +02:00
AI Assistant 4f694d4458 perf(geoportal): 4-level UAT simplification + intravilan layer + preserve view on basemap switch
UAT zoom-dependent views (read-only, original geom NEVER modified):
- gis_uats_z0 (z0-5): 2000m simplification — country outlines
- gis_uats_z5 (z5-8): 500m — regional overview
- gis_uats_z8 (z8-12): 50m — county/city level with labels
- gis_uats_z12 (z12+): 10m — near-original precision

New layers:
- gis_administrativ (intravilan, arii speciale) — orange dashed, no simplification
- Toggle in layer panel (off by default)

Basemap switching:
- Now preserves current center + zoom when switching between basemaps

Parcels + buildings: NO simplification (exact geometry needed)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 20:34:15 +02:00
AI Assistant 76c19449f3 perf(geoportal): zoom-dependent UAT simplification + Martin config + tile cache
PostGIS:
- gis_uats view: ST_SimplifyPreserveTopology(geom, 50) + only name/county/siruta
- gis_uats_simple view: ST_SimplifyPreserveTopology(geom, 500) for z0-z9

Martin config (martin.yaml):
- Explicit source definitions (auto_publish: false)
- gis_uats_simple (z0-9): only name+siruta, 500m simplified geometry
- gis_uats (z0-14): name+siruta+county, 50m simplified
- gis_terenuri (z10-18): object_id+siruta+cadastral_ref+area_value+layer_id
- gis_cladiri (z12-18): same properties
- 24h cache headers on all tiles

MapViewer:
- Dual UAT sources: simplified (z0-9) + detailed (z9+) with seamless handoff
- Zoom-interpolated paint: thin lines at z5, thicker at z12
- UAT labels only z9+, fill opacity z-interpolated (0.03→0.08)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 20:24:38 +02:00
AI Assistant 6c55264fa3 feat(geoportal): OpenFreeMap vector basemaps + eTerra ORTO 2024 ortophoto
Basemap options:
- Liberty (OpenFreeMap vector) — default, sharp vector tiles
- Dark (OpenFreeMap) — dark theme, auto-styled
- Satellite (ESRI World Imagery) — raster
- ANCPI Ortofoto 2024 — proxied via /api/eterra/tiles/orto, converts
  Web Mercator z/x/y to EPSG:3844 bbox, authenticates with eTerra
  session, caches 24h. Requires ETERRA_USERNAME/PASSWORD env vars.

Replaces old raster OSM/OpenTopoMap with vector styles.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 18:43:21 +02:00
AI Assistant 06932b5ddc fix(geoportal): remove .pbf extension from Martin tile URLs
Martin v0.15.0 serves tiles at /{source}/{z}/{x}/{y} without .pbf
extension. Requests with .pbf returned 404.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 18:30:50 +02:00
AI Assistant 2248ecc5d3 fix(geoportal): fix basemap switching + OpenTopoMap maxzoom 17
- Basemap switching now recreates the map (basemap in useEffect deps)
  instead of buggy remove/re-add that swallowed errors
- OpenTopoMap maxzoom set to 17 (was requesting z19 → 400 errors)
- Basemap maxzoom applied to both source and map maxZoom

Note: Martin vector tiles return 404 — PostGIS views or Martin container
need to be checked on the server.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 18:24:47 +02:00
AI Assistant fff20e0cb9 fix(geoportal): use w-full h-full on map container (MapLibre overrides position to relative)
MapLibre sets position:relative on its container element, which overrides
our absolute inset-0 and causes height to collapse to 0. Using w-full h-full
instead works because the parent (absolute inset-0) has a definite computed
height from positioning.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 18:13:55 +02:00
AI Assistant b13a038eb1 fix(geoportal): use absolute inset-0 on MapViewer wrapper (fixes 0-height canvas)
h-full (height:100%) doesn't propagate through absolutely positioned
parents. The MapLibre container had width=1065 but height=0. Using
absolute inset-0 on the wrapper fills the parent directly via positioning
instead of percentage height.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 18:07:48 +02:00
AI Assistant 1a9ed1ef76 fix(geoportal): use absolute positioning to fill main (fixes h-full/flex-1 chain)
height: 100% doesn't work when the parent gets its height from flex-1
(flexbox-computed, not explicit height). Fixed by adding position:relative
to main in fullscreen mode and using absolute inset-0 on the geoportal
container.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 17:23:55 +02:00
AI Assistant 2278226ff1 fix(geoportal): fullscreen route + local CSS + proper layout
- Add /geoportal to FULLSCREEN_ROUTES (overflow-hidden, no padding)
- Copy maplibre-gl.css to public/ and load from same origin (avoids CDN/CSP)
- Simplify layout: fill parent via h-full w-full (no negative margin hack)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 17:14:09 +02:00
AI Assistant 437d734df6 fix(geoportal): load MapLibre CSS via CDN link injection + fullscreen layout
- Static CSS import doesn't work with next/dynamic + standalone output.
  Now injects a <link> tag to unpkg CDN at module load time (bulletproof).
- Geoportal is now fullscreen: map fills entire viewport below the header,
  no duplicate title/description, negative margins bleed to edges.
- Removed page-level CSS imports (no longer needed).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 17:01:48 +02:00
AI Assistant 3346ec709d fix(geoportal): import MapLibre CSS at page level (fixes blank map with next/dynamic)
CSS imports inside dynamically loaded components (ssr: false) don't get
included in the production bundle. Importing maplibre-gl CSS at the page
level ensures it's always available. Applied to both geoportal and
parcel-sync pages.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 16:49:40 +02:00
AI Assistant 1b5876524a feat(geoportal): add search, basemap switcher, feature info panel, selection + export
Major geoportal enhancements:
- Basemap switcher (OSM/Satellite/Terrain) with ESRI + OpenTopoMap tiles
- Search bar with debounced lookup (UATs by name, parcels by cadastral ref, owners by name)
- Feature info panel showing enrichment data from ParcelSync (cadastru, proprietari, suprafata, folosinta)
- Parcel selection mode with amber highlight + export (GeoJSON/DXF/GPKG via ogr2ogr)
- Next.js /tiles rewrite proxying to Martin (fixes dev + avoids mixed content)
- Fixed MapLibre web worker relative URL resolution (window.location.origin)

API routes: /api/geoportal/search, /api/geoportal/feature, /api/geoportal/export

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 16:43:01 +02:00
AI Assistant 4ea7c6dbd6 fix(geoportal): use relative /tiles URL for Martin (avoids mixed content + build-time env) 2026-03-23 15:49:37 +02:00
AI Assistant 4a144fc397 fix(geoportal): use HTTPS Martin URL via Traefik /tiles proxy 2026-03-23 15:35:40 +02:00
AI Assistant 00a691debd chore: add NEXT_PUBLIC_MARTIN_URL env var for geoportal 2026-03-23 14:52:40 +02:00
AI Assistant c297a2c5f7 feat: add Geoportal module with MapLibre GL JS + Martin vector tiles
Phase 1 of the geoportal implementation:

Infrastructure:
- Martin vector tile server in docker-compose (port 3010)
- PostGIS setup SQL for GisUat: native geom column, Esri→PostGIS
  trigger, GiST index, gis_uats view for Martin auto-discovery

Geoportal module (src/modules/geoportal/):
- map-viewer.tsx: MapLibre GL JS canvas with OSM base, Martin MVT
  sources (gis_uats, gis_terenuri, gis_cladiri), click-to-inspect,
  zoom-level-aware layer visibility, layer styling
- layer-panel.tsx: collapsible sidebar with layer toggles
- geoportal-module.tsx: standalone page wrapper
- Module registered in config/modules.ts, flags.ts, i18n

ParcelSync integration:
- 6th tab "Harta" with lazy-loaded MapViewer (ssr: false)
- Centered on selected UAT

Dependencies: maplibre-gl v5.21.0

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 14:21:37 +02:00
AI Assistant 53595fdf94 docs: add ANCPI ePay env vars to CONFIGURATION.md, bump ParcelSync to 0.6.0
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 14:02:30 +02:00