-
Notifications
You must be signed in to change notification settings - Fork 0
/
openaq.js
93 lines (80 loc) · 3.4 KB
/
openaq.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import { delay } from './utils.js';
const corsProxy = 'https://wastheinternetamistake.com/index.php?url=';
async function fetchWithRetry(url, retries = 3, backoff = 1000) {
try {
const response = await fetch(url, {
method: 'GET',
headers: {
'accept': 'application/json'
}
});
if (response.status === 429 && retries > 0) {
console.log(`Rate limited. Retrying in ${backoff}ms...`);
await delay(backoff);
return fetchWithRetry(url, retries - 1, backoff * 2);
}
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.json();
} catch (error) {
if (retries > 0) {
console.log(`Error occurred. Retrying in ${backoff}ms...`);
await delay(backoff);
return fetchWithRetry(url, retries - 1, backoff * 2);
} else {
throw error;
}
}
}
export const openaq = {
async fetchAvailableParameters() {
const url = `${corsProxy}https://api.openaq.org/v2/parameters`;
try {
const data = await fetchWithRetry(url);
return data.results;
} catch (error) {
console.error('Error fetching parameters:', error);
return [{id: 'pm25', name: 'PM2.5'}];
}
},
async fetchDataAlongRoute(route, selectedParameter = 'pm25') {
if (!route || route.length === 0) {
console.error('No route available');
return;
}
const numPoints = 10; // Fixed number of points to sample
const routeLength = turf.length(turf.lineString(route), {units: 'meters'});
const interval = routeLength / (numPoints - 1); // Distance between each sample point in meters
// Get the date for 1 week ago
const oneWeekAgo = new Date();
oneWeekAgo.setDate(oneWeekAgo.getDate() - 7);
const dateFrom = oneWeekAgo.toISOString();
const dateTo = new Date().toISOString();
const airQualityData = [];
for (let i = 0; i < numPoints; i++) {
const distance = i * interval;
const point = turf.along(turf.lineString(route), distance, {units: 'meters'}).geometry.coordinates;
const roundedLon = parseFloat(point[0].toFixed(8));
const roundedLat = parseFloat(point[1].toFixed(8));
const url = `${corsProxy}https://api.openaq.org/v2/measurements?date_from=${dateFrom}&date_to=${dateTo}¶meter_id=${selectedParameter}&coordinates=${roundedLat},${roundedLon}&radius=25000&limit=1`;
try {
const result = await fetchWithRetry(url);
if (result.results && result.results.length > 0) {
const measurement = result.results[0];
airQualityData.push({
coordinates: [roundedLon, roundedLat],
value: measurement.value,
unit: measurement.unit,
parameter: measurement.parameter,
date: measurement.date.utc
});
}
} catch (error) {
console.error(`Failed to fetch data for point ${i + 1}/${numPoints}:`, error);
}
await delay(300); // 300ms delay between requests
}
return airQualityData;
}
};