rexyai / RestRserve

R web API framework for building high-performance microservices and app backends
https://restrserve.org
276 stars 32 forks source link

set_encode_type to image/tiff #168

Closed Tartomas closed 4 years ago

Tartomas commented 4 years ago

Hello everyone, Thanks for your API system, work pretty well for my intentions. I'm just playing with Satellite information and I would like to create a endpoint to download a .tif file. It is a very common type of information in my field and I do not know how to implemented here as a serialized endpoint. I found that Plumber has a _*serializertiff(..., type = "image/tiff") function, that I think would work in a similar ways.

# example   
raster_handler = function(req, res) {   
library(raster)
tmp <- tempdir()
r <- raster(system.file("external/test.grd", package="raster"))

# take a small part
r <- crop(r, extent(179880, 180800, 329880, 330840) )
rf <- writeRaster(r, filename=file.path(tmp, "test.tif"), format="GTiff", overwrite=TRUE)
tmp = tempfile(fileext = ".tif")
raster::writeRaster(rst, filename=tmp, format="GTiff", overwrite=TRUE)

# form response
res$set_content_type("image/tiff")
# res$set_content_type("image/tiff")
res$set_body(c("tmpfile" = tmp))

Response: 500 Internal Server Error: can't encode body with content_type = 'image/tiff'

Please any would be great !

dselivanov commented 4 years ago

There are couple of options:

  1. add res$encode = identity in the raster_handler()
  2. modify EncodeDecodeMiddleware as described in #156

Your example seems work fine:

library(RestRserve)
library(raster)
raster_handler = function(req, res) {
  tmp <- tempdir()
  r <- raster(system.file("external/test.grd", package="raster"))

  # take a small part
  r <- crop(r, extent(179880, 180800, 329880, 330840) )
  tmp = tempfile(fileext = ".tif")
  raster::writeRaster(r, filename=tmp, format="GTiff", overwrite=TRUE)

  # form response
  res$set_content_type("image/tiff")
  # res$set_content_type("image/tiff")
  res$set_body(c("tmpfile" = tmp))
  res$encode = identity
}

app = Application$new()
app$add_get('/tiff', raster_handler)

back = BackendRserve$new()
back$start(app, 8080)

Another interesting question is how to serve cloud-optimized geotiff (COG) using range request... This is something we need to consider to implement.

Tartomas commented 4 years ago

Hi @dselivanov work perfect ! Just a question, do you know how can a reformat the filename? in order to get a human radeable as client_index_date.tif I just try it and it download a "tiff" image which response with the endpoint name. Thanks again

dselivanov commented 4 years ago

I'm not sure how to assign different name while serving file from disk.