Automatizar el paso de GPX a SHP desde R

Desde la lógica más pura del trabajo con datos en R, lo mejor es tener los datos originales sin modificar, ya que siempre que se modifican es una posibilidad nueva de error. Para poder trabajar con esos datos originales lo que hacemos es convertirlos en una matriz de datos con los que podamos trabajar.

En nuestro caso tenemos en una carpeta los datos GPX tal cual salen del GPS y una tabla CSV con el mismo nombre que contiene los datos recogidos en la libreta (Especie, nombre parcela, otros datos) sobre los mismos puntos que contiene el GPX. Es importante que el número de registros en uno y en otro sean los mismos y que estén en el mismo orden, aunque no es necesario que se llamen igual, es interesante hacerlo para poder comprobar que se han unido bien.

Pasos a seguir:

  1. Instalar rgdal
  2. Elegir directorios de trabajo
  3. Importar datos GPX en R
  4. Importar datos CSV en R
  5. Juntar todos los datos en una única SpatialPointsDataFrame
  6. Corregir errores de transcripción
  7. Eliminar repetidos
  8. Exportar SHP

Instalar rgdal

Para importar datos GPX en R necesitaremos instalar la librería rgdal. Al intentar instalarla puede ocurrir que falte gdal-config, por lo que habrá que instalarlo primero en la consola de Linux:

sudo apt-get install libgdal1-dev libproj-dev

y en la consola de R:

install.packages("rgdal", dep=T)         #rgdal package
library(rgdal)

Una vez instalada, sólo es necesario correr la última línea de código para volver a activar la librería las siguientes veces.

Elegir directorios de trabajo

Lo primero que vamos a hacer es fijar los directorios de trabajo:

#   Directorio de entrada de datos
DirDatosBrutos <- "Directorio donde están los datos GPX y CSV/"
#   Directorios para exportar datos
DirDatosSHPwp  <- "Directorio donde se querran guardar los archivos shp de puntos/"
DirDatosSHPtrk <- "Directorio donde se querrán guardar los shp de tracks/"

Observar que al principio no hay barra y al final hay una barra inclinada (en Mac o en Windows puede ser diferente). Para comprobar que están bien elegidos, podemos utilizar:

list.files()
list.files(DirDatosBrutos)
list.files(DirDatosBrutos, ".csv")
list.files(DirDatosSHPwp, ".shp")
list.files(DirDatosSHPtrk, ".shp")

Importar datos GPX en R

Para importar los datos GPX y convertirlos en variables espaciales de puntos (waypoints) o lineas (tracks) utilizaremos readOGR()

#=============================================================================== 
#          LEER DATOS GPX y csv y crear listas
#=============================================================================== 
GPXinNombres <- list.files(DirDatosBrutos, ".GPX")  # Lista nombres gpx importar
CSVinNombres <- list.files(DirDatosBrutos, ".csv")  # Lista nombres csv importar
#
#                         GPXwp           Lista de SpatialPointsDataFrame PUNTOS
GPXwp <- list()
for (i in GPXinNombres){
    nombre <- paste(DirDatosBrutos,i,sep="")
    GPXwp[[i]] <- readOGR(dsn = nombre, layer="waypoints")
}
#
#                       GPXtrk             Lista de SpatialLinesDataFrame TRACKS
GPXtrk <- list()
for (i in GPXinNombres){
  nombre <- paste(DirDatosBrutos,i,sep="")
  GPXtrk[[i]] <- readOGR(dsn = nombre, layer="tracks")
}
#                       COMPROBAR
for (i in 1:length(GPXwp)){
   plot(GPXwp[[i]])
   plot(GPXtrk[[i]],add=T)
}
# Debería salir un dibujo con los traks y waypoints de cada archivo gpx

Importar datos CSV en R

Lo ideal es que tengan el mismo nombre que los correspondientes GPX, pero si no, al menos deberían estar en el mismo orden alfabético. También los nombres de las variables deberían ser en todas las mismas. En el ejemplo son ID, Tipo, Lugar Parcela y Fecha, pero habrá que poner en cada caso los datos tomados en la libreta.

#                         CSVwp     Lista de matrices de datos espaciales
CSVwp <- list()
for (i in CSVinNombres){
nombre <- paste(DirDatosBrutos,i,sep="")
CSVwp[[i]] <- read.table(nombre,header=T,sep=",")      #,sep="\t")     #   Leer tabla
names(CSVwp[[i]]) <- c("ID","Tipo","Lugar","Parcela","Fecha")          #   Arreglar nombres variables
}
#

Limpiar variables del GPX

Podemos ver todas las variables introducidas en cada una de las tablas utilizando str() o head(). En el ejemplo sólo nos quedaremos con las variables 5, 1 y 2, “nombre”, “ele” y “time”, respectivamente, eliminando todas las demás ya que están vacías o no tienen información relevante. Comprobar siempre antes, ya que pueden variar en función del modelo de gps. Para eliminarlas de toda la lista de tablas a la vez, utilizaremos for().

#===============================================================================
#          LIMPIAR GPXs
#===============================================================================
#          Seleccionar las variables útiles y crear variable VarUtiles
head(GPXwp[[1]])
VarUtiles <- c(5,1,2)                           # Puede cambiar según modelo GPS
for(i in 1:length(GPXwp)){
GPXwp[[i]] <- GPXwp[[i]][,VarUtiles]
}
head(GPXwp[[1]])                                             # Comprobar cambios
#

Juntar las variables de los GPX con las de los CSV

Un detalle importante en este paso es que los nombres de las variables en el CSV no deben coincidir con las variables que se hayan conservado del GPX. Si es así debería cambiarse el nombre de una de las dos. En este momento tenemos una lista de gpx con tres variables cada uno y una lista de csv con 4 variables cada uno. Podrían ser más y no pasaría nada mientras estén en el mismo orden y lógicamente el número de puntos en los gpx coincida con el número de lineas de datos de cada csv. Si es así, esto debería funcionar.

#===============================================================================
#          JUNTAR GPX Y CSV
#===============================================================================
for(i in 1:length(GPXwp)){
for (j in names(CSVwp[[i]])){
GPXwp[[i]][[j]] <- CSVwp[[i]][[j]]
}
}
#                       COMPROBAR si se han añadido
head(GPXwp[[1]])

Juntar todos los datos en una única SpatialPointsDataFrame

para juntar todos los datos en una única tabla de datos espaciales “SpatialPointsDataFrame” creamos un objeto introduciremos la primera tabla y luego con for() vamos añadiendo las demás utilizando rbind() para añadir cada vez más filas. Más tarde quitaremos los elementos duplicados por lo que no debemos  preocuparnos si los archivos solapan o si se tomaron puntos repetidos.

WP <- GPXwp[[1]] # Crea tabla GPXWP
for(i in 2:length(GPXwp)){
WP <- rbind(WP,GPXwp[[i]]) # Une resto de tablas a GPXWP
}
# COMPROBAR
WP

Corregir errores de transcripción

Además de comprobar que se han introducido todos los casos es interesante comprobar también si existen errores de transcripción que haya que corregir. Para las variables cuantitativas suele ser interesante ver los valores máximos y mínimos. Las cualitativas se pueden comprobar viendo los niveles de cada factor.

levels (WP$Tipo)                                 # Debería haber sólo 4: A,H,R,S

En nuestro ejemplo resulta que en la variable Tipo se han introducido en algunos casos “Ref” en vez de “R” y “X”  en vez de “H”. Para corregirlo

levels(WP$Tipo)[levels(WP$Tipo)=="REF"] <- "R"   # Cambia REF por R
levels(WP$Tipo)[levels(WP$Tipo)=="X"] <- "H"     # Cambia X por H
levels (WP$Tipo)                                 # Debería haber sólo 4: A,H,R,S

Eliminar repetidos

Los puntos que coinciden en coordenadas y en Tipo se consideran puntos repetidos y por tanto serán eliminados para que en cada coordenada sólo pueda haber un punto de cada tipo.

#===============================================================================
#          ELIMINAR REPETIDOS
#===============================================================================
coordTipo <- cbind(coordinates(WP),WP$Tipo)           # Variables para repetidos
dupl <- duplicated (coordTipo)                        # casos duplicados
#                       COMPROBAR
# length(subset(dupl,dupl==TRUE))                     # Numero casos duplicados
# length(subset(dupl,dupl==FALSE))                    # Numero casos sin duplicar
#
str(WP)
WP <- WP[!dupl,]                                      # ELIMINAR CASOS REPETIDOS
str(WP)
#

Exportar SHP

Ahora ya podemos exportar un shp con todos los puntos de todos los gpx y con los datos del csv incluidos en la tabla de atributos utilizando la función writeOGR().

writeOGR(WP, dsn = DirDatosSHPwp, "WP-Definitivo", driver = "ESRI Shapefile", overwrite_layer = T)  # Crea WP.shp DEFINITIVO

También se puede exportar en otros formatos (GPX, CSV, etc.). Si además queremos exportar una capa de shp para cada uno de los archivos de traks de cada gpx, se puede hacer así

for(i in 1:length(GPXtrk)){
writeOGR(GPXtrk[[i]],DirDatosSHPtrk,names(GPXtrk)[i],driver="ESRI Shapefile",overwrite_layer = T)
}

No he conseguido (tampoco lo he necesitado por ahora) juntar todas las “SpatialLinesDataFrame” de las tracks de los gpx en una sólo ni eliminar los segmentos repetidos. Si en algún momento veo cómo hacerlo lo añadiría aquí. Si sabes cómo hacerlo puedes comentarlo.

Cómo pasar los datos de tu GPS a capas de GIS en shape utilizando Qgis

La mayor parte de la información cartográfica pública se publica en formato shp, por lo que suele ser la mejor forma de editar, pasar a limpio y almacenar nuestros datos de distribución espacial. Los datos que recogemos con el receptor GPS se guardan normalmente (o al menos se pueden exportar) en formato GPX. Los datos de cada punto se suelen meter en libreta y de ahí a una tabla (o directamente en una tablet), pero no suele ser cómodo hacerlo en el mismo aparato, por lo que luego hay que juntar los datos. Vamos a ver cómo juntarlos en formato shp para poder utilizar otras capas de información geográfica y en futuros posts veré la forma de pasar los datos shp a R para poder realizar análisis de distribución espacial.

Si lo único que se quiere es visualizar o modificar los puntos o tracks y volver a guardarlos en gpx o volver a meterlos en el gps, lo mejor sería no complicarse la vida y utilizar Qlandkartegt o su nueva versión Qmapshack.

En este caso vamos a complicarlo un poco más que eso. Partimos de la base de que tenemos un archivo gpx con puntos y tracks y una tabla con los datos de cada punto en .csv (se puede exportar a .csv desde ods, xls o cualquier otro formato). Vamos a juntar ambos con Qgis y guardarlo todo en formato shp, o incluso volver a guardarlo como gpx. Pero mejor, paso a paso.

Si tienes muchos archivos gpx y csv, igual es mejor automatizar el proceso y juntar todos los archivos en un único shp utilizando R.

Primer paso: Abrir gpx en Qgis

Se pueden abrir los archivos gpx en Qgis clicando Capa>Añadir capa>Añadir capa vectorial…

qgis1

Se selecciona el archivo y se abren dos capas, la de waypoints (puntos) y la de tracks (líneas). Obviamente si se quieren guardar el resto de datos también se puede, pero no suelen ser interesantes.

qgis2 qgis3 qgis4

Paso 2: Comprobar que está todo en su sitio

Para comprobar que está todo en su sitio la mejor opción es utilizar alguno de los plugins de mapas web aconsejados (QuickMapServices, OpenLayers) y abrir de fondo algún mapa (osm, gmaps) para ver si los puntos están colocados donde se supone que deben estar. Si no está donde debe lo más probable es que haya que ajustar la proyección.

qgis5

Paso 3: limpiar tabla de atributos

Antes de añadir nuevos datos y marcas en la tabla de atributos es interesante ver qué es lo que hay ahí dentro y quitar todo lo que no sea útil. De todas las variables que introduce el gps en la tabla de atributos,  en nuestro caso la única información  útil es el nombre de cada waypoint, ya que es lo que vamos a utilizar para identificarlos y unir los datos de la tabla csv. Para quitar el resto de variables de la tabla de atributos hay que darle primero a editar y luego a eliminar columnas.

Importante: hay que haber guardado previamente la capa para poder editarla. Para ello: botón derecho>guardar como

qgis6 qgis7

 

 

 

 

 

 

 

En otros casos puede interesar conservar “ele” elevaciones, o “time” el momento en que se realizó el waypoint.

Un detalle importante es fijarse en que el nombre de los waypoints en este caso empiezan en 005. Los  ceros a la izquierda cuentan en el nombre, por lo que tendremos que ponerlos igual en la tabla csv. Para ello es importante ver en formato de número y añadir números a la izquierda antes de exportarlo como csv.

Paso 4: añadir datos a los waypoints a partir de una tabla de datos csv

Lo más importante que tiene que tener la tabla es una de las variables igual a alguna de las variables de la tabla de atributos de la capa. En el ejemplo la variable ID del archivo .csv es el nombre del punto, escrito exactamente igual que la variable “nombre” de la tabla de atributos, ceros a la izquierda incluidos.

qgis8

Para añadir los datos utilizamos el plugin MMQgis, que ya describí anteriormente.

qgis9qgis10

Importante fijarse en cada dato que te pide el formulario:

  • elegir el archivo csv,
  • poner el nombre de la variable,
  • la capa vectorial
  • y el nombre de la misma variable en la capa, para que los datos se unan adecuadamente.
  • También es interesante poner un nombre de archivo shape con el nombre de la nueva capa (ejemplo.shp)
  • y de los datos que no se han unido por si acaso (si todo va bien debería quedar vacío).

 

qgis11qgis12qgis13qgis14

Y como siempre que se trabaja con GIS, que no se te olvide guardar, en dos fases:

  • Cada capa por separado (formato shp, botón derecho y guardar como) para guardar los cambios en las tablas y situación de los puntos.
  • Y el proyecto (formato qgs) para guardar las localizaciones de cada capa, el orden y los colores elegidos.

Paso 5, o cerrando el bucle: Volver a guardar de shp a gpx

En caso necesario podéis volver a guardar la capa que queráis como gpx para volver a introducirla en vuestro gps, pero con los nuevos datos. Para ello botón_derecho, guardar _como,  gpx.