* Replace Math.log2 with ol/math.log2 * TypedArray.from() browser compatibility fallback * listen for input and change events for range
94 lines
2.7 KiB
JavaScript
94 lines
2.7 KiB
JavaScript
import Map from '../src/ol/Map.js';
|
|
import View from '../src/ol/View.js';
|
|
import {OSM, XYZ} from '../src/ol/source.js';
|
|
import {WebGLTile as TileLayer} from '../src/ol/layer.js';
|
|
|
|
const variables = {};
|
|
|
|
// The method used to extract elevations from the DEM.
|
|
// In this case the format used is
|
|
// red + green * 2 + blue * 3
|
|
//
|
|
// Other frequently used methods include the Mapbox format
|
|
// (red * 256 * 256 + green * 256 + blue) * 0.1 - 10000
|
|
// and the Terrarium format
|
|
// (red * 256 + green + blue / 256) - 32768
|
|
function elevation(xOffset, yOffset) {
|
|
return [
|
|
'+',
|
|
['*', 256, ['band', 1, xOffset, yOffset]],
|
|
[
|
|
'+',
|
|
['*', 2 * 256, ['band', 2, xOffset, yOffset]],
|
|
['*', 3 * 256, ['band', 3, xOffset, yOffset]],
|
|
],
|
|
];
|
|
}
|
|
|
|
// Generates a shaded relief image given elevation data. Uses a 3x3
|
|
// neighborhood for determining slope and aspect.
|
|
const dp = ['*', 2, ['resolution']];
|
|
const z0x = ['*', ['var', 'vert'], elevation(-1, 0)];
|
|
const z1x = ['*', ['var', 'vert'], elevation(1, 0)];
|
|
const dzdx = ['/', ['-', z1x, z0x], dp];
|
|
const z0y = ['*', ['var', 'vert'], elevation(0, -1)];
|
|
const z1y = ['*', ['var', 'vert'], elevation(0, 1)];
|
|
const dzdy = ['/', ['-', z1y, z0y], dp];
|
|
const slope = ['atan', ['^', ['+', ['^', dzdx, 2], ['^', dzdy, 2]], 0.5]];
|
|
const aspect = ['clamp', ['atan', ['-', 0, dzdx], dzdy], -Math.PI, Math.PI];
|
|
const sunEl = ['*', Math.PI / 180, ['var', 'sunEl']];
|
|
const sunAz = ['*', Math.PI / 180, ['var', 'sunAz']];
|
|
|
|
const cosIncidence = [
|
|
'+',
|
|
['*', ['sin', sunEl], ['cos', slope]],
|
|
['*', ['*', ['cos', sunEl], ['sin', slope]], ['cos', ['-', sunAz, aspect]]],
|
|
];
|
|
const scaled = ['*', 255, cosIncidence];
|
|
|
|
const shadedRelief = new TileLayer({
|
|
opacity: 0.3,
|
|
source: new XYZ({
|
|
url: 'https://{a-d}.tiles.mapbox.com/v3/aj.sf-dem/{z}/{x}/{y}.png',
|
|
crossOrigin: 'anonymous',
|
|
}),
|
|
style: {
|
|
variables: variables,
|
|
color: ['color', scaled, scaled, scaled],
|
|
},
|
|
});
|
|
|
|
const controlIds = ['vert', 'sunEl', 'sunAz'];
|
|
controlIds.forEach(function (id) {
|
|
const control = document.getElementById(id);
|
|
const output = document.getElementById(id + 'Out');
|
|
function updateValues() {
|
|
output.innerText = control.value;
|
|
variables[id] = Number(control.value);
|
|
}
|
|
updateValues();
|
|
const listener = function () {
|
|
updateValues();
|
|
shadedRelief.updateStyleVariables(variables);
|
|
};
|
|
control.addEventListener('input', listener);
|
|
control.addEventListener('change', listener);
|
|
});
|
|
|
|
const map = new Map({
|
|
target: 'map',
|
|
layers: [
|
|
new TileLayer({
|
|
source: new OSM(),
|
|
}),
|
|
shadedRelief,
|
|
],
|
|
view: new View({
|
|
extent: [-13675026, 4439648, -13580856, 4580292],
|
|
center: [-13615645, 4497969],
|
|
minZoom: 10,
|
|
maxZoom: 16,
|
|
zoom: 13,
|
|
}),
|
|
});
|