-
Notifications
You must be signed in to change notification settings - Fork 51
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 371a3fa
Showing
24 changed files
with
9,649 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
= GPX Gem | ||
Copyright (C) 2006 Doug Fales | ||
Doug Fales mailto:doug.fales@gmail.com | ||
|
||
== What It Does | ||
This library reads GPX files and provides an API for reading and manipulating | ||
the data as objects. For more info on the GPX format, see | ||
http://www.topografix.com/gpx.asp. | ||
|
||
In addition to parsing GPX files, this library is capable of converting | ||
Magellan NMEA files to GPX, and writing new GPX files. It can crop and delete | ||
rectangular areas within a file, and it also calculates some meta-data about | ||
the tracks and points in a file (such as distance, duration, average speed, | ||
etc). | ||
|
||
== Examples | ||
Reading a GPX file, and cropping its contents to a given area: | ||
gpx = GPX::GPXFile.new(:gpx_file => filename) # Read GPX file | ||
bounds = GPX::Bounds.new(params) # Create a rectangular area to crop | ||
gpx.crop(bounds) # Crop it | ||
gpx.write(filename) # Save it | ||
|
||
Converting a Magellan track log to GPX: | ||
if GPX::MagellanTrackLog::is_magellan_file?(filename) | ||
GPX::MagellanTrackLog::convert_to_gpx(filename, "#{filename}.gpx") | ||
end | ||
|
||
|
||
== Notes | ||
This library was written to bridge the gap between my Garmin Geko | ||
and my website, WalkingBoss.org. For that reason, it has always been more of a | ||
work-in-progress than an attempt at full GPX compliance. The track side of the | ||
library has seen much more use than the route/waypoint side, so if you're doing | ||
something with routes or waypoints, you may need to tweak some things. | ||
|
||
Since this code uses REXML to read an entire GPX file into memory, it is not | ||
the fastest possible solution for working with GPX data, especially if you are | ||
working with tracks from several days or weeks. | ||
|
||
Finally, it should be noted that none of the distance/speed calculation or | ||
crop/delete code has been tested under International Date Line-crossing | ||
conditions. That particular part of the code will likely be unreliable if | ||
you're zig-zagging across 180 degrees longitude routinely. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
require 'rubygems' | ||
require 'rake' | ||
require 'rake/testtask' | ||
require 'rake/rdoctask' | ||
require 'rake/gempackagetask' | ||
require File.dirname(__FILE__) + '/lib/gpx' | ||
|
||
PKG_VERSION = GPX::VERSION | ||
PKG_NAME = "gpx" | ||
PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}" | ||
RUBY_FORGE_PROJECT = "gpx" | ||
RUBY_FORGE_USER = ENV['RUBY_FORGE_USER'] || "dougfales" | ||
RELEASE_NAME = "#{PKG_NAME}-#{PKG_VERSION}" | ||
|
||
PKG_FILES = FileList[ | ||
"lib/**/*", "bin/*", "tests/**/*", "[A-Z]*", "Rakefile", "doc/**/*" | ||
] | ||
|
||
desc "Default Task" | ||
task :default => [ :test ] | ||
|
||
# Run the unit tests | ||
desc "Run all unit tests" | ||
Rake::TestTask.new("test") { |t| | ||
t.libs << "lib" | ||
t.pattern = 'tests/*_test.rb' | ||
t.verbose = true | ||
} | ||
|
||
# Make a console, useful when working on tests | ||
desc "Generate a test console" | ||
task :console do | ||
verbose( false ) { sh "irb -I lib/ -r 'gpx'" } | ||
end | ||
|
||
# Genereate the RDoc documentation | ||
desc "Create documentation" | ||
Rake::RDocTask.new("doc") { |rdoc| | ||
rdoc.title = "Ruby GPX API" | ||
rdoc.rdoc_dir = 'html' | ||
rdoc.rdoc_files.include('README') | ||
rdoc.rdoc_files.include('lib/**/*.rb') | ||
} | ||
|
||
# Genereate the package | ||
spec = Gem::Specification.new do |s| | ||
|
||
s.name = 'gpx' | ||
s.version = PKG_VERSION | ||
s.summary = <<-EOF | ||
A basic API for reading and writing GPX files. | ||
EOF | ||
s.description = <<-EOF | ||
A basic API for reading and writing GPX files. | ||
EOF | ||
|
||
s.files = PKG_FILES | ||
|
||
s.require_path = 'lib' | ||
s.autorequire = 'gpx' | ||
|
||
s.has_rdoc = true | ||
|
||
s.author = "Doug Fales" | ||
s.email = "doug.fales@gmail.com" | ||
s.homepage = "http://gpx.rubyforge.com/" | ||
end | ||
|
||
Rake::GemPackageTask.new(spec) do |pkg| | ||
pkg.need_zip = true | ||
pkg.need_tar = true | ||
end | ||
|
||
desc "Report code statistics (KLOCs, etc) from the application" | ||
task :stats do | ||
require 'code_statistics' | ||
CodeStatistics.new( | ||
["Library", "lib"], | ||
["Units", "tests"] | ||
).to_s | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
#-- | ||
# Copyright (c) 2006 Doug Fales | ||
# | ||
# Permission is hereby granted, free of charge, to any person obtaining | ||
# a copy of this software and associated documentation files (the | ||
# "Software"), to deal in the Software without restriction, including | ||
# without limitation the rights to use, copy, modify, merge, publish, | ||
# distribute, sublicense, and/or sell copies of the Software, and to | ||
# permit persons to whom the Software is furnished to do so, subject to | ||
# the following conditions: | ||
# | ||
# The above copyright notice and this permission notice shall be | ||
# included in all copies or substantial portions of the Software. | ||
# | ||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | ||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
#++ | ||
$:.unshift(File.dirname(__FILE__)) | ||
require 'rexml/document' | ||
require 'date' | ||
require 'time' | ||
require 'csv' | ||
require 'gpx/gpx' | ||
require 'gpx/gpx_file' | ||
require 'gpx/bounds' | ||
require 'gpx/track' | ||
require 'gpx/route' | ||
require 'gpx/segment' | ||
require 'gpx/point' | ||
require 'gpx/trackpoint' | ||
require 'gpx/waypoint' | ||
require 'gpx/magellan_track_log' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
#-- | ||
# Copyright (c) 2006 Doug Fales | ||
# | ||
# Permission is hereby granted, free of charge, to any person obtaining | ||
# a copy of this software and associated documentation files (the | ||
# "Software"), to deal in the Software without restriction, including | ||
# without limitation the rights to use, copy, modify, merge, publish, | ||
# distribute, sublicense, and/or sell copies of the Software, and to | ||
# permit persons to whom the Software is furnished to do so, subject to | ||
# the following conditions: | ||
# | ||
# The above copyright notice and this permission notice shall be | ||
# included in all copies or substantial portions of the Software. | ||
# | ||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | ||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
#++ | ||
module GPX | ||
class Bounds < Base | ||
attr_accessor :min_lat, :max_lat, :max_lon, :min_lon, :center_lat, :center_lon | ||
|
||
# Creates a new bounds object with the passed-in min and max longitudes | ||
# and latitudes. | ||
def initialize(opts = { :min_lat => 90.0, :max_lat => -90.0, :min_lon => 180.0, :max_lon => -180.0}) | ||
@min_lat, @max_lat = opts[:min_lat].to_f, opts[:max_lat].to_f | ||
@min_lon, @max_lon = opts[:min_lon].to_f, opts[:max_lon].to_f | ||
end | ||
|
||
# Returns the middle latitude. | ||
def center_lat | ||
distance = (max_lat - min_lat)/2.0 | ||
(min_lat + distance) | ||
end | ||
|
||
# Returns the middle longitude. | ||
def center_lon | ||
distance = (max_lon - min_lon)/2.0 | ||
(min_lon + distance) | ||
end | ||
|
||
def to_xml | ||
bnd = REXML::Element.new('bounds') | ||
bnd.attributes['min_lat'] = min_lat | ||
bnd.attributes['min_lon'] = min_lon | ||
bnd.attributes['max_lat'] = max_lat | ||
bnd.attributes['max_lon'] = max_lon | ||
bnd | ||
end | ||
|
||
# Returns true if the pt is within these bounds. | ||
def contains?(pt) | ||
(pt.lat >= min_lat and pt.lat <= max_lat and pt.lon >= min_lon and pt.lon <= max_lon) | ||
end | ||
|
||
# Adds an item to itself, expanding its min/max lat/lon as needed to | ||
# contain the given item. The item can be either another instance of | ||
# Bounds or a Point. | ||
def add(item) | ||
if(item.respond_to?(:lat) and item.respond_to?(:lon)) | ||
@min_lat = item.lat if item.lat < @min_lat | ||
@min_lon = item.lon if item.lon < @min_lon | ||
@max_lat = item.lat if item.lat > @max_lat | ||
@max_lon = item.lon if item.lon > @max_lon | ||
else | ||
@min_lat = item.min_lat if item.min_lat < @min_lat | ||
@min_lon = item.min_lon if item.min_lon < @min_lon | ||
@max_lat = item.max_lat if item.max_lat > @max_lat | ||
@max_lon = item.max_lon if item.max_lon > @max_lon | ||
end | ||
end | ||
|
||
# Returns the min_lat, min_lon, max_lat, and max_lon in a labeled string. | ||
def to_s | ||
"min_lat: #{min_lat} min_lon: #{min_lon} max_lat: #{max_lat} max_lon: #{max_lon}" | ||
end | ||
|
||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
#-- | ||
# Copyright (c) 2006 Doug Fales | ||
# | ||
# Permission is hereby granted, free of charge, to any person obtaining | ||
# a copy of this software and associated documentation files (the | ||
# "Software"), to deal in the Software without restriction, including | ||
# without limitation the rights to use, copy, modify, merge, publish, | ||
# distribute, sublicense, and/or sell copies of the Software, and to | ||
# permit persons to whom the Software is furnished to do so, subject to | ||
# the following conditions: | ||
# | ||
# The above copyright notice and this permission notice shall be | ||
# included in all copies or substantial portions of the Software. | ||
# | ||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | ||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
#++ | ||
module GPX | ||
VERSION = "0.1" | ||
|
||
# A common base class which provides a useful initializer method to many | ||
# class in the GPX library. | ||
class Base | ||
include REXML | ||
|
||
# This initializer can take a REXML::Element and scrape out any text | ||
# elements with the names given in the "text_elements" array. Each | ||
# element found underneath "parent" with a name in "text_elements" causes | ||
# an attribute to be initialized on the instance. This means you don't | ||
# have to pick out individual text elements in each initializer of each | ||
# class (Route, TrackPoint, Track, etc). Just pass an array of possible | ||
# attributes to this method. | ||
def instantiate_with_text_elements(parent, text_elements) | ||
text_elements.each do |el| | ||
unless parent.elements[el].nil? | ||
val = parent.elements[el].text | ||
code = <<-code | ||
attr_accessor #{ el } | ||
#{el}=#{val} | ||
code | ||
class_eval code | ||
end | ||
end | ||
|
||
end | ||
|
||
end | ||
end |
Oops, something went wrong.