Read and Display Data from GPS Devices Using R

Two examples demonstrate the use of the R environment to process data sets from GPS devices:

  1. Read, transform, and display point and track data stored in industry-standard GPS Exchange (GPX) format using the readGPS()function, from the maptools package.
  2. Translate point data in proprietary format, collected with a Trimble GPS Receiver, into a cross-platform ASCII output file. During processing, apply Differential Correction to the point set, using Trimble-supplied software.

Both examples use methods from the sp and maptools packages.

Download data and R Code for both of these examples.

Case 1: Read, translate, display tracks and waypoints stored in GPS Exchange (GPX) format

Data collected using GPS receivers are stored in a myriad of formats; scientists wishing to use GPS data must be prepared to read any of these formats in order to import their GPS data into a scientific software package.

The R Language environment is well-suited for input, display, and analysis of geospatial data such as single-point locations and collections of points (tracks): R's data architecture includes geospatially-aware data structures, the language has versitile plotting and visualization commands, and add-on packages provide tools for importing and exporting many geospatial data formats.

This Use Case demonstrates use of the readGPS function, included in the R maptools package. readGPS() is an R interface to the GPSBabel utility, which provides file conversion and data manipulation tools for many popular GPS data formats.

For this demonstration, we selected the GPS Exchange (GPX) format, GPS platform-independent and widely-used by Web-aware programs to exchange geospatial data.

 To run the sample code discussed here, expand this .zip archive from the download: ReadGPXFormatGPSDataWithR.zip

The base grDevices package provides base graphics services to other R packages, including point, line, and polygon drawing as well as color and pattern control.

If you have not already added the maptools package to your local R installation, you can do so using the Packages/Install Packages option in the R GUI toolbar (MS Windows XP users), or using the following statement at the R command line:

install.packages(c("maptools")) # install 'maptools' package into local R installation. Package 'sp' also installed
library(maptools) # load 'maptools' (and 'sp') into current R workspace.

For tips on installing R on the Ubuntu Linux platform widely used at NCEAS visit the link:

http://help.nceas.ucsb.edu/R

The Demonstration:

The demonstration has three parts:

  • Read the input files into R Data Frames
  • Plot the data points
  • Write a subset of the input data to CSV output files

Let's look at the R script, section by section. This example code contains two functions:

TheDriver(), which manages execution and generates data plots, and ConvertGPXFiles(), which extracts and filters GPS data and / writes .CSV files.

Let's look at the R source code.

First, here is the program documentation: This describes the two functions in the package.


################################################################################
#
# Demonstration: Reading and converting GPS datasets 
# using the R readGPS function (maptools package)
#
# Abstract: This program reads GPX-format files containing, respectively,
# waypoints and tracks collected with a GPS reciever, into 
# an R Data Frame. Then, it extracts selected columns from
# each incoming data frame (date/time/latitude/longitude/altitude)
# into a new and separate data frame. The new data frame
# is then written to a comma-separated-value (CSV) file.
#
# Functions: TheDriver() - Manages execution of demonstration function 
# ConvertGPXFiles() - Reads input .GPX- format file, writes
# a subset to an output .CSV file.
#
# Note: The R debug() and browser() statements are incorporated to allow the 
# analysis to 'single-step' through the example:
# debug() : Sets up single-line execution of the function.
# browser(): Interrupts execution of function, allows inspection
# of R variable values.
# 
# Author: Rick Reeves, NCEAS Scientific Programmer
#
# Copyright 2008 National Center for Ecological Anslysis and Synthesis 
# All Rights Reserved
# Intended for use by the scientific community
#################################################################################

Here is TheDriver()


TheDriver <-function()
{
 library(maptools)
#
# debug(): single-step execution begins here.
#
 debug(ConvertGPXFiles)
 setwd("C:/Projects/scicomp/NewSite/UseCases/ReadGPXFormatGPSData")
#
# convert a file containing Waypoints
# 
# browser() - execution stops here, waiting for a keystroke...
#
 ConvertGPXFiles("SampleWaypointsOnlyNoOutliers.gpx","SampleWaypointsOut.csv","w")
#
# Plot the waypoints 
# 
 plot(dfWayptForPlotting@coords[,1:2],type="p",xlab="longitude",ylab="latitude")
 title("Waypoints from GPX-format GPS file")

Next, call ConvertGPXFiles() twice for two different input files: Once to extract waypoints(single locations), once to extract tracks (linear featues defined by a series of points):


# 
# convert a file containing Tracks
# 
# print(sprintf("Convert tracks file..."))
#browser()
 ConvertGPXFiles("SampleTracksOnly.gpx","SampleTracksOut.csv","t")
#

Finally, create a plot using the tracks data, then add ('overlay') the waypoints:


# Plot the track. Note: with the default form (below), plot axes do not display. 
#
# To plot x and y axes, 'deconstruct' the # x and y coordinates:
# 'embedded' in the SpatialLinesDataFrame. Thus the syntax:
#
 print(sprintf("Plot tracks/waypoints together..."))
#browser()
 plot(sldfTracksForPlotting@lines[[1]]@Lines[[1]]@coords[,1],
 sldfTracksForPlotting@lines[[1]]@Lines[[1]]@coords[,2],
 type="l",xlab="longitude",ylab="latitude",add=TRUE)
 points(dfWayptForPlotting@coords[,1:2],type="p",col="red",pch=19) 
 title("GPX/GPS Tracks (black) | Waypoints (red)") 
# 
 print(sprintf("done with program"))
# browser()
}

Here is ConvertGPXFiles():


#
# Routine ConvertGPXFiles demonstrates 1) extraction of GPS data 
# stored in the standard GPX format into an R data frame,
# using the R readGPS function; 2) extraction of key fields
# (Date/Time, Latitude/Longitude, Elevation) from the initial 
# data frame into a new data frame.
#
# function arguments: 
# 
# inGPSFile (string): Input GPX file name
# outConvertFile (string): Output CSV file name
# FileType (string): Flag indicates input
# file data type: "w" for waypoints,
# "t" for tracks.
#
ConvertGPXFiles <- function(inGPSFile,outConvertFile,FileType) 
{
# browser()

Two processing sections,based on file type: Here is the section for waypoints:
(Consult inline comments for details)


 if (FileType == "w")
 { 
#
# Read the GPX-format waypoints into a Data Frame
# Note here: readGPS converts waypoints and tracks into 
# data frames with different column layouts. 
# Columns are labeled V1 - Vn)
#
 gRawWaypt = readGPS("gpx",inGPSFile,"w")
# 
# Get number of observations (waypoints)
# gRawWaypoint data frame contains the attributes that 
# we desire in the following columns:
#
# V3: Observation Date (factor)
# V4: Observation Time (factor)
# V8: Descruptive Label (string)
# V10: Latitude (numeric)
# V11: Longitude (numeric)
# V21: Elevation (Factor, includes M in last character position)
#
# Lets extract these columns, convert Date, Time to strings 
# and elevation to numeric format, and construct a new data frame
# containing only the columns of interest.
#
 nObs = length(gRawWaypt[,"V3"])
 sDate = as.character(gRawWaypt[,"V3"])
 sTime = as.character(gRawWaypt[,"V4"])
 sLabel = as.character(gRawWaypt[,"V9"]) 
 fLat = as.numeric(gRawWaypt[,"V10"])
 fLong = as.numeric(gRawWaypt[,"V11"])
#
# compute the spatial bounding box for the waypoint set:
#
 bounds = c(range(fLong),range(fLat))
 dim(bounds) = c(2,2)
 
#
# Elevation is a factor with the letter 'M' appended.
# Remove this, and convert the elevation to numeric
# This formula extracted from the HTML help file for the R readGPS package
# 
 fAlt <- as.numeric(substring(as.character(gRawWaypt$V21),
 1,(nchar(as.character(gRawWaypt$V21))-1)))
#
# Output data frames - One 'standard' DF for file output,
# one 'SpatialPointsDataFrame' for plotting.
#
 dfWaypoints <<- as.data.frame(cbind(sLabel,sDate,sTime,fLat,fLong,fAlt)) 
 write.csv(dfWaypoints,outConvertFile)
 LatLongCoords = SpatialPoints(cbind(fLong,fLat),proj4string = CRS("+proj=longlat"))
 dfWayptForPlotting <<- SpatialPointsDataFrame(LatLongCoords,
 bbox=as.matrix(bounds),dfWaypoints[1])
 print(sprintf("done - waypoints"))
 }

Here is the section for tracks:


 
 else if (FileType == "t")
 { 
 gRawTracks = readGPS("gpx",inGPSFile,"t")
# 
# A GPX file can include multiple tracks, known as track sequences, each
# of which contains the vertices for a single track (line)
# However, the current version of readGPS() combines all points in all 
# track sequences into a single track. This may change in the future.
# For this demonstration, we will convert these track points into a 
# SpatialLinesData Frame (with a single SpatialLines object in one 'row'
# and a single attribute - "Track_1" - attached to the track (and stored
# in a DataFrame).
# The data frame generated by readGPS for Tracks has a different layout:
# 
# V3: Latitude (numeric) 
# V4: Longitude (numeric)
# V14: Elevation (Factor, includes 'M' in last character position)
# 

We use two R geospatial data structures, provided by the sppackage:
SpatialPointsDataFrame for waypoints, SpatialLinesDataFrame for tracks.
Consult the sp package documentation for details on spatial Data Frame components.


#
# SpatialPointsDataFrame: one attribute (altitude) per point.
# 
 dfTrackPoints <<- SpatialPointsDataFrame(LatLongCoords,data.frame(fAlt))
#
# Create SpatialLinesDF from the SpatialPointsDF.
# First, SpatialLines object:
#
 slTrackLine = Lines(list(Line(dfTrackPoints@coords)))
 slTrackLine@ID = "Track_One"
 SLPath = SpatialLines(list(slTrackLine),proj4string = CRS("+proj=longlat"))
#
# Finally, the SpatialLinesDataFrame:
# Create a global variable using the "<<-" operator, Plot this in TheDriver().
# 
 sldfTracksForPlotting <<- SpatialLinesDataFrame(SLPath,TrackAttributes,match.ID=FALSE)
#
# Write the original track points to a CSV file.
#
 write.csv(dfTrackPoints,outConvertFile)
 print(sprintf("done - tracks")) 
 }
}

Here is the R command sequence that loads and runs the program:

    R> source("ExtractWaypoints.r")
    R> TheDriver()

Here are the plots. Note that two 'outlier' waypoints are omitted from the right-side plot as they do not fall within the tracks.

Waypoints plotted Tracks plotted

End of Example 1.

Case 2: Read, translate, display points from Trimble GPS Reciever


 

In this Use Case, we download, correct, and export to a text file a set of six point locations from a handheld GPS, using the proprietary software provided by the GPS manufacturer to transfer the points to an ASCII file on our computer. Then we use the R Programming Environment to perform the remaining steps. Note: this use case includes a brief discussion of a specific GPS software package, The R procedures discussed will work with GPS points downloaded from any GPS device, providing that the points can be downloaded into an industry-standard file format, for example, ASCII Comma-Separated Value (.CSV).

This example uses the following R packages:

  • maptools provides functions for spatial and space-time point pattern analysis of polygons.
  • sp is a critical base package for spatial operations in R. It provides definitions for basic spatial classes (points, lines, polygons, pixels, and grids) in an attempt to unify the way R packages represent and manage these sorts of data. It also includes several core functions for creating and manipulating these data structures. The sp package is automatically loaded when the maptools package is used.
  • The base grDevices package provides base graphics services to other R packages, including point, line, and polygon drawing as well as color and pattern control.

If you have not already added these packages to your local R installation, you can do so using the Packages/Install Packages option in the R GUI toolbar (MS Windows XP users), or using the following statement at the R command line:

install.packages(c("maptools")) # sp also installed
library(maptools) # sp also loaded

For tips on installing R on the Ubuntu Linux platform widely used at NCEAS visit the link:

http://help.nceas.ucsb.edu/R

To run the sample code discussed here, expand this .zip archive from the download: ExportGPSPointsUsingR.zip

Step 1) Download and apply Differential Correction to point locations from GPS (using vendor-specific software)

The GPS coordinates used in this example were collected using a Trimble GPS receiver. While point files from some other GPS recievers can be read with open source software, at this writing (August 2007), there is no Trimble-compatible open-source GPS software. Therefore, we use the Trimble Pathfinder software, supplied with the GPS unit, to download and apply Differential Correction to the points. Here is a screen shot of the Trimble Pathfinder Differential Correction and Export (to ASCII file) graphical interface, which is representative of the features in other GPS receiver. utility programs:

Trimble Pathfinder Diff Corr
Trimble Pathfinder Export

Trimble Pathfinder GPS Software Interface: Differential Correction (Top), Export to ASCII File(Bottom)

Step 2) Import Point set into R, create a simple plot

Now that the point locations have been exported to the local computer, we can perform the rest of the processing steps using the R Programming Environment. First, we start R, load the maptools package, read the point shape file into an R Spatial Points Data Frame object, and display the points using a simple plot with labeled X (longitude) and Y (latitude) axes. The R code follows the plot diagram:


>library(maptools)
>setwd("c:/UseCases/ExportGPSPoints")
#
# Read and create simple plot using the ASCII input point file
# Default output shape file from Trimble Pathfinder is 'Gpoint'
#
>PointsFromGPS <- read.csv("Gpoint.csv")
#
# Create a SpatialPointsDataFrame data object, which streamlines
# use of the plot() and spTransform() methods.
# Column 1 is the single point attribute (ID number),
# Columns 2 - 3 are Longitude (X) and Latitude (Y) components.
#
>PointsAsFrame <- SpatialPointsDataFrame(PointsFromGPS[2:3],PointsFromGPS[1])
>plot(PointsAsFrame@coords[,1:2],xlab="longitude",ylab="latitude")
>title("Points From GPS (latitude/longitude in decimal degrees)"
GPS Points in Lat/Long

Step 3) Transform Points into the Universal Transverse Mercator (UTM) coordinate system

Because it uses a single-axis grid to represent any point on the Earth surface, latitude/longitude is the preferred coordinate system for geographic field coordinates. However, in some cases, scientists may need to re-project geographic coordinates into a different coordinate system. For example,all previous field measurements have been stored in a different coordinate system, such as the Universal Transverse Mercator (UTM) system. Therefore, to demonstrate R's point transformation capability, we convert the input points from latitude/longitude into UTM, using R's rgdal library version of the widely-used PROJ.4 Cartographic Projections software library:

GPS Points in UTM

>library(rgdal)
#
# we need to set the projection string attribute to the point set to be transformed.
# The following line sets the incoming point set to the closet guess to the GPS environment:
#
>proj4string(PointsAsFrame) <- CRS("+proj=longlat +datum=NAD27")
#
# perform the transformation and plot the points
#
>ThePointsUTM <- spTransform(PointsAsFrame,CRS("+proj=utm +zone=11 +datum=NAD27"))
>dev.set(1)
>plot(ThePointsUTM@coords[,1:2],axes=TRUE)
>title("Points From GPS (latitude/longitude in UTM-meters)",xlab="longitude",ylab="latitude")

Step 4) Export points to CSV-format file

Next, we write the point file's latitude and longitude coordinates, along with the ID code for each point, to a CSV file.

Let's have a look at the fields/columns in the point file, in order to select the columns to include in the output file, along with a screen shot of the data, in both Latitude/Longitude and UTM, as displayed in a standard text editor:

 

GPS Points in UTM

> attributes(ThePointsUTM)
$bbox
 min max
coords.x1 537581.1 544890.9
coords.x2 4305702.7 4315291.5

$proj4string
CRS arguments:
 +proj=utm +zone=11 +datum=NAD27 +ellps=clrk66
 +nadgrids=@conus,@alaska,@ntv2_0.gsb,@ntv1_can.dat 

$coords
 coords.x1 coords.x2
 [1,] 538241.5 4313928
 [2,] 538918.3 4312980
 [3,] 539749.7 4312335
 [4,] 540040.2 4312119
 [5,] 540499.1 4311955
 [6,] 541898.2 4311682
 [7,] 542372.7 4310662
 [8,] 542282.0 4309891
 [9,] 542113.7 4309578
[10,] 542367.2 4308874
[11,] 542699.5 4308117
[12,] 543365.2 4307364
[13,] 544489.9 4306441
[14,] 544890.9 4306147
[15,] 544661.2 4305703
[16,] 544135.1 4306436
[17,] 537581.1 4315291

$data
 id
0 DO01
1 DO02
2 DO03
3 DO04
4 DO05
5 DO06
6 DO07
7 DO09
8 DO10
9 DO11
10 DO12
11 DO13
12 DO15
13 DO16
14 DO17
15 DO14
16 DO00

$coords.nrs
numeric(0)

$class
[1] "SpatialPointsDataFrame"
attr(,"package")
[1] "sp"
#
# The default behavior for the write.table() 
# method is to write the $coords and $data fields
#
> write.table(ThePointsUTM,"CoordsUTM.csv",sep=",",row.names=FALSE,
 col.names=c("ID","easting","northing"))

End of Example 2.

Learning More:

UTM Coordinates: What You Need to Know: A Good Description for GPS Navigators

The GPS Exchange (GPX) Format Web Page

Point of Contact for this Use Case:reeves [at] nceas [dot] ucsb [dot] edu (Rick Reeves), NCEAS Scientific Programmer
This Use Case was developed June, 2008 and updated June, 2010.

scicomp: