tf1_converter 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +1 -1
- data/lib/tf1_converter/gpx/track.rb +25 -0
- data/lib/tf1_converter/gpx/trackpoint.rb +22 -0
- data/lib/tf1_converter/gpx/waypoint.rb +53 -0
- data/lib/tf1_converter/gpx_file.rb +19 -0
- data/lib/tf1_converter/kml_file.rb +102 -0
- data/lib/tf1_converter/translation.rb +7 -113
- data/lib/tf1_converter/version.rb +1 -1
- metadata +8 -3
data/Gemfile.lock
CHANGED
@@ -0,0 +1,25 @@
|
|
1
|
+
require_relative 'trackpoint'
|
2
|
+
|
3
|
+
module TF1Converter
|
4
|
+
module Gpx
|
5
|
+
class Track
|
6
|
+
def initialize(xml_node)
|
7
|
+
@node = xml_node
|
8
|
+
end
|
9
|
+
|
10
|
+
def name
|
11
|
+
@node.xpath('name').first.text
|
12
|
+
end
|
13
|
+
|
14
|
+
def display_color
|
15
|
+
color_name = @node.xpath('extensions/TrackExtension/DisplayColor').first.text
|
16
|
+
Config.colors[color_name]
|
17
|
+
end
|
18
|
+
|
19
|
+
def coordinate_string
|
20
|
+
trackpoints = @node.xpath('trkseg/trkpt').map{ |node| Trackpoint.new(node) }
|
21
|
+
trackpoints.inject([]) { |points, tp| points << tp.to_s }.join(' ')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
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,53 @@
|
|
1
|
+
module TF1Converter
|
2
|
+
module Gpx
|
3
|
+
class Waypoint
|
4
|
+
def initialize(xml_node)
|
5
|
+
@node = xml_node
|
6
|
+
end
|
7
|
+
|
8
|
+
def name
|
9
|
+
@node.xpath('name').first.text
|
10
|
+
end
|
11
|
+
|
12
|
+
def icon_name
|
13
|
+
Config.icons[symbol_name]['icon']
|
14
|
+
end
|
15
|
+
|
16
|
+
def icon_meaning
|
17
|
+
Config.icons[symbol_name]['meaning']
|
18
|
+
end
|
19
|
+
|
20
|
+
def timestamp
|
21
|
+
@node.children.select{ |child| child.name == 'cmt' }.first.text
|
22
|
+
end
|
23
|
+
|
24
|
+
def lat
|
25
|
+
@node.attribute('lat').value
|
26
|
+
end
|
27
|
+
|
28
|
+
def long
|
29
|
+
@node.attribute('lon').value
|
30
|
+
end
|
31
|
+
|
32
|
+
def usng
|
33
|
+
u = utm_object
|
34
|
+
GeoSwap.utm_to_usng(u.easting, u.northing, u.zone.number, u.zone.letter)
|
35
|
+
end
|
36
|
+
|
37
|
+
def utm
|
38
|
+
utm_object.to_s
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def utm_object
|
44
|
+
@_utm_object ||= GeoSwap.lat_long_to_utm(lat.to_f, long.to_f)
|
45
|
+
end
|
46
|
+
|
47
|
+
def symbol_name
|
48
|
+
@node.children.select{ |child| child.name == 'sym' }.first.text
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
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,102 @@
|
|
1
|
+
module TF1Converter
|
2
|
+
class KmlFile
|
3
|
+
def initialize(waypoints, tracks)
|
4
|
+
@waypoints = waypoints
|
5
|
+
@tracks = tracks
|
6
|
+
end
|
7
|
+
|
8
|
+
def to_xml
|
9
|
+
Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml|
|
10
|
+
xml.kml('xmlns' => 'http://www.opengis.net/kml/2.2') do
|
11
|
+
xml.Document do
|
12
|
+
write_xml_header(xml)
|
13
|
+
|
14
|
+
xml.Folder do
|
15
|
+
xml.name "Waypoints"
|
16
|
+
@waypoints.each do |waypoint|
|
17
|
+
write_waypoint_xml(waypoint, xml)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
xml.Folder do
|
22
|
+
xml.name "Tracks"
|
23
|
+
@tracks.each do |track|
|
24
|
+
write_track_xml(track, xml)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end.to_xml
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def write_xml_header(xml)
|
36
|
+
xml.open 1
|
37
|
+
xml.Snippet(maxLines: '1')
|
38
|
+
xml.description do
|
39
|
+
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/>"
|
40
|
+
end
|
41
|
+
xml.Style(id: "sn_noicon") { xml.IconStyle { xml.Icon } }
|
42
|
+
end
|
43
|
+
|
44
|
+
def write_waypoint_xml(waypoint, xml)
|
45
|
+
xml.Placemark do
|
46
|
+
xml.name(waypoint.name)
|
47
|
+
xml.Snippet(maxLines: '0')
|
48
|
+
xml.Style(id: 'normalPlacemark') do
|
49
|
+
xml.IconStyle do
|
50
|
+
xml.Icon do
|
51
|
+
xml.href("#{Config.icon_path}#{waypoint.icon_name}")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
xml.description do
|
57
|
+
xml.cdata description_for(waypoint)
|
58
|
+
end
|
59
|
+
|
60
|
+
xml.Point do
|
61
|
+
xml.coordinates "#{waypoint.long},#{waypoint.lat}"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
def write_track_xml(track, xml)
|
68
|
+
xml.Style(id: "#{track.name}_Style") do
|
69
|
+
xml.LineStyle do
|
70
|
+
xml.color track.display_color
|
71
|
+
xml.width 3
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
xml.Placemark(id: track.name) do
|
76
|
+
xml.name track.name
|
77
|
+
xml.description do
|
78
|
+
xml.cdata "KML file, track, and waypoint comment."
|
79
|
+
end
|
80
|
+
xml.styleUrl "##{track.name}_Style"
|
81
|
+
xml.LineString do
|
82
|
+
xml.extrude 1
|
83
|
+
xml.tessellate 1
|
84
|
+
xml.altitudeMode 'clampedToGround'
|
85
|
+
xml.coordinates track.coordinate_string
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
|
91
|
+
def description_for(waypoint)
|
92
|
+
desc = ""
|
93
|
+
desc << waypoint.timestamp
|
94
|
+
desc << '<br>' << waypoint.icon_meaning
|
95
|
+
desc << '<br>' << "KML file, track, and waypoint comment."
|
96
|
+
desc << "<br>" << "USNG: #{waypoint.usng}"
|
97
|
+
desc << "<br>" << "UTM: #{waypoint.utm}"
|
98
|
+
desc << "<br>" << "#{Config.start_path} - #{Config.end_path}"
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
require 'nokogiri'
|
2
2
|
require 'geo_swap'
|
3
|
+
require_relative 'gpx_file'
|
4
|
+
require_relative 'kml_file'
|
3
5
|
|
4
6
|
module TF1Converter
|
5
7
|
class Translation
|
@@ -8,124 +10,16 @@ module TF1Converter
|
|
8
10
|
end
|
9
11
|
|
10
12
|
def initialize(gpx_file)
|
11
|
-
|
12
|
-
|
13
|
+
parsed_gpx = Nokogiri::XML(gpx_file)
|
14
|
+
parsed_gpx.remove_namespaces!
|
15
|
+
@gpx = GpxFile.new(parsed_gpx)
|
13
16
|
end
|
14
17
|
|
15
18
|
def into(output_file)
|
16
|
-
|
17
|
-
output_file.puts
|
19
|
+
kml = KmlFile.new(@gpx.waypoints, @gpx.tracks).to_xml
|
20
|
+
output_file.puts kml
|
18
21
|
output_file.close
|
19
22
|
end
|
20
23
|
|
21
|
-
def build_kml_from(gpx)
|
22
|
-
icon_path = Config.icon_path
|
23
|
-
Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml|
|
24
|
-
xml.kml('xmlns' => 'http://www.opengis.net/kml/2.2') do
|
25
|
-
xml.Document do
|
26
|
-
xml.open 1
|
27
|
-
xml.Snippet(maxLines: '1')
|
28
|
-
xml.description do
|
29
|
-
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/>"
|
30
|
-
end
|
31
|
-
|
32
|
-
xml.Style(id: "sn_noicon") { xml.IconStyle { xml.Icon } }
|
33
|
-
|
34
|
-
xml.Folder do
|
35
|
-
xml.name "Waypoints"
|
36
|
-
|
37
|
-
gpx.xpath('//gpx/wpt').each do |waypoint|
|
38
|
-
xml.Placemark do
|
39
|
-
xml.name(waypoint.xpath('name').first.text)
|
40
|
-
xml.Snippet(maxLines: '0')
|
41
|
-
xml.Style(id: 'normalPlacemark') do
|
42
|
-
xml.IconStyle do
|
43
|
-
xml.Icon do
|
44
|
-
#TODO: put this path in a config file
|
45
|
-
xml.href("#{icon_path}#{icon_name_for(waypoint)}")
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
lat = waypoint.attribute("lat").value
|
51
|
-
long = waypoint.attribute("lon").value
|
52
|
-
|
53
|
-
xml.description do
|
54
|
-
xml.cdata description_for(waypoint, lat, long)
|
55
|
-
end
|
56
|
-
|
57
|
-
xml.Point do
|
58
|
-
xml.coordinates "#{long},#{lat}"
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
xml.Folder do
|
65
|
-
xml.name "Tracks"
|
66
|
-
|
67
|
-
gpx.xpath('//gpx/trk').each do |track|
|
68
|
-
name = track.xpath('name').first.text
|
69
|
-
xml.Style(id: "#{name}_Style") do
|
70
|
-
xml.LineStyle do
|
71
|
-
display_color = track.xpath('extensions/TrackExtension/DisplayColor').first.text
|
72
|
-
xml.color(color_for(display_color))
|
73
|
-
xml.width 3
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
xml.Placemark(id: name) do
|
78
|
-
xml.name name
|
79
|
-
xml.description do
|
80
|
-
xml.cdata "KML file, track, and waypoint comment."
|
81
|
-
end
|
82
|
-
xml.styleUrl "##{name}_Style"
|
83
|
-
xml.LineString do
|
84
|
-
xml.extrude 1
|
85
|
-
xml.tessellate 1
|
86
|
-
xml.altitudeMode 'clampedToGround'
|
87
|
-
xml.coordinates(coordinates_for(track))
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
end
|
92
|
-
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
def icon_name_for(waypoint)
|
100
|
-
sym = field_for(waypoint, 'sym')
|
101
|
-
Config.icons[sym]['icon']
|
102
|
-
end
|
103
|
-
|
104
|
-
def description_for(waypoint, lat, long)
|
105
|
-
utm = GeoSwap.lat_long_to_utm(lat.to_f, long.to_f)
|
106
|
-
usng = GeoSwap.utm_to_usng(utm.easting, utm.northing, utm.zone.number, utm.zone.letter)
|
107
|
-
desc = ""
|
108
|
-
desc << field_for(waypoint, 'cmt')
|
109
|
-
desc << '<br>' << Config.icons[field_for(waypoint, 'sym')]['meaning']
|
110
|
-
desc << '<br>' << "KML file, track, and waypoint comment."
|
111
|
-
desc << "<br>" << "USNG: #{usng}"
|
112
|
-
desc << "<br>" << "UTM: #{utm.to_s}"
|
113
|
-
desc << "<br>" << "#{Config.start_path} - #{Config.end_path}"
|
114
|
-
end
|
115
|
-
|
116
|
-
def color_for(color)
|
117
|
-
Config.colors[color]
|
118
|
-
end
|
119
|
-
|
120
|
-
def coordinates_for(track)
|
121
|
-
track.xpath('trkseg/trkpt').inject([]) { |points, trackpoint|
|
122
|
-
points << ("" << trackpoint.attribute('lon').value.strip << ',' << trackpoint.attribute('lat').value.strip << ',0')
|
123
|
-
}.join(' ')
|
124
|
-
end
|
125
|
-
|
126
|
-
def field_for(waypoint, field)
|
127
|
-
waypoint.children.select{|c| c.name == field }.first.text
|
128
|
-
end
|
129
|
-
|
130
24
|
end
|
131
25
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tf1_converter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -160,6 +160,11 @@ files:
|
|
160
160
|
- input/test.gpx
|
161
161
|
- lib/tf1_converter.rb
|
162
162
|
- lib/tf1_converter/config.rb
|
163
|
+
- lib/tf1_converter/gpx/track.rb
|
164
|
+
- lib/tf1_converter/gpx/trackpoint.rb
|
165
|
+
- lib/tf1_converter/gpx/waypoint.rb
|
166
|
+
- lib/tf1_converter/gpx_file.rb
|
167
|
+
- lib/tf1_converter/kml_file.rb
|
163
168
|
- lib/tf1_converter/translation.rb
|
164
169
|
- lib/tf1_converter/version.rb
|
165
170
|
- output/test.kml
|
@@ -182,7 +187,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
182
187
|
version: '0'
|
183
188
|
segments:
|
184
189
|
- 0
|
185
|
-
hash: -
|
190
|
+
hash: -2100924703055666907
|
186
191
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
187
192
|
none: false
|
188
193
|
requirements:
|
@@ -191,7 +196,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
191
196
|
version: '0'
|
192
197
|
segments:
|
193
198
|
- 0
|
194
|
-
hash: -
|
199
|
+
hash: -2100924703055666907
|
195
200
|
requirements: []
|
196
201
|
rubyforge_project:
|
197
202
|
rubygems_version: 1.8.23
|