Public
Edited
Apr 30, 2024
Insert cell
Insert cell
Insert cell
viewof map = {
const target = html`<div style="width:100%;height:500px;">`;
yield target;
const canvasFunction = function (bbox, resolution, pixelRatio, size, projection) {
const [width, height] = size.map(e => Math.floor(e));
const cv = document.createElement("canvas");
cv.width = width;
cv.height = height;
const ctx = cv.getContext("2d");
createHillShadeMap(width, height, bbox).then(cv2 => {
const img = new Image();
img.src = cv2.toDataURL();
img.onload = function(){
ctx.clearRect(0,0,width,height);
ctx.drawImage(img,0,0,width,height);
map.render();
};
});

return cv;
};
const layer = new ol.layer.Image({
source: new ol.source.ImageCanvas({
canvasFunction,
ratio: 1,
interpolate: false,
}),
// opacity: 0.5,
});
const projection = "EPSG:4326";

const map = new ol.Map({
target,
pixelRatio: 1,
layers: [
new ol.layer.Tile({
source: new ol.source.OSM(),
}),
layer,
],

view: new ol.View({
center: ol.proj.fromLonLat([138.73, 35.36], projection),
zoom: 12,
projection,
}),
});
return target;
}
Insert cell
createHillShadeMap = async function (width, height, bbox) {

//Get elevation data
const img = await je.getImage({
collection: "https://s3.ap-northeast-1.wasabisys.com/je-pds/cog/v1/JAXA.EORC_ALOS.PRISM_AW3D30.v3.2_global/collection.json",
bbox, //[west,south,east,north]
width, //px
height, //px

//Bilinear resampling is required to calculate slopes
bilinearResampling: true,
});
const data = img.getData();

//HTML canvas element for drawing an image
const cv = document.createElement("canvas");
cv.width = width;
cv.height = height;
const ctx = cv.getContext("2d");
const imgdata = ctx.getImageData(0, 0, width, height);

//Approximate distance of pixels [m] (Earth's polar radius 6356752 [m])
const mppx = 6356752 * (data.bbox[3] - data.bbox[1]) * (Math.PI / 180) / height;
// hc: Elevation of the center pixel [m]
// dh: Elevation difference in north-south direction (Elevation of south pixel - Elevation of north pixel) [m]
// Simplified as dh << mppx
const getRGB = function(hc,dh){
if(isNaN(dh)) dh = 0;
if(isNaN(hc)) hc = 0;
return 255 * (0.5 + 0.3 * dh / mppx - hc * 0.00003);
};

//Processing each pixel
for (let j = 1; j < height - 1; j++) {
let index = j * width;
for (let i = 0; i < width; i++) {
const hn = data.data[index - width];
const hc = data.data[index];
const hs = data.data[index + width];
const rgb = getRGB(hc,hs - hn);
imgdata.data.set([rgb, rgb, rgb, 255], index << 2);
index++;
}
}

ctx.putImageData(imgdata, 0, 0);
return cv;
}
Insert cell
je = require("https://data.earth.jaxa.jp/api/javascript/v1.2.3/jaxa.earth.umd.js");
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