技术问询:能否基于机场跑道地理坐标计算offset-angle等参数?
offset-angle, offset-x, and offset-y from Runway Geographic Coordinates Absolutely! You can derive these SVG positioning parameters directly from your runway's latitude/longitude data. Here's a step-by-step breakdown tailored to your svg-airports setup:
1. Clarify Parameter Context
First, let's make sure we're on the same page about what each svg-airports parameter does:
true-heading: The actual geographic bearing of the runway (you already have a solid function to calculate this).offset-angle: The rotation angle applied to align the runway (or entire airport diagram) with the SVG canvas's coordinate system.offset-x/offset-y: The position of the runway's reference point (usually its center) relative to theairport-diagramelement's origin, measured in feet.
2. Step 1: Convert Geographic Coordinates to Local Plane Coordinates
Latitude/longitude are spherical coordinates, so we first convert them to a local planar system to calculate distances and relative positions in feet:
a. Pick a Reference Point
Choose a fixed origin for your airport (e.g., the start point of your first runway: runways[0].latitude1, runways[0].longitude1). This will act as the (0,0) point for your local plane calculations.
b. Calculate Relative Planar Coordinates
Use this function to compute any point's east-west (x) and north-south (y) distance from your reference point, converted to feet:
function radians(n) { return n * (Math.PI / 180); } const METERS_TO_FEET = 3.28084; const METERS_PER_DEG_LAT = 111319.9; // Approx meters per degree latitude function getLocalCoordinates(lat, lon, refLat, refLon) { // East (x) distance: meters per degree longitude depends on latitude const metersPerDegLon = METERS_PER_DEG_LAT * Math.cos(radians(refLat)); const xMeters = (lon - refLon) * metersPerDegLon; // North (y) distance const yMeters = (lat - refLat) * METERS_PER_DEG_LAT; // Convert to feet return { x: xMeters * METERS_TO_FEET, y: yMeters * METERS_TO_FEET }; }
c. Compute Runway Center Coordinates
For each runway, calculate its center point's local coordinates (this will be our reference for offset-x/offset-y):
function getRunwayCenter(runway) { const centerLat = (runway.latitude1 + runway.latitude2) / 2; const centerLon = (runway.longitude1 + runway.longitude2) / 2; return { lat: centerLat, lon: centerLon }; } // Example usage with your sample runways const refPoint = { lat: runways[0].latitude1, lon: runways[0].longitude1 }; const runway0Center = getRunwayCenter(runways[0]); const runway0Offset = getLocalCoordinates(runway0Center.lat, runway0Center.lon, refPoint.lat, refPoint.lon); // runway0Offset.x and runway0Offset.y are your raw offset values
3. Step 2: Calculate offset-angle
SVG uses a top-left origin with x-axis right and y-axis downward, while geographic headings are measured clockwise from true north. To align your runway's true-heading with the SVG canvas, use this formula (which matches your sample's 119° true heading → 29° offset angle):
function getOffsetAngle(trueHeading) { // Convert true north-based heading to SVG's right-aligned rotation return (trueHeading - 90) % 360; }
Testing this with your sample: 119 - 90 = 29, which perfectly matches the offset-angle in your example SVG.
4. Step 3: Adjust Offsets for SVG's Y-Axis
Since SVG's y-axis increases downward (opposite of our northward planar y-axis), invert the y-offset value to get the correct SVG position:
const runway0OffsetSVG = { x: runway0Offset.x, y: -runway0Offset.y // Flip y for SVG's downward axis };
5. Full Implementation for Your Sample Runways
Here's how to generate all parameters dynamically for your data:
// Process first runway const runway1 = runways[0]; const trueHeading1 = getBearing(runway1.latitude1, runway1.longitude1, runway1.latitude2, runway1.longitude2); const center1 = getRunwayCenter(runway1); const offset1 = getLocalCoordinates(center1.lat, center1.lon, refPoint.lat, refPoint.lon); const offsetAngle1 = (trueHeading1 - 90) % 360; // Process second runway const runway2 = runways[1]; const trueHeading2 = getBearing(runway2.latitude1, runway2.longitude1, runway2.latitude2, runway2.longitude2); const center2 = getRunwayCenter(runway2); const offset2 = getLocalCoordinates(center2.lat, center2.lon, refPoint.lat, refPoint.lon); const offsetAngle2 = (trueHeading2 - 90) % 360;
You can now plug these values directly into your <airport-runway> elements.
Quick Notes
- For larger airports or higher precision, replace the planar approximation with the UTM projection (it converts latitude/longitude to precise east/north coordinates in meters, which you can still convert to feet).
- If you want all runways to share the same
offset-angle, use the true heading of your main runway as the reference for all calculations.
内容的提问来源于stack exchange,提问作者Hatem Alimam

