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>
This commit is contained in:
AI Assistant
2026-03-23 14:21:37 +02:00
parent 53595fdf94
commit c297a2c5f7
15 changed files with 1227 additions and 2 deletions
+33
View File
@@ -0,0 +1,33 @@
"use client";
import { FeatureGate } from "@/core/feature-flags";
import { useI18n } from "@/core/i18n";
import { GeoportalModule } from "@/modules/geoportal";
export default function GeoportalPage() {
const { t } = useI18n();
return (
<FeatureGate flag="module.geoportal" fallback={<ModuleDisabled />}>
<div className="mx-auto max-w-7xl space-y-6">
<div>
<h1 className="text-2xl font-bold tracking-tight">
{t("geoportal.title")}
</h1>
<p className="text-muted-foreground">
{t("geoportal.description")}
</p>
</div>
<GeoportalModule />
</div>
</FeatureGate>
);
}
function ModuleDisabled() {
return (
<div className="mx-auto max-w-7xl py-12 text-center text-muted-foreground">
<p>Modulul Geoportal este dezactivat.</p>
</div>
);
}