open_gpx_2_kml 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +11 -0
 - data/.rbenv-version +1 -0
 - data/Gemfile +3 -0
 - data/Gemfile.lock +46 -0
 - data/README.md +17 -0
 - data/Rakefile +2 -0
 - data/bin/openGpx2Kml +21 -0
 - data/example/config.csv +57 -0
 - data/example/windowsconfig.csv +57 -0
 - data/harness.rb +16 -0
 - data/input/test.gpx +724 -0
 - data/lib/tf1_converter/config.rb +63 -0
 - data/lib/tf1_converter/csv_file.rb +19 -0
 - data/lib/tf1_converter/gpx/track.rb +30 -0
 - data/lib/tf1_converter/gpx/trackpoint.rb +22 -0
 - data/lib/tf1_converter/gpx/waypoint.rb +76 -0
 - data/lib/tf1_converter/gpx_file.rb +19 -0
 - data/lib/tf1_converter/kml/track_color.rb +28 -0
 - data/lib/tf1_converter/kml/track_node.rb +36 -0
 - data/lib/tf1_converter/kml_file.rb +80 -0
 - data/lib/tf1_converter/kmz_file.rb +27 -0
 - data/lib/tf1_converter/translation.rb +34 -0
 - data/lib/tf1_converter/version.rb +3 -0
 - data/lib/tf1_converter.rb +3 -0
 - data/openGpx2Kml.gemspec +30 -0
 - data/output/test.kml +329 -0
 - data/spec/fixtures/expected.kml +329 -0
 - data/spec/fixtures/ftwood2.gpx +7481 -0
 - data/spec/fixtures/ftwood2_expected.kml +1 -0
 - data/spec/fixtures/test.gpx +724 -0
 - data/spec/fixtures/waypoint-by-name.gpx +709 -0
 - data/spec/lib/tf1_converter/gpx/track_spec.rb +20 -0
 - data/spec/lib/tf1_converter/gpx/waypoint_spec.rb +70 -0
 - data/spec/lib/tf1_converter/kml/track_color_spec.rb +29 -0
 - data/spec/lib/tf1_converter/kmz_file_spec.rb +18 -0
 - data/spec/lib/tf1_converter/translation_spec.rb +48 -0
 - metadata +242 -0
 
| 
         @@ -0,0 +1,63 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'csv'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module TF1Converter
         
     | 
| 
      
 4 
     | 
    
         
            +
              class Config
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
                def self.load(path)
         
     | 
| 
      
 7 
     | 
    
         
            +
                  last_key = nil
         
     | 
| 
      
 8 
     | 
    
         
            +
                  current_control = nil
         
     | 
| 
      
 9 
     | 
    
         
            +
                  @constant_color_switch = false
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                  CSV.read(path).each do |row|
         
     | 
| 
      
 12 
     | 
    
         
            +
                    if last_key == 'INPUT'
         
     | 
| 
      
 13 
     | 
    
         
            +
                      @input = row[0]
         
     | 
| 
      
 14 
     | 
    
         
            +
                    elsif last_key == 'OUTPUT'
         
     | 
| 
      
 15 
     | 
    
         
            +
                      @output = row[0]
         
     | 
| 
      
 16 
     | 
    
         
            +
                    elsif last_key == 'ICON_PATH'
         
     | 
| 
      
 17 
     | 
    
         
            +
                      @icon_path = row[0]
         
     | 
| 
      
 18 
     | 
    
         
            +
                    elsif last_key == 'ICONS'
         
     | 
| 
      
 19 
     | 
    
         
            +
                      @icons = {}
         
     | 
| 
      
 20 
     | 
    
         
            +
                      current_control = 'ICONS'
         
     | 
| 
      
 21 
     | 
    
         
            +
                    elsif last_key == 'COLORS'
         
     | 
| 
      
 22 
     | 
    
         
            +
                      @colors = {}
         
     | 
| 
      
 23 
     | 
    
         
            +
                      current_control = 'COLORS'
         
     | 
| 
      
 24 
     | 
    
         
            +
                    elsif last_key == 'USE_CONSTANT_COLOR'
         
     | 
| 
      
 25 
     | 
    
         
            +
                      @use_constant_color = row[0].strip.downcase == 'true'
         
     | 
| 
      
 26 
     | 
    
         
            +
                    elsif last_key == 'CONSTANT_COLOR'
         
     | 
| 
      
 27 
     | 
    
         
            +
                      @constant_color = row[0]
         
     | 
| 
      
 28 
     | 
    
         
            +
                    end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                    if current_control == 'ICONS'
         
     | 
| 
      
 31 
     | 
    
         
            +
                      if row.empty?
         
     | 
| 
      
 32 
     | 
    
         
            +
                        current_control = nil
         
     | 
| 
      
 33 
     | 
    
         
            +
                      else
         
     | 
| 
      
 34 
     | 
    
         
            +
                        @icons[row[0]] = {
         
     | 
| 
      
 35 
     | 
    
         
            +
                          'icon' => row[1],
         
     | 
| 
      
 36 
     | 
    
         
            +
                          'meaning' => row[2], 
         
     | 
| 
      
 37 
     | 
    
         
            +
                          'name' => row[3] 
         
     | 
| 
      
 38 
     | 
    
         
            +
                        }
         
     | 
| 
      
 39 
     | 
    
         
            +
                      end
         
     | 
| 
      
 40 
     | 
    
         
            +
                    elsif current_control == 'COLORS'
         
     | 
| 
      
 41 
     | 
    
         
            +
                      if row.empty?
         
     | 
| 
      
 42 
     | 
    
         
            +
                        current_control = nil
         
     | 
| 
      
 43 
     | 
    
         
            +
                      else
         
     | 
| 
      
 44 
     | 
    
         
            +
                        @colors[row[0]] = row[1]
         
     | 
| 
      
 45 
     | 
    
         
            +
                      end
         
     | 
| 
      
 46 
     | 
    
         
            +
                    end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                    last_key = row[0]
         
     | 
| 
      
 49 
     | 
    
         
            +
                  end
         
     | 
| 
      
 50 
     | 
    
         
            +
                end
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                %w(icon_path icons colors input output use_constant_color).each do |name|
         
     | 
| 
      
 53 
     | 
    
         
            +
                  define_singleton_method(name.to_sym) do
         
     | 
| 
      
 54 
     | 
    
         
            +
                    instance_variable_get("@#{name}")
         
     | 
| 
      
 55 
     | 
    
         
            +
                  end
         
     | 
| 
      
 56 
     | 
    
         
            +
                end
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
              end
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
              def self.constant_color
         
     | 
| 
      
 61 
     | 
    
         
            +
                colors[@constant_color]
         
     | 
| 
      
 62 
     | 
    
         
            +
              end
         
     | 
| 
      
 63 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,19 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'csv'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module TF1Converter
         
     | 
| 
      
 4 
     | 
    
         
            +
              class CsvFile
         
     | 
| 
      
 5 
     | 
    
         
            +
                def initialize(waypoints, path)
         
     | 
| 
      
 6 
     | 
    
         
            +
                  @waypoints = waypoints
         
     | 
| 
      
 7 
     | 
    
         
            +
                  @path = path
         
     | 
| 
      
 8 
     | 
    
         
            +
                end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                def to_csv!
         
     | 
| 
      
 11 
     | 
    
         
            +
                  CSV.open(@path, 'wb') do |csv|
         
     | 
| 
      
 12 
     | 
    
         
            +
                    csv << ['filename', 'name', 'meaning', 'time', 'lat', 'long', 'usng', 'elevation']
         
     | 
| 
      
 13 
     | 
    
         
            +
                    @waypoints.each do |wp|
         
     | 
| 
      
 14 
     | 
    
         
            +
                      csv << [@path.split('.').first, wp.name, wp.icon_meaning, wp.timestamp, wp.lat, wp.long, wp.usng, wp.elevation]
         
     | 
| 
      
 15 
     | 
    
         
            +
                    end
         
     | 
| 
      
 16 
     | 
    
         
            +
                  end
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
              end
         
     | 
| 
      
 19 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,30 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require_relative 'trackpoint'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module TF1Converter
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Gpx
         
     | 
| 
      
 5 
     | 
    
         
            +
                class Track
         
     | 
| 
      
 6 
     | 
    
         
            +
                  def initialize(xml_node, color_map = TF1Converter::Config.colors)
         
     | 
| 
      
 7 
     | 
    
         
            +
                    @node = xml_node
         
     | 
| 
      
 8 
     | 
    
         
            +
                    @color_map = color_map
         
     | 
| 
      
 9 
     | 
    
         
            +
                  end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                  def name
         
     | 
| 
      
 12 
     | 
    
         
            +
                    @node.xpath('name').first.text
         
     | 
| 
      
 13 
     | 
    
         
            +
                  end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                  def display_color
         
     | 
| 
      
 16 
     | 
    
         
            +
                    color_node = @node.xpath('extensions/TrackExtension/DisplayColor').first
         
     | 
| 
      
 17 
     | 
    
         
            +
                    if color_node
         
     | 
| 
      
 18 
     | 
    
         
            +
                      @color_map[color_node.text]
         
     | 
| 
      
 19 
     | 
    
         
            +
                    else
         
     | 
| 
      
 20 
     | 
    
         
            +
                      'f0000080'
         
     | 
| 
      
 21 
     | 
    
         
            +
                    end
         
     | 
| 
      
 22 
     | 
    
         
            +
                  end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                  def coordinate_string
         
     | 
| 
      
 25 
     | 
    
         
            +
                    trackpoints = @node.xpath('trkseg/trkpt').map{ |node| Trackpoint.new(node) }
         
     | 
| 
      
 26 
     | 
    
         
            +
                    trackpoints.inject([]) { |points, tp| points << tp.to_s }.join(' ')
         
     | 
| 
      
 27 
     | 
    
         
            +
                  end
         
     | 
| 
      
 28 
     | 
    
         
            +
                end
         
     | 
| 
      
 29 
     | 
    
         
            +
              end
         
     | 
| 
      
 30 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,22 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module TF1Converter
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Gpx
         
     | 
| 
      
 3 
     | 
    
         
            +
                class Trackpoint
         
     | 
| 
      
 4 
     | 
    
         
            +
                  def initialize(xml_node)
         
     | 
| 
      
 5 
     | 
    
         
            +
                    @node = xml_node
         
     | 
| 
      
 6 
     | 
    
         
            +
                  end
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                  def lat
         
     | 
| 
      
 9 
     | 
    
         
            +
                    @node.attribute('lat').value.strip
         
     | 
| 
      
 10 
     | 
    
         
            +
                  end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                  def long
         
     | 
| 
      
 13 
     | 
    
         
            +
                    @node.attribute('lon').value.strip
         
     | 
| 
      
 14 
     | 
    
         
            +
                  end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                  def to_s
         
     | 
| 
      
 17 
     | 
    
         
            +
                    "" << long << ',' << lat << ',0'
         
     | 
| 
      
 18 
     | 
    
         
            +
                  end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                end
         
     | 
| 
      
 21 
     | 
    
         
            +
              end
         
     | 
| 
      
 22 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,76 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module TF1Converter
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Gpx
         
     | 
| 
      
 3 
     | 
    
         
            +
                class Waypoint
         
     | 
| 
      
 4 
     | 
    
         
            +
                  def initialize(xml_node, icon_map = TF1Converter::Config.icons)
         
     | 
| 
      
 5 
     | 
    
         
            +
                    @node = xml_node
         
     | 
| 
      
 6 
     | 
    
         
            +
                    @icon_map = icon_map
         
     | 
| 
      
 7 
     | 
    
         
            +
                  end
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                  def name
         
     | 
| 
      
 10 
     | 
    
         
            +
                    name_node = @node.xpath('name').first
         
     | 
| 
      
 11 
     | 
    
         
            +
                    name_node.nil? ? '' : name_node.text
         
     | 
| 
      
 12 
     | 
    
         
            +
                  end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                  def icon_name
         
     | 
| 
      
 15 
     | 
    
         
            +
                    if symbol_name
         
     | 
| 
      
 16 
     | 
    
         
            +
                      map_entry = @icon_map[symbol_name]
         
     | 
| 
      
 17 
     | 
    
         
            +
                      return map_entry['icon'] if map_entry
         
     | 
| 
      
 18 
     | 
    
         
            +
                    elsif name
         
     | 
| 
      
 19 
     | 
    
         
            +
                      @icon_map.values.each do |icon_data|
         
     | 
| 
      
 20 
     | 
    
         
            +
                        return icon_data['icon'] if icon_data['name'] == name
         
     | 
| 
      
 21 
     | 
    
         
            +
                      end
         
     | 
| 
      
 22 
     | 
    
         
            +
                    end
         
     | 
| 
      
 23 
     | 
    
         
            +
                    'default.png'
         
     | 
| 
      
 24 
     | 
    
         
            +
                  end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                  def icon_meaning
         
     | 
| 
      
 27 
     | 
    
         
            +
                    if symbol_name
         
     | 
| 
      
 28 
     | 
    
         
            +
                      map_entry = @icon_map[symbol_name]
         
     | 
| 
      
 29 
     | 
    
         
            +
                      return map_entry['meaning'] if map_entry
         
     | 
| 
      
 30 
     | 
    
         
            +
                    end
         
     | 
| 
      
 31 
     | 
    
         
            +
                    'Default'
         
     | 
| 
      
 32 
     | 
    
         
            +
                  end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                  def timestamp
         
     | 
| 
      
 35 
     | 
    
         
            +
                    @node.children.select{ |child| child.name == 'cmt' }.first.text
         
     | 
| 
      
 36 
     | 
    
         
            +
                  end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                  def lat
         
     | 
| 
      
 39 
     | 
    
         
            +
                    @node.attribute('lat').value
         
     | 
| 
      
 40 
     | 
    
         
            +
                  end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                  def long
         
     | 
| 
      
 43 
     | 
    
         
            +
                    @node.attribute('lon').value
         
     | 
| 
      
 44 
     | 
    
         
            +
                  end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                  def elevation
         
     | 
| 
      
 47 
     | 
    
         
            +
                    @node.children.select{ |child| child.name == 'ele' }.first.text
         
     | 
| 
      
 48 
     | 
    
         
            +
                  end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                  def usng
         
     | 
| 
      
 51 
     | 
    
         
            +
                    u = utm_object
         
     | 
| 
      
 52 
     | 
    
         
            +
                    GeoSwap.utm_to_usng(u.easting, u.northing, u.zone.number, u.zone.letter)
         
     | 
| 
      
 53 
     | 
    
         
            +
                  end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                  def utm
         
     | 
| 
      
 56 
     | 
    
         
            +
                    utm_object.to_s
         
     | 
| 
      
 57 
     | 
    
         
            +
                  end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                  private
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
                  def utm_object
         
     | 
| 
      
 62 
     | 
    
         
            +
                    @_utm_object ||= GeoSwap.lat_long_to_utm(lat.to_f, long.to_f)
         
     | 
| 
      
 63 
     | 
    
         
            +
                  end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                  def symbol_name
         
     | 
| 
      
 66 
     | 
    
         
            +
                    sym_node = @node.children.select{ |child| child.name == 'sym' }.first
         
     | 
| 
      
 67 
     | 
    
         
            +
                    if sym_node
         
     | 
| 
      
 68 
     | 
    
         
            +
                      sym_node.text
         
     | 
| 
      
 69 
     | 
    
         
            +
                    else
         
     | 
| 
      
 70 
     | 
    
         
            +
                      nil
         
     | 
| 
      
 71 
     | 
    
         
            +
                    end
         
     | 
| 
      
 72 
     | 
    
         
            +
                  end
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
                end
         
     | 
| 
      
 75 
     | 
    
         
            +
              end
         
     | 
| 
      
 76 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,19 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require_relative 'gpx/waypoint'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require_relative 'gpx/track'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            module TF1Converter
         
     | 
| 
      
 5 
     | 
    
         
            +
              class GpxFile
         
     | 
| 
      
 6 
     | 
    
         
            +
                def initialize(gpx_file)
         
     | 
| 
      
 7 
     | 
    
         
            +
                  @gpx = gpx_file
         
     | 
| 
      
 8 
     | 
    
         
            +
                end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                def waypoints
         
     | 
| 
      
 11 
     | 
    
         
            +
                  @gpx.xpath('//gpx/wpt').map{ |node| Gpx::Waypoint.new(node) }
         
     | 
| 
      
 12 
     | 
    
         
            +
                end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                def tracks
         
     | 
| 
      
 15 
     | 
    
         
            +
                  @gpx.xpath('//gpx/trk').map{ |node| Gpx::Track.new(node) }
         
     | 
| 
      
 16 
     | 
    
         
            +
                end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
              end
         
     | 
| 
      
 19 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,28 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module TF1Converter::Kml
         
     | 
| 
      
 2 
     | 
    
         
            +
              class TrackColor
         
     | 
| 
      
 3 
     | 
    
         
            +
                def self.next
         
     | 
| 
      
 4 
     | 
    
         
            +
                  if config.use_constant_color
         
     | 
| 
      
 5 
     | 
    
         
            +
                    config.constant_color
         
     | 
| 
      
 6 
     | 
    
         
            +
                  else
         
     | 
| 
      
 7 
     | 
    
         
            +
                    @colors ||= config.colors.values
         
     | 
| 
      
 8 
     | 
    
         
            +
                    @color_index ||= 0
         
     | 
| 
      
 9 
     | 
    
         
            +
                    return_color = @colors[@color_index]
         
     | 
| 
      
 10 
     | 
    
         
            +
                    @color_index += 1
         
     | 
| 
      
 11 
     | 
    
         
            +
                    if @color_index >= @colors.length
         
     | 
| 
      
 12 
     | 
    
         
            +
                      @color_index = 0
         
     | 
| 
      
 13 
     | 
    
         
            +
                    end
         
     | 
| 
      
 14 
     | 
    
         
            +
                    return_color
         
     | 
| 
      
 15 
     | 
    
         
            +
                  end
         
     | 
| 
      
 16 
     | 
    
         
            +
                end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                def self.uncache!
         
     | 
| 
      
 19 
     | 
    
         
            +
                  @colors = nil
         
     | 
| 
      
 20 
     | 
    
         
            +
                  @color_index = nil
         
     | 
| 
      
 21 
     | 
    
         
            +
                end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                private
         
     | 
| 
      
 24 
     | 
    
         
            +
                def self.config
         
     | 
| 
      
 25 
     | 
    
         
            +
                  ::TF1Converter::Config
         
     | 
| 
      
 26 
     | 
    
         
            +
                end
         
     | 
| 
      
 27 
     | 
    
         
            +
              end
         
     | 
| 
      
 28 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,36 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require_relative 'track_color'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module TF1Converter
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Kml
         
     | 
| 
      
 5 
     | 
    
         
            +
                class TrackNode
         
     | 
| 
      
 6 
     | 
    
         
            +
                  def initialize(track, filename)
         
     | 
| 
      
 7 
     | 
    
         
            +
                    @track = track
         
     | 
| 
      
 8 
     | 
    
         
            +
                    @filename = filename
         
     | 
| 
      
 9 
     | 
    
         
            +
                  end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                  def write_to(xml)
         
     | 
| 
      
 12 
     | 
    
         
            +
                    xml.Style(id: "#{@track.name}_Style") do
         
     | 
| 
      
 13 
     | 
    
         
            +
                      xml.LineStyle do
         
     | 
| 
      
 14 
     | 
    
         
            +
                        xml.color TrackColor.next
         
     | 
| 
      
 15 
     | 
    
         
            +
                        xml.width 3
         
     | 
| 
      
 16 
     | 
    
         
            +
                      end
         
     | 
| 
      
 17 
     | 
    
         
            +
                    end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                    xml.Placemark(id: @track.name) do
         
     | 
| 
      
 20 
     | 
    
         
            +
                      xml.name @track.name
         
     | 
| 
      
 21 
     | 
    
         
            +
                      xml.description do
         
     | 
| 
      
 22 
     | 
    
         
            +
                        xml.cdata @filename
         
     | 
| 
      
 23 
     | 
    
         
            +
                      end
         
     | 
| 
      
 24 
     | 
    
         
            +
                      xml.styleUrl "##{@track.name}_Style"
         
     | 
| 
      
 25 
     | 
    
         
            +
                      xml.LineString do
         
     | 
| 
      
 26 
     | 
    
         
            +
                        xml.extrude 1
         
     | 
| 
      
 27 
     | 
    
         
            +
                        xml.tessellate 1
         
     | 
| 
      
 28 
     | 
    
         
            +
                        xml.altitudeMode 'clampedToGround'
         
     | 
| 
      
 29 
     | 
    
         
            +
                        xml.coordinates @track.coordinate_string
         
     | 
| 
      
 30 
     | 
    
         
            +
                      end
         
     | 
| 
      
 31 
     | 
    
         
            +
                    end
         
     | 
| 
      
 32 
     | 
    
         
            +
                  end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                end
         
     | 
| 
      
 35 
     | 
    
         
            +
              end
         
     | 
| 
      
 36 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,80 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require_relative 'kml/track_node'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module TF1Converter
         
     | 
| 
      
 4 
     | 
    
         
            +
              class KmlFile
         
     | 
| 
      
 5 
     | 
    
         
            +
                def initialize(waypoints, tracks, filename)
         
     | 
| 
      
 6 
     | 
    
         
            +
                  @waypoints = waypoints
         
     | 
| 
      
 7 
     | 
    
         
            +
                  @tracks = tracks
         
     | 
| 
      
 8 
     | 
    
         
            +
                  @filename = filename
         
     | 
| 
      
 9 
     | 
    
         
            +
                end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                def to_xml
         
     | 
| 
      
 12 
     | 
    
         
            +
                  Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml|
         
     | 
| 
      
 13 
     | 
    
         
            +
                    xml.kml('xmlns' => 'http://www.opengis.net/kml/2.2') do
         
     | 
| 
      
 14 
     | 
    
         
            +
                      xml.Document do
         
     | 
| 
      
 15 
     | 
    
         
            +
                        write_xml_header(xml)
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                        xml.Folder do
         
     | 
| 
      
 18 
     | 
    
         
            +
                          xml.name "Waypoints"
         
     | 
| 
      
 19 
     | 
    
         
            +
                          @waypoints.each do |waypoint|
         
     | 
| 
      
 20 
     | 
    
         
            +
                            write_waypoint_xml(waypoint, xml)
         
     | 
| 
      
 21 
     | 
    
         
            +
                          end
         
     | 
| 
      
 22 
     | 
    
         
            +
                        end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                        xml.Folder do
         
     | 
| 
      
 25 
     | 
    
         
            +
                          xml.name "Tracks"
         
     | 
| 
      
 26 
     | 
    
         
            +
                          @tracks.each do |track|
         
     | 
| 
      
 27 
     | 
    
         
            +
                            Kml::TrackNode.new(track, @filename).write_to(xml)
         
     | 
| 
      
 28 
     | 
    
         
            +
                          end
         
     | 
| 
      
 29 
     | 
    
         
            +
                        end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                      end
         
     | 
| 
      
 32 
     | 
    
         
            +
                    end
         
     | 
| 
      
 33 
     | 
    
         
            +
                  end.to_xml
         
     | 
| 
      
 34 
     | 
    
         
            +
                end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                private
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                def write_xml_header(xml)
         
     | 
| 
      
 39 
     | 
    
         
            +
                  xml.open 1
         
     | 
| 
      
 40 
     | 
    
         
            +
                  xml.Snippet(maxLines: '1')
         
     | 
| 
      
 41 
     | 
    
         
            +
                  xml.description do
         
     | 
| 
      
 42 
     | 
    
         
            +
                    xml.cdata "#{Time.now.strftime('%m-%d-%Y %I:%M:%S %p')}<br/><br/>TF1 Converter Version 1.0<br/>MO Task Force 1<br/>"
         
     | 
| 
      
 43 
     | 
    
         
            +
                  end
         
     | 
| 
      
 44 
     | 
    
         
            +
                  xml.Style(id: "sn_noicon") { xml.IconStyle { xml.Icon } }
         
     | 
| 
      
 45 
     | 
    
         
            +
                end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                def write_waypoint_xml(waypoint, xml)
         
     | 
| 
      
 48 
     | 
    
         
            +
                  xml.Placemark do
         
     | 
| 
      
 49 
     | 
    
         
            +
                    xml.name(waypoint.name)
         
     | 
| 
      
 50 
     | 
    
         
            +
                    xml.Snippet(maxLines: '0')
         
     | 
| 
      
 51 
     | 
    
         
            +
                    xml.Style(id: 'normalPlacemark') do
         
     | 
| 
      
 52 
     | 
    
         
            +
                      xml.IconStyle do
         
     | 
| 
      
 53 
     | 
    
         
            +
                        xml.Icon do
         
     | 
| 
      
 54 
     | 
    
         
            +
                          xml.href("files/#{waypoint.icon_name}")
         
     | 
| 
      
 55 
     | 
    
         
            +
                        end
         
     | 
| 
      
 56 
     | 
    
         
            +
                      end
         
     | 
| 
      
 57 
     | 
    
         
            +
                    end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                    xml.description do
         
     | 
| 
      
 60 
     | 
    
         
            +
                      xml.cdata description_for(waypoint)
         
     | 
| 
      
 61 
     | 
    
         
            +
                    end
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                    xml.Point do
         
     | 
| 
      
 64 
     | 
    
         
            +
                      xml.coordinates "#{waypoint.long},#{waypoint.lat}"
         
     | 
| 
      
 65 
     | 
    
         
            +
                    end
         
     | 
| 
      
 66 
     | 
    
         
            +
                  end
         
     | 
| 
      
 67 
     | 
    
         
            +
                end
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                def description_for(waypoint)
         
     | 
| 
      
 70 
     | 
    
         
            +
                  desc = ""
         
     | 
| 
      
 71 
     | 
    
         
            +
                  desc << waypoint.timestamp
         
     | 
| 
      
 72 
     | 
    
         
            +
                  desc << '<br>' << waypoint.icon_meaning
         
     | 
| 
      
 73 
     | 
    
         
            +
                  desc << '<br>' << "Filename: #{@filename}"
         
     | 
| 
      
 74 
     | 
    
         
            +
                  desc << "<br>" << "USNG:  #{waypoint.usng}"
         
     | 
| 
      
 75 
     | 
    
         
            +
                  desc << "<br>" << "Lat,Long:  #{waypoint.lat},#{waypoint.long}"
         
     | 
| 
      
 76 
     | 
    
         
            +
                  desc << "<br>" << "Elevation:  #{waypoint.elevation}"
         
     | 
| 
      
 77 
     | 
    
         
            +
                end
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
              end
         
     | 
| 
      
 80 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,27 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'fileutils'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'zip/zip'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            module TF1Converter
         
     | 
| 
      
 5 
     | 
    
         
            +
              class KmzFile
         
     | 
| 
      
 6 
     | 
    
         
            +
                def self.assemble!(filename)
         
     | 
| 
      
 7 
     | 
    
         
            +
                  raw_name = filename.split(/[\/\\]/).last
         
     | 
| 
      
 8 
     | 
    
         
            +
                  zip_path = "#{filename}.zip"
         
     | 
| 
      
 9 
     | 
    
         
            +
                  FileUtils.rm(zip_path) if File.exists?(zip_path)
         
     | 
| 
      
 10 
     | 
    
         
            +
                  Zip::ZipFile.open(zip_path, Zip::ZipFile::CREATE) do |zipfile|
         
     | 
| 
      
 11 
     | 
    
         
            +
                    zipfile.add("#{raw_name}.kml", "#{filename}.kml")
         
     | 
| 
      
 12 
     | 
    
         
            +
                    zipfile.mkdir("files")
         
     | 
| 
      
 13 
     | 
    
         
            +
                    Dir.foreach(TF1Converter::Config.icon_path) do |item|
         
     | 
| 
      
 14 
     | 
    
         
            +
                      if item != '.' && item != '..'
         
     | 
| 
      
 15 
     | 
    
         
            +
                        zipfile.add("files/#{item}", full_filepath(item))
         
     | 
| 
      
 16 
     | 
    
         
            +
                      end
         
     | 
| 
      
 17 
     | 
    
         
            +
                    end
         
     | 
| 
      
 18 
     | 
    
         
            +
                  end
         
     | 
| 
      
 19 
     | 
    
         
            +
                  FileUtils.mv(zip_path, "#{filename}.kmz")
         
     | 
| 
      
 20 
     | 
    
         
            +
                end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                def self.full_filepath(filename)
         
     | 
| 
      
 23 
     | 
    
         
            +
                  path = "#{TF1Converter::Config.icon_path}/#{filename}"
         
     | 
| 
      
 24 
     | 
    
         
            +
                  path.gsub('//', '/')
         
     | 
| 
      
 25 
     | 
    
         
            +
                end
         
     | 
| 
      
 26 
     | 
    
         
            +
              end
         
     | 
| 
      
 27 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,34 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'nokogiri'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'geo_swap'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require_relative 'gpx_file'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require_relative 'kml_file'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require_relative 'kmz_file'
         
     | 
| 
      
 6 
     | 
    
         
            +
            require_relative 'csv_file'
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            module TF1Converter
         
     | 
| 
      
 9 
     | 
    
         
            +
              class Translation
         
     | 
| 
      
 10 
     | 
    
         
            +
                def self.from(file)
         
     | 
| 
      
 11 
     | 
    
         
            +
                  new(file)
         
     | 
| 
      
 12 
     | 
    
         
            +
                end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                def initialize(gpx_file)
         
     | 
| 
      
 15 
     | 
    
         
            +
                  @filename = File.basename(gpx_file.path).split('.').first
         
     | 
| 
      
 16 
     | 
    
         
            +
                  parsed_gpx = Nokogiri::XML(gpx_file)
         
     | 
| 
      
 17 
     | 
    
         
            +
                  parsed_gpx.remove_namespaces!
         
     | 
| 
      
 18 
     | 
    
         
            +
                  @gpx = GpxFile.new(parsed_gpx)
         
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                def into(output_file)
         
     | 
| 
      
 22 
     | 
    
         
            +
                  raw_file_name = output_file.path.split('.').first
         
     | 
| 
      
 23 
     | 
    
         
            +
                  csv_path = raw_file_name + '.csv'
         
     | 
| 
      
 24 
     | 
    
         
            +
                  CsvFile.new(@gpx.waypoints, csv_path).to_csv!
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                  kml = KmlFile.new(@gpx.waypoints, @gpx.tracks, @filename).to_xml
         
     | 
| 
      
 27 
     | 
    
         
            +
                  output_file.puts kml
         
     | 
| 
      
 28 
     | 
    
         
            +
                  output_file.close
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                  kmz = KmzFile.assemble!(raw_file_name)
         
     | 
| 
      
 31 
     | 
    
         
            +
                end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
              end
         
     | 
| 
      
 34 
     | 
    
         
            +
            end
         
     | 
    
        data/openGpx2Kml.gemspec
    ADDED
    
    | 
         @@ -0,0 +1,30 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # -*- encoding: utf-8 -*-
         
     | 
| 
      
 2 
     | 
    
         
            +
            lib = File.expand_path('../lib', __FILE__)
         
     | 
| 
      
 3 
     | 
    
         
            +
            $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'tf1_converter/version'
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            Gem::Specification.new do |gem|
         
     | 
| 
      
 7 
     | 
    
         
            +
              gem.name          = "open_gpx_2_kml"
         
     | 
| 
      
 8 
     | 
    
         
            +
              gem.version       = TF1Converter::VERSION
         
     | 
| 
      
 9 
     | 
    
         
            +
              gem.authors       = ["Ethan Vizitei"]
         
     | 
| 
      
 10 
     | 
    
         
            +
              gem.email         = ["ethan.vizitei@gmail.com"]
         
     | 
| 
      
 11 
     | 
    
         
            +
              gem.description   = %q{A GPX to KML converter for FEMA US&R}
         
     | 
| 
      
 12 
     | 
    
         
            +
              gem.summary       = %q{A GPX to KML converter for FEMA US&R}
         
     | 
| 
      
 13 
     | 
    
         
            +
              gem.homepage      = ""
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
              gem.files         = `git ls-files`.split($/)
         
     | 
| 
      
 16 
     | 
    
         
            +
              gem.executables   = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
         
     | 
| 
      
 17 
     | 
    
         
            +
              gem.test_files    = gem.files.grep(%r{^(test|spec|features)/})
         
     | 
| 
      
 18 
     | 
    
         
            +
              gem.require_paths = ["lib"]
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
              gem.add_development_dependency 'rake', '10.0.3'
         
     | 
| 
      
 21 
     | 
    
         
            +
              gem.add_development_dependency 'rspec', '2.12.0'
         
     | 
| 
      
 22 
     | 
    
         
            +
              gem.add_development_dependency 'pry', '0.9.11.4'
         
     | 
| 
      
 23 
     | 
    
         
            +
              gem.add_development_dependency 'timecop', '0.5.9.2'
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
              gem.add_dependency 'thor', '0.17.0'
         
     | 
| 
      
 26 
     | 
    
         
            +
              gem.add_dependency 'nokogiri', '1.5.6'
         
     | 
| 
      
 27 
     | 
    
         
            +
              gem.add_dependency 'builder', '3.1.4'
         
     | 
| 
      
 28 
     | 
    
         
            +
              gem.add_dependency 'geo_swap', '0.2.1'
         
     | 
| 
      
 29 
     | 
    
         
            +
              gem.add_dependency 'rubyzip', '0.9.9'
         
     | 
| 
      
 30 
     | 
    
         
            +
            end
         
     |