journeyPoints = {
const stepMinutes = 5;
const legs = journey.map((leg) => {
let spaceInterpolator = d3.geoInterpolate(
[leg.start.airport.longitude, leg.start.airport.latitude],
[leg.end.airport.longitude, leg.end.airport.latitude]
);
let timeInterpolate = d3
.scaleLinear()
.domain([0, 1])
.range([+leg.start.time, +leg.end.time]);
let legPoints = [];
for (
let time = leg.start.time;
time <= leg.end.time;
time = d3.utcMinute.offset(time, stepMinutes)
) {
const t = timeInterpolate.invert(time);
let [longitude, latitude] = spaceInterpolator(t);
legPoints.push({
time: new Date(timeInterpolate(t)),
longitude,
latitude,
type: "flying"
});
}
return legPoints;
});
let allPoints = [...legs[0]];
for (let [i, leg] of legs.entries()) {
if (i === 0) continue;
let start = journey[i - 1].end.time;
let end = journey[i].start.time;
let airport = journey[i].start.airport;
for (
let cursor = start;
cursor < end;
cursor = d3.timeMinute.offset(cursor, stepMinutes)
) {
allPoints.push({
time: cursor,
longitude: airport.longitude,
latitude: airport.latitude,
type: "layover"
});
}
allPoints = [...allPoints, ...leg];
}
let lastLeg = journey.at(-1);
allPoints.push({
time: lastLeg.end.time,
longitude: lastLeg.end.airport.longitude,
latitude: lastLeg.end.airport.latitude
});
return pipe(
allPoints,
($) =>
$.map((d) => ({
...d,
sun: suncalc.getPosition(d.time, d.latitude, d.longitude)
})),
($) =>
$.map((d) => ({
time: d.time,
longitude: d.longitude,
latitude: d.latitude,
sunAzimuth: (d.sun.azimuth / Math.PI) * 180,
sunAltitude: (d.sun.altitude / Math.PI) * 180,
type: d.type
}))
);
return allPoints;
}