Coordinates to GIS with R

En muchos casos, una capa de puntos viene dada en forma de excel o archivo .csv donde 2 columnas definen las coordenadas de estos. Si estas fuentes son enormes (> 100 millones de líneas) la cosa puede ponerse chunca en QGIS (los esriadictos quizá no tengan ese problema, como siempre). R tiene la solución, como siempre.

En este caso no hay mucho más que dar respuesta a esta pregunta de GIS StackExchange: What’s the fastest way to convert large csvs to point shapefile

En este caso, se proponen dos métodos (1) transformar todos los archivo .csv localizados en un directorio y enviarlos con epsg a una ubicación y (2) transformar un enorme .csv (en este caso si imita uno multiplicando un data.frame) en una archivo gpkg. Estos archivos tienen ciertas ventajas respecto a los shp, incluída la mayor cantidad de líneas escribibles en un mismo archivo.

Se debe considerar que el proceso parte de una función básica de la librería landtools, de la cual solo será necesaria la función dftocoords. En esta se transforma una tabla de coordenadas en un objeto espacial, permitiendo además la transformación entre los epsg de input y output (por ejemplo, si se tuviera un csv con coordenadas geográficas en grados y se quisiera aplicar una transformación a UTM).

library(landtools)
library(mapview)
library(stringr)
library(sf)
#------------------------------------------------------------------------
# METHOD 1 --> CSV'S TO SHP
#------------------------------------------------------------------------
# List cvs files
csvs <- list.files("./data/", '.csv', full.names = TRUE)

# Read all csv files
dfs <- lapply(csvs, function(x) read.csv(x, sep = ';'))

# See where your coords are stored (next AtriCoords parameter)
names(dfs[[1]])

# TRANSFORM CSV (data.frame) INTO SPATIAL
layers <- lapply(dfs, function(x) dftopoints(x,
                                             "EPSG:25829",
                                             "EPSG:25829",
                                             AtriCoords = c("x", "y")))

# Export the layers, setting the name as the original name
outnames <- paste0(str_replace(basename(csvs), '.csv', ''), '.shp')
outfiles <- paste0('./output/', outnames)
for(i in 1:length(layers)){st_write(layers[[i]],
				outfiles[[i]], append = FALSE)}

# Check the results
# mapview(layers[[1]], zcol = 'Altura..m.')

#------------------------------------------------------------------------
# METHOD 2 --> NOT PARALLEL PROCESS
#------------------------------------------------------------------------
#------------------------------------------------------------------------
# Create a huge (data.frame) to imitate a huge csv 
x <- dfs[[1]]
while(dim(x)[[1]] < 100000000){x <- rbind(x, x)}
str(x)

# export x for testing
# write.csv(x, file = './data/HUGECSV.csv')
# x <- read.csv('./data/HUGECSV.csv')

# TRANSFORM CSV (data.frame) INTO SPATIAL
system.time({
        lay <- dftopoints(x,
                          "EPSG:25829",
                          "EPSG:25829",
                          AtriCoords = c("x", "y"))
})

# Export file
system.time({
        fname <- paste0("./output/", 'try01.pgkg')
        st_write(lay, fname, append = FALSE)     
})