In my attempt to visually represent an airport and its airspace using an SVG, I have encountered a persistent issue with the y-axis and its conversion. Despite verifying the coordinates multiple times, the positioning of the lines representing the runways (09L/27R above 09R/27L) and the placement of LON above both lines seem to be incorrect. Is there a specific technique or logic that can be applied in SVG to address this discrepancy?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Radar Screen</title>
<style>
body {
margin: 0;
padding: 0;
overflow: hidden; /* Prevent scrolling */
}
#radar-container {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
}
svg {
width: 100%; /* Take full width of container */
height: 100%; /* Take full height of container */
border: 1px solid black;
}
</style>
</head>
<body>
<div id="radar-container">
<svg id="radar-svg">
<!-- Runways, waypoints, and airport will be dynamically drawn here -->
</svg>
</div>
<script>
// Function to convert latitude and longitude to screen coordinates
function convertCoordinates(latitude, longitude) {
// Airport coordinates
const airportLatitude = 51.4775; // Decimal degrees
const airportLongitude = -0.46139; // Decimal degrees
// Calculate center of SVG based on airport coordinates
const centerX = window.innerWidth / 2;
const centerY = window.innerHeight / 2;
// Assume some mapping between latitude and y-axis, and longitude and x-axis
// You may need to adjust these calculations based on your specific mapping
const scaleFactor = 2000; // Adjust based on the scale of your radar screen
const offsetX = centerX - (airportLongitude * scaleFactor);
const offsetY = centerY - (airportLatitude * scaleFactor);
const screenX = (longitude * scaleFactor) + offsetX;
const screenY = (latitude * scaleFactor) + offsetY;
return { x: screenX, y: screenY };
}
// Waypoint coordinates
const waypointCoordinates = [
{ name: "LON", latitude: 51.4861, longitude: -0.4666 },
];
// Runway coordinates
const runwayCoordinates = [
{ id: "27R", start: { latitude: 51.4776, longitude: -0.4332 }, end: { latitude: 51.4775, longitude: -0.4849 }},
{ id: "09L", start: { latitude: 51.4775, longitude: -0.4849 }, end: { latitude: 51.4776, longitude: -0.4332 }},
{ id: "09R", start: { latitude: 51.4647, longitude: -0.4823 }, end: { latitude: 51.4655, longitude: -0.4341 }},
{ id: "27L", start: { latitude: 51.4655, longitude: -0.4341 }, end: { latitude: 51.4647, longitude: -0.4823 }}
];
// Get the SVG container
const svgContainer = document.getElementById('radar-svg');
// Function to draw waypoints
function drawWaypoints() {
// Draw new waypoints
waypointCoordinates.forEach(waypoint => {
const position = convertCoordinates(waypoint.latitude, waypoint.longitude);
console.log(`Waypoint ${waypoint.name} position: (${position.x}, ${position.y})`);
// Draw square representing waypoint
const square = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
square.setAttribute('x', position.x - 5); // Adjust position to center square
square.setAttribute('y', position.y - 5); // Adjust position to center square
square.setAttribute('width', 10);
square.setAttribute('height', 10);
square.setAttribute('fill', 'blue');
svgContainer.appendChild(square);
// Add label for the waypoint
const label = document.createElementNS('http://www.w3.org/2000/svg', 'text');
label.setAttribute('x', position.x + 10); // Offset label position
label.setAttribute('y', position.y - 10); // Offset label position
label.setAttribute('text-anchor', 'start'); // Align text to start of label
label.setAttribute('dominant-baseline', 'middle'); // Center the text vertically
label.setAttribute('font-family', 'Arial');
label.setAttribute('font-size', '12');
label.setAttribute('fill', 'black');
label.textContent = waypoint.name;
svgContainer.appendChild(label);
});
}
// Function to draw runways
function drawRunways() {
// Draw new runways
runwayCoordinates.forEach(runway => {
const start = convertCoordinates(runway.start.latitude, runway.start.longitude);
const end = convertCoordinates(runway.end.latitude, runway.end.longitude);
console.log(`Runway ${runway.id} start: (${start.x}, ${start.y})`);
console.log(`Runway ${runway.id} end: (${end.x}, ${end.y})`);
const line = document.createElementNS('http://www.w3.org/2000/svg', 'line');
line.setAttribute('x1', start.x);
line.setAttribute('y1', start.y);
line.setAttribute('x2', end.x);
line.setAttribute('y2', end.y);
line.setAttribute('stroke', 'black');
line.setAttribute('stroke-width', '2');
svgContainer.appendChild(line);
// Add label
const label = document.createElementNS('http://www.w3.org/2000/svg', 'text');
label.setAttribute('x', start.x + 10); // Offset label position
label.setAttribute('y', start.y - 10); // Offset label position
label.setAttribute('text-anchor', 'start'); // Align text to start of label
label.setAttribute('dominant-baseline', 'middle'); // Center the text vertically
label.setAttribute('font-family', 'Arial');
label.setAttribute('font-size', '12');
label.setAttribute('fill', 'black');
label.textContent = runway.id;
svgContainer.appendChild(label);
});
}
// Draw waypoints and runways initially
drawWaypoints();
drawRunways();
</script>
</body>
</html>
In my attempt to address the inverted Y-axis issue, I experimented with:
const screenY = -(latitude * scaleFactor) + offsetY;
Despite thorough verification of the coordinates, the problem persists.