Global Raster of geographic distances - r

Im wondering if someone has built a raster of the continents of the world where each cell equals the distance of that cell cell to the nearest shore. This map would highlight the land areas that are most isolated inland.
I would imagine this would simply rasterize a shapefile of the global boundaries and then calculate the distances.

You can do this with raster::distance, which calculates the distance from each NA cell to the closest non-NA cell. You just need to create a raster that has NA for land pixels, and some other value for non-land pixels.
Here's how:
library(raster)
library(maptools)
data(wrld_simpl)
# Create a raster template for rasterizing the polys.
# (set the desired grid resolution with res)
r <- raster(xmn=-180, xmx=180, ymn=-90, ymx=90, res=1)
# Rasterize and set land pixels to NA
r2 <- rasterize(wrld_simpl, r, 1)
r3 <- mask(is.na(r2), r2, maskvalue=1, updatevalue=NA)
# Calculate distance to nearest non-NA pixel
d <- distance(r3)
# Optionally set non-land pixels to NA (otherwise values are "distance to non-land")
d <- d*r2
To create the plot above (I like rasterVis for plotting, but you could use plot(r)):
library(rasterVis)
levelplot(d/1000, margin=FALSE, at=seq(0, maxValue(d)/1000, length=100),
colorkey=list(height=0.6), main='Distance to coast')

Related

How to find area (in hectares) of a raster in R

I am trying to find the area of my raster as shown:
#reading in my raster
abvco2=raster("Avitabile_AGB_Map.tif")
#clipping it to Indonesia
abvco2new=mask(abvco2,Indonesia)
#finding the area
area=area(abvco2new)
However, area() is not helpful as it does not return me with a single area value.
Thank you.
The area function is to compute cell sizes for lon/lat data. From what you say that does not apply to your case. All cells have the same size, so the area of the raster x is
ncell(x) * prod(dim(x)[1:2])
Here is a minimal reproducible example
library(raster)
f <- system.file("external/test.grd", package="raster")
x <- raster(f)
# area of one cell
aone <- prod(dim(x)[1:2])
# total area
ncell(x) * aone
# 84640000
If you want to exclude some areas (e.g. NA) you can use cellStats or zonal
Area excluding NA
b <- cellStats(!is.na(x), sum)
b * aone
#[1] 29237600

How to rasterize shape without exact raster mask?

I have a polygon of the extent I would like to rasterize and i have a raster with the projection and pixelsize etc that I want to use for the polygon, but the raster is smaller than the polygon.
I need to have a new raster with the extent of the polygon but also with the pixelsize and pixel order and place like the smaller raster.
Example data
library(raster)
p <- readRDS(system.file('external/lux.rds', package='raster'))
r <- raster(p[4,])
res(r) <- 0.05
Say you want to rasterize all of p. r has the desired resolution, but the extent is too small.
To get a larger raster, you can do
rr1 <- setExtent(r, extent(p)+res(r), keepres=TRUE, snap=TRUE)
#or
rr2 <- extend(r, extent(p)+res(r))
followed by
x <- rasterize(p, rr1)
You can also do something a variation on this
r2 <- raster(xmn=5.7, xmx=6.6, ymn=49.4, ymx=50.2)
res(r2) <- 0.03
y <- rasterize(p, r2)

How to subset a raster based on grid cell values

My following question builds on the solution proposed by #jbaums on this post: Global Raster of geographic distances
For the purpose of reproducing the example, I have a raster dataset of distances to the nearest coastline:
library(rasterVis); library(raster); library(maptools)
data(wrld_simpl)
# Create a raster template for rasterizing the polys.
r <- raster(xmn=-180, xmx=180, ymn=-90, ymx=90, res=1)
# Rasterize and set land pixels to NA
r2 <- rasterize(wrld_simpl, r, 1)
r3 <- mask(is.na(r2), r2, maskvalue=1, updatevalue=NA)
# Calculate distance to nearest non-NA pixel
d <- distance(r3) # if claculating distances on land instead of ocean: d <- distance(r3)
# Optionally set non-land pixels to NA (otherwise values are "distance to non-land")
d <- d*r2
levelplot(d/1000, margin=FALSE, at=seq(0, maxValue(d)/1000, length=100),colorkey=list(height=0.6), main='Distance to coast (km)')
The data looks like this:
From here, I need to subset the distance raster (d), or create a new raster, that only contains cells for which the distance to coastline is less than 200 km. I have tried using getValues() to identify the cells for which the value <= 200 (as show below), but so far without success. Can anyone help? Am I on the right track?
#vector of desired cell numbers
my.pts <- which(getValues(d) <= 200)
# create raster the same size as d filled with NAs
bar <- raster(ncols=ncol(d), nrows=nrow(d), res=res(d))
bar[] <- NA
# replace the values with those in d
bar[my.pts] <- d[my.pts]
I think this is what you are looking for, you can treat a raster like a matrix here right after you d <- d*r2 line:
d[d>=200000]<-NA
levelplot(d/1000, margin=FALSE, at=seq(0, maxValue(d)/1000, length=100),colorkey=list(height=0.6), main='Distance to coast (km)')
(in case you forgot: the unit is in meters so the threshold should be 200000, not 200)

R - find point farthest from set of points on rasterized USA map

New to spatial analysis on R here. I have a shapefile for the USA that I downloaded from HERE. I also have a set of lat/long points (half a million) that lie within the contiguous USA.
I'd like to find the "most remote spot" -- the spot within the contiguous USA that's farthest from the set of points.
I'm using the rgdal, raster and sp packages. Here's a reproducible example with a random sample of 10 points:
# Set wd to the folder tl_2010_us_state_10
usa <- readOGR(dsn = ".", layer = "tl_2010_us_state10")
# Sample 10 points in USA
sample <- spsample(usa, 10, type = "random")
# Set extent for contiguous united states
ext <- extent(-124.848974, -66.885444, 24.396308, 49.384358)
# Rasterize USA
r <- raster(ext, nrow = 500, ncol = 500)
rr <- rasterize(usa, r)
# Find distance from sample points to cells of USA raster
D <- distanceFromPoints(object = rr, xy = sample)
# Plot distances and points
plot(D)
points(sample)
After the last two lines of code, I get this plot.
However, I'd like it to be over the rasterized map of the USA. And, I'd like it to only consider distances from cells that are in the contiguous USA, not all cells in the bounding box. How do I go about doing this?
I'd also appreciate any other tips regarding the shape file I'm using -- is it the best one? Should I be worried about using the right projection, since my actual dataset is lat/long? Will distanceFromPoints be able to efficiently process such a large dataset, or is there a better function?
To limit raster D to the contiguous USA you could find the elements of rr assigned values of NA (i.e. raster cells within the bounding box but outside of the usa polygons), and assign these same elements of D a value of NA.
D[which(is.na(rr[]))] <- NA
plot(D)
lines(usa)
You can use 'proj4string(usa)' to find the projection info for the usa shapefile. If your coordinates of interest are based on a different projection, you can transform them to match the usa shapefile projection as follows:
my_coords_xform <- spTransform(my_coords, CRS(proj4string(usa)))
Not sure about the relative efficiency of distanceFromPoints, but it only took ~ 1 sec to run on my computer using your example with 10 points.
I think you were looking for the mask function.
library(raster)
usa <- getData('GADM', country='USA', level=1)
# exclude Alaska and Hawaii
usa <- usa[!usa$NAME_1 %in% c( "Alaska" , "Hawaii"), ]
# get the extent and create raster with preferred resolution
r <- raster(floor(extent(usa)), res=1)
# rasterize polygons
rr <- rasterize(usa, r)
set.seed(89)
sample <- spsample(usa, 10, type = "random")
# Find distance from sample points to cells of USA raster
D <- distanceFromPoints(object = rr, xy = sample)
# remove areas outside of polygons
Dm <- mask(D, rr)
# an alternative would be mask(D, usa)
# cell with highest value
mxd <- which.max(Dm)
# coordinates of that cell
pt <- xyFromCell(r, mxd)
plot(Dm)
points(pt)
The distances should be fine, also when using long/lat data. But rasterFromPoints could indeed be a bit slow with a large data set as it uses a brute force algorithm.

Count points from shapefile within raster cells

Is it in some way possible to count the number of points from a shapefile within each cell of a rasterfile using R?
The Idea is to retrieve a dataframe containing one row for each cell in the raster and a column with the number of points within that cell while keeping the original value from the raster cell.
library(raster)
# example raster and points data
r <- raster(ncols=10, nrows=5)
n <- 100
x <- runif(n) * 360 - 180
y <- runif(n) * 180 - 90
xy <- cbind(x, y)
rp <- rasterize(xy, r, fun=function(x,...)length(x))
as.data.frame(rp)
This answers the question in the title "how to count the number of points from a shapefile within each cell"
library(rgdal) # this package to read and manipulate shapefiles
library(raster) # this package for rasters
shp <- readOGR("my_shape_file.shp") # read in your points from the shape file
ras <- raster("my_raster_file") # read in your raster
shp <- spTransform(shp, projection(ras)) # make sure that the two spatial objects share the same coordinate system
cells <- cellFromXY(ras,shp) # find which cells the points are in
table(cells) # and make a table of number of occurences in each cell

Resources