GPX Doctor

A Ruby gem for parsing and manipulating GPX 1.1 routes.

Installation

Add to your Gemfile:

gem "gpx_doctor"

Or install directly:

gem install gpx_doctor

Configuration

GpxDoctor.configure do |config|
  config.elevation_server          = true
  config.elevation_server_url      = "https://elevation.example.com"
  config.elevation_server_user     = "user"
  config.elevation_server_password = "secret"
end

GpxDoctor.configuration.elevation_server_url # => "https://elevation.example.com"
GpxDoctor.reset_configuration!               # resets to defaults
Option Type Default Description
elevation_server Boolean false Whether to use an elevation server
elevation_server_url String nil URL of the elevation server
elevation_server_user String nil Username for the elevation server
elevation_server_password String nil Password for the elevation server

Parsing

From a file

result = GpxDoctor::Parser.parse("path/to/file.gpx")

From a string

result = GpxDoctor::Parser.parse_string(xml_string)

Parsing with processing parameters

Both parse and parse_string accept an optional params: hash to enable post-processing:

result = GpxDoctor::Parser.parse("path/to/file.gpx", params: {
  max_distance:       200,           # insert interpolated points so no two consecutive points exceed this distance (metres)
  max_points:         500,           # reduce each segment to at most this many points
  segment_statistics: true,          # compute distance_to_next, elevation_change, direction for each point
  enhance_elevation:  true           # fetch missing elevations from the configured elevation server
})

Processing is applied in the following order:

  1. max_distance — segment splitting (interpolates intermediate points)
  2. max_points — point reduction
  3. segment_statistics — per-point statistics (distance, bearing, elevation change)
  4. enhance_elevation — elevation lookup via the elevation server

enhance_elevation: true requires the elevation server to be configured (see Configuration above). It only fills in points that have no elevation value; existing elevations are left unchanged.

Accessing data

result.points    # => [#<Waypoint lat=…, lon=…, ele=…>, …]  (all geographic points)
result.waypoints # => [#<Waypoint …>]  (top-level <wpt> elements only)
result.routes    # => [#<Route …>]
result.tracks    # => [#<Track …>]
result.  # => #<Metadata …>  (or nil)

result.points is a flat array containing all geographic points from:

  • Top-level <wpt> elements
  • <rtept> elements inside each <rte>
  • <trkpt> elements inside each <trkseg> inside each <trk>

Model field reference

Waypoint

Field Type Notes
lat Float Required
lon Float Required
ele Float Elevation in metres
time Time
magvar Float Magnetic variation
geoidheight Float
name String
cmt String Comment
desc String Description
src String Source
links Array
sym String Symbol
type String
fix String none, 2d, 3d, dgps, pps
sat Integer Number of satellites
hdop Float
vdop Float
pdop Float
ageofdgpsdata Float
dgpsid Integer 0–1023

Waypoint#to_h returns a hash of all non-nil fields.

Metadata

Field Type
name String
desc String
author Person
copyright Copyright
links Array
time Time
keywords String
bounds Bounds

Route

Field Type
name String
cmt String
desc String
src String
links Array
number Integer
type String
points Array

Track

Field Type
name String
cmt String
desc String
src String
links Array
number Integer
type String
segments Array
points Array (all points across all segments)

TrackSegment

Field Type
points Array

Person

Field Type
name String
email Email
link Link
Field Type
author String
year String
license String
Field Type
href String
text String
type String

Email

Field Type
id String
domain String

Email#to_s returns "id@domain".

Bounds

Field Type
minlat Float
minlon Float
maxlat Float
maxlon Float

Development

Building the gem

gem build gpx_doctor.gemspec

This produces a file like gpx_doctor-0.1.0.gem in the current directory.

Running tests

bundle install
bundle exec rspec

Publishing to RubyGems

  1. Create an account at https://rubygems.org if you don't have one.

  2. Set up credentials (one-time):

   gem signin

This stores your API key in ~/.gem/credentials.

  1. Build and push:
   gem build gpx_doctor.gemspec
   gem push gpx_doctor-0.1.0.gem
  1. Verify the release at https://rubygems.org/gems/gpx_doctor.

Tip: Bump GpxDoctor::VERSION in lib/gpx_doctor/version.rb before each release and tag the commit:

git tag -a v0.1.0 -m "Release 0.1.0"
git push origin v0.1.0

License

MIT