【问题标题】:How to combine multiple TIFF's into one large Geotiff in scala?如何在scala中将多个TIFF组合成一个大的Geotiff?
【发布时间】:2019-04-04 10:44:19
【问题描述】:

我正在开展一个使用数字地面模型 (DGM) 查找水深和范围的项目。我有多个覆盖感兴趣区域的 tiff 文件,我想将它们组合成一个 tiff 文件以进行快速处理。 如何使用下面我自己的代码或任何其他方法将它们组合起来?

我试图将这些图块连接起来,将它们逐个作为输入,然后将它们组合起来,但它会抛出 GC error 可能是因为代码本身有问题。下面提供代码

import geotrellis.proj4._
import geotrellis.raster._
import geotrellis.raster.io.geotiff._
object waterdepth {
  val directories = List("data")

  //constants to differentiate which bands to use
  val R_BAND = 0
  val G_BAND = 1
  val NIR_BAND = 2

  // Path to our landsat band geotiffs.
  def bandPath(directory: String) = s"../biggis-landuse/radar_data/${directory}"

  def main(args: Array[String]): Unit = {
    directories.map(directory => generateMultibandGeoTiffFile(directory))
  }

  def generateMultibandGeoTiffFile(directory: String) = {
    val tiffFiles = new java.io.File(bandPath(directory)).listFiles.map(_.toString)

    val singleBandGeoTiffArray = tiffFiles.foldLeft(Array[SinglebandGeoTiff]())((acc, el:String) => {
      acc :+ SinglebandGeoTiff(el)
    })

    val tileArray = ArrayMultibandTile(singleBandGeoTiffArray.map(_.tile))

    println(s"Writing out $directory multispectral tif")
    MultibandGeoTiff(tileArray, singleBandGeoTiffArray(0).extent, singleBandGeoTiffArray(0).crs).write(s"data/$directory.tif")

它应该能够从所有单独的文件创建单个 tif 文件,但它会引发内存错误。

【问题讨论】:

    标签: scala tiff geotiff geotrellis


    【解决方案1】:

    您遵循的想法是正确的,可能会发生 OOM,因为您将大量 TIFF 加载到内存中,所以这并不奇怪。解决方案是为 JVM 分配更多内存。但是,您可以尝试这个小优化(可能会起作用):

    import geotrellis.proj4._
    import geotrellis.raster._
    import geotrellis.raster.io.geotiff._
    import geotrellis.raster.io.geotiff.reader._
    
    import java.io.File
    
    def generateMultibandGeoTiffFile(directory: String) = {
      val tiffs =
        new File(bandPath(directory))
          .listFiles
          .map(_.toString)
          // streaming = true won't force all bytes to load into memory
          // only tiff metadata is fetched here
          .map(GeoTiffReader.readSingleband(_, streaming = true))
    
      val (extent, crs) = {
        val tiff = tiffs.head
        tiff.extent -> tiff.crs
      }
    
      // TIFF segments bytes fetch will start only during the write
      MultibandGeoTiff(
        MultibandTile(tiffs.map(_.tile)), 
        extent, crs
      ).write(s"data/$directory.tif")
    }
    

    }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-03
      • 2011-04-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-30
      • 1970-01-01
      • 2014-08-14
      相关资源
      最近更新 更多