import React, { useState, useEffect, useRef } from "react";
import { MapContainer, TileLayer, GeoJSON } from "react-leaflet";
import "leaflet/dist/leaflet.css";
import axios from "axios";
function Catalogue() {
const [showLocations, setShowLocations] = useState(false);
const [tables, setTables] = useState([]);
const [selectedTable, setSelectedTable] = useState(null);
const [geojsonData, setGeojsonData] = useState(null);
const [mapCenter, setMapCenter] = useState([51.505, -0.09]); // Default center for the map
// Ref to hold the map instance
const mapRef = useRef();
useEffect(() => {
// Fetch the table names from your Express server
axios
.get("http://localhost:5000/tables")
.then((response) => {
setTables(response.data.tables);
// Assume the first table in the response as the default selected table
if (response.data.tables.length > 0) {
setSelectedTable(response.data.tables[0]);
}
})
.catch((error) => {
console.error("Error fetching table names:", error);
});
}, []);
useEffect(() => {
// Fetch GeoJSON data when the selected table changes
if (selectedTable) {
axios
.get(`http://localhost:5000/data/${selectedTable}`)
.then((response) => {
setGeojsonData(response.data);
})
.catch((error) => {
console.error(
`Error fetching data for table ${selectedTable}:`,
error
);
});
}
}, [selectedTable]);
useEffect(() => {
// Check if the GeoJSON data contains valid features and set the map center
if (geojsonData && geojsonData.features.length > 0) {
const coordinates = geojsonData.features[0].geometry.coordinates;
setMapCenter(coordinates.reverse()); // Leaflet expects [lat, lng], so we reverse the order
}
}, [geojsonData]);
const handleToggleLocations = () => {
setShowLocations(!showLocations);
};
const handleTableChange = (table) => {
setSelectedTable(table);
};
return (
<div style={containerStyle}>
<div className="catalogue" style={customStyle}>
<h2 onClick={handleToggleLocations} style={{ cursor: "pointer" }}>
Forest Locations
</h2>
{showLocations && (
<ul>
{tables.map((table) => (
<li
key={table}
onClick={() => handleTableChange(table)}
style={{ cursor: "pointer" }}
>
{table}
</li>
))}
</ul>
)}
</div>
<div style={mapContainerStyle}>
{geojsonData && geojsonData.features.length > 0 && (
<MapContainer
ref={mapRef} // Set the ref to the map instance
center={mapCenter}
zoom={13}
style={{ height: "100%", width: "100%" }}
>
<TileLayer
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
/>
<GeoJSON data={geojsonData} />
</MapContainer>
)}
</div>
</div>
);
}
export default Catalogue;
In the initial state data is fetched for the layer1 and is mapped, but when I click on the other layers, data is fetched but they are not mapped. I want this to behave like when I click on any other layer, it should be mapped and map should fly to that location.
How can I change the mapping state, what should I do to fly the map to the selected layer location.