This example is explained at the post https://geoexamples.com/other/2019/02/08/cog-tutorial.html
The represented data is a temperature interpolation over Catalonia, and the GeoTIFF is very big. In this case, we only use a small region of the data. Since the GeoTIFF is cloud optimized, only the nearest blocks to the data are downloaded, and the amount of data and used bandwidth is small.
<!DOCTYPE html>
<meta charset="utf-8">
<head>
<script src="geotiff.bundle.min.js"></script>
<script src="d3-marching-squares.min.js"></script>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
</head>
<body>
<script>
(async function() {
let origin = [700, 600];
let size = [500, 450];
const tiff = await GeoTIFF.fromUrl("/rveciana/raw/9d9ef3282959a41c3e54cedb717bdddf/sample.tiff");
let image = await tiff.getImage(0);
let rasterData = await image.readRasters({window: [origin[0], origin[1],
origin[0] + size[0], origin[1] + size[1]],
samples: [0]});
rasterData = rasterData[0];
let data = new Array(size[1]);
for (let j = 0; j<size[1]; j++){
data[j] = new Array(size[0]);
for (let i = 0; i<size[0]; i++){
data[j][i] = rasterData[i + j*size[0]];
}
}
let intervals = [-2, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20];
let bands = rastertools.isobands(data, [0, 1, 0, 0, 0, 1], intervals);
let colorScale = d3.scaleSequential(d3.interpolateBuPu);
let canvas = d3.select("body").append("canvas")
.attr("width", 680)
.attr("height", 500);
let context = canvas.node().getContext("2d");
let path = d3.geoPath()
.context(context);
bands.features.forEach(function(d, i) {
context.beginPath();
context.globalAlpha = 0.7;
context.fillStyle = colorScale((2 + intervals[i])/22);
path(d);
context.fill();
});
})();
</script>
</body>