Fixing loading in docker environment, updated markers
This commit is contained in:
@@ -31,8 +31,7 @@ export default function AirportLayer({ setAirport }: { setAirport: (airport: Air
|
||||
getAirports({
|
||||
bounds: boundsParam,
|
||||
metars: true,
|
||||
categories: [AirportCategory.SMALL, AirportCategory.MEDIUM, AirportCategory.LARGE],
|
||||
limit: 200
|
||||
categories: [AirportCategory.HELIPORT, AirportCategory.SMALL, AirportCategory.MEDIUM, AirportCategory.LARGE]
|
||||
})
|
||||
.then((response) => {
|
||||
setAirports(response.data);
|
||||
@@ -53,9 +52,39 @@ export default function AirportLayer({ setAirport }: { setAirport: (airport: Air
|
||||
}
|
||||
}, [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) => {
|
||||
{sortedAirports.map((airport, index) => {
|
||||
return <AirportMarker airport={airport} index={index} setAirport={setAirport} />;
|
||||
})}
|
||||
</>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Airport } from '@lib/airport.types.ts';
|
||||
import { Marker } from 'react-leaflet';
|
||||
import { Airport, AirportCategory } from '@lib/airport.types.ts';
|
||||
import { Marker, Popup } from 'react-leaflet';
|
||||
import L from 'leaflet';
|
||||
import { useRef } from 'react';
|
||||
|
||||
export default function AirportMarker({
|
||||
index,
|
||||
@@ -11,52 +12,96 @@ export default function AirportMarker({
|
||||
airport: Airport;
|
||||
setAirport: (airport: Airport) => void;
|
||||
}) {
|
||||
const markerColor = getMarkerColor(airport);
|
||||
const icon = createCustomIcon(markerColor);
|
||||
const icon = createCustomIcon(airport);
|
||||
const markerRef = useRef<L.Marker>(null);
|
||||
|
||||
return (
|
||||
<Marker
|
||||
key={index}
|
||||
ref={markerRef}
|
||||
position={[airport.latitude, airport.longitude]}
|
||||
icon={icon}
|
||||
eventHandlers={{
|
||||
click: () => setAirport(airport)
|
||||
click: () => setAirport(airport),
|
||||
mouseover: () => markerRef.current?.openPopup(),
|
||||
mouseout: () => markerRef.current?.closePopup()
|
||||
}}
|
||||
/>
|
||||
>
|
||||
<Popup closeButton={false}>
|
||||
{airport.icao} - {airport.name}
|
||||
</Popup>
|
||||
</Marker>
|
||||
);
|
||||
}
|
||||
|
||||
function getMarkerColor(airport: Airport): string {
|
||||
if (airport.latest_metar) {
|
||||
switch (airport.latest_metar.flight_category.toUpperCase()) {
|
||||
case 'IFR':
|
||||
return '#ff0100';
|
||||
case 'LIFR':
|
||||
return '#7f007f';
|
||||
case 'MVFR':
|
||||
return '#00f';
|
||||
case 'VFR':
|
||||
return '#018000';
|
||||
case 'UNKNOWN':
|
||||
return '#3e3e3e';
|
||||
default:
|
||||
return '#3e3e3e';
|
||||
}
|
||||
} else {
|
||||
return '#696969';
|
||||
function getMarkerColor(flightCategory: 'VFR' | 'MVFR' | 'LIFR' | 'IFR' | 'UNKN'): string {
|
||||
switch (flightCategory) {
|
||||
case 'IFR':
|
||||
return '#ff0100';
|
||||
case 'LIFR':
|
||||
return '#7f007f';
|
||||
case 'MVFR':
|
||||
return '#00f';
|
||||
case 'VFR':
|
||||
return '#018000';
|
||||
case 'UNKN':
|
||||
return '#696969';
|
||||
}
|
||||
}
|
||||
|
||||
function createCustomIcon(color: string): L.DivIcon {
|
||||
return L.divIcon({
|
||||
html: `<div style="
|
||||
background-color: ${color};
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border-radius: 50%;
|
||||
border: 2px solid #fff;
|
||||
"></div>`,
|
||||
className: '',
|
||||
iconSize: [20, 20],
|
||||
iconAnchor: [10, 10]
|
||||
});
|
||||
function createCustomIcon(airport: Airport): L.DivIcon {
|
||||
if (airport.category === AirportCategory.HELIPORT) {
|
||||
return L.divIcon({
|
||||
html: `
|
||||
<div style="
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
border-radius: 50%;
|
||||
border: 2px solid black;
|
||||
background-color: white;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;">
|
||||
<span style="color: black; font-size: 8px; font-weight: bold;">H</span>
|
||||
</div>
|
||||
`,
|
||||
className: '',
|
||||
iconSize: [20, 20],
|
||||
iconAnchor: [10, 10]
|
||||
});
|
||||
} else {
|
||||
// Default to a filled circle.
|
||||
const flightCategory = airport.latest_metar?.flight_category || 'UNKN';
|
||||
const color = getMarkerColor(flightCategory);
|
||||
if (flightCategory == 'UNKN') {
|
||||
return L.divIcon({
|
||||
html: `
|
||||
<div style="
|
||||
background-color: ${color};
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 50%;">
|
||||
</div>
|
||||
`,
|
||||
className: '',
|
||||
iconSize: [20, 20],
|
||||
iconAnchor: [10, 10]
|
||||
});
|
||||
} else {
|
||||
return L.divIcon({
|
||||
html: `
|
||||
<div style="
|
||||
background-color: ${color};
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
border-radius: 50%;
|
||||
border: 2px solid #fff;">
|
||||
</div>
|
||||
`,
|
||||
className: '',
|
||||
iconSize: [20, 20],
|
||||
iconAnchor: [10, 10]
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,7 +137,7 @@ export function Header() {
|
||||
<Group align='center' gap='xs'>
|
||||
<Burger opened={opened} onClick={toggle} hiddenFrom='xs' size='sm' />
|
||||
<Avatar src='/logo.svg' alt='logo' />
|
||||
<Text>FlightLink</Text>
|
||||
<Text>Aviation Data</Text>
|
||||
</Group>
|
||||
{/*<Group gap={5} visibleFrom='xs' className={classes.navGroup}>*/}
|
||||
{/* {navItems}*/}
|
||||
|
||||
Reference in New Issue
Block a user