Working on drawer

This commit is contained in:
2025-04-20 20:51:10 -04:00
parent 19ed8ef2ca
commit 06f9a96498
11 changed files with 109 additions and 427 deletions

View File

@@ -1,15 +1,12 @@
import { useEffect, useState } from 'react';
import { useEffect, useRef, useState } from 'react';
import { Airport, AirportCategory } from '@lib/airport.types.ts';
import { useMapEvents } from 'react-leaflet';
import debounce from 'lodash.debounce';
import { getAirports } from '@lib/airport.ts';
import AirportMarker from '@components/AirportMarker.tsx';
import { LeafletEvent } from 'leaflet';
import { LayerInfo } from '@/App.tsx';
interface Bounds {
northEast: { lat: number; lon: number };
southWest: { lat: number; lon: number };
}
const EXPANSION_FACTOR = 0.5;
export default function AirportLayer({
setAirport,
@@ -21,76 +18,48 @@ export default function AirportLayer({
selectedLayer: LayerInfo;
}) {
const [airports, setAirports] = useState<Airport[]>([]);
const lastBoundsRef = useRef<{ ne: any; sw: any } | null>(null);
function loadAirports(event: LeafletEvent) {
const map = event.target;
const bounds = map.getBounds();
const debouncedLoad = useRef(
debounce(async (map: any) => {
const b = map.getBounds();
const north = b.getNorth(),
south = b.getSouth();
const east = b.getEast(),
west = b.getWest();
const latDelta = (north - south) * EXPANSION_FACTOR;
const lonDelta = (east - west) * EXPANSION_FACTOR;
const boundsParam: Bounds = {
northEast: {
lat: bounds.getNorth(),
lon: bounds.getEast()
},
southWest: {
lat: bounds.getSouth(),
lon: bounds.getWest()
}
};
// expanded bbox
const ne = { lat: north + latDelta, lon: east + lonDelta };
const sw = { lat: south - latDelta, lon: west - lonDelta };
lastBoundsRef.current = { ne, sw };
getAirports({
bounds: boundsParam,
metars: true,
categories: [AirportCategory.HELIPORT, AirportCategory.SMALL, AirportCategory.MEDIUM, AirportCategory.LARGE]
})
.then((response) => {
setAirports(response.data);
})
.catch((error) => {
console.error('Error fetching airports:', error);
try {
const resp = await getAirports({
bounds: { northEast: ne, southWest: sw },
metars: true,
categories: [AirportCategory.HELIPORT, AirportCategory.SMALL, AirportCategory.MEDIUM, AirportCategory.LARGE]
});
setAirports(resp.data);
} catch (err) {
console.error('fetch error', err);
setAirports([]);
});
}
}
}, 300)
).current;
const map = useMapEvents({
moveend: loadAirports
move: () => debouncedLoad(map)
});
useEffect(() => {
if (map) {
loadAirports({ target: map } as LeafletEvent);
}
if (map) debouncedLoad(map);
return () => {
debouncedLoad.cancel();
};
}, [map]);
// const categoryOrder: { [key in AirportCategory]?: number } = {
// [AirportCategory.LARGE]: 3,
// [AirportCategory.MEDIUM]: 2,
// [AirportCategory.SMALL]: 1,
// [AirportCategory.HELIPORT]: 0
// };
// const sortedAirports = airports.slice().sort((a, b) => {
// // Compare by airport category first.
// const categoryA = categoryOrder[a.category] ?? 4;
// const categoryB = categoryOrder[b.category] ?? 4;
// if (categoryA !== categoryB) {
// return categoryA - categoryB;
// }
//
// // Then compare by flight category if available.
// // Assuming that latest_metar.flight_category is a string and "UNKN" needs to come last.
// const fcA = a.latest_metar?.flight_category ?? 'UNKN';
// const fcB = b.latest_metar?.flight_category ?? 'UNKN';
//
// if (fcA === 'UNKN' && fcB !== 'UNKN') return 1;
// if (fcB === 'UNKN' && fcA !== 'UNKN') return -1;
//
// // If both flight categories are not "UNKN", do a simple alphabetical comparison.
// // (You may wish to customize this logic based on the actual flight category values.)
// if (fcA < fcB) return -1;
// if (fcA > fcB) return 1;
// return 0;
// });
return (
<>
{airports.map((airport, index) => (