const MAPBOX_FORWARD_GEOCODE_BASE_URL = 'https://api.mapbox.com/geocoding/v5/mapbox.places/'; const MAPBOX_REVERSE_GEOCODE_BASE_URL = 'https://api.mapbox.com/geocoding/v5/mapbox.places/'; const MAPBOX_DIRECTIONS_BASE_URL = 'https://api.mapbox.com/directions/v5/mapbox'; const MAPBOX_ACCESS_TOKEN = 'pk.eyJ1IjoiemF1bHRhdmFuZ2FyIiwiYSI6ImNscHgwNDd1MDA3MXIydm92ODdianp6cGYifQ.WFAqbhwxtMHOWSPtu0l2uQ'; export type TransportationType = 'driving' | 'cycling' | 'walking'; export class MapboxApiUtility { static forwardGeocodeForFeatures = async (searchText: string) => { try { const url = MAPBOX_FORWARD_GEOCODE_BASE_URL + encodeURI(searchText) +'.json' +`?access_token=${MAPBOX_ACCESS_TOKEN}`; const response = await fetch(url); const data = await response.json(); return data.features; } catch (error: any){ // TODO: handle error in better way return null; } } static reverseGeocodeForFeatures = async (longitude: number, latitude: number) => { try { const url = MAPBOX_REVERSE_GEOCODE_BASE_URL + encodeURI(longitude.toString() + "," + latitude.toString()) + '.json' + `?access_token=${MAPBOX_ACCESS_TOKEN}`; const response = await fetch(url); const data = await response.json(); return data.features; } catch (error: any){ return null; } } static getDirections = async (origin: number[], destination: number[]): Promise | undefined> => { try { const drivingQuery = await fetch( `${MAPBOX_DIRECTIONS_BASE_URL}/driving/${origin[0]},${origin[1]};${destination[0]},${destination[1]}?steps=true&geometries=geojson&access_token=${MAPBOX_ACCESS_TOKEN}`); const cyclingQuery = await fetch( `${MAPBOX_DIRECTIONS_BASE_URL}/cycling/${origin[0]},${origin[1]};${destination[0]},${destination[1]}?steps=true&geometries=geojson&access_token=${MAPBOX_ACCESS_TOKEN}`); const walkingQuery = await fetch( `${MAPBOX_DIRECTIONS_BASE_URL}/walking/${origin[0]},${origin[1]};${destination[0]},${destination[1]}?steps=true&geometries=geojson&access_token=${MAPBOX_ACCESS_TOKEN}`); const drivingJson = await drivingQuery.json(); const cyclingJson = await cyclingQuery.json(); const walkingJson = await walkingQuery.json(); console.log("Driving: ", drivingJson); console.log("Cycling: ", cyclingJson); console.log("Waling: ", walkingJson); const routeMap = { 'driving': drivingJson.routes[0], 'cycling': cyclingJson.routes[0], 'walking': walkingJson.routes[0] } const routeInfoMap: Record = { 'driving': {}, 'cycling': {}, 'walking': {}, }; Object.entries(routeMap).forEach(([key, routeData]) => { const transportationTypeKey = key as TransportationType; const geometry = routeData.geometry; const coordinates = geometry.coordinates; console.log(coordinates); routeInfoMap[transportationTypeKey] = { duration: this.secondsToMinutesHours(routeData.duration), distance: this.metersToMiles(routeData.distance), coordinates: coordinates } }) return routeInfoMap; // return current route info, and the temporary route } catch (error: any){ return undefined; console.log("Error: ", error); } } private static secondsToMinutesHours = (seconds: number) => { const hours = Math.floor(seconds / 3600); const minutes = Math.floor((seconds % 3600) / 60).toFixed(2); if (hours === 0){ return `${minutes} min` } else { return `${hours} hr ${minutes} min` } } private static metersToMiles = (meters: number) => { return `${parseFloat((meters/1609.34).toFixed(2))} mi`; } }