【问题标题】:R: read GeoTiff from gz file with a connection and raster packageR:使用连接和光栅包从 gz 文件中读取 GeoTiff
【发布时间】:2017-02-07 11:27:25
【问题描述】:

我想从服务器读取 gzip 压缩的 GeoTIFF 而不下载它。我只是不想创建很多以后必须删除的临时文件。

I see it is possible.csv.gz 文件。

通过下载,我按以下方式进行:

library(raster)
link <- "ftp://ftp.glcf.umd.edu/glcf/SRTM/Degree_Tiles/n000/SRTM_ff03_n000e010
/SRTM_ff03_n000e010.tif.gz"

download.file(link, "test.tif.gz")
gunzip("test.tif.gz")
myras <- raster("test.tif")
plot(myras)

我可以直接从链接中读取未压缩的文件:

link <- "http://download.osgeo.org/geotiff/samples/usgs/o41078a5.tif"
myras <- raster(link)
plot(myras)
myextent <- drawExtent()
plot(myras, ext=myextent)

在这里,我意识到不将其下载到本地存储可能不是一个好主意,因为我假设您随后对 myras 执行的每个操作都需要数据再次通过 Internet 流动。但无论如何,只是为了证明概念,我想这样做。在某些情况下,您只想显示 TIFF 而不对其进行任何进一步的计算,因此不想为其创建临时文件。

要读取(下载的)tiff.gz 文件而不先解压缩,我尝试过:

> raster(gzfile("test.tif.gz"))
Error in (function (classes, fdef, mtable)  : 
  unable to find an inherited method for function ‘raster’ for signature ‘"gzfile"’

要通过连接直接从服务器读取tiff.gz 文件,我尝试了以下操作:

> con <- gzcon(url("ftp://ftp.glcf.umd.edu/glcf/SRTM/Degree_Tiles/n000/SRTM_ff03_n000e010/SRTM_ff03_n000e010.tif.gz"))
> raster(con)
Error in (function (classes, fdef, mtable)  : 
  unable to find an inherited method for function ‘raster’ for signature ‘"gzcon"’

> raw <- textConnection(readLines(con))
> raster(raw)
Error in (function (classes, fdef, mtable)  : 
  unable to find an inherited method for function ‘raster’ for signature ‘"textConnection"’

> rawBin <- textConnection(readBin(con))
Error in readBin(con) : argument "what" is missing, with no default

> con <- gzfile("ftp://ftp.glcf.umd.edu/glcf/SRTM/Degree_Tiles/n000/SRTM_ff03_n000e010/SRTM_ff03_n000e010.tif.gz")
> myras <- raster(con)
Error in (function (classes, fdef, mtable)  : 
  unable to find an inherited method for function ‘raster’ for signature ‘"gzfile"’

我找到了this Stackoverflow question 关于如何读取压缩二进制文件连接的信息,但我不确定 GeoTIFF 是否为二进制(是吗?)以及将哪些参数传递给 readBin() 函数。

我想随意尝试一下,因为我不太了解连接是如何工作的。谁能帮我解决这个问题?

【问题讨论】:

    标签: r r-raster gzip geotiff


    【解决方案1】:

    我找到了解决方案,也许你也有。

    tiff 包中的函数 readTIFF() 可以从原始向量中读取 tiff 图像。因此,您可以使用readBin() 将您的连接读入原始向量,然后使用readTiff() 读取该原始向量。

    # create connection to a gz file
    con <- gzfile("test.tif.gz", open = "rb")
    
    # read data from this connection into a raw vector
    myras.raw <- readBin(con, what = "raw", n = 1e10)
    
    # read this raw vector
    myras <- readTIFF(myras.raw)
    

    我希望这可以帮助:)

    【讨论】:

      【解决方案2】:

      另一个解决方案是底层 GDAL 库提供一些特定的“虚拟”文件系统,允许读取压缩和/或远程资源。

      https://gdal.org/user/virtual_file_systems.html

      raster 命令支持这些,基本上将提供的文件路径直接传递给 GDAL 以读取数据。所以你应该可以使用以下直接加载数据。

      library(raster)
      link <- "/vsigzip//vsicurl/ftp://ftp.glcf.umd.edu/glcf/SRTM/Degree_Tiles/n000/SRTM_ff03_n000e010
      /SRTM_ff03_n000e010.tif.gz"
      

      【讨论】:

      • 关于使用 gdal 文件系统的评论中似乎缺少一些东西。一旦您分配了链接的路径,您是否意味着 raster(link) 应该能够读取它?我想在本地 gz 文件上使用它,但没有成功。
      • 回答有点稀疏,真的!是的,您可以使用带有raster(link) 的链接,但对于本地文件,您不需要vsicurl 位,它有助于远程数据。所以:link &lt;- "/vsigzip/DigitalTerrain_BNG.tif.gz"; r &lt;- raster(link) 如果存档中有多个图像,它会变得更有趣,但这适用于单个 gzip 光栅文件。
      • 在上面的目标链接中提供了几个选项。 /vsigzip/my.gz # (.gz 的相对路径) /vsigzip//home/even/my.gz # (.gz 的绝对路径)
      • 这是一个相对版本。 link = "/vsigzip/Barley.crop.calendar.fill.nc.gz"; raster(link) 返回Error in .rasterObjectFromFile(x, band = band, objecttype = "RasterLayer", : Cannot create a RasterLayer object from this file. (file does not exist)。但是,当我单击 .gz 文件时,会自动提取 .nc 文件。当我尝试使用光栅加载 .nc 文件时,它返回一个错误,我需要选择一个变量,但确实可以识别它。
      • 我的问题是不是因为gz文件里面的文件是netcdf文件而不是tif文件
      猜你喜欢
      • 2020-03-06
      • 2016-05-10
      • 2020-05-07
      • 1970-01-01
      • 1970-01-01
      • 2016-10-10
      • 1970-01-01
      • 2020-03-02
      • 1970-01-01
      相关资源
      最近更新 更多