0
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='&copy; <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.

0

Browse other questions tagged or ask your own question.