Функция оптимизации для получения значений пикселей геотифов для большого количества точек (javascript) - PullRequest
0 голосов
/ 20 января 2020

Я написал метод для опроса изображений TIF ASTGTM_v3 для повышения. Он работает нормально, но медленно, и я был бы признателен за некоторые советы, как его улучшить. Я использую geotiff. js для тяжелой работы с чтением изображений tiff.

Сначала я создаю цепочку обещаний для последовательного выполнения запросов - это важно, потому что я хочу получить возвышения обратно в массиве того же порядка, что и массив координат, которым он предоставляется ... Я думаю, что было бы быстрее работать параллельно, но тогда у меня возникла проблема с сортировкой полученных данных обратно в правильный порядок ...

return new Promise( (resolve, reject) => {

  // promise chain running each point sequentially and returning the result as an array
  points.reduce( (promise, point) => {
    return promise.then( (allResults) => 
      getElevation(point).then( thisResult => 
        [...allResults, thisResult]
      ));
  }, Promise.resolve([])).then( result => {
    resolve(result);
  });

});

Затем я использую следующую функцию, чтобы: 1) получить координаты x, y нужного пикселя, получить изображение и пиксель

function getElevation(point) {

  return new Promise( (res, rej) => { 

    // get the desired pixel in tiff(x,y) coordinate frame
    const pixel = getPixelPosition(point);
    const id = pixel.px.toString() + pixel.py.toString() + pixel.fname; 

    // get image and pixel if not cached
    getImage(pixel.fname).then( (image) => {
      readPixels(image, pixel.px, pixel.py, id).then( (rawElevs) => {
        const elev = rawElevs[0][0];
        res({lat: point.lat, lng: point.lng, elev: Math.round(elev * 10)/10});
      })
    })

  })
}

Именно здесь я проверяю, кэшируется ли нужное изображение, и возвращаю его - на самом деле мне не нужно загружать более одного изображения, поэтому это, по-видимому, экономит время.

function getImage(fn) {

  return new Promise( (rs, rj) => {

    // if image is in the CACHE, the return this image
    if (fn in CACHE.images) { 
      rs( CACHE.images[fn] );

    // otherwise, load a new image from file (and store it in the CACHE)
    } else {
      GeoTIFF.fromFile(TIFF_PATH + fn).then( (tiff) => {
        tiff.getImage().then( (img) => {
          CACHE.images[fn] = img;
          rs(img);
        })
      });
    }
  })
}

И, наконец, именно здесь Я получаю значение пикселя. Я кэшировал значение пикселя, но на самом деле каждая новая точка была отдельным пикселем, и было очень мало кэширования и все более и более крупного объекта для поиска, поэтому я избавился от него:

function readPixels(img, px, py, id, boo) {

  return new Promise( (rs, rj) => {
    promise = img.readRasters({ window: [px, py, px, py] });
    promise.then( (result) => {
      rs(result); 
    })
  })

}

Итак, Итак, есть ли другой подход, который я могу использовать, который позволит мне быстрее возвращать высотные отметки для большого количества точек данных (> 2000) (в настоящий момент 2000 точек составляют порядка минут) и возвращать точки к вызывающему приложению в том же порядке, чтобы были указаны координаты?

...