Просторово-часова інтерполяція в R або ArcGIS?


12

Я намагаюся обчислити середню величину опадів з кількох балів за допомогою інструменту зворотної зваженої відстані в ArcGIS 9.3.

Моя проблема полягає в тому, що: кожен момент має свій часовий ряд, тому процес інтерполяції повинен бути в змозі здійснюватися протягом усіх років (так би мовити ітерація).

Далі наведена зразкова таблиця атрибутів:

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 ......
......

Хтось може мені показати, як це зробити?


Редагувати 1: Нарешті я зробив це за допомогою коду C ++, який вимагав сітки масок ArcGIS, файлів даних та розташування всіх точок.


Редагувати 2: Нещодавно я використовував R, щоб зробити це завдання інтерполяції. Ви можете використовувати або пакети hydroTSM, gstatабо spacetimeпакети. Кілька прикладів посилань нижче:

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

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


Edit 3: Додано робочий приклад нижче для майбутніх читачів


Чи допоможе це? Часовий ряд
Бред Несом

Це можна зробити в R, але я думаю, що існує простий спосіб зробити це безпосередньо в ArcMap. Все, що ОП хоче, - це повторити через окремі змінні (роки) та обчислити інтерпольований растр для кожної окремої змінної. Той факт, що значення в цьому прикладі є послідовними роками, не має значення.
Енді Ш

Thx для вашої відповіді. Насправді є пакетний варіант, коли клацніть правою кнопкою миші на інструменті IDW, але все-таки це досить копітка робота, якщо у вас є дані щогодини або щодня. KR
Tung

@thecatalyst - Якщо інструмент пакетного IDW виконує цю роботу, то слід надіслати це як відповідь. Хоча це може бути нудно, якщо це нечасто (оскільки щорічні оцінки кількості опадів нечасті), то для пошуку інших рішень мало підстав.
Енді Ш

@Andy: Пакетний інструмент допоможе, якщо у вас обмежена кількість, але у мене є сотні даних, які роблять ідею їх використання трохи нереальною. Я все ще шукаю рішення цієї проблеми. KR
Tung

Відповіді:


3

Я вирішив це, вставивши в модель ітератор "Вибір функції". (У вікні ModelBuilder під меню Вставити-> Ітератори.)

Використовуйте своє часове поле як змінну "група за". Роблячи це, модель буде повторюватися один раз для кожного разу у вашому класі функцій.

Потім приєднайте бажаний інструмент інтерполяції (сплайн, IDW та інше) до виводу функції з ітератора. Запустіть модель, вирушайте у відпустку на кілька тижнів, і коли ви повернетесь, у вас буде стільки сіток, скільки у вас є часових точок у класах функцій.

Зауважте, що це рішення передбачає, що у вас є дискретні точки відбору часу з датою або числовим полем, яке вказує на одну точку часу для кожного запису у вашому наборі функцій. Якщо ви використовуєте формати "час початку" та "час закінчення", це може бути не таким прямим вперед.


1
Крім того, не забувайте використовувати змінну "% n%" у своєму імені вихідного файлу (або якийсь інший спосіб генерування унікального імені файлу), інакше ви можете перезаписати растр кожної ітерації. Докладніші відомості див. У help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#//… або просто в google "Приклади заміни рядкової змінної з системними змінними

TY. Добре знати, що є інший спосіб зробити це. Ура!
Тунг

2

Здається, на цей потік відповідає інструмент IDW, але якби ви вимагали і вводили рік початку, а потім повторювали поля року за допомогою вбудованої змінної в конструкторі моделей, це був би більш елегантний спосіб впоратися з моделюванням .

PS: Я погоджуюся з @AndyW, що якщо ви вирішили це за допомогою IDW, опублікуйте як відповідь самостійно, а потім "позначте галочкою"


1

Додайте власне рішення за допомогою Rданих про випадкові опади

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)

Перетворити на об'єкт sp

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

Додайте просторову систему відліку (SRS) або координатну систему відліку (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"

Перетворити в UTM 10N

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

Гіпотетичні щорічні дані опадів, отримані за допомогою розподілу Пуассона.

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

Об'єднайте кадр даних Prec з профілем Prec

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

Об'єднати кадр даних опадів із формою опадів (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")))

Визначте міру просторової інтерполяції. Зробіть його на 4 км більшим у кожному напрямку

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

Створіть потрібну сітку з роздільною здатністю 1 км

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

Інтерполювати за допомогою зваженої відстані (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)

Результати інтерполяції сюжету

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>
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.