Files
observable/docs/data/ufo-ca-sightings-v2.json.js

84 lines
2.2 KiB
JavaScript

const candidates = [
"https://raw.githubusercontent.com/richaude/blue-book/master/scrubbed.csv",
"https://raw.githubusercontent.com/alecfirrincieli/UFO-sightings/main/ufo-sightings.csv",
];
let csvText = null;
for (const url of candidates) {
try {
const response = await fetch(url);
if (!response.ok) continue;
const text = await response.text();
if (text && text.includes("datetime,city,state")) {
csvText = text;
break;
}
} catch {}
}
if (!csvText) {
throw new Error("Unable to fetch UFO sightings dataset from public mirrors.");
}
const { csvParse } = await import("d3-dsv");
const rows = csvParse(csvText);
const normalizeKey = (value) =>
String(value ?? "")
.trim()
.toLowerCase();
function readField(row, key) {
const target = normalizeKey(key);
for (const [field, value] of Object.entries(row)) {
if (normalizeKey(field) === target) return value;
}
return undefined;
}
function parseNumber(value) {
const parsed = Number(value);
return Number.isFinite(parsed) ? parsed : null;
}
const ufo = rows
.map((row, index) => {
const state = String(readField(row, "state") ?? "")
.trim()
.toLowerCase();
const country = String(readField(row, "country") ?? "")
.trim()
.toLowerCase();
const latitude = parseNumber(readField(row, "latitude"));
const longitude = parseNumber(readField(row, "longitude"));
if (state !== "ca" || country !== "us") return null;
if (latitude === null || longitude === null) return null;
const inCaliforniaBounds =
latitude >= 32 &&
latitude <= 42.5 &&
longitude >= -125 &&
longitude <= -114;
if (!inCaliforniaBounds) return null;
const durationSeconds =
parseNumber(readField(row, "duration (seconds)")) ?? 0;
return {
id: `ufo/${index}`,
datetime: readField(row, "datetime") ?? null,
city: readField(row, "city") ?? "Unknown",
state,
shape: String(readField(row, "shape") ?? "unknown").toLowerCase(),
durationSeconds,
comments: readField(row, "comments") ?? "",
latitude,
longitude,
};
})
.filter(Boolean);
process.stdout.write(JSON.stringify(ufo));