Downloading SRTM data with raster package?

孤街醉人 提交于 2019-12-23 12:11:52

问题


I'm trying to get SRTM data with "raster" package in R, but as soon as I'm choosing SRTM in getData command, I would get the following error:

library(raster)

srtm <- getData('SRTM', lon=16, lat=48)
trying URL 'ftp://xftp.jrc.it/pub/srtmV4/tiff/srtm_40_03.zip'
trying URL 'http://hypersphere.telascience.org/elevation/cgiar_srtm_v4/tiff/zip/srtm_40_03.ZIP'
downloaded 572 bytes

Error in .SRTM(..., download = download, path = path) : file not found
In addition: Warning messages:
1: In utils::download.file(url = aurl, destfile = fn, method = "auto",  :
  URL 'ftp://xftp.jrc.it/pub/srtmV4/tiff/srtm_40_03.zip': status was 'Couldn't resolve host name'
2: In utils::unzip(zipfilename, exdir = dirname(zipfilename)) :
  error 1 in extracting from zip file

Any Idea what is this error for ?


回答1:


I have the same problem, it seems to be a bug. The getData function in raster package checks for availability of the raster file in three different url's.

1. ftp://xftp.jrc.it/pub/srtmV4/tiff/FILENAME
2. http://hypersphere.telascience.org/elevation/cgiar_srtm_v4/tiff/zip/FILENAME
3. http://srtm.csi.cgiar.org/SRT-ZIP/SRTM_V41/SRTM_Data_GeoTiff/FILENAME

The first two of them (as of today) are not working or cannot be accessible. However for some reason a small bit data is getting transferred across the server, so the package assumes it to be a available file only to reach an error by utils. The third url however is most trusted one among the three.

I did some digging and came up with the following function after slightly modifying the raster package itself so that it uses the third url. You can input Longitude and Latitude values here. Note that this is only useful if you want to download the files based on Latitude & Longitude.

SRTM<-function(lon, lat) {
  stopifnot(lon >= -180 & lon <= 180)
  stopifnot(lat >= -60 & lat <= 60)
  rs <- raster(nrows=24, ncols=72, xmn=-180, xmx=180, ymn=-60, ymx=60 )
  rowTile <- rowFromY(rs, lat)
  colTile <- colFromX(rs, lon)
  if (rowTile < 10) { rowTile <- paste('0', rowTile, sep='') }
  if (colTile < 10) { colTile <- paste('0', colTile, sep='') }

  f <- paste('srtm_', colTile, '_', rowTile, sep="")
  theurl <- paste("http://srtm.csi.cgiar.org/wp-content/uploads/files/srtm_5x5/TIFF/", f, ".ZIP", sep="")
  utils::download.file(url=theurl, destfile='srtm_40_0.zip', method="auto", quiet = FALSE, mode = "wb", cacheOK = TRUE)
}

Example:

SRTM(lon=16, lat=48)

This will result in a file named srtm_40_03.zip in your folder which would normally contain a tif, a hdr and a tfw file of the same name. Use them for further process as usual.

EDIT DATE 22-JAN-19: The srtm link as changed (as well), the above code has been adapted to reflect this.




回答2:


I had the exact same error while trying to downldoad SRTM data using raster::getData(). As mentioned by samAct, the problem is related to the URL's that are not accessible anymore.

My solution was to edit the getData function so that it tries first the http://srtm.csi.cgiar.org/SRT-ZIP/SRTM_V41/SRTM_Data_GeoTiff/FILENAME URL.

To use my edited version of the raster package simply use `devtools::install_github("pokyah/raster"). This will overwrite your current version and make the getData work with the valid URL.

devtools::install_github("pokyah/raster")
library(raster)

Then, you can use this function to download the SRTM data for your region of interest :

# @param country_code.chr a character specifying the ISO contrycode. Ex : BE for belgium
# @param NAME_1.chr a character specifying the NAME_1 value for lower than country level information
# @param aggregation_factor.num a numeric specifying the aggregation factor to get the desired spatial resolution
# @param EPSG.chr a character specifying the EPSG code of the desired Coordiante Reference System (CRS)
# @param path.chr a character specifying the path where to dowload the SRTM data

build_highRes_terrain_rasters.fun <- function(country_code.chr, NAME_1.chr=NULL, aggregation_factor.num=NULL, EPSG.chr=NULL, path.chr) {
  # Path to downloaded SRTM Tiles refs
  srtm.tiles.ref <- raster::shapefile("<PATH_TO_DOWNLOADED_TILES_REFS")

  # Get country geometry first
  extent.sp <- raster::getData('GADM', country=country_code.chr, level=1)

  if(!is.null(NAME_1.chr)){
    extent.sp <- subset(extent.sp, NAME_1 == NAME_1.chr)
  }

  # Intersect extent geometry and tile grid
  intersects <- rgeos::gIntersects(extent.sp, srtm.tiles.ref, byid=T)
  tiles      <- srtm.tiles.ref[intersects[,1],]

  # Download tiles using getData
  # inspired from https://www.gis-blog.com/download-srtm-for-an-entire-country/
  srtm_list  <- list()
  for(i in 1:length(tiles)) {
    lon <- extent(tiles[i,])[1]  + (extent(tiles[i,])[2] - extent(tiles[i,])[1]) / 2
    lat <- extent(tiles[i,])[3]  + (extent(tiles[i,])[4] - extent(tiles[i,])[3]) / 2

    tile <- getData('SRTM', #data are downloaded from http://www.cgiar-csi.org/. See getData do of pokyah/raster repo on github
                    lon=lon,
                    lat=lat,
                    download = FALSE,
                    path = path.chr)

    srtm_list[[i]] <- tile
  }

  # Mosaic tiles
  srtm_list$fun <- mean
  srtm_mosaic.ras <- do.call(raster::mosaic, srtm_list)

  # Crop tiles to extent borders
  extent.elevation.ras <- raster::crop(srtm_mosaic.ras, extent.sp)
  extent.elevation.ras <- raster::mask(extent.elevation.ras, extent.sp)

  # transform to desired CRS
  if(!is.null(EPSG.chr)){
    raster::projectRaster(extent.elevation.ras, crs = toString((dplyr::filter(rgdal::make_EPSG(), code==EPSG.chr))$prj4))
  }

  # aggregate to lower resolution
  # inspired from https://stackoverflow.com/questions/32278825/how-to-change-the-resolution-of-a-raster-layer-in-r
  if(!is.null(aggregation_factor.num)){
    extent.elevation.ras <- raster::aggregate(extent.elevation.ras, fact=aggregation_factor.num)
  }

  # compute the slope from the elevation
  # inspired from https://rpubs.com/etiennebr/visualraster
  extent.slope.ras <- raster::terrain(extent.elevation.ras, opt="slope", unit="degrees")
  extent.aspect.ras <- raster::terrain(extent.elevation.ras, opt="aspect", unit="degrees")
  extent.roughness.ras <- raster::terrain(extent.elevation.ras, opt="roughness")

  # compute the aspect from the elevation
  extent.terrain.ras = raster::stack(
    extent.elevation.ras,
    extent.slope.ras,
    extent.aspect.ras,
    extent.roughness.ras)
}

hope it helps !




回答3:


today, 21-01-2019, the link was still broken, even the one corrected by pokyah. New working version at:

devtools::install_github("fedefyco/raster")
library(raster)


来源:https://stackoverflow.com/questions/47997347/downloading-srtm-data-with-raster-package

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!