Skip to content

Commit

Permalink
Merge pull request #10 from vatger/dev
Browse files Browse the repository at this point in the history
v2.1.0 - filter EDYY sectors & declutter map tables
  • Loading branch information
LeoKle authored Aug 4, 2023
2 parents 8f111c4 + 6323e10 commit 84b8e09
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 35 deletions.
2 changes: 1 addition & 1 deletion backend/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "loa-viewer-backend",
"version": "2.0.1",
"version": "2.1.0",
"description": "",
"main": "app.js",
"scripts": {
Expand Down
5 changes: 5 additions & 0 deletions frontend/src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,9 @@

.custom-icon {
color: white;
}

.background-black {
background-color: rgb(10,10,10);
color: white;
}
6 changes: 5 additions & 1 deletion frontend/src/components/Map.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,11 @@ export default function LoaViewerMap() {
for (const airspace of airspaces) {
if (airspace.group === selectedFir) {
const owner = airspace.owner[0];
if (!owner.includes('_')) {
// filter approach stations not belonging to vACC Germany - all approach sectors are not using Vatsim callsigns i.e. no _ in their name
const isNonGermanApproachStation = owner.includes('_');
// filter Maastricht Sectors belonging to vACC Germany - sectors belonging to vACC Germany have 3 or more characters
const isGermanMaastrichtSector = owner.length > 2;
if (!isNonGermanApproachStation && isGermanMaastrichtSector) {
stationsSet.add(owner);
}
}
Expand Down
145 changes: 112 additions & 33 deletions frontend/src/components/Markers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,72 @@ import { WaypointRecord } from 'interfaces/waypointRecord.interface';
import location from '../img/location.png';
import React from 'react';

interface ExtendedWaypointRecord extends WaypointRecord {
drawn: boolean;
zIndex: number;
}

function Markers({ conditions }: { conditions: WaypointRecord[] }) {
const [drawnConditions, setDrawnConditions] = useState<ExtendedWaypointRecord[]>([]);
const [countConditionsDrawn, setCountConditionsDrawn] = useState<Number>(0);

useEffect(() => {
setDrawnConditions(
conditions.map(condition => {
return {
...condition,
drawn: false,
zIndex: 0,
};
})
);
}, [conditions]);

const map = useMap();
const [zoom, setZoom] = useState<number>(map.getZoom());
const [MarkerIcon, setMarkerIcon] = useState<Icon>();

const handleMarkerClick = (name: string) => {
const copy = drawnConditions.map(condition => {
if (condition.waypoint.name === name) {
if (condition.drawn === true && condition.zIndex === 0) {
if (countConditionsDrawn === 1) {
condition.drawn = false;
} else {
condition.zIndex = 1001;
}
} else if (condition.drawn === true) {
condition.drawn = false;
condition.zIndex = 0;
} else {
condition.drawn = true;
condition.zIndex = 1001;
}
} else {
condition.zIndex = 0;
}
// console.log(condition.waypoint.name + ' ' + condition.zIndex);
return condition;
});
setDrawnConditions(copy);

setCountConditionsDrawn(
drawnConditions.reduce((count, condition) => {
if (condition.drawn === true) {
return count + 1;
} else {
return count;
}
}, 0)
);
};

useMapEvent('zoomend', () => {
setZoom(map.getZoom());
});

useEffect(() => {
const IconSize = 1 / zoom + 15;
const IconSize = 1 / (zoom * 2) + 15;
setMarkerIcon(
new Icon({
iconUrl: location,
Expand All @@ -29,21 +84,45 @@ function Markers({ conditions }: { conditions: WaypointRecord[] }) {
return null; // Return null if there are no conditions to render
}

// Render markers based on the conditions
const markers = conditions.map((condition, index) => {
const { waypoint } = condition;
const { latitude, longitude } = waypoint;

// Render a marker using the latitude and longitude
return (
<React.Fragment key={index}>
<Marker position={[latitude, longitude]} key={`${waypoint.name}-marker`} icon={MarkerIcon} />
<Marker position={[latitude, longitude]} key={`${waypoint.name}-table`} icon={MarkerConditionTable(condition, zoom)} />
</React.Fragment>
);
});
return (
<>
{drawnConditions &&
drawnConditions.map(condition => {
const { waypoint } = condition;
const { latitude, longitude } = waypoint;
if (condition.drawn) {
return (
<React.Fragment key={`drawn-${waypoint.name}`}>
<Marker key={`${waypoint.name}`} position={[latitude, longitude]} icon={MarkerNameWidget(waypoint.name)} eventHandlers={{ click: () => handleMarkerClick(waypoint.name) }} zIndexOffset={condition.zIndex} />
<Marker key={`${waypoint.name}-marker`} position={[latitude, longitude]} icon={MarkerIcon} eventHandlers={{ click: () => handleMarkerClick(waypoint.name) }} zIndexOffset={condition.zIndex} />
<Marker
key={`${waypoint.name}-table`}
position={[latitude, longitude]}
icon={MarkerConditionTable(condition, zoom)}
eventHandlers={{ click: () => handleMarkerClick(waypoint.name) }}
zIndexOffset={condition.zIndex}
/>
</React.Fragment>
);
}

return <>{markers}</>;
return (
<React.Fragment key={`not-drawn-${waypoint.name}`}>
<Marker key={`${waypoint.name}`} position={[latitude, longitude]} icon={MarkerNameWidget(waypoint.name)} eventHandlers={{ click: () => handleMarkerClick(waypoint.name) }} />;
<Marker key={`${waypoint.name}-marker`} position={[latitude, longitude]} icon={MarkerIcon} eventHandlers={{ click: () => handleMarkerClick(waypoint.name) }} />{' '}
</React.Fragment>
);
})}
</>
);
}

function MarkerNameWidget(name: string) {
return new DivIcon({
className: 'Marker',
iconAnchor: [-10, 20],
html: renderToStaticMarkup(<span style={{ fontWeight: 'normal', fontSize: 13 }}>{name}</span>),
});
}

function MarkerConditionTable(condition: WaypointRecord, zoom: number) {
Expand Down Expand Up @@ -79,41 +158,41 @@ function ConditionTableIcon({ zoom, conditions }: PropsTable) {
<thead>
<tr>
<th className="center" colSpan={columnSpan} />
<th className="center line" colSpan={2}>
<th className="center line background-black" colSpan={2}>
Sector
</th>
<th className="center line " colSpan={2}>
<th className="center line background-black " colSpan={2}>
FIR
</th>
</tr>
<tr>
<th className="line">AD</th>
<th className="line">COP</th>
<th className="line">Level</th>
{hasSpecialConditions ? <th className="line">Special Conditions</th> : null}
<th className="line">From</th>
<th className="line">To</th>
<th className="line">From</th>
<th className="line">To</th>
<th className="line background-black background-black">AD</th>
<th className="line background-black">COP</th>
<th className="line background-black">Level</th>
{hasSpecialConditions ? <th className="line background-black">Special Conditions</th> : null}
<th className="line background-black">From</th>
<th className="line background-black">To</th>
<th className="line background-black">From</th>
<th className="line background-black">To</th>
</tr>
</thead>
<tbody>
{agreements.map((condition, index) => (
<tr key={index}>
<td className="line">
<td className="line background-black">
{condition.adep_ades === 'ADEP' ? '\u2191' : condition.adep_ades === 'ADES' ? '\u2193' : ''} {condition.aerodrome}
</td>
<td className="line">{condition.cop}</td>
<td className="line">
<td className="line background-black">{condition.cop}</td>
<td className="line background-black">
{condition.feet ? 'A' : 'FL'}
{condition.level}
{condition.xc}
</td>
{hasSpecialConditions ? <td className="line">{condition.special_conditions}</td> : null}
<td className="line">{condition.from_sector}</td>
<td className="line">{condition.to_sector}</td>
<td className="line">{condition.from_fir}</td>
<td className="line">{condition.to_fir}</td>
{hasSpecialConditions ? <td className="line background-black">{condition.special_conditions}</td> : null}
<td className="line background-black">{condition.from_sector}</td>
<td className="line background-black">{condition.to_sector}</td>
<td className="line background-black">{condition.from_fir}</td>
<td className="line background-black">{condition.to_fir}</td>
</tr>
))}
</tbody>
Expand Down

0 comments on commit 84b8e09

Please sign in to comment.