【openlayers系统学习】3.6-3.7添加可视化选择器,手动选择可视化的图像源

六、添加可视化选择器(选择可视化的图像类型)

在前面的示例中,我们已经看到了同一Sentinel-2图像的真彩色合成、假彩色合成和NDVI渲染。如果能让用户从这些可视化中选择一个或更多,而不必每次都更改我们的代码,那就太好了。为此,我们将创建一个可用可视化的列表,并在页面中添加一个 <select>​ 元素,让用户选择要显示的内容。

除了真彩色、假彩色和NDVI可视化之外,我们还将添加一个新的归一化差异水指数(NDWI)。这与归一化差异植被指数类似,不同之处在于它可用于监测水体的变化。

js 复制代码
NDWI = (GREEN - NIR) / (GREEN + NIR)

正如我们所看到的,每个可视化都需要有一个 sources​ 数组(这些是单波段或多波段GeoTIFF的URL),一个可选的 max​ 值用于缩放GeoTIFF值,一个可选的 style​ 用于渲染图层。此外,我们将为每个可视化提供给予一个 name​ ,以便显示给用户。

编辑您的 main.js​ 以包含以下可视化数据:

js 复制代码
const visualizations = [
  {
    name: 'True Color',
    sources: ['TCI'],
  },
  {
    name: 'False Color',
    sources: ['B08', 'B04', 'B03'],
    max: 5000,
  },
  {
    name: 'NDVI',
    sources: ['B04', 'B08'],
    max: 10000,
    style: {
      color: [
        'interpolate',
        ['linear'],
        ['/', ['-', ['band', 2], ['band', 1]], ['+', ['band', 2], ['band', 1]]],
        ...getColorStops('earth', -0.5, 1, 10, true),
      ],
    },
  },
  {
    name: 'NDWI',
    sources: ['B03', 'B08'],
    max: 10000,
    style: {
      color: [
        'interpolate',
        ['linear'],
        ['/', ['-', ['band', 1], ['band', 2]], ['+', ['band', 1], ['band', 2]]],
        ...getColorStops('viridis', -1, 1, 10, true),
      ],
    },
  },
];

现在,我们需要一个函数来在用户选择可视化时创建这些,而不是一次性创建GeoTIFF源和层。这个函数将接受一个 base​ URL和一个 visualization​ ,并返回一个 layer​ 。编辑您的 main.js​ 以删除源和层定义,并包含此函数:

js 复制代码
function createLayer(base, visualization) {
  const source = new GeoTIFF({
   //使用map函数遍历可视化配置中的每个数据源ID
    sources: visualization.sources.map((id) => ({
      url: `${base}/${id}.tif`,
      max: visualization.max,
    })),
  });

  return new TileLayer({
    source: source,
    style: visualization.style,
  });
}

接下来,我们可以更改 main.js​ 中的地图定义,使其根本不包含任何图层(这些图层将在用户选择可视化时添加):

js 复制代码
const map = new Map({
  target: 'map-container',
});

现在,我们需要一种方法来让用户选择要显示的可视化。为此,我们将在 <script>​ 标记之前的 index.html​ 中添加一个 <select>​ 元素:

js 复制代码
<div id="controls">
  <select id="visualization"></select>
</div>

要让这个 <select>​ 元素显示在地图的右上角,请将以下块添加到 index.html​ 中的 <style>​ 标签:

js 复制代码
#controls {
  position: absolute;
  top: 20px;
  right: 20px;
}

有了 <select>​ 元素,我们需要为每个可视化名称填充一个 <option>​ 。要做到这一点,请将以下内容添加到 main.js​ 数组下面的某个位置:

js 复制代码
const visualizationSelector = document.getElementById('visualization');
visualizations.forEach((visualization) => {
  const option = document.createElement('option');
  option.textContent = visualization.name;
  visualizationSelector.appendChild(option);
});

最后,我们将创建一个函数,根据选定的可视化使用新层更新地图。我们将在 <select>​ 元素上添加这个函数作为 change​ 侦听器,并调用它来初始化我们的应用:

js 复制代码
function updateVisualization() {
  const visualization = visualizations[visualizationSelector.selectedIndex];
  const base =
    'https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/21/H/UB/2021/9/S2B_21HUB_20210915_0_L2A';

  const layer = createLayer(base, visualization);
  map.setLayers([layer]);

}

visualizationSelector.addEventListener('change', updateVisualization);
updateVisualization();
map.setView(layer.getSource().getView());

现在,http://localhost:5173/应该显示一个可视化浏览器。

Visualization chooser 可视化选择器

好极了!现在,用户可以选择要呈现的可视化类型。但是如果能改变图像来源不是很好吗?下一个。

七、可视化选择器(选择可视化的图像源)

最后一个缺失部分是使用户可以选择图像源。添加图像处理器并不需要做太多的工作。我们开始吧!

首先,我们需要列出应该显示的图像列表。对于每个图像,我们希望在 <select>​ 元素中显示一个名称供用户选择,并且我们需要有一个 GeoTIFF URL 的base​。因此,我们将在 main.js ​中添加类似以下内容的代码:

js 复制代码
const images = [
  {
    name: 'Buenos Aires',
    base: 'https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/21/H/UB/2021/9/S2B_21HUB_20210915_0_L2A',
  },
  {
    name: 'Minneapolis',
    base: 'https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/15/T/WK/2021/9/S2B_15TWK_20210918_0_L2A',
  },
  {
    name: 'Cape Town',
    base: 'https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/34/H/BH/2021/9/S2B_34HBH_20210922_0_L2A',
  },
];

接下来,我们将添加另一个 <select>​ 元素,让用户选择图像。在 index.html​ 中,调整控件,使其看起来像这样:

js 复制代码
<div id="controls">
  <select id="image"></select>
  <select id="visualization"></select>
</div>

回到JavaScript,我们需要为每个图像源填充一个 <option>​ 元素。在您的 main.js​ 中添加以下内容:

js 复制代码
const imageSelector = document.getElementById('image');
images.forEach((image) => {
  const option = document.createElement('option');
  option.textContent = image.name;
  imageSelector.appendChild(option);
});

现在,我们只需要对更新可视化的函数做一个小的调整,这样它就可以从选定的图像源中获取 base​ URL。在 main.js​ 中,编辑 updateVisualization​ 使base动态选择,并且设置如果基图改变,调整地图视图,使其看起来像这样:

js 复制代码
let previousBase;
function updateVisualization() {
    // 获取当前选择的可视化选项和图像选项
  const visualization = visualizations[visualizationSelector.selectedIndex];
  const base = images[imageSelector.selectedIndex].base;
  const newBase = base !== previousBase;
  previousBase = base;

  const layer = createLayer(base, visualization);
  map.setLayers([layer]);

    // 如果是新的基图,则调整地图视图
  if (newBase) {
    map.setView(layer.getSource().getView());
  }
}

visualizationSelector.addEventListener('change', updateVisualization);
imageSelector.addEventListener('change', updateVisualization);
updateVisualization();

请注意,现在只有在用户选择了新的图像源时才更新视图。这比在选择新的可视化类型时缩放到完整范围更好。

重新加载 http://localhost:5173/。

相关推荐
小马哥编程1 分钟前
Function.prototype和Object.prototype 的区别
javascript
小白学前端6661 分钟前
React Router 深入指南:从入门到进阶
前端·react.js·react
web1309332039822 分钟前
前端下载后端文件流,文件可以下载,但是打不开,显示“文件已损坏”的问题分析与解决方案
前端
王小王和他的小伙伴24 分钟前
解决 vue3 中 echarts图表在el-dialog中显示问题
javascript·vue.js·echarts
虾球xz27 分钟前
游戏引擎学习第59天
学习·游戏引擎
学前端的小朱28 分钟前
处理字体图标、js、html及其他资源
开发语言·javascript·webpack·html·打包工具
outstanding木槿34 分钟前
react+antd的Table组件编辑单元格
前端·javascript·react.js·前端框架
枫零NET1 小时前
学习思考:一日三问(学习篇)之匹配VLAN
网络·学习·交换机
好名字08211 小时前
前端取Content-Disposition中的filename字段与解码(vue)
前端·javascript·vue.js·前端框架
摇光931 小时前
js高阶-async与事件循环
开发语言·javascript·事件循环·宏任务·微任务