Projection error with autoKrige function - r

I have a problem with autoKrig function and I try to make a reproducible example here:
library(automap)
library(raster)
library(dismo)
bio <- getData("worldclim", var="bio", res=10)
bio1 <- raster(bio, layer=1)
bio12 <- raster(bio, layer=12)
predictors <- stack(bio1, bio12)
bg <- randomPoints(bio1, 50)
data <- extract(predictors, bg)
data <- cbind(bg,data)
data <- data.frame(data)
coordinates(data)=~x+y
proj4string(data) = CRS("+proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0")
kg <- autoKrige(bio1~bio12, data, new_data=predictors)
This will result in:
Error in autoKrige(bio1 ~ bio12, data, new_data = predictors) :
Either input_data or new_data is in LongLat, please reproject.
input_data: +proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0
new_data: +proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0
I get the same error with my original data. I appreciate any help.

If you read the help file, it will tell you why it is throwing that error.
autoKrige performs some checks on the coordinate systems of input_data
and new_data. If one or both is NA, it is assigned the projection of
the other. If they have different projections, an error is raised.
If one or both has a non-projected system (i.e. latitude-longitude), an error is raised. This error is raised because 'gstat does use
spherical distances when data are in geographical coordinates, however
the usual variogram models are typically not non-negative definite on
the sphere, and no appropriate models are available' (Edzer Pebesma on
r-sig-geo).
It looks like you need to project your data before calling autoKrige.

Related

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.

R - transition function for modelling surface water flow with gdistance

I am trying to model overland (surface) water flow from specified origin points to a single downslope goal point using the gdistance shortestPath function. I need help with defining the appropriate transitionFunction for this, as I need to make sure the least cost path only allows water to flow along the path to elevation cells of equal or lesser value than the previous cell. The transitionFunction in the example below selects the minimum elevation cell but, based on the transitionFunction I have defined, this value may still be greater than the previous cell value.
I realize that, when the above is defined as I want it, the path may terminate before reaching the goal point. This is fine, although I would ideally like to be able to preserve the path from the origin to wherever it terminates if possible.
Also, if anyone knows of a different R package capable of modelling this kind of thing, please let me know.
library(gdistance)
library(raster)
library(elevatr)
library(sp)
#load example DEM raster
data(lake)
elevation <- get_elev_raster(lake, z = 9)
#remove negative elevation values from raster
elevation[elevation < 0] <- NA
#create origin and goal points with same projection as elevation raster
origin <- SpatialPoints(cbind(1790000, 640000), proj4string = CRS("+proj=aea +lat_1=20 +lat_2=60 +lat_0=40 +lon_0=-96 +x_0=0 +y_0=0 +datum=NAD83 +units=m +no_defs +ellps=GRS80 +towgs84=0,0,0"))
goal <- SpatialPoints(cbind(1820000, 540000), proj4string = CRS("+proj=aea +lat_1=20 +lat_2=60 +lat_0=40 +lon_0=-96 +x_0=0 +y_0=0 +datum=NAD83 +units=m +no_defs +ellps=GRS80 +towgs84=0,0,0"))
#create df data and convert to SpatialPointsDataFrame
odf <- data.frame("flowreg" = 1)
gdf <- data.frame("flowreg" = 2)
origindf <- SpatialPointsDataFrame(origin, odf)
goaldf <- SpatialPointsDataFrame(goal, gdf)
trCost1 <- transition(elevation, transitionFunction=function(x) 1/min(x), directions=8)
trCost1gc <- geoCorrection(trCost1, type="c")
plot(raster(trCost1))
sPath1 <- shortestPath(trCost1, origin, goal,
output="SpatialLines")
plot(elevation)
plot(origindf, add = TRUE, col='red', cex = 5)
plot(goaldf, add = TRUE, col='green', cex = 5)
lines(sPath1)
I have found the GRASS GIS (accessed in R using rgrass7) r.drain function OR raster::flowPath achieve what I am trying to do in the above question.

Spatial polygons with messed up shape

I am new to spatial data. My goal is to get the gpx files from openstreetmap and plot polygons of Hungary's boundaries. I could successfully plot the boundaries under Járások but there are some boundaries under Kistérségek which are messed up, containing loops between points.
Image
Reproducable example for a specific boundary
library(XML)
library(magrittr)
library(sp)
parsed <- xmlParse("http://osmrm.openstreetmap.de/gpx.jsp?relation=1368104") %>% xmlToList()
coord <- do.call(rbind, parsed$rte)
name <- coord[1, 1]
coord <- coord[-(1:2), ]
coord <- apply(coord, 2, as.numeric)
poly <- Polygons(list(Polygon(coord)), name)
sp <- SpatialPolygons(list(poly), proj4string = CRS("+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0"))
plot(sp)
Result
Is the error because I missed something, or is it simply an issue with openstreetmap data? Any help is appreciated.

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)), ]

Map raw data and mean data based on the shapefile

sI have the dataset (pts) like this:
x <- seq(-124.25,length=115,by=0.5)
y <- seq(26.25,length=46,by=0.5)
z = 1:5290
longlat <- expand.grid(x = x, y = y) # Create an X,Y grid
pts=data.frame(longlat,z)
names(pts) <- c( "x","y","data")
I knew that I can map the dataframe (pts) into a map by doing:
library(sp)
library(rgdal)
library(raster)
library(maps)
coordinates(pts)=~x+y
proj4string(pts)=CRS("+init=epsg:4326") # set it to long, lat
pts = spTransform(pts,CRS(" +init=epsg:4326 +proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs +towgs84=0,0,0"))
pts <- as(pts, "SpatialPixelsDataFrame")
r = raster(pts)
projection(r) = CRS(" +init=epsg:4326 +proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs +towgs84=0,0,0")
plot(r)
map("usa",add=T)
Now I would like to create a separate map which shows the means of pts across different regions. The shapefile I want to use is from ftp://ftp.epa.gov/wed/ecoregions/cec_na/NA_CEC_Eco_Level2.zip , however, this is a north america map. How can I create the map showing only US based on this north america map? Or is there another better way to do this? thanks so much.
I think that cutting out the non-US data based on the data in the shapefile alone would be hard, since the regions do not correspond to political boundaries - that could be done with rgeos though.
Assuming that "eco" is a SpatialPolygonsDataFrame read in by rgdal::readOGR or maptools::readShapeSpatial, see the available key data for indexing:
sapply(as.data.frame(eco), function(x) if(!is.numeric(x)) unique(x) else NULL)
If you just want to plot it, set up a map with only the US region to start with and then overplot.
library(maps)
map("usa", col = "transparent")
We see that the data is in Lambert Azimuthal Equal Area:
proj4string(eco)
[1] " +proj=laea +lat_0=45 +lon_0=-100 +x_0=0 +y_0=0 +a=6370997 +b=6370997 +units=m +no_defs"
So
require(rgdal)
eco.laea <- spTransform(eco, CRS("+proj=longlat +ellpse=WGS84"))
plot(eco.laea, add = TRUE)
If you want to plot in the original Lambert Azimuthal Equal Area you'll need to get the bounding box in that projection and start the plot based on that, I just used existing data to make an easy example. I'm pretty sure the data could also be cropped with rgeos against another boundary too, but depends what you actually want.

Resources