Jak zrobić RASTER z nieregularnych danych punktowych bez interpolacji

13

Próbowałem zrobić obraz rastrowy z bazy danych punktów o nieregularnych odstępach. Dane wyglądają jak

> 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

Chcę te wartości „z” w siatce, którą utworzyłem

# 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))

Chcę również, aby wartości Z były przypisane jako „NA” dla tych punktów siatki, które znajdują się poza punktami danych. Punkty nad siatką wyglądają tak: https://drive.google.com/file/d/0B6GUNg-8d30vYzlwTkhvaHBFTnc/edit?usp=sharing podczas rysowania

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

Problem polega na tym, że nie jestem pewien, jak to zrobić, poniższe kroki nie działają, ponieważ moja siatka siatki i punkty danych nie są w tej samej skali !!

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

Jeśli spróbuję utworzyć raster tylko przy użyciu punktów danych (bez siatki), R zgłasza błąd, ponieważ moje dane są nieregularnie rozmieszczone!

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

Co więcej, próbowałem grać z funkcją „rasterize” (dla nieregularnych siatek) „pakietu raster”, ale nie mogłem się z tym pogodzić :(. Wiem, jak interpolować i robić regularną siatkę, ale dla dobra oryginalności, chcę UNIKNĄĆ interpolacji. Czy można zrobić raster nieregularnie rozmieszczonych punktów danych bez metod idw lub kriging?

NIE
źródło
Problem z siatkami o nieregularnych odstępach polega na tym, że algorytm zawodzi, jeśli punkty leżą zbyt blisko / daleko razem. (Nieoptymalne) obejście: dlaczego nie wziąć minimalnej odległości między komórkami i stworzyć prostokątną siatkę wektorową. Następnie połącz średnie wartości punktów z tą siatką i zrasteryzuj ją.
Curlew
Miałem ten sam problem - rozwiązaniem było użycie SpatialPixelsDataFramesugerowanego toleranceargumentu (w twoim przypadku 0.916421).
Tomas

Odpowiedzi:

18

Zakładam, że chcesz mieć dane o nieregularnych punktach na zwykłym rastrze. W takim przypadku rasterize powinno działać, a przykłady w? Rasterize pokazują, jak to zrobić. Oto coś na podstawie twoich danych

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
źródło
doskonałe rozwiązanie problemu @ Robert
ToNoY
Przepraszamy, możesz wyjaśnić, dlaczego dodajesz e <- e + 1000?
mmann1123
@ mman1123 To tylko po to, aby wszystko działało z tymi dziwnymi przykładowymi danymi. Wszystkie współrzędne y są takie same, a zatem zasięg wynosi zero w kierunku y, więc dodaję 1000 --- całkowicie dowolnych ---, aby móc zrobić raster na podstawie zasięgu.
Robert Hijmans,
Czy istnieje na to pytanie w Pythonie?
raaj
5

To działało dla mnie - rozwiązaniem było użycie SpatialPixelsDataFrame z sugerowanym argumentem tolerancji (w twoim przypadku 0.916421):

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

jednak ze względu na wysoką wartość tolerancji raster nie pasuje zbyt dobrze do oryginalnych punktów. Może być lepiej dopasowany.

Tomas
źródło
1
W pierwszym wierszu kodu brakuje nawiasu zamykającego?
Antti
@Antti dzięki, poprawione!
Tomas