6 votos

ModelBuilder: Cómo extraer datos por fecha, exportar a tablas separadas e interpolar tablas a rasters

He estado usando ArcGIS durante un par de años, pero cuando se trata de construir modelos sólo he trabajado con modelos muy simples. Espero que alguien mucho más inteligente que yo pueda ayudarme a construir un modelo complicado.

Tengo una tabla de datos muy grande (unas 300k filas) que contiene puntos con datos de lat/lon, velocidad del viento y fecha/hora. Hay unos 60 puntos diferentes con valores de viento que se han registrado para cada hora durante 2012. Lo que me gustaría hacer es construir un modelo que:

  1. Iterar a través de cada fila y seleccionar/exportar los datos asociados con la primera hora (00Z) del 1 de enero de 2012 (unas 60 filas) a una tabla separada, luego la segunda hora (01Z) del 1 de enero de 2012 a su propia tabla separada y así sucesivamente durante todo el año 2012.
  2. Realice la ponderación de la distancia inversa en todas las tablas horarias con los valores de lat/lon y viento que se crearon a partir del paso 1 anterior
  3. Reclasificar los raster para que los puntos del raster que tienen valores de viento de 5 o más se reclasifiquen a "1" y todos los demás valores de viento de la célula se reclasifiquen a "0"
  4. Luego iterar a través de los patrones creados en el paso 3 y usar algo como "Recopilar Valores" y "Estadísticas Celulares" para resumir todos los patrones en un patrón sumado final para todas las horas en 2012.

Iba a incluir una captura de pantalla de mis datos, pero supongo que como este es mi primer post no soy de confianza todavía. He desglosado la fecha de varias maneras diferentes (sólo la fecha, sólo la hora, la fecha-hora y la fecha-hora en formato de texto) porque he tenido problemas al intentar iterar y seleccionar los datos en mi tabla original, muy grande, sólo por fecha.

Espero haber dado suficiente información, pero si no, trataré de entrar en más detalles. Gracias de antemano por cualquier ayuda.

5voto

cjstehno Puntos 131

Usando el Analista Espacial, podemos esperar que cada iteración de IDW, umbral y acumulación de resultados tome desde una fracción de segundo hasta unos pocos segundos. Multiplicar por 24 * 365 = 8760 horas en un año sugiere este cálculo llevará horas como mínimo.

Puede ser mucho más rápido. Más rápido no siempre es mejor, pero aquí -porque hay cuestiones importantes relativas al método de interpolación, ya que es poco probable que el IDW sea preciso para esos datos- será una verdadera ventaja poder realizar los cálculos rápidamente a una escala realista para ver los resultados y experimentar con otras opciones.

Para ilustrar esto y para estimar cuán rápido se puede hacer realmente, implementé el cálculo a escala completa en R usando datos simulados. (Es una cuestión simple leer sus datos en R y exportar la cuadrícula resultante en formato ESRI usando, por ejemplo, el Raster paquete.) Después de los preliminares habituales de conseguir los datos en el formato correcto (los valores se almacenan en una matriz de 60 por 8760 y las ubicaciones de los puntos en una matriz de 60 por 2 de coordenadas (x,y)), el manejo de los valores perdidos, y así sucesivamente, todo el cómputo se reduce a dos líneas de código:

thresh <- threshold * xy %*% one  # Compute the denominators
a <- matrix(rowMeans(xy %*% z >= thresh), n.x, n.y)

xy ha precalculado los pesos de los IDW (no normalizados). one indica dónde no faltan datos y z es la matriz de todos los datos. Las dos multiplicaciones de la matriz xy %*% one y xy %*% z computar los denominadores y numeradores de todos los 8760 cálculos de IDW a la vez. La comparación en la segunda línea crea las cuadrículas de 8760 de unos y ceros y rowMeans los promedia para todo el año. El resultado, a es una única cuadrícula de dimensiones n.x y n.y .

Reduciendo este gran número de interpolaciones lineales a unas pocas operaciones de matriz, se puede lograr la mayor velocidad y eficiencia posibles. Además, este enfoque es general: literalmente cualquier El método de interpolación lineal (como el Kriging) puede ser implementado de esta manera.

En mi estación de trabajo (ejecutando esto en un solo núcleo, aunque es posible una paralelización masiva) se tarda poco menos de 60 segundos en procesar una cuarta parte de la red. Al reducir la resolución de la red se pierden pocos detalles y los datos de todo el año pueden ser procesados en segundos.

Para ilustrar, Aquí están los resultados para 60 puntos y 8760 horas en una cuadrícula de 125 por 310 (media resolución; 58 segundos de tiempo total). Para simplificar, utiliza todos los datos disponibles para la interpolación. Si se desea que los vecindarios locales más pequeños participen en un paso de precalculo (muy rápido), donde los pesos xy son computados, pero de otra manera nada más cambiaría.

Plot

Las velocidades del viento durante la primera hora se trazan como círculos cuyas áreas son proporcionales a la velocidad media durante el año; los promedios van de 1 a 5,9 m/seg.

Hay un precio que pagar: este método precomputa algunos valores y los almacena en la RAM. Este cálculo de un cuarto de tamaño requería 6,75 GB de RAM. Por lo tanto, un cálculo de tamaño completo requeriría 27 GB de RAM. Sin embargo, si no se dispone de tanto, es sencillo tallar la cuadrícula en rectángulos más pequeños, hacer el cálculo para cada rectángulo por separado y hacer un mosaico de las piezas después. El tiempo total de cálculo no aumentaría de forma apreciable.

Sigue el código completo.

set.seed(23)
n.points <- 60
n.hours <- 24 * 365
n.x <- 620/2          # Number of columns in grid
n.y <- 250/2          # Number of rows in grid
threshold <- 5        # Wind speed threshold
#
# The data: point locations.
#
points <- matrix(rnorm(n.points*2, 10^5, 10^4), ncol=2)
points <- points[order(points[,1]), ] # Sort by x-coordinate for testing
#
# Expand the extent of the points by about 10% to define the extent of the grid.
#
ranges <- apply(points, 2, range)
d.r <- diff(ranges)
x <- seq(ranges[1,1] - .05*d.r[1], ranges[2,1] + 0.05*d.r[1], length.out=n.x)
y <- seq(ranges[1,2] - .05*d.r[2], ranges[2,2] + 0.05*d.r[2], length.out=n.y)
#
# Obtain the inverse squared distances to the points.
#
distance.to <- function(u, x, y, eps=10^(-8)) {
  e <- eps * (max(x) - min(x) + max(y) - min(y))^2
  return(1 / (e + (x-u[1])^2 + (y-u[2])^2))
}
system.time(
  xy <- apply(points, 1, 
            function(u) outer(x, y, function(x0, y0) distance.to(u, x0, y0)))
  )
#
# The data: an array of values, one per column.
#
p.x <- points[,1]
z.scale <- rgamma(n.points, 5, scale=((p.x - min(x))/10^4 + 2)/50)
z <- matrix(rgamma(n.points * n.hours, 10, scale=z.scale), nrow=n.points)
z[z > 10] <- NA  # Introduce some missing values
#
# Perform the interpolation, thresholding, and averaging.
#
system.time({
  one <- !is.na(z)                  # Indicates the valid values
  z[is.na(z)] <- 0                  # Replace missing with 0
  thresh <- threshold * xy %*% one  # Compute the denominators
  a <- matrix(rowMeans(xy %*% z >= thresh), n.x, n.y)
  })
#
# Plot the results.
#
z.sum <- rowSums(z)
z.max <- max(z.sum)
z.root <- sqrt(z.sum / z.max) * 3
filled.contour(x=x, y=y, a, color.palette=terrain.colors, 
               plot.axes={axis(1); axis(2); 
                          points(points, col="Black", cex=z.root)},
               main="Proportion of Year at or above 5 m/sec",
               xlab="Easting")

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X