PageSourceSearch

https://www.kitepharma.com/Areas/Kite/Content/mapbox/assets/mapbox/js/isochrone.js

js kitepharma.com collected 2026-10-02 06:22:03 UTC 5,454 bytes, 208 lines download raw bytes

1/**
2 * @file Gets an isochrone from the Mapbox Isochrone API and updates the map sources to reflect the new isochrone
3 */
4
5import { fetchWithCache, getDistance } from './utilities.js';
6
7const empty = { type: 'FeatureCollection', features: [] };
8
9/**
10 * Get the isochrone for a given center and add it to the map
11 * @param {Object} map - Mapbox map
12 * @param {Array} selectedPlace - Selected place
13 * @param {string} type - Type of isochrone
14 */
15export async function updateIsochrone(map, selectedPlace, type = 'time') {
16	const isochrone = await getIsochrone({
17		location: selectedPlace,
18		type
19	});
20
21	const alternateType = type === 'distance' ? 'time' : 'distance';
22
23	map.getSource(`${type}_isochrone`).setData(isochrone);
24	map.getSource(`${alternateType}_isochrone`).setData(empty);
25}
26
27/**
28 * Get the extended isochrone for a given center and add it to the map
29 * @param {Object} map - Mapbox map
30 * @param {Array} selectedPlace - Selected place
31 * @param {string} type - Type of isochrone
32 */
33export async function updateExtendedIsochrone(map, selectedPlace, type = 'time') {
34	const isochrone = await getExtendedIsochrone(selectedPlace, type);
35
36	const alternateType = type === 'distance' ? 'time' : 'distance';
37
38	map.getSource(`extended_${type}_isochrone`).setData(isochrone);
39	map.getSource(`extended_${alternateType}_isochrone`).setData(empty);
40}
41
42/**
43 * Get the extended isochrone for a given center and add it to the map
44 * @param {Object} map - Mapbox map
45 * @returns {Promise} Mapbox Isochrone API response
46 */
47export async function getIsochrone(options = {}) {
48	const defaultOptions = {
49		location: [-74.0, 40.75]
50	};
51
52	options = Object.assign(defaultOptions, options);
53
54	const type = options.type || 'time';
55
56	const queries = {
57		distance: {
58			access_token: window.mapboxgl.accessToken,
59			contours_meters: `80467`,
60			generalize: 250,
61			polygons: true
62		},
63		time: {
64			access_token: window.mapboxgl.accessToken,
65			contours_minutes: `60`,
66			generalize: 250,
67			polygons: true
68		}
69	};
70
71	const query = queries[type];
72
73	/*
74	const query = {
75		access_token: window.mapboxgl.accessToken,
76		contours_minutes: `60`,
77		generalize: 250,
78		polygons: true
79	};
80	*/
81
82	const [lat, lng] = options.location;
83
84	const base = `https://api.mapbox.com/isochrone/v1/mapbox/driving`;
85
86	const url = `${base}/${lat},${lng}?${optionsToQueryString(query)}`;
87	const encoded = encodeURI(url);
88
89	return fetchWithCache(encoded);
90}
91
92/**
93 * Get the extended isochrone for a given center
94 * @param {Array} center - Center of the isochrone
95 * @returns {Object} - Feature collection
96 */
97export async function getExtendedIsochrone(center, type) {
98	let keyPoints = await getSamples(center);
99	keyPoints.push(center);
100
101	const extendedBuffers = await Promise.all(
102		keyPoints.map((point) => getIsochrone({ location: point, type }))
103	);
104
105	const features = extendedBuffers.reduce((collected, buffer) => {
106		return [...collected, ...buffer.features];
107	}, []);
108
109	let combined = combine(features);
110	combined.geometry.coordinates = combined.geometry.coordinates.slice(0, 1);
111
112	return combined;
113}
114
115/**
116 * Get the extended isochrone for a given center
117 * @param {Array} center - Center of the isochrone
118 * @param {string} type - Type of isochrone
119 * @returns {Array} - Array of max points
120 */
121export async function getSamples(center, type) {
122	const samplesToCalculate = 8;
123
124	const firstRing = await getIsochrone({ location: center, type });
125
126	const points = firstRing.features[0].geometry.coordinates[0];
127	// const interval = Math.floor(points.length / samplesToCalculate);
128
129	const samples = chunk(points, samplesToCalculate).map(getMax(center));
130	return samples;
131}
132
133/**
134 * Get the extended isochrone for a given center
135 * @param {Array} center - Center of the isochrone
136 * @param {string} type - Type of isochrone
137 * @returns {Array} - Array of max points
138 */
139function getMax(center) {
140	return (points) => {
141		let maxPoint = null;
142		let maxDistance = 0;
143
144		points.forEach((point, index) => {
145			const distance = getDistance(center, point);
146
147			if (index === 0) {
148				maxPoint = point;
149				maxDistance = distance;
150
151				return;
152			}
153
154			if (distance > maxDistance) {
155				maxPoint = point;
156				maxDistance = distance;
157			}
158		});
159
160		return maxPoint;
161	};
162}
163
164/**
165 * Splits an array into chunks of a given size
166 * @param {Array} points
167 * @param {number} segments
168 * @returns {Array} - An array of arrays
169 */
170function chunk(points, segments) {
171	const interval = Math.floor(points.length / segments);
172
173	let chunks = [];
174
175	for (let i = 0; i < segments; i++) {
176		chunks.push(points.slice(i * interval, i * interval + interval));
177	}
178
179	return chunks;
180}
181
182/**
183 * Combines an array of features into a single unionized feature collection
184 * @param {Array} features - array of features
185 * @returns {Object} - feature collection
186 */
187function combine(features) {
188	let union = features[0];
189
190	for (let i = 1; i < features.length; i++) {
191		union = turf.union(union, features[i]);
192	}
193
194	return union;
195}
196
197/**
198 * Converts an object of key/value pairs into a query string
199 * @param {Object} options - key/value pairs
200 * @returns {string} - query string
201 */
202function optionsToQueryString(options) {
203	return Object.entries(options)
204		.map(([key, value]) => {
205			return `${key}=${value}`;
206		})
207		.join('&');
208}

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.