Skip to content

Commit

Permalink
getByProximity
Browse files Browse the repository at this point in the history
return a list of countries within a specified proximity of the given country.
  • Loading branch information
erikyo committed May 13, 2024
1 parent 2de10d8 commit 879df94
Showing 1 changed file with 60 additions and 40 deletions.
100 changes: 60 additions & 40 deletions src/getByProximity.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { getIso } from './getIso'
import { countriesExtra } from './data/countries-extra'
import { countriesExtra } from "./data/countries-extra";
import { getIso } from "./getIso";

/**
* Calculate the distance between two sets of coordinates using the Haversine formula.
Expand All @@ -8,25 +8,28 @@ import { countriesExtra } from './data/countries-extra'
* @param {Array<number>} coordinates2 - The second set of coordinates [latitude, longitude]
* @return {number} The distance between the two sets of coordinates in kilometers
*/
function getDistance(coordinates: [number, number], coordinates2: [number, number]) {
const lat1 = coordinates[0]
const lon1 = coordinates[1]
const lat2 = coordinates2[0]
const lon2 = coordinates2[1]
// radius of the Earth in kilometers (6371 km)
const R = 6371
const dLat = ((lat2 - lat1) * Math.PI) / 180
const dLon = ((lon2 - lon1) * Math.PI) / 180
// Haversine formula
const a =
Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos((lat1 * Math.PI) / 180) *
Math.cos((lat2 * Math.PI) / 180) *
Math.sin(dLon / 2) *
Math.sin(dLon / 2)
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a))
const d = R * c
return d
function getDistance(
coordinates: [number, number],
coordinates2: [number, number],
) {
const lat1 = coordinates[0];
const lon1 = coordinates[1];
const lat2 = coordinates2[0];
const lon2 = coordinates2[1];
// radius of the Earth in kilometers (6371 km)
const R = 6371;
const dLat = ((lat2 - lat1) * Math.PI) / 180;
const dLon = ((lon2 - lon1) * Math.PI) / 180;
// Haversine formula
const a =
Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos((lat1 * Math.PI) / 180) *
Math.cos((lat2 * Math.PI) / 180) *
Math.sin(dLon / 2) *
Math.sin(dLon / 2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
const d = R * c;
return d;
}

/**
Expand All @@ -36,25 +39,42 @@ function getDistance(coordinates: [number, number], coordinates2: [number, numbe
* @param {number} maxDistance - the maximum distance in kilometers
* @return {Record<string, any> | undefined} a record of countries within the specified proximity
*/
export function getNearestCountries(
country: string,
maxDistance: number,
): { iso: string; coordinates: number[] | undefined; distance: number }[] {
const countryCoordinates = getIso(country, "country", "coordinates") as
| [number, number]
| null;
if (!countryCoordinates) {
throw new Error("Country not found");
}
return getByProximity(countryCoordinates, maxDistance);
}

export function getByProximity(
country: string,
maxDistance: number
coordinates: [number, number],
maxDistance: number,
): { iso: string; coordinates: number[] | undefined; distance: number }[] {
const countryCoordinates = getIso(country, 'country', 'coordinates') as [number, number] | null
const countriesbyDistance: {
iso: string
coordinates: number[] | undefined
distance: number
}[] = []
if (countryCoordinates !== null) {
Object.entries(countriesExtra).forEach(([iso, extras]) => {
const distance = getDistance(countryCoordinates, extras.coordinates as [number, number])
if (distance <= maxDistance) {
countriesbyDistance.push({ iso, coordinates: extras.coordinates, distance })
}
})
// return the countries sorted by distance
countriesbyDistance.sort((a, b) => a.distance - b.distance)
}
return countriesbyDistance
const countriesbyDistance: {
iso: string;
coordinates: number[] | undefined;
distance: number;
}[] = [];
for (const [iso, extras] of Object.entries(countriesExtra)) {
const distance = getDistance(
coordinates,
extras.coordinates as [number, number],
);
if (distance <= maxDistance) {
countriesbyDistance.push({
iso,
coordinates: extras.coordinates,
distance,
});
}
}
// return the countries sorted by distance
countriesbyDistance.sort((a, b) => a.distance - b.distance);
return countriesbyDistance;
}

0 comments on commit 879df94

Please sign in to comment.