Comment faire RASTER à partir de données ponctuelles irrégulières sans interpolation

13

J'essayais de créer une image raster à partir d'une base de données de points espacés de manière irrégulière. Les données ressemblent à

> head(s100_ras)
         x       y         z
1 267573.9 2633781 213.29545
2 262224.4 2633781  69.78261
3 263742.7 2633781  51.21951
4 259328.4 2633781 301.98413
5 264109.8 2633781 141.72414
6 255094.8 2633781  88.90244

Je veux ces valeurs «z» dans un maillage que j'ai créé par

# Create a fine mesh grid
my_mesh=expand.grid(seq(min(s100_ras$Y),max(s100_ras$Y),l=100),
                    seq(min(s100_ras$X),max(s100_ras$X),l=100))

Je souhaite également que les valeurs z soient attribuées en tant que «NA» pour les points de maillage situés en dehors des points de données. Les points sur le maillage ressemblent à ceci: https://drive.google.com/file/d/0B6GUNg-8d30vYzlwTkhvaHBFTnc/edit?usp=sharing lorsque je trace

plot(my_mesh)
points(s100_ras$Y, s100_ras$X, pch="*", col='blue')

Le problème est que je ne sais pas comment construire sur cela, les étapes suivantes ne fonctionnent pas parce que ma grille maillée et mes points de données ne sont pas de la même échelle !!

library(rgdal)
library(raster)
xyz<-cbind(my_mesh, s100_ras)
r <- rasterFromXYZ(xyz)
image(r)

Si j'essaie de créer un raster en utilisant simplement les points de données (sans aucun maillage), R génère une erreur car mes données sont espacées de manière irrégulière!

library(sp)
s100_ras <- data.frame(expand.grid(x = s100_ras$Y, y = s100_ras$X), 
                       z = as.vector(s100_ras$mean))
coordinates(s100_ras) <- ~x+y
proj4string(s100_ras) <- CRS("+proj=utm +zone=46 +datum=WGS84")
gridded(s100_ras) = TRUE

suggested tolerance minimum: 0.916421 
Error in points2grid(points, tolerance, round) : 
  dimension 1 : coordinate intervals are not constant

De plus, j'essayais de jouer avec la fonction 'rasterize' (pour les grilles irrégulières) de 'raster package', mais je ne pouvais pas y arriver :(. Je sais comment interpoler et créer une grille régulière, mais pour le bien d'originalité, je veux ÉVITER l'interpolation. Est-il possible de faire un raster de points de données irrégulièrement espacés sans idw ou méthodes de krigeage?

ToNoY
la source
Le problème avec les grilles espacées irrégulières est que l'algorithme échoue si les points sont trop proches / trop rapprochés. Solution de contournement (non optimale): pourquoi ne pas prendre la distance minimale entre les cellules et créer une grille vectorielle rectangulaire. Joignez ensuite les valeurs moyennes des points à cette grille et pixellisez-la.
Courlis
J'ai eu le même problème - la solution a été d'utiliser SpatialPixelsDataFrameavec l' toleranceargument suggéré (0.916421 dans votre cas).
Tomas

Réponses:

18

Je suppose que vous voulez vos données ponctuelles irrégulières sur un raster régulier. Dans ce cas, la pixellisation devrait fonctionner et les exemples de la? Pixellisation montrent comment. Voici quelque chose basé sur vos données

s100 <- matrix(c(267573.9, 2633781, 213.29545, 262224.4, 2633781, 69.78261, 263742.7, 2633781, 51.21951, 259328.4, 2633781, 301.98413, 264109.8, 2633781, 141.72414, 255094.8, 2633781, 88.90244),  ncol=3,  byrow=TRUE)
colnames(s100) <- c('X', 'Y', 'Z')

library(raster)
# set up an 'empty' raster, here via an extent object derived from your data
e <- extent(s100[,1:2])
e <- e + 1000 # add this as all y's are the same

r <- raster(e, ncol=10, nrow=2)
# or r <- raster(xmn=, xmx=,  ...

# you need to provide a function 'fun' for when there are multiple points per cell
x <- rasterize(s100[, 1:2], r, s100[,3], fun=mean)
plot(x)
Robert Hijmans
la source
excellente solution au problème @ Robert
ToNoY
Désolé, pouvez-vous préciser pourquoi vous ajoutez e <- e + 1000?
mmann1123
@ mman1123 C'est juste pour que les choses fonctionnent avec ces exemples de données étranges. Toutes les coordonnées y sont les mêmes et donc l'étendue est nulle dans la direction y, donc j'ajoute 1000 --- entièrement arbitraire --- pour pouvoir faire un raster à partir de l'étendue.
Robert Hijmans
Existe-t-il une solution pythonique pour cela?
raaj
5

Cela a fonctionné pour moi - la solution était d'utiliser SpatialPixelsDataFrame avec l'argument de tolérance suggéré (0,916421 dans votre cas):

points <- SpatialPoints(s100_ras[,c('x','y')], s100_ras[,c('z')])
pixels <- SpatialPixelsDataFrame(points, tolerance = 0.916421, points@data)
raster <- raster(pixels[,'z'])

cependant, en raison de la valeur de tolérance élevée, le raster ne s'adapte pas très bien aux points d'origine. Pourrait être beaucoup mieux adapté.

Tomas
la source
1
La première ligne de code a un crochet de fermeture manquant?
Antti
@Antti merci, corrigé!
Tomas