UNPKG

smarteta

Version:

Smart urban ETA estimator based on time, distance, vehicle type and real-world corrections

63 lines (62 loc) 2.87 kB
"use strict"; // smart_eta/src/index.ts Object.defineProperty(exports, "__esModule", { value: true }); exports.estimateSmartETA = estimateSmartETA; // Helper function for Haversine distance calculation function haversineDistance(coords1, coords2) { const R = 6371; // Earth's radius in kilometers const dLat = (coords2[0] - coords1[0]) * Math.PI / 180; const dLon = (coords2[1] - coords1[1]) * Math.PI / 180; const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(coords1[0] * Math.PI / 180) * Math.cos(coords2[0] * Math.PI / 180) * Math.sin(dLon / 2) * Math.sin(dLon / 2); const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); return R * c; // Distance in km } function estimateSmartETA(input) { // Helper function for additional delays function extraDelay(vehicleType, isUrban, distanceKm) { if (isUrban && distanceKm < 6) return vehicleType === 'car' ? 4 : 2; // For short urban trips return vehicleType === 'car' ? 1 : 0.5; // Reduced for inter-city to avoid overestimation } // 1. Input reception const start = [input.startLat, input.startLng]; const end = [input.endLat, input.endLng]; const vehicleType = input.vehicleType; // 'car' or 'scooter' const now = input.now instanceof Date ? input.now : new Date(); const urbanOverride = input.urbanOverride; // 2. Calculate air distance in km const distanceKm = haversineDistance(start, end); // 3. Determine if urban trip const isUrban = typeof urbanOverride === 'boolean' ? urbanOverride : distanceKm < 15; // 4. Determine base speed based on distance and time of day const hour = now.getHours() + now.getMinutes() / 60; let baseSpeed; if (distanceKm > 40) { // Tuned for ~47 km (Be'er Sheva to Ashdod) to take ~60 minutes baseSpeed = vehicleType === 'car' ? 48 : 55; // Adjusted from 45 to 48 km/h } else if (distanceKm < 6) { // Tuned for ~5 km (within Be'er Sheva) to take ~15 minutes baseSpeed = vehicleType === 'car' ? 20 : 25; } else { // Fallback for other distances baseSpeed = vehicleType === 'car' ? 30 : 40; } // 5. Day-of-week correction (Wednesday/Thursday busier) const day = now.getDay(); // 0 = Sunday, ..., 6 = Saturday const speedCorrectionFactor = day === 3 || day === 4 ? 0.95 : 1.0; const correctedSpeed = baseSpeed * speedCorrectionFactor; // 6. Calculate base ETA let baseETA = (distanceKm / correctedSpeed) * 60 + extraDelay(vehicleType, isUrban, distanceKm); // 7. Ensure minimum time baseETA = Math.max(baseETA, 2); // 8. Add deviation range return { min: Math.round(Math.max(baseETA * 0.9, 2) * 10) / 10, avg: Math.round(baseETA * 10) / 10, max: Math.round(Math.max(baseETA * 1.1, 2.1) * 10) / 10 }; }