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 directionsPromises: Promise[] = []; const transportationTypes: TransportationType[] = ['driving', 'cycling', 'walking']; transportationTypes.forEach(type => { directionsPromises.push(fetch(`${MAPBOX_DIRECTIONS_BASE_URL}/${type}/${origin[0]},${origin[1]};${destination[0]},${destination[1]}?steps=true&geometries=geojson&access_token=${MAPBOX_ACCESS_TOKEN}`).then(response => response.json())); }); const results = await Promise.all(directionsPromises); const routeInfoMap: Record = { driving: {}, cycling: {}, walking: {}, }; transportationTypes.forEach((type, index) => { const routeData = results[index].routes[0]; if (routeData) { const { geometry } = routeData; const { coordinates } = geometry; routeInfoMap[type] = { 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; } }; 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`; } return `${hours} hr ${minutes} min`; }; private static metersToMiles = (meters: number) => `${parseFloat((meters / 1609.34).toFixed(2))} mi`; } // 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 // } // })