Published
Edited
Nov 16, 2021
2 stars
Insert cell
Insert cell
Insert cell
Insert cell
viewof file = Inputs.file({ accept: ".tif" }) // default file is "IJ.tif"
Insert cell
teFile = file || FileAttachment("IJ.tif")
Insert cell
Tiff = await teFile.arrayBuffer()
Insert cell
mt = GeoTIFF.fromArrayBuffer(Tiff)
Insert cell
mt.getImageCount() // how many image layers are in the TIFF
Insert cell
# Load the shape files for the rivers.

The default shape file is the rivers file
Insert cell
taranaki_rivers_shapefile_complete = shapefile.read(
await FileAttachment("nz-river-name-lines-pilot.shp").stream(), // *.shp files contain the shape information (feature coordinates)
await FileAttachment("nz-river-name-lines-pilot.dbf").stream() // *.dbf gives the rivers an ID
)
Insert cell
Insert cell
mt_image = mt.getImage()
Insert cell
//mt_image.getGDALNoData()
NoData = mt_image.getFileDirectory().GDAL_NODATA
Insert cell
tiff_bbox = mt_image.getBoundingBox()
Insert cell
pool = new GeoTIFF.Pool() // woot web workers
Insert cell
Insert cell
async function getPoints(mt_image) {
const [x0, y0, x1, y1] = mt_image.getBoundingBox();
const { 0: values, width, height } = await mt_image.readRasters({ pool });
const X = d3.scaleLinear().domain([x0, x1]).range([0, width]);
const Y = d3.scaleLinear().domain([y0, y1]).range([height, 0]);

return (x, y) => values[Math.floor(X(x)) + width * Math.floor(Y(y))];
}
Insert cell
getPoint = getPoints(mt_image)
Insert cell
Insert cell
xyzCords = {
const C = [];
for (const d of taranaki_rivers_shapefile_complete.features) {
let id = `r${d.properties.river_sect}`;
let name = d.properties.name;
let feature = d.properties.feat_type;

let cord = await Promise.all(
d.geometry.coordinates.map(async (c) => {
let hi = [];
if (
c[0] >= tiff_bbox[0] &&
c[0] <= tiff_bbox[2] &&
c[1] >= tiff_bbox[1] &&
c[1] <= tiff_bbox[3]
) {
hi = getPoint(c[0], c[1]);
// if (hi == mt_image.getFileDirectory().GDAL_NODATA) hi = 0
} else {
hi = NaN;
}
return [c[0], c[1], hi];
})
);
// if (!(id === "outside")) C.push({ id, name, feature, cord }); // I need these dataum as some rivers cross tiles
C.push({ id, name, feature, cord }); // I need these dataum as some rivers cross tiles
}
return C;
}
Insert cell
Insert cell
Insert cell
tiffBytes = await mt_image.readRasters({ pool })
Insert cell
p5((sketch) => {
let w = tiffBytes.width;
let h = tiffBytes.height;
let t = tiffBytes[0];

sketch.setup = function () {
// sketch.createCanvas(w, h);
// sketch.noLoop();
// for (let p = 0; p < t.length; ++p) {
// let c = colourScale(t[p]);
// sketch.stroke(c);
// let x = p % w;
// let y = p / w;
// sketch.point(x, y);
// }
};
sketch.draw = function () {};
})
Insert cell
colourScale = d3.scaleLinear().domain(cRange).range(colours)
Insert cell
cRange = {
let r = d3.extent(tiffBytes[0]);
let range = r[1] - r[0];
let cut = range / colours.length;

return d3.range(r[0], r[1], cut);
}
Insert cell
colours = batlowK.map((d) => d3.color(d).formatHex())
Insert cell
import { batlowK } from "@hellonearthis/fabio-crameri-scientific-colour-maps"
Insert cell
import { p5 } from "@tmcw/p5"
Insert cell
GeoTIFF = require("geotiff.js@1.0.1/dist/geotiff.bundle.min.js")
Insert cell
shapefile = require("shapefile")
Insert cell
import { toc } from "@nebrius/indented-toc"
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more