1/** 2 * @file Get the closest centers to a geographic center and adds them to the centers list 3 */ 4 5import { getDirections, getTravelTimes } from './mapbox.js'; 6import { createElement, updateTemplate, getDistance } from './utilities.js'; 7 8/** 9 * Sorts centers by distance from a geographic center 10 * @param {Array} centers - Centers to sort 11 * @param {Array} geographicCenter - Geographic center to sort the centers by 12 * @returns {Array} - Sorted centers 13 */ 14export function sortCenters(centers, geographicCenter) { 15 return centers 16 .map((center) => { 17 if (geographicCenter) { 18 const distance = getDistance(geographicCenter, center.location); 19 20 center.distance = Number(distance.toFixed(1)); 21 } else { 22 center.distance = 0; 23 } 24 25 return center; 26 }) 27 .sort((a, b) => { 28 if (a.distance === b.distance) { 29 return a.name.localeCompare(b.name); 30 } 31 32 return a.distance - b.distance; 33 }); 34} 35 36/** 37 * 38 * @param {Element} elementId - ID of the element to add the centers to 39 * @param {Array} centers - Centers to add 40 * @param {Array} geographicCenter - Geographic center to sort the centers by 41 * @param {Function} onSelect - Function to call when a center is selected 42 */ 43export async function updateCenters(elementId, centers, geographicCenter, onSelect = () => {}) { 44 const sortedCenters = sortCenters(centers, geographicCenter); 45 46 const within250 = sortedCenters.filter((center) => { 47 return center.distance < 250; 48 }); 49 50 // centers = within250.length > 3 ? within250 : sortedCenters.slice(0, 3); 51 centers = sortedCenters.slice(0, 10); 52 53 const container = document.getElementById(elementId); 54 container.innerHTML = ''; 55 56 // Add distances to first results 57 58 if (geographicCenter) { 59 let numberToQuery = 10; 60 61 const centersWithTimes = await Promise.all( 62 centers.slice(0, numberToQuery).map((center) => { 63 return new Promise(async (resolve, reject) => { 64 /* 65 const matrix = await getTravelTimes(center.location, geographicCenter); 66 67 const miles = Number(((matrix.distances[0][1] / 1000) * 0.621).toFixed(1)); 68 const minutes = Math.floor(matrix.durations[0][1] / 60); 69 70 */ 71 72 const directions = await getDirections(center.location, geographicCenter); 73 const route = directions.routes[0]; 74 75 if (directions.routes && directions.routes[0]) { 76 const rawMiles = route.distance * 0.000621371; 77 const rawMinutes = route.duration / 60; 78 79 center.matrix = { 80 miles: Number(rawMiles).toFixed(1), 81 minutes: Math.floor(rawMinutes), 82 83 rawMiles 84 }; 85 } else { 86 center.matrix = { 87 miles: null, 88 minutes: null 89 }; 90 } 91 92 resolve(center); 93 94 return; 95 }); 96 }) 97 ); 98 99 // centers = [...centersWithTimes, ...centers.slice(numberToQuery)]; 100 101 centers = [...centersWithTimes].sort((a, b) => { 102 if (a.matrix && b.matrix) { 103 return a.matrix.rawMiles - b.matrix.rawMiles; 104 } 105 106 return 0; 107 }); 108 } 109 110 centers.forEach((center, index) => { 111 function formatMinutes(totalminutes) { 112 if (!totalminutes) return ''; 113 114 const hours = Math.floor(totalminutes / 60); 115 const minutes = totalminutes % 60; 116 117 const formattedHours = !hours 118 ? '' 119 : hours === 1 120 ? `${hours} ${dictionary['hour']}` 121 : `${hours} ${dictionary['hours']}`; 122 123 return `${formattedHours} ${minutes} ${dictionary['min']}`; 124 } 125 126 function getDistance(center) { 127 if (center.matrix && center.matrix.miles && center.matrix.minutes) { //No value return, BUG 128 return `${center.matrix.miles} ${dictionary['mi']} ⢠${formatMinutes( 129 center.matrix.minutes 130 )}`; 131 } 132 133 return `${center.distance} ${dictionary['mi']}`; 134 } 135 136 const template = updateTemplate(centerTemplate, { 137 ...center, 138 distance: getDistance(center), 139 logo: center.logo ? `<img alt=${dictionary['centerPhoto']} src='${center.logo}'/>` : '' 140 }); 141 142 const element = createElement(template); 143 144 element.addEventListener('click', (e) => { 145 //Pass user flow 146 onSelect(center, "centerName"); 147 }); 148 149 container.append(element); 150 }); 151}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.