Public
Edited
Oct 16, 2023
9 forks
Importers
63 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
parquetBuffer = fetch(buildingsUrl).then((response) => response.arrayBuffer())
Insert cell
arrowTable = {
const parquetBytes = new Uint8Array(parquetBuffer);
const decodedArrowBytes = parquet.readParquet(parquetBytes);
const arrowTable = arrow.tableFromIPC(decodedArrowBytes);
return arrowTable;
}
Insert cell
Insert cell
arrowTable.schema.fields[0]
Insert cell
geometryColumn = arrowTable.getChildAt(0)
Insert cell
Insert cell
{
const firstGeometry = geometryColumn.get(0);
const firstRing = firstGeometry.get(0);
const firstCoord = firstRing.get(0);
return firstCoord.toArray();
}
Insert cell
Insert cell
// Pretty print the first geometry
// One ring with five coordinates
{
const firstGeom = geometryColumn.get(0);
const printedGeom = [];
for (const ring of firstGeom) {
const printedRing = [];
for (const coord of ring) {
const printedCoord = [coord.get(0), coord.get(1)];
printedRing.push(printedCoord);
}
printedGeom.push(printedRing);
}
return printedGeom;
}
Insert cell
Insert cell
Insert cell
Insert cell
// Note that `data` here is an array with only one element because this Parquet file only had one row group
// Otherwise we'd need to do this process for each batch of columnar data
polygonIndices = geometryColumn.data[0].valueOffsets
Insert cell
Insert cell
ringIndices = geometryColumn.getChildAt(0).data[0].valueOffsets
Insert cell
Insert cell
resolvedPolygonIndices = {
const resolvedIndices = new Int32Array(polygonIndices.length);
for (let i = 0; i < resolvedIndices.length; ++i) {
// Perform the lookup into the ringIndices array using the polygonIndices array
resolvedIndices[i] = ringIndices[polygonIndices[i]]
}
return resolvedIndices;
}
Insert cell
Insert cell
coordinateVector = geometryColumn.getChildAt(0).getChildAt(0)
Insert cell
Insert cell
flatCoordinateVector = geometryColumn.getChildAt(0).getChildAt(0).getChildAt(0)
Insert cell
flatCoordinateArray = flatCoordinateVector.data[0].values
Insert cell
Insert cell
deckglLayer = {
// Refer to https://deck.gl/docs/api-reference/layers/solid-polygon-layer#use-binary-attributes
const data = {
// Number of geometries
length: arrowTable.numRows,
// Indices into coordinateArray where each polygon starts
startIndices: resolvedPolygonIndices,
// Flat coordinates array
attributes: {
getPolygon: { value: flatCoordinateArray, size: 2 }
}
};
const layer = new deck.SolidPolygonLayer({
// This is an Observable hack - changing the id will force the layer to refresh when the cell reevaluates
id: `layer-${Date.now()}`,
data,
// Skip normalization for binary data
_normalize: false,
// Counter-clockwise winding order
_windingOrder: "CCW",
getFillColor: [0, 100, 60, 160],
});

deckglMap.setProps({ layers: [layer] });

return layer;
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more