Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
95ed0e339f | ||
|
|
28fd782a40 |
@@ -370,10 +370,34 @@ export default defineComponent({
|
|||||||
link.click()
|
link.click()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function loopPoints(origin: LngLat, radiusDeg = 0.2, steps = 48): LngLat[] {
|
||||||
|
const [lng, lat] = origin
|
||||||
|
|
||||||
|
// Widen the longitude radius to compensate for mercator distortion at this latitude
|
||||||
|
const lngRadius = radiusDeg / Math.max(Math.cos(lat * Math.PI / 180), 0.15)
|
||||||
|
|
||||||
|
// Center the loop above the origin so the airport point sits at the bottom of the loop
|
||||||
|
const centerLat = lat + radiusDeg
|
||||||
|
|
||||||
|
const points: LngLat[] = []
|
||||||
|
for (let i = 0; i <= steps; i++) {
|
||||||
|
const theta = (i / steps) * Math.PI * 2
|
||||||
|
points.push([
|
||||||
|
lng + Math.sin(theta) * lngRadius,
|
||||||
|
centerLat - radiusDeg * Math.cos(theta),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
return points // first and last point === origin, at the bottom of the loop
|
||||||
|
}
|
||||||
|
|
||||||
const getArc = (flight: Flight): LngLat[] => {
|
const getArc = (flight: Flight): LngLat[] => {
|
||||||
const key = routeKey(flight.departure_airport, flight.arrival_airport)
|
const key = routeKey(flight.departure_airport, flight.arrival_airport)
|
||||||
if (!arcCache.has(key)) {
|
if (!arcCache.has(key)) {
|
||||||
arcCache.set(key, greatCirclePoints(
|
const isSameAirport = flight.departure_airport.id === flight.arrival_airport.id
|
||||||
|
|
||||||
|
arcCache.set(key, isSameAirport
|
||||||
|
? loopPoints([flight.departure_airport.longitude_deg, flight.departure_airport.latitude_deg])
|
||||||
|
: greatCirclePoints(
|
||||||
[flight.departure_airport.longitude_deg, flight.departure_airport.latitude_deg],
|
[flight.departure_airport.longitude_deg, flight.departure_airport.latitude_deg],
|
||||||
[flight.arrival_airport.longitude_deg, flight.arrival_airport.latitude_deg],
|
[flight.arrival_airport.longitude_deg, flight.arrival_airport.latitude_deg],
|
||||||
))
|
))
|
||||||
@@ -666,8 +690,10 @@ export default defineComponent({
|
|||||||
? { top: 20, bottom: 20, left: 55, right: 55 }
|
? { top: 20, bottom: 20, left: 55, right: 55 }
|
||||||
: { top: 60, bottom: 60, left: 60, right: 60 }
|
: { top: 60, bottom: 60, left: 60, right: 60 }
|
||||||
|
|
||||||
const lngs = props.flights.flatMap(f => [f.departure_airport.longitude_deg, f.arrival_airport.longitude_deg])
|
// Use full arc/loop geometry, not just endpoints, so loops aren't clipped
|
||||||
const lats = props.flights.flatMap(f => [f.departure_airport.latitude_deg, f.arrival_airport.latitude_deg])
|
const allPoints = props.flights.flatMap(getArc)
|
||||||
|
const lngs = allPoints.map(p => p[0])
|
||||||
|
const lats = allPoints.map(p => p[1])
|
||||||
|
|
||||||
const minLat = Math.min(...lats)
|
const minLat = Math.min(...lats)
|
||||||
const maxLat = Math.max(...lats)
|
const maxLat = Math.max(...lats)
|
||||||
@@ -689,7 +715,6 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
map!.fitBounds([[minLng, minLat], [maxLng, maxLat]], { padding, duration: 0 })
|
map!.fitBounds([[minLng, minLat], [maxLng, maxLat]], { padding, duration: 0 })
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Map init ──────────────────────────────────────────────────────────
|
// ── Map init ──────────────────────────────────────────────────────────
|
||||||
|
|
||||||
const initMap = (): void => {
|
const initMap = (): void => {
|
||||||
|
|||||||
Reference in New Issue
Block a user