R and Export raster extent as esri shapefile - r

I am working with a raster dataset in R and would like to make a polygon of its extent and then export this as an ESRI shapefile. My problem, or at least what I think is the problem, occurs when I try to export the spatial polygon dataframe as I get the following error:
Error in writeOGR(p, ".", "xyz_extent", driver="ESRI Shapefile") :
obj must be a SpatialPointsDataFrame, SpatialLinesDataFrame or
SpatialPolygonsDataFrame
My script follows. Please note, I have a beginner skillset when working with spatial data in R so I do ask that answers be well described. Thank you in advance to those that chime in.
Script:
library(raster)
xyz <- raster("xyz.asc")
crs(xyz)
# CRS arguments: +proj=tmerc +lat_0=0 +lon_0=-115 +k=0.9992 +x_0=500000 +y_0=0 +datum=NAD83 +units=m +no_defs +ellps=GRS80 +towgs84=0,0,0
e <- extent(xyz)
p <- as(e, 'SpatialPolygons')
crs(p) <- crs(xyz)
library(rgdal)
writeOGR(p, ".", "xyz_extent", driver="ESRI Shapefile")

The error occurs because you have a SpatialPolygons, not a SpatialPolygonsDataFrame object. An easy way around this is to use the shapefile function instead.
library(raster)
xyz <- raster()
e <- extent(xyz)
p <- as(e, 'SpatialPolygons')
crs(p) <- crs(xyz)
shapefile(p, "xyz_extent.shp")
And you can read the file again with the same function
x <- shapefile("xyz_extent.shp")

Related

How to change the projection of a map (created from ETOPO1 bathymetry data) in R

I have downloaded a TIF file from the ETOPO1 website, which contains bathymetry information. I have plotted the bathymetry map using the following code:
bathy <- raster("ice_data.tif")
plot(bathy)
bathy[bathy>0] <-0
dev.new()
plot(bathy)
intervals<-c(-0.000001, -500, -1000, -5000)
colourscale<-colorRampPalette(c("blue","lightblue1"))
plot(bathy, breaks=intervals, col = colourscale(4))
I am wanting to change the project of the map (to this: +proj=laea +lon_0=-21.09375 +lat_0=-90 +datum=WGS84 +units=m +no_defs). I have tried using the code below (with st_transform() function), but am getting an error message
Error in UseMethod("st_transform") : no applicable method for 'st_transform' applied to an object of class "c('RasterLayer', 'Raster', 'BasicRaster')
new_map = st_transform(bathy, crs = "+proj=laea +lon_0=-21.09375 +lat_0=-90 +datum=WGS84 +units=m +no_defs")
Has anyone got any suggestions? It would be very much appreciated!
Thanks
For rasters you need to use the raster::crs() function to change the crs.
The sf::st_transform() function needs an sf object as input.
Try:
new_crs <- "+proj=laea +lon_0=-21.09375 +lat_0=-90 +datum=WGS84 +units=m +no_defs"
crs(bathy) <- new_crs

How to project Hydrologic Rainfall Analysis Data (MPE/AHPS) raster to a usable format?

Apparently NOAA and the NWS use a non-traditional projection for some of their rainfall data and don't offer a lot of help in terms of projecting it to a traditional format for other users. I've had a bit of success in getting the raster to overlay for part of the United States but it still isn't quite right.
I'm hoping someone can help me decipher what I am missing and correct the projection of this data.
You can find more information of this data here: https://polyploid.net/blog/?p=216
https://water.weather.gov/precip/download.php
library(tidyverse)
library(raster)
library(rgdal)
library(sp)
setwd("C:/Users/MPE_Data/")
file_list <- list.files("201809")
grib0<-raster::brick("201809//ST4_2018091307_24h.nc", varname="APCP_SFC")[[1]]
grib0#crs
crs(grib0) <- "+proj=longlat +a=6371200 +b=6371200 +no_defs"
crs(grib0) <- "+proj=stere +lat_0=90 +lat_ts=60 +lon_0=-105 +x_0=0 +y_0=0 +a=6371200 +b=6371200 +units=m +no_defs"
us_shp <- rgdal::readOGR("C:/Users/cb_2017_us_state_500k/US_clipped.shp")
shp <- rgdal::readOGR("C:/Users/nc_sc_counties_wgs1984.shp")
wgs<-"+proj=longlat +datum=WGS84 +ellps=WGS84 +no_defs"
wgsraster <- projectRaster(grib0, crs=wgs)
plot(wgsraster)
shp <- spTransform(shp, CRS(wgs))
us_shp <- spTransform(us_shp, CRS(wgs))
plot(shp,add=TRUE)
plot(us_shp,add=TRUE)
I couldn't find your exact map but here is an example using recent precipitation data. You don't need to assign a CRS as the netCDF file already has a CRS associated with it, you can simply projectRaster. Also the NOAA website has the option to download to geoTIFF which I would recommend if you are more comfortable with that.
require(raster)
require(ncdf4)
require(maptools)
data(wrld_simpl)
us_shp=wrld_simpl[which(wrld_simpl$NAME=="United States"),]
rs=raster::brick("./nws_precip_1day_20200509_netcdf/nws_precip_1day_20200509_conus.nc",varname="observation")[[1]]
rs#crs ##note already has a crs associated with it
+proj=stere +lat_0=90 +lat_ts=60 +lon_0=-105 +x_0=0 +y_0=0 +a=6371200
+b=6371200 +units=m +no_defs
##assign the pixels with -10000 to NA.
NAvalue(rs) = -10000
##reproject to longlat WGS84
rs=projectRaster(rs,crs=crs(us_shp))
plot(rs,col=rainbow(100))
lines(us_shp)
##note the data extends outside the bounds of country
##use mask to remove data that is not over the land area
rs=mask(rs,us_shp)
plot(rs,col=rainbow(100)
lines(us_shp)
Note that the maximum value of rs changed from 7.8 to 7.0 due to the bilinear interpolation method used in projectRaster. You need to consider whether you require bilinear or nearest neighbour interpolation and if you need to be specific about the output raster resolution and extent I would suggest supplying a model raster for the to argument.
Edited to incorporate #Robert Hijmans' suggestion.

Plotting a shapefile on a raster layer in R

I want to plot a raster layer with points from a shapefile on top.
I have checked previous answers on this, but i still have a problem.
I can plot the point shapefile and the raster layer separately without problem, but not together.
As far as I can see they should be in same projection and location.
require(maptools)
myproj <- "+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0"
shape <- readShapeSpatial("directory/mypoints.shp", proj4string = CRS(myproj))
plot(r <- raster(listVI[200]))
plot(shape)
I found the answer, I will put it here for others who may encounter same problem.
The solution is simply: (as long as raster and shapefile is in same CRS)
plot(r)
plot(shape, add = TRUE)

R Levelplot overlaying two SpatialPolygonsDataFrame on a RasterLayer projection

posted also on gis.stackexchange
I'm having some trouble plotting a RasterLayer and a SpatialPolygonsDataFrame in a level plot in R. Something is wrong with the projection, but I don't understand what.
Here you can find my
reproducible example data and code:
library(sp)
library(rgdal)
library(rgeos)
library(raster)
library(rasterVis)
library(maptools)
setwd("C:/...path_to/test2")
data<-read.csv("test.csv", header=TRUE)
#creating the raster from a data.frame and giving projection
raster<-rasterFromXYZ(data, crs="+proj=longlat")
raster_proj<-projectRaster(raster, crs="+proj=longlat +datum=WGS84
+ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +no_defs")
#loading shapes
nuts<-readShapePoly("NUTS_RG_WGS84.shp", proj4string=CRS("+proj=longlat"))
countries<-readShapePoly("countries.shp", proj4string=CRS("+proj=longlat"))
#subsetting the raster
raster_clip<- crop(raster_proj, countries, snap="near")
#plot
p.strip <- list(cex=1.5, lines=1, fontface='bold')
x.scale <- list(cex=1.5)
y.scale <- list(cex=1.5)
label <- list(labels=list(width=1, cex=1.5), height=0.95)
levelplot(raster_clip, par.settings = RdBuTheme, margin=FALSE,
at=seq(min(na.omit(values(raster_clip))), max(na.omit(values(raster_clip))), length.out=15),scales=list(x=x.scale, y=y.scale),
par.strip.text=p.strip, colorkey=label, xlab=list(label="Longitude", cex=2), ylab=list(label="Latitude", cex=2))+
layer(sp.polygons(nuts))+layer(sp.polygons(countries))
The error message is:
Error: Attempted to create layer with no geom.
But the raster and the polygons are in the same projection. I also tried to re-project the polygons using:
nuts <- spTransform(nuts, CRS("+proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +no_defs"))
countries <- spTransform(countries, CRS("+proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +no_defs"))
Any Idea?
If you don't want to or can't detach ggplot2 because you need it for something else, you can also call the layer function specifically from the latticeExtra package using:
levelplot(myRaster) +
latticeExtra::layer(sp.polygon(myPolygon))
detach("package:ggplot2", unload=TRUE)
I solved this problem by detaching ggplot2 from my library.

Extracting points with polygon in R

I'm trying to extract points by a polygon using the 'sp' package function 'over'
library(sp)
library(rgeos)
#my polygon plgn (many polygon features in one)
plot(plgn)
proj4string(plgn) = CRS("+proj=utm +zone=46 +datum=WGS84 +units=m +no_defs")
#giving spatial reference to point data d
coordinates(d) <- ~X+Y
proj4string(d) = CRS("+proj=utm +zone=46 +datum=WGS84 +units=m +no_defs")
#USE overlay (there are many NAs)
overlay=d[!is.na(over(d, plgn)),]
Unfortunately, I'm getting an ERROR
Error in d[!is.na(over(d, plgn)), ] :
matrix argument not supported in SpatialPointsDataFrame selection
Any idea?? Is it because my polygon contains 100s of features?
Your plgn is a SpatialPolygonsDataFrame, and as such, is.na(over(d, plgn)) returns a logical matrix. This cannot be used to subset your SpatialPoints*. You can do the following to convert the logical matrix to a vector that the subsetting operation can accommodate:
d[complete.cases(over(d, plgn)), ]

Resources