Advertisement
Guest User

Untitled

a guest
Jun 16th, 2019
60
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.51 KB | None | 0 0
  1. ## * Function to fill in gaps (with NA, NaN, or Inf value) in a raster
  2. ## ** Takes the mean of the 4 or 8 finite neighbouring values, iteratively, using 8 different strategies,
  3. ## ** and returning the overall mean
  4. library(inline)
  5.  
  6. src <- "
  7. Rcpp::NumericMatrix Am(A);
  8. int na = Rcpp::as<int>(missval);
  9. int neighb = Rcpp::as<int>(nneighb);
  10. int dir = Rcpp::as<int>(direction);
  11. int xfirst = Rcpp::as<int>(ythenx);
  12. int istart;
  13. int istep;
  14. int jstart;
  15. int jstep;
  16. int i;
  17. int j;
  18. NumericMatrix Bm = Am;
  19. int nrows = Am.nrow();
  20. int ncolumns = Am.ncol();
  21. int n = 0;
  22. float sum = 0;
  23.  
  24. if (dir == 1) {
  25. istart = 1;
  26. istep = 1;
  27. jstart = 1;
  28. jstep = 1;
  29. }
  30. if (dir == 2) {
  31. istart = ncolumns-1;
  32. istep = -1;
  33. jstart = 1;
  34. jstep = 1;
  35. }
  36. if (dir == 3) {
  37. istart = 1;
  38. istep = 1;
  39. jstart = nrows-1;
  40. jstep = -1;
  41. }
  42. if (dir == 4) {
  43. istart = ncolumns-1;
  44. istep = -1;
  45. jstart = nrows-1;
  46. jstep = -1;
  47. }
  48.  
  49. if (xfirst) {
  50. i = istart;
  51. while (i >= 1 && i <= (ncolumns-1)) {
  52. j = jstart;
  53. while (j >= 1 && j <= (nrows-1)) {
  54. if (Am(j,i)==na && ((Am(j+1,i) != na || Am(j-1,i) != na || Am(j,i+1) != na || Am(j,i-1) != na || (neighb == 8 && (Am(j-1,i-1) != na || Am(j-1,i+1) != na || Am(j+1, i-1) != na || Am(j+1, i+1) != na))))) {
  55. n = 0;
  56. sum = 0;
  57. if (Am(j+1,i) != na) {
  58. n = n+1;
  59. sum = sum + Am(j+1,i);
  60. }
  61. if (Am(j-1,i) != na) {
  62. n = n+1;
  63. sum = sum + Am(j-1,i);
  64. }
  65. if (Am(j,i+1) != na) {
  66. n = n+1;
  67. sum = sum + Am(j,i+1);
  68. }
  69. if (Am(j,i-1) != na) {
  70. n = n+1;
  71. sum = sum + Am(j,i-1);
  72. }
  73.  
  74. if (neighb == 8) {
  75. if (Am(j-1,i-1) != na) {
  76. n = n+1;
  77. sum = sum + Am(j-1,i-1);
  78. }
  79. if (Am(j-1,i+1) != na) {
  80. n = n+1;
  81. sum = sum + Am(j-1,i+1);
  82. }
  83. if (Am(j+1,i-1) != na) {
  84. n = n+1;
  85. sum = sum + Am(j+1,i-1);
  86. }
  87. if (Am(j+1,i+1) != na) {
  88. n = n+1;
  89. sum = sum + Am(j+1,i+1);
  90. }
  91. }
  92.  
  93. Bm(j,i) = sum/n;
  94. }
  95. j = j + jstep;
  96. }
  97. i = i + istep;
  98. }
  99. } else {
  100.  
  101. j = jstart;
  102. while (j >= 1 && j <= (nrows-1)) {
  103. i = istart;
  104. while (i >= 1 && i <= (ncolumns-1)) {
  105. if (Am(j,i)==na && (Am(j+1,i) != na || Am(j-1,i) != na || Am(j,i+1) != na || Am(j,i-1) != na || (neighb == 8 && (Am(j-1,i-1) != na || Am(j-1,i+1) != na || Am(j+1, i-1) != na || Am(j+1, i+1) != na)))) {
  106. n = 0;
  107. sum = 0;
  108. if (Am(j+1,i) != na) {
  109. n = n+1;
  110. sum = sum + Am(j+1,i);
  111. }
  112. if (Am(j-1,i) != na) {
  113. n = n+1;
  114. sum = sum + Am(j-1,i);
  115. }
  116. if (Am(j,i+1) != na) {
  117. n = n+1;
  118. sum = sum + Am(j,i+1);
  119. }
  120. if (Am(j,i-1) != na) {
  121. n = n+1;
  122. sum = sum + Am(j,i-1);
  123. }
  124.  
  125. if (neighb == 8) {
  126. if (Am(j-1,i-1) != na) {
  127. n = n+1;
  128. sum = sum + Am(j-1,i-1);
  129. }
  130. if (Am(j-1,i+1) != na) {
  131. n = n+1;
  132. sum = sum + Am(j-1,i+1);
  133. }
  134. if (Am(j+1,i-1) != na) {
  135. n = n+1;
  136. sum = sum + Am(j+1,i-1);
  137. }
  138. if (Am(j+1,i+1) != na) {
  139. n = n+1;
  140. sum = sum + Am(j+1,i+1);
  141. }
  142. }
  143.  
  144. Bm(j,i) = sum/n;
  145. }
  146. i = i + istep;
  147. }
  148. j = j + jstep;
  149. }
  150.  
  151. }
  152. return Bm;
  153. "
  154.  
  155. fillin <- cxxfunction(signature(A = "numeric", missval = "integer", nneighb = "integer",
  156. direction = "integer", ythenx = "integer"),
  157. body = src, plugin="Rcpp")
  158.  
  159.  
  160. ## * Main function to be called in scripts
  161. fill_raster_gaps <- function(r, na.recode=-9999, n.neighb=8) {
  162. ## r : input raster with gaps (cells with non-finite value: NA, NaN, Inf...)
  163. ## na.recode : value to replace NA cells with, before being processed in C++
  164. ## n.neighb : number of neighbours to take mean from. Either 4 or 8 (including diagonals)
  165. ## Returns the input raster with gaps filled in
  166. lst <- list()
  167. dir=1L
  168. for (dir in 1L:4L) {
  169. y.then.x=0L
  170. for (y.then.x in 0L:1L) {
  171. r1 <- r
  172. r1[!is.finite(r1[])] <- na.recode
  173. prevvals <- rep(0, length(r1[]))
  174. while (!identical(prevvals, r1[])) {
  175. prevvals <- r1[]
  176. m <- fillin(as.matrix(r1), na.recode, n.neighb, dir, y.then.x)
  177. r1 <- setValues(r1, m)
  178. }
  179. r1 <- reclassify(r1, cbind(missval, NA))
  180. lst <- c(lst, r1)
  181. }
  182. }
  183. rout <- calc(stack(lst), mean)
  184. return(rout)
  185. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement