Interpolasi spatio-temporal dalam R atau ArcGIS?

12

Saya mencoba menghitung nilai curah hujan rata-rata dari sejumlah titik menggunakan alat Inverse Weighted Distance di ArcGIS 9.3.

Masalah saya adalah: setiap titik memiliki deret waktunya sendiri, oleh karena itu proses interpolasi harus dapat dilakukan untuk semua tahun (jenis iterasi bisa dikatakan).

Berikut ini adalah tabel atribut sampel:

ID X Y Name Rain1990 Rain1991 Rain1992 Rain1993 .... Rain2010

1 xx1 yy1 AA 1210 1189 1863 1269 ......  
2 xx2 yy2 BB 1492 1502 2187 1923 ......
......

Adakah yang bisa menunjukkan kepada saya bagaimana melakukan itu?


Sunting 1: Saya akhirnya melakukan ini dengan menggunakan kode C ++ yang membutuhkan grid mask ArcGIS, file data & lokasi semua titik.


Sunting 2: Saya baru-baru ini menggunakan R untuk melakukan tugas interpolasi ini. Anda dapat menggunakan salah satu hydroTSM, gstatatau spacetimepaket. Beberapa tautan contoh di bawah ini:

http://spatial-analyst.net/wiki/index.php?title=Spatial_interpolation_exercises_%28NL%29

http://www.geostat-course.org/Topic_Bivand_2012


Sunting 3: Menambahkan contoh yang berfungsi di bawah ini untuk pembaca di masa mendatang

Tung
sumber
Akankah ini membantu? Seri waktu
Brad Nesom
Itu bisa dilakukan di R, tapi saya membayangkan ada cara sederhana untuk melakukannya langsung di ArcMap. Yang diinginkan OP adalah beralih melalui variabel yang terpisah (tahun) dan menghitung raster yang diinterpolasi untuk setiap variabel yang terpisah. Fakta bahwa nilai-nilai dalam contoh ini adalah tahun berurutan tidak membuat perbedaan.
Andy W
Terima kasih atas balasan Anda. Sebenarnya ada opsi batch ketika klik kanan pada alat IDW tapi tetap itu pekerjaan yang cukup membosankan jika Anda memiliki data per jam atau harian. KR
Tung
@thecatalyst - Jika alat batch IDW melakukan pekerjaan, Anda harus mempostingnya sebagai jawaban. Meskipun mungkin membosankan, jika jarang (karena perkiraan curah hujan tahunan jarang) maka ada sedikit alasan untuk mencari solusi lain.
Andy W
@Andy: Alat batch akan membantu jika Anda memiliki jumlah terbatas tetapi saya memiliki ratusan data yang membuat gagasan untuk menggunakannya sedikit tidak realistis. Saya masih mencari solusi untuk masalah ini. KR
Tung

Jawaban:

3

Saya memecahkan ini dengan memasukkan iterator "Pemilihan Fitur" ke dalam model. (Di Window ModelBuilder, di bawah menu Insert-> Iterators.)

Gunakan bidang waktu Anda sebagai variabel "grup per". Dengan melakukan ini, model akan mengulangi sekali untuk setiap kali di kelas fitur Anda.

Kemudian pasang alat interpolasi pilihan Anda (spline, IDW, apa pun) ke output fitur dari iterator. Jalankan model, pergi berlibur selama beberapa minggu, dan ketika Anda kembali, Anda akan memiliki grid sebanyak yang Anda punya poin waktu di kelas fitur.

Perhatikan bahwa solusi ini mengasumsikan Anda memiliki titik pengambilan sampel waktu diskrit dengan bidang tanggal atau angka yang menunjukkan satu titik waktu untuk setiap catatan dalam rangkaian fitur Anda. Jika Anda menggunakan format "waktu mulai" dan "waktu selesai", mungkin tidak terlalu mudah.


sumber
1
Juga, jangan lupa untuk menggunakan variabel "% n%" dalam nama file output Anda (atau cara lain untuk menghasilkan nama file unik), atau Anda dapat menimpa Anda raster setiap iterasi. Untuk info lebih lanjut, lihat help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#//… atau hanya google "Contoh substitusi variabel in-line dengan variabel sistem ModelBuilder"
TY. Senang mengetahui ada cara berbeda untuk melakukannya. Bersulang!
Tung
2

Tampaknya utas ini dijawab oleh alat IDW, tetapi jika Anda meminta dan menginput tahun awal dan kemudian mengulangi bidang tahun menggunakan variabel sebaris dalam pembangun model maka ini akan menjadi cara yang lebih elegan untuk menangani pemodelan .

PS: Saya setuju dengan @AndyW bahwa jika Anda menyelesaikannya menggunakan IDW, posting sebagai jawaban sendiri dan kemudian "tandai dengan centang"

CDBrown
sumber
1

Tambahkan solusi saya sendiri menggunakan R& data curah hujan acak

library(tidyverse)
library(sp) # for coordinates, CRS, proj4string, etc
library(gstat)
library(maptools)

# Coordinates of gridded precipitation cells
precGridPts <- ("ID lat long
                1 46.78125 -121.46875
                2 46.84375 -121.53125
                3 46.84375 -121.46875
                4 46.84375 -121.40625
                5 46.84375 -121.34375
                6 46.90625 -121.53125
                7 46.90625 -121.46875
                8 46.90625 -121.40625
                9 46.90625 -121.34375
                10 46.90625 -121.28125
                11 46.96875 -121.46875
                12 46.96875 -121.40625
                13 46.96875 -121.34375
                14 46.96875 -121.28125
                15 46.96875 -121.21875
                16 46.96875 -121.15625
                ")

# Read precipitation cells
precGridPtsdf <- read.table(text = precGridPts, header = TRUE)

Konversi ke objek sp

sp::coordinates(precGridPtsdf) <- ~long + lat # longitude first

Tambahkan sistem referensi spasial (SRS) atau sistem referensi koordinat (CRS).

# CRS database: http://spatialreference.org/ref/epsg/
sp::proj4string(precGridPtsdf) <- sp::CRS("+proj=longlat +ellps=WGS84 +datum=WGS84")
str(precGridPtsdf)
#> Formal class 'SpatialPointsDataFrame' [package "sp"] with 5 slots
#>   ..@ data       :'data.frame':  16 obs. of  1 variable:
#>   .. ..$ ID: int [1:16] 1 2 3 4 5 6 7 8 9 10 ...
#>   ..@ coords.nrs : int [1:2] 3 2
#>   ..@ coords     : num [1:16, 1:2] -121 -122 -121 -121 -121 ...
#>   .. ..- attr(*, "dimnames")=List of 2
#>   .. .. ..$ : chr [1:16] "1" "2" "3" "4" ...
#>   .. .. ..$ : chr [1:2] "long" "lat"
#>   ..@ bbox       : num [1:2, 1:2] -121.5 46.8 -121.2 47
#>   .. ..- attr(*, "dimnames")=List of 2
#>   .. .. ..$ : chr [1:2] "long" "lat"
#>   .. .. ..$ : chr [1:2] "min" "max"
#>   ..@ proj4string:Formal class 'CRS' [package "sp"] with 1 slot
#>   .. .. ..@ projargs: chr "+proj=longlat +ellps=WGS84 +datum=WGS84 +towgs84=0,0,0"

Konversi ke UTM 10N

utm10n <- "+proj=utm +zone=10 ellps=WGS84"
precGridPtsdf_UTM <- spTransform(precGridPtsdf, CRS(utm10n))

Data curah hujan tahunan hipotetis dihasilkan menggunakan distribusi Poisson.

precDataTxt <- ("ID PRCP2016 PRCP2017 PRCP2018
                1 2125 2099 2203
                2 2075 2160 2119
                3 2170 2153 2180
                4 2130 2118 2153
                5 2170 2083 2179
                6 2109 2008 2107
                7 2109 2189 2093
                8 2058 2170 2067
                9 2154 2119 2139
                10 2056 2184 2120
                11 2080 2123 2107
                12 2110 2150 2175
                13 2176 2105 2126
                14 2088 2057 2199
                15 2032 2029 2100
                16 2133 2108 2006"
)

precData <- read_table2(precDataTxt, col_types = cols(ID = "i"))

Gabungkan frame data Prec dengan Prec shapefile

precGridPtsdf <- merge(precGridPtsdf, precData, by.x = "ID", by.y = "ID")
precdf <- data.frame(precGridPtsdf)

Kerangka data curah hujan gabungan dengan Prec presipitasi shapefile (UTM)

precGridPtsdf_UTM <- merge(precGridPtsdf_UTM, precData, by.x = "ID", by.y = "ID")

# sample extent
region_extent <- structure(c(612566.169007975, 5185395.70942594, 639349.654465079, 
                             5205871.0782451), .Dim = c(2L, 2L), .Dimnames = list(c("x", "y"
                             ), c("min", "max")))

Tentukan sejauh mana interpolasi spasial. Jadikan 4km lebih besar di setiap arah

x.range <- c(region_extent[1] - 4000, region_extent[3] + 4000)
y.range <- c(region_extent[2] - 4000, region_extent[4] + 4000)

Buat kisi yang diinginkan pada resolusi 1 km

grd <- expand.grid(x = seq(from = x.range[1], to = x.range[2], by = 1000), 
                   y = seq(from = y.range[1], to = y.range[2], by = 1000))   

# Convert grid to spatial object
coordinates(grd) <- ~x + y
# Use the same projection as boundary_UTM
proj4string(grd) <- "+proj=utm +zone=10 ellps=WGS84 +ellps=WGS84"
gridded(grd) <- TRUE

Interpolasi menggunakan Inverse Distance Weighted (IDW)

idw <- idw(formula = PRCP2016 ~ 1, locations = precGridPtsdf_UTM, newdata = grd)  
#> [inverse distance weighted interpolation]

# Clean up
idw.output = as.data.frame(idw)
names(idw.output)[1:3] <- c("Longitude", "Latitude", "Precipitation")

precdf_UTM <- data.frame(precGridPtsdf_UTM)

Plot hasil interpolasi

idwPlt1 <- ggplot() + 
  geom_tile(data = idw.output, aes(x = Longitude, y = Latitude, fill = Precipitation)) +
  geom_point(data = precdf_UTM, aes(x = long, y = lat, size = PRCP2016), shape = 21, colour = "red") +
  viridis::scale_fill_viridis() + 
  scale_size_continuous(name = "") +
  theme_bw() +
  scale_x_continuous(expand = c(0, 0)) +
  scale_y_continuous(expand = c(0, 0)) +
  theme(axis.text.y = element_text(angle = 90)) +
  theme(axis.title.y = element_text(margin = margin(t = 0, r = 10, b = 0, l = 0))) 
idwPlt1

### Now looping through every year 
list.idw <- colnames(precData)[-1] %>% 
  set_names() %>% 
  map(., ~ idw(as.formula(paste(.x, "~ 1")), 
               locations = precGridPtsdf_UTM, newdata = grd)) 

#> [inverse distance weighted interpolation]
#> [inverse distance weighted interpolation]
#> [inverse distance weighted interpolation]

idw.output.df = as.data.frame(list.idw) %>% as.tibble()
idw.output.df

#> # A tibble: 1,015 x 12
#>    PRCP2016.x PRCP2016.y PRCP2016.var1.pred PRCP2016.var1.var PRCP2017.x
#>  *      <dbl>      <dbl>              <dbl>             <dbl>      <dbl>
#>  1    608566.   5181396.              2114.                NA    608566.
#>  2    609566.   5181396.              2115.                NA    609566.
#>  3    610566.   5181396.              2116.                NA    610566.
#>  4    611566.   5181396.              2117.                NA    611566.
#>  5    612566.   5181396.              2119.                NA    612566.
#>  6    613566.   5181396.              2121.                NA    613566.
#>  7    614566.   5181396.              2123.                NA    614566.
#>  8    615566.   5181396.              2124.                NA    615566.
#>  9    616566.   5181396.              2125.                NA    616566.
#> 10    617566.   5181396.              2125.                NA    617566.
#> # ... with 1,005 more rows, and 7 more variables: PRCP2017.y <dbl>,
#> #   PRCP2017.var1.pred <dbl>, PRCP2017.var1.var <dbl>, PRCP2018.x <dbl>,
#> #   PRCP2018.y <dbl>, PRCP2018.var1.pred <dbl>, PRCP2018.var1.var <dbl>
Tung
sumber