Have you ever been in a situation where you wanted to inspect the distance between two points on a map? Not the distance by roads and rail networks but the direct distance? Maybe you weren’t but are you curious to know how you can do it?
Let’s think of a food delivery app where a customer accesses the app and then orders food. Next, a delivery partner picks up the order from the restaurant from where the customer has placed his online order and goes out to deliver it to the customer. Now, the delivery partner could press the button in the app to inform that he has reached the delivery location without even reaching the actual location which may confuse the customer about the whereabouts of their order. Such issues could jeopardize location-based services like cab booking and parcel delivery.
In this blog, I will talk about solving such distance-related problems. Let me explain it in detail.
The Solution: Haversine Formula
Here’s a simple trick on how we can calculate the distance. It’s pretty quick, easy, and accessible. One of the simple solutions is to calculate the radial distance between both the locations and enforce a distance check on these actions.
Radial distance is a distance measured by a straight line drawn between both the locations, ignoring all the roads and trails. In a sci-fi or a war movie, you might have seen a screen with warplanes appearing on the radar and closing in on the location. The distance shown on the screen is measured by drawing a straight line from the warplane to the radar location; this distance is the radial distance between these points.
What is the haversine formula and how to use it?
We can use the haversine formula to calculate the distance between two coordinates. To do so, first, we need to calculate the radial distance between any two points on a sphere using the haversine formula.
But talking about our planet earth, it is not a perfect sphere. It is an oblate spheroid from which getting accurate results is quite difficult.
The haversine formula works perfectly in practical cases with relatively short distances, and by short distances, I mean a few hundred kilometers. The haversine formula is an old equation used by navigators before the invention of modern-day navigation systems. However, you can use it to calculate distances on land as well.
Let’s have a look at the haversine formula:
a = sin²(Δφ/2) + cos φ1 ⋅ cos φ2 ⋅ sin²(Δλ/2)
c = 2 ⋅ atan2( √a, √(1−a) )
Distance = R ⋅ c
Here, φ is latitude, λ is longitude, R is earth’s radius (mean radius = 6,371km).
Visit this page for all the technical definitions. I have implemented the haversine formula in TypeScript below.
export interface Coordinates {
latitude: number;
longitude: number;
}
const getRadiansFromDegrees = (degrees: number) => {
return (degrees * Math.PI) / 180;
};
export const calculateRadialDistanceBetweenCoordinates = (
sourceCoordinates: Coordinates,
destinationCoordinates: Coordinates
) => {
const EARTH_RADIUS_IN_METERS = 6371e3;
const sourceLatitudeInRadians = getRadiansFromDegrees(
sourceCoordinates.latitude
);
const destinationLatitudeInRadians = getRadiansFromDegrees(
destinationCoordinates.latitude
);
const latitudeDifference = getRadiansFromDegrees(
destinationCoordinates.latitude – sourceCoordinates.latitude
);
const longitudeDifference = getRadiansFromDegrees(
destinationCoordinates.longitude – sourceCoordinates.longitude
);
const haversineOfCentralAngle =
Math.pow(Math.sin(latitudeDifference / 2), 2) +
Math.cos(sourceLatitudeInRadians) *
Math.cos(destinationLatitudeInRadians) *
Math.pow(Math.sin(longitudeDifference / 2), 2);
const centralAngle =
2 *
Math.atan2(
Math.sqrt(haversineOfCentralAngle),
Math.sqrt(1 – haversineOfCentralAngle)
);
const distanceInMeters = EARTH_RADIUS_IN_METERS * centralAngle;
return Number(distanceInMeters.toFixed(3));
};
We can just add a simple function to check if the delivery partner is within the allowed distance or not, like the one mentioned below.
export const isDeliveryPartnerInAllowedRange = (
sourceCoordinates: Coordinates,
destinationCoordinates: Coordinates,
allowedMaxDistanceInMeters: number
) => {
const radialDistanceInMeters = calculateRadialDistanceBetweenCoordinates(
sourceCoordinates,
destinationCoordinates
);
if (radialDistanceInMeters > allowedMaxDistanceInMeters) {
return false;
}
return true;
};
Add about 0.3% error margin in the total distance allowed so that you don’t get false negatives.
Final Thoughts
The haversine formula discussed above is an effortless and cost-effective way to calculate the proper distance between two points and it doesn’t need internet connectivity. I have hosted the above snippet in this GitHub gist. You should try the haversine formula and see the results for yourself. Do share your experience with us in the comments section.