Photo by Maxim Hopman on Unsplash

How to Get Nearest Locations and Their Driving Distance and Time (Roughly) Without Using Google Maps or Any Other Providers — React JS/Next JS

Chathuranga CPM

--

In various scenarios, such as developing location-based applications or optimizing delivery routes, it’s often necessary to find the nearest locations to a given point and estimate the driving distance and time to reach them. While popular map providers like Google Maps offer robust APIs for such tasks, sometimes you may need a solution that doesn’t rely on external services. In this article, we’ll explore how to achieve this using basic geometric calculations and simple assumptions about driving speed.

  1. Calculating the Distance between Coordinates

The first step is to calculate the distance between two geographical coordinates. We’ll use the Haversine formula for this purpose, which provides reasonably accurate results for short to medium distances on a sphere like the Earth.

https://en.wikipedia.org/wiki/Haversine_formula

const calculateDistance = (point1, point2) => {
// Split each coordinate string into latitude and longitude values
const [lat1, lon1] = point1.split(",").map(parseFloat);
const [lat2, lon2] = point2.split(",").map(parseFloat);
// Convert degrees to radians for accurate distance calculation
const lat1Rad = lat1 * Math.PI / 180;
const lat2Rad = lat2 * Math.PI / 180;
const lon1Rad = lon1 * Math.PI / 180;
const lon2Rad = lon2 * Math.PI / 180;
// Implement the Haversine formula to calculate distance between points
const dLat = lat2Rad - lat1Rad;
const dLon = lon2Rad - lon1Rad;
const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(lat1Rad) * Math.cos(lat2Rad) *
Math.sin(dLon / 2) * Math.sin(dLon / 2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
const earthRadius = 6371; // Earth's radius in kilometers
return earthRadius * c; // Distance in kilometers
}

Here’s a breakdown of the code

  • The function takes two arguments: point1 and point2, both of which are strings representing the latitude and longitude of a point, separated by a comma (e.g. “37.7749, -122.4194” for San Francisco).
  • The function first splits the string representation of each point into separate latitude and longitude values using the split() method and parseFloat() function.
  • The latitude and longitude values are then converted from degrees to radians for use in the Haversine formula.
  • The Haversine formula is then implemented using the Math.sin(), Math.cos(), Math.atan2(), and Math.sqrt() functions to calculate the distance between the two points.
  • The distance is returned as a numeric value representing the distance in kilometers.

2. Sorting Locations by Distance

Once we have a function to calculate distances, the next step is to sort the locations based on their distances from a given reference point. We’ll also estimate the driving time to each location assuming a random average car speed(40–80).

const sortByDistance = (coordinates, currentCoordinate) => {
return coordinates.map((coord) => {
const distance = calculateDistance(coord, currentCoordinate);
// Estimate average car speed (considering potential variations)
const averageSpeed = Math.random() * (80 - 40) + 60; // Km/h (random between 40 and 80)
const estimatedDriveTime = distance / averageSpeed * 60; // Minutes (distance / speed * 60 minutes/hour)
return {
coordinates: coord,
distanceInKm: distance,
estimatedDriveTimeInMinutes: `${Math.round(estimatedDriveTime) + 1} to ${Math.round(estimatedDriveTime) + 5} min`, // Round to nearest minute
};
}).sort((obj1, obj2) => obj1.distanceInKm - obj2.distanceInKm);
}

This code defines a function called sortByDistance which takes in two parameters: coordinates (an array of coordinate objects, each containing latitude and longitude properties) and currentCoordinate (an object with the same structure).

The function performs the following steps:

  1. It invokes a hypothetical calculateDistance function to determine the distance in kilometers between each coordinate in coordinates and the currentCoordinate.
  2. For each coordinate, it estimates the driving time by dividing the distance by an average speed ranging from 40 to 80 km/h (calculated using Math.random() for randomness). The estimated drive time is then multiplied by 60 to convert it from hours to minutes.
  3. It returns a new array of objects, each containing the original coordinate, the distance to the currentCoordinate, and a string representation of the estimated drive time (rounded to the nearest minute).
  4. Finally, it sorts the resulting array in ascending order based on the distanceInKm property.

This function helps in sorting a list of coordinates based on their distance from a given point and provides a rough estimate of the drive time.

Note that the actual driving time might vary based on various factors like road conditions, traffic, and speed limits.

3. Implementation

Now, let’s put it all together. In this example, we’ll consider a set of predefined coordinates and a current coordinate, and then we’ll find the nearest locations along with their driving distances and estimated times.

useEffect(()=> {
const coordinates = [
"7.901608815706607, 79.98959996815196",
"7.864370228889747, 80.0007579570843",
"7.911566016234709, 80.03336183892753",
"7.878834434939188, 80.0255512466749"
];
const currentCoordinate = "7.877769789373152, 80.01097075196722";
const sortedCoordinates = sortByDistance(coordinates, currentCoordinate);
console.log(sortedCoordinates);
}, [])

useEffect hook from React to run a function when the component is mounted. The function does the following:

  1. Defines an array coordinates containing four pairs of latitude and longitude values, representing the locations of some points on a map.
  2. Defines a string currentCoordinate containing a pair of latitude and longitude values, representing the current location of an object or a user.
  3. Calls the sortByDistance function, passing coordinates and currentCoordinate as arguments. This function returns a new array of coordinates sorted by distance from the currentCoordinate.
  4. Logs the sorted array of coordinates to the console.

Final Sorted Coordinates Array

Here’s the final sortedCoordinates array with the updated estimated drive time range:

[
{"coordinates": "7.878834434939188, 80.0255512466749", "distanceInKm": 1.610331874489484, "estimatedDriveTimeInMinutes": "2 to 6 min"},
{"coordinates": "7.864370228889747, 80.0007579570843", "distanceInKm": 1.8669272537493835, "estimatedDriveTimeInMinutes": "3 to 7 min"},
{"coordinates": "7.901608815706607, 79.98959996815196", "distanceInKm": 3.545016016804148, "estimatedDriveTimeInMinutes": "4 to 8 min"},
{"coordinates": "7.911566016234709, 80.03336183892753", "distanceInKm": 4.494926420862967, "estimatedDriveTimeInMinutes": "4 to 8 min"}
]

Conclusion

By implementing these simple yet effective algorithms, you can determine the nearest locations to a given point and estimate the driving distance and time without relying on external map providers. This approach can be particularly useful in scenarios where you need to minimize external dependencies or have specific performance requirements.

However, it’s essential to acknowledge the limitations of this approach, such as its reliance on geometric approximations and assumptions about driving speeds

Happy coding….

--

--