1

I would like to measure the shortest distance between a raster cell center and the cell center of another raster.

The low resolution raster (dark grey in the picture) has NA cell values and I would like to assign to it the distance in meter to the closest raster cell of the small raster (the one with the small cells in light grey). enter image description here

I tried to use the QGIS Proximity(raster distance) tool but somehow it is not working as I wish.

How do I assign to the big raster cells the distance to the nearest raster cell of the small raster?

There are more than one million raster cells which excludes the possibility to vectorize the raster cells (not enough computing power).

Does anyone know an R approach?

  • Sketch solution: get the XY coordinates of each raster and use the FNN package to compute the nearest neighbours quickly. 1M points not a problem. – Spacedman May 4 at 17:02
  • When you say "closest sell of the small raster" do you mean "closest non-zero" or "non-missing" cell? Can you edit for clarity? – Spacedman May 4 at 17:03
  • @Spacedman I mean the nearest raster cell. I edited it, hoping it is clearer now. Every cell of the big raster should have a nearest neighbor small raster cell. – Quarantäne May 4 at 17:51
  • @Spacedman again: getting the XY coordinates of the raster cells is actually a good idea. My raster is irregular, it is not a rectangle or square, otherwise I could use this approach link – Quarantäne May 4 at 18:02
  • 1
    No, your raster is definitely rectangular, but some cells are masked out with NA or zero values. Which is why when you say "nearest cell" I think you mean "nearest white cell" in the diagram. – Spacedman May 4 at 18:26
2

Okay time for a full solution... First make some sample data. You should do this in your question to save us all time creating our own.

First a raster with mostly 0, and 10 NA values scattered around (yours are NAs near the edges, but the code applies):

set.seed(310366)
r1 = raster(ncol=20,nrow=12)
r1[] = 0
r1[sample(ncell(r1),10)]=rep(NA,10)

Next a finer raster that's mostly NA, except for 20 1s, scattered around:

r2 = raster(ncol=200, nrow=120)
r2[] = NA
r2[sample(ncell(r2),20)] = 1

Now plot them.

plot(r1, col="grey")
plot(r2, add=TRUE, col=c("white","black"), legend=FALSE)

two rasters

Next get the cell centres of the NA cells in raster one, and the non-NA cells in raster two. The only difference in these lines apart from r1 and r2 everywhere is a little ! in the second section:

p1 = as.data.frame(r1,xy=TRUE)
p1 = p1[is.na(p1[,3]),1:2]

p2 = as.data.frame(r2, xy=TRUE)
p2 = p2[!is.na(p2[,3]),1:2]

Check it out:

plot(r1, col="grey")
plot(r2, add=TRUE, col=c("white","black"),legend=FALSE)
points(p1$x, p1$y)
points(p2$x, p2$y, pch=3)

rasters and points

Now we are set up for knnx.dist.

dnear = knnx.dist(p2, p1, k=1)

Since k=1 that object is a one-column matrix. We can fill the missing values in r1 with that column:

r1[is.na(r1)] = dnear[,1]

And plot:

plot(r1)
points(p2$x, p2$y, pch=3)

rasters and points with distance

Adding the points lets us check that the missing values have been filled in with the distance to the nearest other point correctly, and it looks reasonable. The dark green (high) cells are further from the points than the brown or lower valued ones, although the colour palette isn't brilliant and if you really want to test this you'd set up some data with known distance and check thoroughly.

| improve this answer | |
  • It is working! Thank you very much for the perfect explanation – Quarantäne May 6 at 8:14
  • Now wrap it in a function: fill_NA_nearest=function(r1, r2){.... – Spacedman May 6 at 9:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.