微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

带有R Plumber的REST API-GeoJSON作为输入

如何解决带有R Plumber的REST API-GeoJSON作为输入

我正在尝试使用plumber R Package将函数包装到REST API中。作为Input,函数获取一个形状文件,并在转换后返回 GeoJSON作为输出

#* Return Spatial polygon Object in form of GeoJSON
#* @param dsn:character Path to Shapefile with Name
#* @param design:character one or two
#* @post /sprayermap

sprayer_map <-
  function(dsn,design = c("one","two")) {
# library
require(rgeos)
require(rgdal)
require(sp)
require(raster)
require(cleangeo)

#Import Shapefile
a_shape <- raster::shapefile(dsn)

result <-
  list("success" = F,additional_info = NULL,GeoJSON = NULL)

if (class(a_shape) == "SpatialpolygonsDataFrame") {
  a_shape <- tryCatch (
    rgeos::gBuffer(a_shape,byid = TRUE,width = 0),error = function(err) {
      return(paste("sprayer map : ",err))

    }
  )

  if (design == "one") {
    sprayer_map <- tryCatch (
      aggregate(a_shape,"Rx"),error = function(err) {
        return(paste("sprayer map : ",err))

      }
    )

    sprayer_map@data$Rx <- as.integer(sprayer_map@data$Rx)

  } else if (design == "two") {
    return(paste0("Design Two !"))

  }

  temppath <- file.path(tempdir(),"sprayermap.GeoJSON")
  rgdal::writeOGR(
    sprayer_map,dsn = temppath,layer = "geojson",driver = "GeoJSON",overwrite_layer = TRUE
  )

  if (file.exists(temppath)) {
    GeoJSON <- readLines(temppath)
    result$success <- T
    result$GeoJSON = GeoJSON
    return(result)
  } else {
    return(paste0("GeoJSON Creation Failed!"))
  }

} else {
  return(paste0("Please provide spatial polygon object !"))

}
  }

现在要使REST API在实现和使用方面更加通用,REST API的 Input 需要更改为 GeoJSON 作为请求正文(req $ postBody)代替形状文件路径导入方法。 寻找指导在这种情况下如何实现相同的目标。 Test Input Shape file as well as GeoJSON

解决方法

使用水管工1.0

只需加载一次库。将它们带出端点。

首先创建一个解析器和一个序列化器来解析geojson内容并返回geojson响应。这也可以在端点内部完成。它只是使其更具可重用性。

解析器负责处理请求正文内容。 序列化器对API响应进行编码。

我重新分配了parser_rds和serializer_rds的用途,只是替换为GeoJSON函数。

然后,您使用刚刚创建的解析器和序列化器完成端点。

如有任何疑问,请不要犹豫。

编辑:添加了一个压缩文件夹序列化器。

library(rgeos)
library(rgdal)
library(sp)
library(raster)
library(cleangeo)
library(plumber)

parser_geojson <- function(...) {
  parser_read_file(function(tmpfile) {
    rgdal::readOGR(tmpfile,...)
  })
}
register_parser("geojson",parser_geojson,fixed = c("application/geo+json","application/vnd.geo+json","application/octet-stream"))

serializer_geojson <- function(type = "application/geo+json") {
  serializer_write_file(
    fileext = ".GeoJSON",type = type,write_fn = function(val,tmpfile) {
      rgdal::writeOGR(val,dsn = tmpfile,layer = "geojson",driver = "GeoJSON",overwrite_layer = TRUE)
    }
  )
}
register_serializer("geojson",serializer_geojson)

serializer_shapezip <- function(type = "application/zip") {
  serializer_content_type(type,function(val) {
    tmpdir <- file.path(tempdir(),"output")
    dir.create(tmpdir)
    on.exit({
      if (dir.exists(tmpdir)) {
        unlink(tmpdir,recursive = TRUE)
      }
    },add = TRUE)
    raster::shapefile(val,file.path(tmpdir,"shapefile"))
    tmpfile <- file.path(tmpdir,"shapefile.zip")
    zip(tmpfile,dir(tmpdir)),extras = "-j")
    readBin(tmpfile,what = "raw",n = file.info(tmpfile)$size)
  })
}
register_serializer("shapezip",serializer_shapezip)

dothething <- function(a_shape,design) {
  if (!class(a_shape) == "SpatialPolygonsDataFrame") stop("Please provide spatial polygon object !")
  a_shape <- rgeos::gBuffer(a_shape,byid = TRUE,width = 0)

  if (design == "one") {
    sprayer_map <- aggregate(a_shape,"Rx")
    sprayer_map@data$Rx <- as.integer(sprayer_map@data$Rx)
  } else if (design == "two") {
    # This should return a geojson too since endpoint should have predictable outputs
    stop(paste0("Design Two !"))
  }

  sprayer_map
}

#* Return Spatial Polygon Object in form of GeoJSON
#* @param dsn:file A GeoJSON file
#* @param design:character one or two
#* @parser multi
#* @parser geojson
#* @serializer geojson
#* @post /sprayermap_geojson
function(dsn,design = c("one","two")) {
  a_shape <- dsn[[1]]
  as_attachment(dothething(a_shape,design),"response.GeoJSON")
}

#* Return Spatial Polygon Object in form of GeoJSON
#* @param dsn:character Path to Shapefile with Name
#* @param design:character one or two
#* @serializer shapezip
#* @post /sprayermap_shapefile
function(dsn,"two")) {
  # Import Shapefile
  a_shape <- raster::shapefile(dsn)
  as_attachment(dothething(a_shape,"response.zip")
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。