duckdb = import("https://cdn.jsdelivr.net/npm/@duckdb/duckdb-wasm/+esm");
async function instantiate(duckdb) {
const CDN_BUNDLES = duckdb.getJsDelivrBundles(),
bundle = await duckdb.selectBundle(CDN_BUNDLES), // Select a bundle based on browser checks
worker_url = URL.createObjectURL(
new Blob([ `importScripts("${bundle.mainWorker}");` ], {
type: "text/javascript"
})
);
// Instantiate the async version of DuckDB-WASM
const worker = new Worker(worker_url),
logger = new duckdb.ConsoleLogger("DEBUG"),
db = new duckdb.AsyncDuckDB(logger, worker);
await db.instantiate(bundle.mainModule, bundle.pthreadWorker);
URL.revokeObjectURL(worker_url);
return db;
}
DuckDB = await instantiate(duckdb);
db = {
const db = await DuckDB.connect();
const parquet_path = "https://s3.beehivebeach.com/smithsonian/occurrence.parquet";
let q = `install h3 from community;`
await db.query(q);
q = 'load h3;';
await db.query(q);
q = `create view occurrence as select * from read_parquet('${parquet_path}')`;
await db.query(q);
return db;
}This page renders content from a static snapshot of Smithinsonian Institution occurrence records retrieved from GBIF on 2025-04-22. The data was converted to parquet and of the approximately 10 million records, there are about 480,000 distinct locations which are shown on the map. Each point represents between 1 and several thousand occurrence records. Clicking on a point will show an excerpt of the records in a table below the map.
h3 = require("h3-js");
mutable data_loaded = "Loading...";
mutable num_points = 0;
colors = {
const c = [
Cesium.Color.CYAN,
Cesium.Color.GOLDENROD,
Cesium.Color.GOLD,
Cesium.Color.HOTPINK,
Cesium.Color.RED,
]
return c;
}
num_records = {
const results = await db.query("select count(*) as n from occurrence");
for (const row of results) {
return row.n;
}
}
pointdata = {
//const colors = await makeColors();
const query = `SELECT h3, h3_cell_to_lat(h3) as latitude, h3_cell_to_lng(h3) as longitude, cast(count(*) as integer) as n from occurrence where h3 is not null group by h3`;
const recorddata = await db.query(query);
const scalar = new Cesium.NearFarScalar(1.5e2, 3, 8.0e6, 0.2);
const color = Cesium.Color.PINK;
const point_size = 4;
let nrecs = 0;
for (const row of recorddata) {
//const recorddata = await db.send(query);
//for await (const batch of (recorddata)) {
//console.log(`Batch ${batch.length}`);
//for (const row of batch) {
content.points.add({
id: `${row.h3}|${row.n}`,
// https://cesium.com/learn/cesiumjs/ref-doc/Cartesian3.html#.fromDegrees
position: Cesium.Cartesian3.fromDegrees(
row.longitude, //longitude
row.latitude, //latitude
0,//randomCoordinateJitter(10.0, 10.0), //elevation, m
),
pixelSize: point_size,
color: colors[Math.round(Math.log10(row.n))],
//color: Cesium.Color.PINK,
scaleByDistance: scalar,
});
nrecs += 1;
if (nrecs % 30000 === 0) {
mutable data_loaded = `Loaded ${nrecs} locations.`;
}
}
//}
mutable num_points = nrecs;
mutable data_loaded = `Loaded ${nrecs} locations.`;
content.enableTracking();
return null;
}class Overlay {
constructor(target, width="140px") {
this.data = {}
this.ele = document.createElement("div")
this.ele.setAttribute("class", "cesium-topleft");
this.ele.style.width = width;
const target_ele = document.getElementById(target);
const container = target_ele.querySelector(".cesium-widget");
container.insertBefore(this.ele, container.firstChild);
}
render() {
const rows=[];
if (this.data.longitude === ""){
rows.push(`<tr><td>XY</td><td></td></tr>`);
} else {
rows.push(`<tr><td>XY</td><td>${this.data.longitude}, ${this.data.latitude}</td></tr>`);
}
for (const [k,v] of Object.entries(this.data)){
if ((k === "latitude") || (k === "longitude")) {
continue;
}
rows.push(`<tr><td>${k}</td><td>${((v === null) ? "" : v)}</td></tr>`);
}
this.ele.innerHTML = `<table>${rows.join("\n")}</table>`;
}
update(data, do_render=true) {
for (const [key,value] of Object.entries(data)) {
this.data[key] = value;
}
if (do_render) {
this.render();
}
}
}
function createShowPrimitive(viewer) {
return async function(movement) {
// Get the point at the mouse end position
const selectPoint = viewer.viewer.scene.pick(movement.endPosition);
// Clear the current selection, if there is one and it is different to the selectPoint
if (viewer.currentSelection !== null) {
//console.log(`selected.p ${viewer.currentSelection}`)
if (Cesium.defined(selectPoint) && selectPoint !== viewer.currentSelection) {
//console.log(`selected.p 2 ${viewer.currentSelection}`)
viewer.currentSelection.primitive.pixelSize = 4;
viewer.currentSelection.primitive.outlineColor = Cesium.Color.TRANSPARENT;
viewer.currentSelection.outlineWidth = 0;
viewer.currentSelection = null;
}
}
// If selectPoint is valid and no currently selected point
if (Cesium.defined(selectPoint) && selectPoint.hasOwnProperty("primitive")) {
//console.log(`showPrimitiveId ${selectPoint.id}`);
const carto = Cesium.Cartographic.fromCartesian(selectPoint.primitive.position)
viewer.pointLabel.position = selectPoint.primitive.position;
viewer.pointLabel.label.show = true;
//viewer.pointLabel.label.text = `id:${selectPoint.id}, ${carto}`;
try {
const label = `n:${selectPoint.id.split("|")[1]}`;
viewer.pointLabel.label.text = `${label}`;
selectPoint.primitive.pixelSize = 20;
selectPoint.primitive.outlineColor = Cesium.Color.YELLOW;
selectPoint.primitive.outlineWidth = 3;
viewer.currentSelection = selectPoint;
} catch {
viewer.currentSelection = null;
viewer.pointLabel.label.show = false;
}
} else {
viewer.pointLabel.label.show = false;
}
// Mouse coordinates
const ray = viewer.viewer.camera.getPickRay(movement.endPosition);
const mousePosition = viewer.viewer.scene.globe.pick(ray, viewer.viewer.scene);
if (Cesium.defined(mousePosition)) {
const cartographic = Cesium.Cartographic.fromCartesian(mousePosition);
viewer.overlay.update({
longitude: Cesium.Math.toDegrees(cartographic.longitude).toFixed(3),
latitude: Cesium.Math.toDegrees(cartographic.latitude).toFixed(3)
})
} else {
viewer.overlay.update({latitude:"", longitude:""});
}
}
}
class CView {
constructor(target) {
this.viewer = new Cesium.Viewer(
target, {
timeline: false,
animation: false,
baseLayerPicker: false,
fullscreenElement: target,
terrain: Cesium.Terrain.fromWorldTerrain()
});
this.overlay = new Overlay(target);
this.currentSelection = null;
this.point_size = 1;
this.n_points = 0;
// https://cesium.com/learn/cesiumjs/ref-doc/PointPrimitiveCollection.html
this.points = new Cesium.PointPrimitiveCollection();
this.viewer.scene.primitives.add(this.points);
this.pointLabel = this.viewer.entities.add({
label: {
show: false,
showBackground: true,
font: "14px monospace",
horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
pixelOffset: new Cesium.Cartesian2(15, 0),
// this attribute will prevent this entity clipped by the terrain
disableDepthTestDistance: Number.POSITIVE_INFINITY,
text:"",
},
});
this.pickHandler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
// Can also do this rather than wait for the points to be generated
//this.pickHandler.setInputAction(createShowPrimitive(this), Cesium.ScreenSpaceEventType.MOUSE_MOVE);
this.selectHandler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
this.selectHandler.setInputAction(async (e) => {
const selectPoint = this.viewer.scene.pick(e.position);
if (Cesium.defined(selectPoint) && selectPoint.hasOwnProperty("primitive")) {
//this.overlay.update(await getRecord(selectPoint.id));
console.log(`Selected h3=${selectPoint.id}`);
getRecords(selectPoint.id);
} else {
//this.overlay.update(await getRecord(null));
getRecords(null);
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
}
enableTracking() {
this.pickHandler.setInputAction(createShowPrimitive(this), Cesium.ScreenSpaceEventType.MOUSE_MOVE);
}
}
async function getRecords(idx) {
if (idx === null) {
mutable selected_h3 = [];
}
console.log(`Looking for record ${idx}...`);
const h3cell = BigInt(idx.split("|")[0]);
const h3cellhex = h3cell.toString(16);
const resolution = h3.getResolution(h3cellhex);
console.log(`resolution = ${resolution}`);
const h3s = h3.cellToChildren(h3.cellToParent(h3cellhex, resolution-1), resolution);
console.log(`h3 = ${h3s}`);
const h3ints = [];
for (const h of h3s) {
h3ints.push(`h3=${BigInt('0x'+h)}`);
}
console.log(h3ints.join((" or ")));
//const q = db.prepare(`select occurrenceID, institutionCode, collectionCode, catalogNumber, family, genus, species, eventDate from occurrence where h3 in ?`);
//console.log(q);
//const result = q.query(h3s);
const q = `select occurrenceID, institutionCode, collectionCode, catalogNumber, family, genus, species, eventDate from occurrence where h3=${h3cell}`;
console.log(q);
const result = db.query(q);
mutable selected_h3 = await result;
console.log("Donel")
}
content = new CView("cesiumContainer");
mutable selected_h3 = [];Selected records.