原文链接及内容

运行界面

两个哨兵2 COGs各有可见红、绿、蓝波段和近红外波段。相邻区域位于各自UTM区域的边缘,因此至少有一个COG必须重新投影才能在同一张地图上显示。

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
import GeoTIFF from 'ol/source/GeoTIFF.js';
import Map from 'ol/Map.js';
import TileLayer from 'ol/layer/WebGLTile.js';
import proj4 from 'proj4';
import {createEmpty, extend, getCenter} from 'ol/extent.js';
import {register} from 'ol/proj/proj4.js';
import {transformExtent} from 'ol/proj.js';

proj4.defs('EPSG:32631', '+proj=utm +zone=31 +datum=WGS84 +units=m +no_defs');
proj4.defs('EPSG:32632', '+proj=utm +zone=32 +datum=WGS84 +units=m +no_defs');
register(proj4);

const channels = ['red', 'green', 'blue'];
for (const channel of channels) {
const selector = document.getElementById(channel);
selector.addEventListener('change', update);
}

function getVariables() {
const variables = {};
for (const channel of channels) {
const selector = document.getElementById(channel);
variables[channel] = parseInt(selector.value, 10);
}
return variables;
}

const sourceNames = ['B04', 'B03', 'B02', 'B08'];
const sources = [
new GeoTIFF({
sources: sourceNames.map(function (name) {
return {
url: `https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/31/T/GJ/2022/7/S2A_31TGJ_20220703_0_L2A/${name}.tif`,
max: 3000,
};
}),
}),
new GeoTIFF({
sources: sourceNames.map(function (name) {
return {
url: `https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/32/T/LP/2022/7/S2A_32TLP_20220703_0_L2A/${name}.tif`,
max: 3000,
};
}),
}),
];

const layer = new TileLayer({
sources: sources,
style: {
variables: getVariables(),
color: [
'array',
['band', ['var', 'red']],
['band', ['var', 'green']],
['band', ['var', 'blue']],
['band', 5],
],
},
});

function update() {
layer.updateStyleVariables(getVariables());
}

const map = new Map({
target: 'map',
layers: [layer],
view: Promise.all(
sources.map(function (source) {
return source.getView();
})
).then(function (options) {
const projection = 'EPSG:3857';
const extent = createEmpty();
options.forEach(function (options) {
extend(
extent,
transformExtent(options.extent, options.projection, projection)
);
});
return {
projection: projection,
center: getCenter(extent),
zoom: 0,
extent: extent,
};
}),
});

界面布局文件index.html代码如下:

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Multiple COG sources</title>
<link rel="stylesheet" href="node_modules/ol/ol.css">
<style>
.map {
width: 100%;
height: 400px;
}
.controls {
display: grid;
grid-template-columns: auto auto 1fr;
align-items: baseline;
gap: 0 1em;
}
</style>
</head>
<body>
<div id="map" class="map"></div>
<div class="controls">
<label for="red">Red channel</label>
<select id="red">
<option value="1" selected>visible red</option>
<option value="2">visible green</option>
<option value="3">visible blue</option>
<option value="4">near infrared</option>
</select>
<label></label>

<label for="green">Green channel</label>
<select id="green">
<option value="1">visible red</option>
<option value="2" selected>visible green</option>
<option value="3">visible blue</option>
<option value="4">near infrared</option>
</select>
<label></label>

<label for="blue">Blue channel</label>
<select id="blue">
<option value="1">visible red</option>
<option value="2">visible green</option>
<option value="3" selected>visible blue</option>
<option value="4">near infrared</option>
</select>
<label></label>
</div>
<!-- Pointer events polyfill for old browsers, see https://caniuse.com/#feat=pointer -->
<script src="https://cdn.jsdelivr.net/npm/elm-pep@1.0.6/dist/elm-pep.js"></script>
<script type="module" src="main.js"></script>
</body>
</html>