How to save WMS images to raster with ows4R so that they can be plotted with other packages such as tmap?
Florent-Demoraes opened this issue · 2 comments
Hello,
I was wondering wether they would be a way of downloading images from a WMS server so as to create a local raster file and to plot it with other packages such as tmap for instance.
Here is what I am doing til now, but it is quite complicated and it does not rely on ows4R package.
The code below is derived from that published here : https://gist.github.com/obrl-soil/73916c6fe223d510293cb1a2bbf2879a
library(sf)
library(raster)
library(httr)
library(tmap)
library(RStoolbox)
web service - QLD Imagery Whole of State Public basemap (no WCS unforts, hence all this)
qldimg_wms <- 'https://spatial-img.information.qld.gov.au/arcgis/services/Basemaps/LatestSatelliteWOS_AllUsers/ImageServer/WMSServer?'
Cubesat 2.4m res, from Q3 2017 @ Oct 2019
going to grab a bit from over Brisbane CBD for testing.
bb <- structure(c(153.00795, -27.49034, 153.04041, -27.45917),
names = c("xmin", "ymin", "xmax", "ymax"),
class = "bbox", crs = sf::st_crs(4326))
bbstr <- paste0(as.vector(bb), collapse = ',')
bbm <- st_bbox(st_transform(st_as_sfc(bb), 28356)) # local UTM grid
about as close to src alignment as u need for a quick grab:
w <- plyr::round_any(abs(bbm[[3]] - bbm[[1]]), 2.4) / 2.4
h <- plyr::round_any(abs(bbm[[2]] - bbm[[4]]), 2.4) / 2.4
construct WMS URL
img_url <-
paste0(qldimg_wms, 'service=WMS', '&version=1.3.0', '&request=GetMap',
'&layers=LatestSatelliteWOS_AllUsers', '&styles=', '&crs=CRS%3A84',
'&bbox=', bbstr, '&width=', w, '&height=', h, '&format=image%2Fpng')
download and save locally
httr::GET(url = img_url
, write_disk(file.path(getwd(), 'BNE.png'), overwrite = TRUE)
)
import PNG
img <- png::readPNG(file.path(getwd(), 'BNE.png'))
convert each band to a raster
rasR <- raster(img[,,1], xmn = bb[1], xmx = bb[3], ymn = bb[2], ymx = bb[4])
rasG <- raster(img[,,2], xmn = bb[1], xmx = bb[3], ymn = bb[2], ymx = bb[4])
rasB <- raster(img[,,3], xmn = bb[1], xmx = bb[3], ymn = bb[2], ymx = bb[4])
create a stack
ras <- stack(rasR, rasG, rasB)
georeference image
crs(ras) <- CRS('+init=EPSG:4326')
write image
writeRaster(ras, file.path(getwd(), 'BNE.tif'))
plotting options:
plotRGB in base
plotRGB(ras, scale = 1, maxpixels = ncell(ras), interpolate = TRUE)
tm_rgb in tmap (bit slow but has interp = T by default)
tm_shape(ras) +
tm_rgb(max.value = 1)
ggRGB in RStoolbox (ggplot-friendly wrapper for the above)
ggRGB(ras, r = 1, g = 2, b = 3, maxpixels = ncell(ras))
@Florent-Demoraes thanks for this, what you shared is actually really useful for investigating how to plug the getMap operation. As soon as I have some time, I will start investigating it
Hi,
If that can help, to implement getMap operation in happign::get_wms_raster()
I used gdal warp operation from sf::gdal_utils()
.
It's quite straightforward :
- Building url for GDAL with WMS driver
- Use
gdal_utils("warp")
to a tempfile - Import in R with
terra::rast()