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)
Related
I'm looking to turn a shapefile with roads (which includes a column of length per road) in the Eastern half of the USA into a raster of 1x1km of road density, using R.
I can't find a straightforward way in Arcmap (Line density works with a radius from the cell center instead of just the cell).
Here is a solution that creates polygons from the raster cells (adapted from my answer here). You may need to to this for subsets of your dataset and then combine.
Example data
library(terra)
v <- vect(system.file("ex/lux.shp", package="terra"))
roads <- as.lines(v)
rs <- rast(v)
Solution
values(rs) <- 1:ncell(rs)
names(rs) <- "rast"
rsp <- as.polygons(rs)
rp <- intersect(roads, rsp)
rp$length <- perim(rp) / 1000 #km
x <- tapply(rp$length, rp$rast, sum)
r <- rast(rs)
r[as.integer(names(x))] <- as.vector(x)
plot(r)
lines(roads)
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
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.
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')
I have two rasters for the same day but with different swaths. I want to combine them but I am conscious that retrieval algorithms may be different. Both rasters are of the same dimension. What's the easiest way to do this in R please? I will be running this on a list.
library(raster)
A <- raster(nrows=108, ncols=21, xmn=0, xmx=10)
A[] <- 1:ncell(A)
xy <- matrix(rnorm(ncell(A)),108,21)
B<- raster(xy)
## Induce NAs in raster B:
B[sample(1:ncell(B), 1000)] <- NA
## Confirm we have 1000 NAs:
sum(is.na(B[]))
If there were NA pixels in raster B that had values in the other raster A, how do I fill the raster B based on the correlation between points with values in both rasters A and B, please?
As long as your rasters are of equal dimension and spatially coincident:
## Create indices for pixels that are NA in B and not NA in A:
indices <- is.na(B)[] & !is.na(A)[]
B[indices] <- A[indices]
If they are not already of the same dimension and spatially coincident then use the resample() function first to match the rasters to the desired dimensions and extent (projecting first if necessary using projectRaster()).