import React, { useEffect, useRef, useState } from 'react'; import Map from 'ol/Map'; import View from 'ol/View'; import TileLayer from 'ol/layer/Tile'; import OSM from 'ol/source/OSM'; import XYZ from 'ol/source/XYZ'; import { fromLonLat, toLonLat } from 'ol/proj'; import 'ol/ol.css'; const TITILER_ENDPOINT = 'https://tiles.portfolio.techarvest.co.zw'; // Dynamic World class mapping for legend const DW_CLASSES = [ { id: 0, name: "No Data", color: "#000000" }, { id: 1, name: "Water", color: "#419BDF" }, { id: 2, name: "Trees", color: "#397D49" }, { id: 3, name: "Grass", color: "#88B53E" }, { id: 4, name: "Flooded Veg", color: "#FFAA5D" }, { id: 5, name: "Crops", color: "#DA913D" }, { id: 6, name: "Shrub/Scrub", color: "#919636" }, { id: 7, name: "Built", color: "#B9B9B9" }, { id: 8, name: "Bare", color: "#D6D6D6" }, { id: 9, name: "Snow/Ice", color: "#FFFFFF" }, ]; interface MapComponentProps { onCoordsSelected: (lat: number, lon: number) => void; resultUrl?: string; roi?: { lat: number, lon: number, radius_m: number }; } const MapComponent: React.FC = ({ onCoordsSelected, resultUrl, roi }) => { const mapRef = useRef(null); const mapInstance = useRef(null); const [activeResultLayer, setActiveResultLayer] = useState | null>(null); useEffect(() => { if (!mapRef.current) return; mapInstance.current = new Map({ target: mapRef.current, layers: [ new TileLayer({ source: new OSM(), }), ], view: new View({ center: fromLonLat([29.1549, -19.0154]), zoom: 6, }), }); mapInstance.current.on('click', (event) => { const coords = toLonLat(event.coordinate); onCoordsSelected(coords[1], coords[0]); }); return () => { if (mapInstance.current) { mapInstance.current.setTarget(undefined); } }; }, []); // Handle Result Layer and Zoom useEffect(() => { if (!mapInstance.current || !resultUrl) return; // Remove existing result layer if any if (activeResultLayer) { mapInstance.current.removeLayer(activeResultLayer); } // Add new result layer // Format: TITILER/cog/tiles/{z}/{x}/{y}?url=S3_URL const newLayer = new TileLayer({ source: new XYZ({ url: `${TITILER_ENDPOINT}/cog/tiles/{z}/{x}/{y}?url=${resultUrl}`, }), }); mapInstance.current.addLayer(newLayer); setActiveResultLayer(newLayer); // Zoom to ROI if provided if (roi) { mapInstance.current.getView().animate({ center: fromLonLat([roi.lon, roi.lat]), zoom: 14, duration: 1000 }); } }, [resultUrl, roi]); return (
{/* Map Legend */}

Class Legend

{DW_CLASSES.map(cls => (
{cls.name}
))}
); }; export default MapComponent;