chore: initial Observable workspace with technical README
This commit is contained in:
118
docs/data/in-n-out-ca-overpass.json.js
Normal file
118
docs/data/in-n-out-ca-overpass.json.js
Normal file
@@ -0,0 +1,118 @@
|
||||
const query = `
|
||||
[out:json][timeout:120];
|
||||
area["ISO3166-2"="US-CA"][admin_level=4]->.searchArea;
|
||||
(
|
||||
node["amenity"="fast_food"]["brand"="In-N-Out Burger"](area.searchArea);
|
||||
way["amenity"="fast_food"]["brand"="In-N-Out Burger"](area.searchArea);
|
||||
relation["amenity"="fast_food"]["brand"="In-N-Out Burger"](area.searchArea);
|
||||
node["amenity"="fast_food"]["name"~"In-N-Out",i](area.searchArea);
|
||||
way["amenity"="fast_food"]["name"~"In-N-Out",i](area.searchArea);
|
||||
relation["amenity"="fast_food"]["name"~"In-N-Out",i](area.searchArea);
|
||||
);
|
||||
out center tags;
|
||||
`;
|
||||
|
||||
function normalizeStores(elements) {
|
||||
const stores = elements
|
||||
.map((element) => {
|
||||
const lat = Number(element.lat ?? element.center?.lat);
|
||||
const lon = Number(element.lon ?? element.center?.lon);
|
||||
if (!Number.isFinite(lat) || !Number.isFinite(lon)) return null;
|
||||
|
||||
const tags = element.tags ?? {};
|
||||
const name = tags.name || "In-N-Out Burger";
|
||||
const city = tags["addr:city"] || "Ville inconnue";
|
||||
const street = tags["addr:street"] || "";
|
||||
const housenumber = tags["addr:housenumber"] || "";
|
||||
const postcode = tags["addr:postcode"] || "";
|
||||
|
||||
return {
|
||||
id: `${element.type}/${element.id}`,
|
||||
latitude: lat,
|
||||
longitude: lon,
|
||||
name,
|
||||
city,
|
||||
address: [housenumber, street].filter(Boolean).join(" "),
|
||||
postcode,
|
||||
};
|
||||
})
|
||||
.filter(Boolean);
|
||||
|
||||
const dedup = new Map();
|
||||
for (const store of stores) {
|
||||
const key = `${store.latitude.toFixed(5)},${store.longitude.toFixed(5)}`;
|
||||
if (!dedup.has(key)) dedup.set(key, store);
|
||||
}
|
||||
|
||||
return Array.from(dedup.values());
|
||||
}
|
||||
|
||||
async function fetchFromOverpass() {
|
||||
const endpoints = [
|
||||
"https://overpass-api.de/api/interpreter",
|
||||
"https://overpass.kumi.systems/api/interpreter",
|
||||
"https://overpass.openstreetmap.fr/api/interpreter",
|
||||
];
|
||||
|
||||
for (const endpoint of endpoints) {
|
||||
try {
|
||||
const response = await fetch(endpoint, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"content-type": "application/x-www-form-urlencoded;charset=UTF-8",
|
||||
},
|
||||
body: new URLSearchParams({ data: query }),
|
||||
});
|
||||
|
||||
if (!response.ok) continue;
|
||||
|
||||
const payload = await response.json();
|
||||
const elements = Array.isArray(payload.elements) ? payload.elements : [];
|
||||
const stores = normalizeStores(elements);
|
||||
if (stores.length >= 50) return stores;
|
||||
} catch {}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
async function fetchFallbackCsv() {
|
||||
const url =
|
||||
"https://raw.githubusercontent.com/madmao/castle-compass/master/csv/In%20N%20Out.csv";
|
||||
const response = await fetch(url);
|
||||
if (!response.ok)
|
||||
throw new Error(`Fallback CSV request failed: ${response.status}`);
|
||||
|
||||
const lines = (await response.text()).split(/\r?\n/).filter(Boolean);
|
||||
const stores = lines
|
||||
.map((line, index) => {
|
||||
const [latRaw, lonRaw] = line.split(",");
|
||||
const latitude = Number(latRaw);
|
||||
const longitude = Number(lonRaw);
|
||||
if (!Number.isFinite(latitude) || !Number.isFinite(longitude))
|
||||
return null;
|
||||
|
||||
const inCaliforniaBounds =
|
||||
latitude >= 32 &&
|
||||
latitude <= 42.5 &&
|
||||
longitude >= -125 &&
|
||||
longitude <= -114;
|
||||
if (!inCaliforniaBounds) return null;
|
||||
|
||||
return {
|
||||
id: `fallback/${index}`,
|
||||
latitude,
|
||||
longitude,
|
||||
name: "In-N-Out Burger",
|
||||
city: "Ville inconnue",
|
||||
address: "",
|
||||
postcode: "",
|
||||
};
|
||||
})
|
||||
.filter(Boolean);
|
||||
|
||||
return stores;
|
||||
}
|
||||
|
||||
const stores = (await fetchFromOverpass()) ?? (await fetchFallbackCsv());
|
||||
process.stdout.write(JSON.stringify(stores));
|
||||
Reference in New Issue
Block a user