← Back to blog

Building Auto-Close Trip Detection with the Haversine Formula

Node.jsGeofencingLogistics

One of the more satisfying problems I've worked on is automatically detecting when a delivery vehicle has arrived at its destination — without relying on the driver to tap "trip complete."

The problem

Drivers forget to close trips. Dispatchers end up manually closing dozens of trips at the end of the day based on guesswork. That breaks turnaround-time (TAT) reporting and delays billing.

The approach

Every vehicle in the fleet streams GPS coordinates at regular intervals via GTRAC/Fleetx hardware. Each trip has a destination geofence — a center point and radius.

For every incoming GPS ping, we calculate the distance between the vehicle's current location and the destination using the Haversine formula, which accounts for the Earth's curvature:

function haversineDistance(lat1, lon1, lat2, lon2) {
  const R = 6371e3; // Earth radius in meters
  const toRad = (deg) => (deg * Math.PI) / 180;

  const dLat = toRad(lat2 - lat1);
  const dLon = toRad(lon2 - lon1);

  const a =
    Math.sin(dLat / 2) ** 2 +
    Math.cos(toRad(lat1)) *
      Math.cos(toRad(lat2)) *
      Math.sin(dLon / 2) ** 2;

  const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
  return R * c; // distance in meters
}

Closing the loop

If a vehicle stays within the destination radius for a configurable dwell time (to avoid false triggers from a vehicle just passing through), the system marks the trip as complete, timestamps it, and pushes an update to the dashboard — all without manual intervention.

What this unlocked

Small formula, big operational impact.