函数 returns 包含图块日期的数组

Function returns array with dates of tiles

我有 js 代码,其中 return 层的日期(使用 OpenLayers 和 Momentjs)存储在我的电脑上。

正如我们所见,函数returns以60秒为步长从文件夹(folder)中获取两个日期之间的所有日期。但我只想 return 我的电脑上有文件(图层)的日期,因为我没有所有日期的图层。

所以我需要的是一个函数returns 一个日期数组,我只有图块,然后根据输入的日期从这一层添加到地图

function loopLayer() {
  const FromDateTime = document.getElementById("fromdate").value;
  const dateFrom = moment(FromDateTime, "YYYY-MM-DD HH:mm:ss", true);
  if (!dateFrom.isValid()) {
    log("something");
    return;
  }

  const ToDateTime = document.getElementById("todate").value;
  const dateTo = moment(ToDateTime, "YYYY-MM-DD HH:mm:ss", true);
  if (!dateTo.isValid()) {
    log("something");
    return;
  }

  let loopDate = dateFrom;
  for(let i=0; dateFrom.isSameOrBefore(dateTo) && i < 100; i++) {
    // preventing from loading thousands of layers
    loopLayerByDate(loopDate);
    loopDate = loopDate.add(60, 'seconds');

  }
}

function loopLayerByDate(dateObject) {
  const folderDate = dateObject.format("YYYY-MM-DD_HHmmss");
  const source = new ol.source.XYZ({
    projection: 'EPSG:3854',
    // adapt url and source tile type to your setup
    url: "folder/" + folderDate + "/{z}/{x}/{-y}.png"

  });


  const layer = new ol.layer.Tile({
    source: source,
    title: "layer"
  });
  map.addLayer(layer)
}

出于安全原因,网站通常无法从您的本地文件系统读取数据。否则任何网站都可以窥探您的硬盘。

如您所知,该规则有一个例外:当您打开本地 HTML 文件时,它可以从硬盘读取文件内容。但是您无法浏览文件夹,因此我们无法读取可用日期的列表。

你现在有两个选择:

  1. 添加 <input type="file" multiple>,上传文件并使用 FileAPI(此处为 example)。
  2. 您的东西是您从硬盘打开的本地 html 文件。您可以使用试错法猜测方法
  3. 找到一种无需猜测即可构建日期列表的方法,例如用递增的数字而不是时间戳来命名文件夹!
  4. 使用服务于一切的服务器软件。服务器可以访问文件系统并向 "front-end" 发送所需的日期列表。我不会在这里提供操作方法,在 Whosebug 和搜索引擎中有大量的软件解决方案和操作方法。

选项 2,本地 html:

由于您大致知道文件名在什么范围内,您可以使用蛮力方法并只查询范围内的所有日期并查看哪些日期实际响应。请注意,这种方法远非理想,而且可能 .

function guessValidDates(arrayOfDates){
    const validDates = [];
    arrayOfDates.forEach((date) => {
        var xhttp = new XMLHttpRequest();
        xhttp.open("GET", "time/" + date + "/1.png", true);
        xhttp.send();
    console.log('request returned', xhttp);
        if (xhttp.response) {
            validDates.push(date;
        }
    });
    return validDates;
}

用法示例:

// example from loopLayer function
let loopDate = dateFromObject;
const allDates = [];
for(let i=0; dateFromObject.isSameOrBefore(dateToObject) && i < 100; i++) {
  // the i counts as a failsafe, preventing us from loading billions of 
  // or whatever the pattern is for your file path
  allDates.push(loopDate.format("YYYY-MM-DD_HHmmss"));

  // step forward by X
  loopDate = loopDate.add(1, 'minutes');
}

const validDates = guessValidDates(allDates);
// now you know the valid dates and can use them. Example:
validDates.forEach(function(someDate){ 
  loopLayerByDate(someDate);
});

或者如果您有一个模式,其中一天的所有图层的数量都在增加,例如 "time/" + yearMontDay + '_' + increasingNumber + "/{z}/{x}/{-y}.png",请继续添加图层,直到您得到无效响应:

function isValidLayer(someDateString, someNumber) {
  var xhttp = new XMLHttpRequest();
  xhttp.open("GET", "time/" + someDateString + "_" + someNumber + "/1.png", true);
  xhttp.send();
  if (xhttp.response) {
      return true;
  }
  return false;
}

// you can now count up until you don't get a valid response anymore:

let someDateString = dateObject.format("YYYY-MM-DD_HHmmss");
let increasingNumber = 0;
while(increasingNumber < 1000) {
    // the condition is just a failsafe
    if(isValidLayer(someDateString, increasingNumber) {
      // add layer with that number to your map
      const source = new ol.source.XYZ({
        projection: 'EPSG:4326',
        wrapX: false,
        url: "time/" + folderDate + "_" + increasingNumber + "/{z}/{x}/{-y}.png"
      });
      // TODO add layer here and so on....
    } else {
      // no more layers, stop!
      console.log('stopped after' + increasingNumber + 'layers on date ' + someDateString);
      break;
    }
}