// Panels: left (layers), right (inspector), and inline UI atoms const { useState: useStateP } = React; // Small icon set (line SVGs) function I({ name, size = 16 }) { const s = { width: size, height: size }; const common = { fill: 'none', stroke: 'currentColor', strokeWidth: 1.6, strokeLinecap: 'round', strokeLinejoin: 'round' }; switch(name) { case 'select': return ; case 'pan': return ; case 'measure': return ; case 'draw': return ; case 'polygon': return ; case 'edit': return ; case 'query': return ; case 'buffer': return ; case 'ai': return ; case '3d': return ; case 'layer': return ; case 'route': return ; case 'sat': return ; case 'drone': return ; case 'download': return ; case 'upload': return ; case 'chart': return ; case 'save': return ; case 'print': return ; case 'settings': return ; case 'compass': return ; case 'grid': return ; default: return null; } } // ---------- Ribbon ---------- function Ribbon({ activeTool, setActiveTool }) { const groups = [ { label: 'File', tools: [ { id: 'open', icon: 'upload', label: 'Open' }, { id: 'save', icon: 'save', label: 'Save' }, { id: 'export', icon: 'download', label: 'Export' }, { id: 'print', icon: 'print', label: 'Print' }, ] }, { label: 'Navigate', tools: [ { id: 'select', icon: 'select', label: 'Select' }, { id: 'pan', icon: 'pan', label: 'Pan' }, { id: 'zoom', icon: 'query', label: 'Zoom' }, { id: 'measure',icon: 'measure', label: 'Measure' }, ] }, { label: 'Edit', tools: [ { id: 'draw', icon: 'draw', label: 'Draw' }, { id: 'polygon',icon: 'polygon', label: 'Polygon' }, { id: 'vertex', icon: 'edit', label: 'Vertex' }, ] }, { label: 'Analyze', tools: [ { id: 'buffer', icon: 'buffer', label: 'Buffer' }, { id: 'overlay', icon: 'layer', label: 'Overlay' }, { id: 'route', icon: 'route', label: 'Route' }, { id: 'chart', icon: 'chart', label: 'Charts' }, ] }, { label: 'AI / Remote Sensing', tools: [ { id: 'aidet', icon: 'ai', label: 'Detect' }, { id: 'segm', icon: 'grid', label: 'Segment' }, { id: 'sat', icon: 'sat', label: 'Imagery' }, { id: 'drone', icon: 'drone', label: 'Drone' }, ] }, { label: '3D & Twin', tools: [ { id: '3d', icon: '3d', label: '3D View' }, { id: 'globe', icon: 'compass', label: 'Globe' }, ] }, { label: 'System', tools: [ { id: 'settings', icon: 'settings', label: 'Settings' }, ] }, ]; return (
{groups.map(g => (
{g.tools.map(t => ( ))}
{g.label}
))}
); } // ---------- Left Panel — Layers ---------- function LayersPanel({ layers, setLayers }) { const [tab, setTab] = useStateP('layers'); const toggle = (id) => setLayers(prev => ({ ...prev, [id]: { ...prev[id], on: !prev[id].on }})); const groups = [ { label: 'AI / Analysis', layers: [ { id: 'ai', name: 'AI Detections', swatch: '#d97706', count: 8, hatch: true }, { id: 'buffer', name: 'Buffer 5/10/15km', swatch: '#e8a33d', count: 3 }, { id: 'routes', name: 'Optimized Routes', swatch: '#d97706', count: 2 }, { id: 'heatmap', name: 'Population Heatmap', swatch: '#c94a3a', count: '—' }, ] }, { label: 'Vector', layers: [ { id: 'assets', name: 'Utility Assets', swatch: '#2f7d4f', count: 7 }, { id: 'cities', name: 'Cities & Towns', swatch: '#0a1a35', count: 20 }, { id: 'labels', name: 'Place Labels', swatch: 'transparent', count: '—' }, { id: 'roads', name: 'National Highways', swatch: '#c94a3a', count: 15 }, { id: 'rivers', name: 'Rivers & Streams', swatch: '#4a90c8', count: 8 }, ] }, { label: 'Boundaries', layers: [ { id: 'districts', name: 'District Boundaries', swatch: '#7a8a68', count: 776 }, { id: 'states', name: 'State Boundaries', swatch: '#3d5978', count: 36 }, ] }, { label: 'Reference', layers: [ { id: 'graticule', name: 'Lat/Lon Graticule', swatch: '#a8b8c8', count: '—' }, ] } ]; return (
{tab === 'layers' && ( <>
Project SAVED
Karnataka LIS Master
KA-LIS-2026-Q2.bcgp • v3.4.1
{groups.map(g => (
{g.label} {g.layers.length} layers
{g.layers.map(l => (
toggle(l.id)}>
{l.name}
{l.count}
))}
))} )} {tab === 'data' && (
Connected Sources
{[ { name: 'PostGIS · ka_lis_prod', kind: 'PostgreSQL 16 · PostGIS 3.4', st: 'ok', ct: 24 }, { name: 'GeoServer · WMS/WFS', kind: 'geoserver.bhoochitra.gov.in', st: 'ok', ct: 42 }, { name: 'S3 · sentinel-imagery', kind: 'GeoTIFF · 4.2 TB', st: 'ok', ct: 1204 }, { name: 'Oracle Spatial · legacy',kind: 'Read-only replication', st: 'warn', ct: 8 }, { name: 'ISRO Bhuvan · WMTS', kind: 'External tile service', st: 'ok', ct: '—' }, ].map((d, i) => (
{d.st.toUpperCase()}
{d.name}
{d.ct}
{d.kind}
))}
)} {tab === 'book' && (
Saved Views
{[ { name: 'National Overview', s: '1:12,000,000', by: 'default' }, { name: 'NCR — Encroachment Scan', s: '1:80,000', by: 'ai.workflow' }, { name: 'Krishna Basin', s: '1:1,200,000', by: 'hydro.team' }, { name: 'Mumbai Metro Utilities', s: '1:20,000', by: 'utility.mh' }, { name: 'NE Forest Cover', s: '1:800,000', by: 'forest.dept' }, ].map((b,i) => (
{b.name}
{b.s} · @{b.by}
OPEN
))}
)}
); } // ---------- Right Panel — Inspector ---------- function InspectorPanel({ selected, activeTool }) { const [tab, setTab] = useStateP('attr'); const renderAttributes = () => { if (!selected) { return (
No feature selected
Use the Select tool on the map — click a city, asset, AI detection, or state to inspect its attributes.
); } if (selected.kind === 'city') { const c = selected.data; return ( <>
Populated Place · Tier {c.tier === 'metro' ? '01' : '02'}
{c.name}
FID · {c.id.toUpperCase()}-1832 · CRS EPSG:4326
{[ ['Population', c.pop], ['State', c.state], ['Category', c.tier === 'metro' ? 'Metropolitan' : 'Tier-I City'], ['Class', 'Municipal Corporation'], ['Latitude', approxLatLon(c).lat.toFixed(5) + '° N'], ['Longitude', approxLatLon(c).lon.toFixed(5) + '° E'], ['Elevation (SRTM)', Math.round(60 + Math.random()*300) + ' m'], ['Land Area', (300 + Math.random()*900).toFixed(1) + ' km²'], ['Last Updated', '2026-06-12'], ['Source', 'Census + ULB verified'], ].map(([k,v]) => (
{k}
{v}
))}
Tags
SMART_CITY ULB AMRUT
); } if (selected.kind === 'ai') { const d = selected.data; const sev = d.conf > 0.9 ? 'HIGH' : d.conf > 0.85 ? 'MED' : 'LOW'; return ( <>
AI Detection · GeoAI v2.7
{d.kind}
DET-{d.id.toUpperCase()}-{Math.floor(Math.random()*9999).toString().padStart(4,'0')}
Confidence
{(d.conf*100).toFixed(1)}%
Severity
{sev}
Area
{d.area}
Model
YOLOv8 · fine-tuned
Source Imagery
Sentinel-2 · 2026-07-11
Ground Truth
Pending field verification
Assigned
field.officer.mh_2
Status
OPEN
Detection Bounds
{d.x-d.w/2},{d.y-d.h/2} → {d.x+d.w/2},{d.y+d.h/2}
); } if (selected.kind === 'asset') { const a = selected.data; return ( <>
Utility Asset
{a.kind}
AST-{a.id.toUpperCase()}-91024
Status
{a.status.toUpperCase()}
Owner
Municipal Corp.
Installed
2019-03-14
Last Inspection
2026-05-22
SLA Uptime
99.94%
Telemetry
LIVE via SCADA
Load
72% / rated
Next Service
2026-09-01
); } if (selected.kind === 'state') { return ( <>
Administrative · Level 1
{selected.name}
STATE-{selected.id.toUpperCase()} · IN-{selected.id.toUpperCase()}
Feature Type
State / UT Polygon
Source
Survey of India
Vertices
{Math.floor(2000 + Math.random()*8000)}
Topology
VALID
CRS
EPSG:4326 (WGS84)
Last Edit
2026-04-18 14:22
); } return null; }; return (
{tab === 'attr' && renderAttributes()} {tab === 'ana' && ( <>
Features Visible
1,284,441
+18,240 this week
Selected
{selected ? '1' : '0'}
Layer Count
14
4 groups
Basemap Cache
2.1 GB
Offline ready
Active Analysis
{[ { name: 'Buffer 15 km @ Delhi', status: 'DONE', kind: 'proximity' }, { name: 'Overlay: LULC × Parcels',status: 'RUN', kind: 'overlay' }, { name: 'Hotspot: Encroachment', status: 'DONE', kind: 'hotspot' }, { name: 'Route: Del → Kol', status: 'DONE', kind: 'route' }, { name: 'NDVI Δ 2024 → 2026', status: 'RUN', kind: 'raster' }, ].map((r,i) => (
{r.status} {r.name} {r.kind}
))}
Bar · Detections by class
)} {tab === 'ai' && ( <>
GeoAI Model Queue 4 RUNNING
{[ { name: 'YOLOv8 · Building Detection', pct: 82, area: 'Karnataka' }, { name: 'U-Net · Land Cover Classify', pct: 47, area: 'Krishna Basin' }, { name: 'SAM · Field Segmentation', pct: 96, area: 'Punjab Kharif' }, { name: 'LSTM · Flood Forecast 7d', pct: 34, area: 'Assam' }, { name: 'Change Detection · Δ2024', pct: 100,area: 'Odisha Coast' }, ].map((m,i) => (
{m.name} {m.pct}%
Region · {m.area}
))}
Prediction · Flood Risk (7d)
Jul 15peak: Jul 28Jul 31
Available Models
{['building.det','road.seg','water.det','crop.seg','forest.mon','mining.det','encr.det','fire.det','flood.pred','landslide.pred','ndvi.calc','change.det','traffic.ana','geoai.gen'].map(m => ( {m} ))}
)}
); } // ---------- Small chart atoms ---------- function BarChart({ data }) { const max = Math.max(...data.map(d => d.v)); return (
{data.map(d => (
{d.label}
{d.v}
))}
); } function Sparkline({ values, color }) { const w = 280, h = 44; const max = Math.max(...values), min = Math.min(...values); const step = w / (values.length - 1); const norm = (v) => h - ((v - min) / (max - min || 1)) * (h - 4) - 2; const path = values.map((v,i) => `${i===0?'M':'L'}${i*step},${norm(v)}`).join(' '); const area = path + ` L${w},${h} L0,${h} Z`; return ( ); } // Approximate SVG coord → lat/lon function approxLatLon(c) { const lon = 68 + (c.x / 612) * (97 - 68); const lat = 37 - (c.y / 696) * (37 - 8); return { lat, lon }; } Object.assign(window, { Ribbon, LayersPanel, InspectorPanel, I, BarChart, Sparkline, approxLatLon });