viewof parquet_path = Inputs.text({label:"Source", value:"https://storage.googleapis.com/opencontext-parquet/oc_isamples_pqg.parquet", width:"100%", submit:true});
Using Cesium for display of remote parquet.
parquet
spatial
recipe
This page renders points from an iSamples parquet file on cesium using point primitives.
Code
= {
db const instance = await DuckDBClient.of();
await instance.query(`create view nodes as select * from read_parquet('${parquet_path}')`)
return instance;
}
async function loadData(query, params=[], waiting_id=null) {
// Get loading indicator
const waiter = document.getElementById(waiting_id);
if (waiter) {
.hidden = false;
waiter
}try {
// Run the (slow) query
const _results = await db.query(query, ...params);
return _results;
catch (error) {
} if (waiter) {
.innerHtml = `<pre>${error}</pre>`;
waiter
}return null;
finally {
} // Hide the waiter (if there is one)
if (waiter) {
.hidden = true;
waiter
}
}
}
= {
locations // get the content form the parquet file
const query = `SELECT pid, latitude, longitude FROM nodes WHERE otype='GeospatialCoordLocation'`;
const data = await loadData(query, [], "loading_1");
// Clear the existing PointPrimitiveCollection
.points.removeAll();
content//content.points = new Cesium.PointPrimitiveCollection();
// create point primitives for cesium display
const scalar = new Cesium.NearFarScalar(1.5e2, 2, 8.0e6, 0.2);
const color = Cesium.Color.PINK;
const point_size = 4;
for (const row of data) {
.points.add({
contentid: row.pid,
// https://cesium.com/learn/cesiumjs/ref-doc/Cartesian3.html#.fromDegrees
position: Cesium.Cartesian3.fromDegrees(
.longitude, //longitude
row.latitude, //latitude
row0,//randomCoordinateJitter(10.0, 10.0), //elevation, m
,
)pixelSize: point_size,
color: color,
scaleByDistance: scalar,
;
})
}.enableTracking();
contentreturn data;
}
function createShowPrimitive(viewer) {
return 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}`)
.currentSelection.primitive.pixelSize = 4;
viewer.currentSelection.primitive.outlineColor = Cesium.Color.TRANSPARENT;
viewer.currentSelection.outlineWidth = 0;
viewer.currentSelection = null;
viewer
}
}
// 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)
.pointLabel.position = selectPoint.primitive.position;
viewer.pointLabel.label.show = true;
viewer//viewer.pointLabel.label.text = `id:${selectPoint.id}, ${carto}`;
.pointLabel.label.text = `${selectPoint.id}`;
viewer.primitive.pixelSize = 20;
selectPoint.primitive.outlineColor = Cesium.Color.YELLOW;
selectPoint.primitive.outlineWidth = 3;
selectPoint.currentSelection = selectPoint;
viewerelse {
} .pointLabel.label.show = false;
viewer
}
}
}
class CView {
constructor(target) {
this.viewer = new Cesium.Viewer(
, {
targettimeline: false,
animation: false,
baseLayerPicker: false,
fullscreenElement: target,
terrain: Cesium.Terrain.fromWorldTerrain()
;
})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((e) => {
const selectPoint = this.viewer.scene.pick(e.position);
if (Cesium.defined(selectPoint) && selectPoint.hasOwnProperty("primitive")) {
= selectPoint.id;
mutable clickedPointId
},Cesium.ScreenSpaceEventType.LEFT_CLICK);
}
}
enableTracking() {
this.pickHandler.setInputAction(createShowPrimitive(this), Cesium.ScreenSpaceEventType.MOUSE_MOVE);
}
}
= new CView("cesiumContainer");
content
async function getGeoRecord(pid) {
if (pid === null || pid ==="" || pid == "unset") {
return "unset";
}const q = `SELECT row_id, pid, otype, latitude, longitude FROM nodes WHERE otype='GeospatialCoordLocation' AND pid=?`;
const result = await db.queryRow(q, [pid]);
return result;
}
async function locationUsedBy(rowid){
if (rowid === undefined || rowid === null) {
return [];
}const q = `select pid, otype from nodes where row_id in (select nodes.s from nodes where list_contains(nodes.o, ?));`;
return db.query(q, [rowid]);
}
= "unset";
mutable clickedPointId = await getGeoRecord(clickedPointId);
selectedGeoRecord
md`Retrieved ${pointdata.length} locations from ${parquet_path}.`;
Loading…
Code
= {
viewof pointdata const data_table = Inputs.table(locations, {
header: {
row_id:"Row ID",
pid: "PID",
latitude: "Latitude",
longitude: "Longitude"
,
};
})return data_table;
}
The click point ID is “”.