* Refactor aircraft photo and hero banner components to reset loading state on photo change - Updated Lightbox component to reset image loading state when navigating between photos. - Modified HeroBanner component to reset loading state when the photo changes. Clean up control panel search logic - Removed unnecessary hasResults variable in SearchContent component. Implement flight API client with fallback mechanism - Added flight-api-client to handle fetching flight data from multiple sources (airplanes.live, adsb.lol, OpenSky). - Introduced flight-api-parsing module to convert raw API responses into standardized FlightState objects. - Created flight-api-types for shared types between API responses. Refactor useFlights hook to utilize new flight API client - Updated useFlights hook to fetch flights using the new flight API client. - Removed credit management logic as it is no longer applicable with the new API structure. Fix useFlightMonitors to fetch flight data by hex address - Changed useFlightMonitors to use fetchFlightByHex instead of fetchFlightByIcao24. Update geo utility function for better readability - Refactored splitAtAntimeridian function to improve variable naming and clarity. Enhance OpenSky types with additional fields - Added typeCode and registration fields to FlightState type for better integration with readsb data. * fix: correct 6 files that diverged during rebase (iata code, globe mode ref, terrain attribution, cache eviction, opensky parsing) * fix: improve keyboard shortcuts help focus trapping feat: add showAirspace option to MapAttribution component fix: clear hideTimer on ScrollArea cleanup refactor: change pendingFpvRef to MutableRefObject in useFlightMonitors fix: handle sessionStorage availability in useFlightTrack refactor: increase POLL_INTERVAL_MS in useFlights for better performance fix: optimize keyboard shortcuts dialog check refactor: optimize useMergedTrails by caching selected flight position feat: extend Settings type with airspace options refactor: improve airline logo normalization functions refactor: enhance flight API client with serialized rate limiting refactor: optimize registration country lookup with pre-built maps refactor: enhance logo cache management with size limits feat: update map attribution to include airspace option fix: validate rawState in parseStateRow function refactor: improve utility functions with clamp implementation * feat: add ATC lookup functionality and GPU memory monitoring - Implemented ATC lookup functions in `atc-lookup.ts` for converting IATA to ICAO codes, finding nearby ATC feeds, and looking up ATC feeds by code. - Introduced `atc-types.ts` to define types and priorities for ATC feeds. - Added GPU memory monitoring in `gpu-memory-monitor.ts` to track WebGL resource allocations and provide memory reports. - Enhanced trail stitching logic in `trail-stitching.ts` by adding a function to clear the splined track cache and optimizing altitude checks. * feat: enhance flight data handling and improve API resilience - Implemented a maximum empty response streak guard in useFlights to prevent data loss during transient API failures. - Added immediate fetch on network reconnect in useFlights to ensure timely data retrieval. - Updated useMergedTrails to include timestamps for trail points. - Removed smoothAnimations setting from useSettings as it is no longer needed. - Enhanced useTrailHistory to preserve last-known trails during empty flight responses and added dynamic jump detection for tab resume scenarios. - Improved flight API client with a circuit breaker mechanism to handle provider failures and prevent excessive retries. - Updated flight API parsing to reject non-JSON responses from OpenSky and other providers. - Enhanced trail smoothing and stitching logic to ensure better continuity at junctions between historical and live data. * feat: migrate aircraft models to Cloudinary CDN and update mapping logic * fix: adjust UI component styles and improve trail smoothing parameters * fix: adjust base aircraft size for improved rendering * feat: update changelog with recent enhancements and modify data source attribution * fix: update model optimization details and remove Draco compression dependency * feat: update changelog with recent code review fixes and fallback provider adjustments
This commit is contained in:
@ -48,33 +48,51 @@ export function adaptiveDownsample(
|
||||
return bestResult;
|
||||
}
|
||||
|
||||
/** Ramer-Douglas-Peucker simplification for 3D points. */
|
||||
/** Iterative Ramer-Douglas-Peucker simplification for 3D points.
|
||||
* Uses an explicit stack instead of recursion to avoid stack overflow
|
||||
* on trails with 5000+ points, and eliminates per-call .slice() allocations. */
|
||||
function rdpSimplify(
|
||||
points: ElevatedPoint[],
|
||||
epsilon: number,
|
||||
): ElevatedPoint[] {
|
||||
if (points.length <= 2) return points.slice();
|
||||
const n = points.length;
|
||||
if (n <= 2) return points.slice();
|
||||
|
||||
const first = points[0];
|
||||
const last = points[points.length - 1];
|
||||
let maxDist = 0;
|
||||
let maxIdx = 0;
|
||||
const keep = new Uint8Array(n);
|
||||
keep[0] = 1;
|
||||
keep[n - 1] = 1;
|
||||
|
||||
for (let i = 1; i < points.length - 1; i++) {
|
||||
const d = perpendicularDistance(points[i], first, last);
|
||||
if (d > maxDist) {
|
||||
maxDist = d;
|
||||
maxIdx = i;
|
||||
// Explicit stack of [startIndex, endIndex] ranges to process
|
||||
const stack: [number, number][] = [[0, n - 1]];
|
||||
|
||||
while (stack.length > 0) {
|
||||
const [start, end] = stack.pop()!;
|
||||
let maxDist = 0;
|
||||
let maxIdx = start;
|
||||
|
||||
const first = points[start];
|
||||
const last = points[end];
|
||||
|
||||
for (let i = start + 1; i < end; i++) {
|
||||
const d = perpendicularDistance(points[i], first, last);
|
||||
if (d > maxDist) {
|
||||
maxDist = d;
|
||||
maxIdx = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (maxDist > epsilon) {
|
||||
keep[maxIdx] = 1;
|
||||
if (maxIdx - start > 1) stack.push([start, maxIdx]);
|
||||
if (end - maxIdx > 1) stack.push([maxIdx, end]);
|
||||
}
|
||||
}
|
||||
|
||||
if (maxDist > epsilon) {
|
||||
const left = rdpSimplify(points.slice(0, maxIdx + 1), epsilon);
|
||||
const right = rdpSimplify(points.slice(maxIdx), epsilon);
|
||||
return [...left.slice(0, -1), ...right];
|
||||
const result: ElevatedPoint[] = [];
|
||||
for (let i = 0; i < n; i++) {
|
||||
if (keep[i]) result.push(points[i]);
|
||||
}
|
||||
|
||||
return [first, last];
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Perpendicular distance from a point to a line segment (2D, using lng/lat). */
|
||||
|
||||
Reference in New Issue
Block a user