-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.js
112 lines (100 loc) · 3.05 KB
/
main.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import Map from 'ol/Map.js';
import View from 'ol/View.js';
import {XYZ} from 'ol/source.js';
import {WebGLTile as TileLayer} from 'ol/layer.js';
import {fromLonLat} from 'ol/proj.js';
const variables = {};
// The method used to extract elevations from the DEM.
// In this case the format used is Terrarium
// red * 256 + green + blue / 256 - 32768
//
// Other frequently used methods include the Mapbox format
// (red * 256 * 256 + green * 256 + blue) * 0.1 - 10000
//
function elevation(xOffset, yOffset) {
const red = ['band', 1, xOffset, yOffset];
const green = ['band', 2, xOffset, yOffset];
const blue = ['band', 3, xOffset, yOffset];
// band math operates on normalized values from 0-1
// so we scale by 255
/*return [
'+',
['*', 255 * 256, red],
['*', 255, green],
['*', 255 / 256, blue],
-32768,
];
*/
return [
'+',
['*', 255*6553.6, red],
['*', 25.6, green],
['*', 255/0.1, blue],
-10000
];
}
// 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', ['sqrt', ['+', ['^', dzdx, 2], ['^', dzdy, 2]]]];
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 API_TOKEN = '<INSERT-YOUR-API-KEY>';
const shadedRelief = new TileLayer({
opacity: 0.7,
source: new XYZ({
url: `TBA/default/v2/WGS84_Pseudo-Mercator/{z}/{y}/{x}.png?api-key=${API_TOKEN}`,
maxZoom: 16
}),
style: {
variables: variables,
color: ['color', scaled, scaled, scaled],
},
});
const mapLayer = new TileLayer({
opacity: 0.5,
source: new XYZ({
url: `https://avoin-karttakuva.maanmittauslaitos.fi/avoin/wmts/1.0.0/maastokartta/default/WGS84_Pseudo-Mercator/{z}/{y}/{x}.png?api-key=${API_TOKEN}`,
maxZoom: 18
})
});
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();
control.addEventListener('input', function () {
updateValues();
shadedRelief.updateStyleVariables(variables);
});
});
const centerLonLat = [27.24535,67.09973],
centerWebMercator = fromLonLat(centerLonLat);
const map = new Map({
target: 'map',
layers: [
shadedRelief,
mapLayer
],
view: new View({
center: centerWebMercator,
zoom: 14
}),
});