UNPKG

mobility-toolbox-js

Version:

Toolbox for JavaScript applications in the domains of mobility and logistics.

75 lines (74 loc) 3.43 kB
import { LineString } from 'ol/geom'; /** * Interpolate or not the vehicle position from a trajectory at a specific date. * * @param {number} now Current date to interpolate a position with. In ms. * @param {RealtimeTrajectory} trajectory The trajectory to interpolate. * @param {boolean} noInterpolate If true, the vehicle position is not interpolated on each render but only once. * @returns {VehiclePosition} * @private */ const getVehiclePosition = (now, trajectory, noInterpolate) => { var _a; const { coordinate, olGeometry, rotation: oldRotation, time_intervals: timeIntervals, } = trajectory.properties; let { coordinates, type } = trajectory.geometry; let geometry = olGeometry; let coord; let rotation = oldRotation; // If an olGeometry exists we use it. It avoids to create one each time. if (geometry) { // @ts-expect-error improve types type = geometry.getType(); coordinates = (_a = geometry.getCoordinates()) !== null && _a !== void 0 ? _a : []; } if (noInterpolate && coordinate) { coord = coordinate; } else if (type === 'Point') { coord = coordinates; } else if (type === 'LineString') { geometry !== null && geometry !== void 0 ? geometry : (geometry = new LineString(coordinates)); const intervals = timeIntervals || [[]]; const firstInterval = intervals[0]; const lastInterval = intervals[intervals.length - 1]; // Between the last time interval of a trajectory event and the beginning // of the new trajectory event, there is few seconds, can be 6 to 30 // seconds (that's why the vehicle jumps sometimes). // So we make the choice here to display the last (or the first) position // of an trajectory event instead of removing them, if the current date is // outside the time intervals we display the vehicle at the last (or first) position known. if (now < firstInterval[0]) { // Display first position known. [, , rotation] = firstInterval; coord = geometry.getFirstCoordinate(); } else if (now > lastInterval[0]) { // Display last position known. [, , rotation] = lastInterval; coord = geometry.getLastCoordinate(); } else { // Interpolate position using time intervals. for (let j = 0; j < intervals.length - 1; j += 1) { // Rotation only available in realtime layer. const [start, startFrac] = intervals[j]; const [end, endFrac] = intervals[j + 1]; if (start <= now && now <= end) { // interpolate position inside the time interval. const timeFrac = Math.min((now - start) / (end - start), 1); const geomFrac = timeFrac * (endFrac - startFrac) + startFrac; coord = geometry === null || geometry === void 0 ? void 0 : geometry.getCoordinateAt(geomFrac); [, , rotation] = intervals[j]; break; } } } } else { // eslint-disable-next-line no-console console.error('This geometry type is not supported. Only Point or LineString are. Current geometry: ', geometry); } return { coord, rotation }; }; export default getVehiclePosition;