Skip to content

Commit a527d9d

Browse files
committed
Add support for line_string_feature_to_track option to create one track per geojson LineString
1 parent 82e4f2a commit a527d9d

3 files changed

Lines changed: 48 additions & 7 deletions

File tree

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,10 @@ gpx_file = GPX::GeoJSON.convert_to_gpx(
7979
)
8080
```
8181

82+
By default, multiple *LineStrings* from the geojson file will get added as segments to the same track. If you want to create a track per *LineString*, please set
83+
`line_string_feature_to_track: true` or `line_string_feature_to_track: ->(ls, trk) { ... }`
84+
85+
8286
Exporting an ActiveRecord to GPXFile (as Waypoints)
8387

8488
```ruby

lib/gpx/geo_json.rb

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class << self
3333
#
3434
def convert_to_gpx(opts = {})
3535
geojson = geojson_data_from(opts)
36-
gpx_file = GPX::GPXFile.new
36+
gpx_file = GPX::GPXFile.new(name: opts[:name], description: opts[:description])
3737
add_tracks_to(gpx_file, geojson, opts)
3838
add_waypoints_to(gpx_file, geojson, opts)
3939
gpx_file
@@ -62,8 +62,12 @@ def parse_geojson_data(data)
6262
end
6363

6464
def add_tracks_to(gpx_file, geojson, opts)
65-
tracks = [line_strings_to_track(geojson, opts)] +
66-
multi_line_strings_to_tracks(geojson, opts)
65+
tracks = if opts[:line_string_feature_to_track]
66+
line_strings_to_tracks(geojson, opts)
67+
else
68+
[line_strings_to_track_segments(geojson, opts)]
69+
end
70+
tracks += multi_line_strings_to_tracks(geojson, opts)
6771
tracks.compact!
6872
gpx_file.tracks += tracks
6973
gpx_file.tracks.each { |t| gpx_file.update_meta_data(t) }
@@ -76,10 +80,31 @@ def add_waypoints_to(gpx_file, geojson, opts)
7680
end
7781

7882
# Converts GeoJSON 'LineString' features.
79-
# Current strategy is to convert each LineString into a
80-
# Track Segment, returning a Track for all LineStrings.
83+
# This method converts each LineString into a
84+
# new Track, returning one Track for each LineString.
8185
#
82-
def line_strings_to_track(geojson, opts)
86+
def line_strings_to_tracks(geojson, opts)
87+
tracks = []
88+
line_strings = line_strings_in(geojson)
89+
return tracks unless line_strings.any?
90+
91+
line_strings.each do |ls|
92+
track = GPX::Track.new
93+
coords = ls['geometry']['coordinates']
94+
segment = coords_to_segment(coords)
95+
96+
opts[:line_string_feature_to_track]&.call(ls, track) if opts[:line_string_feature_to_track].is_a?(Proc)
97+
track.append_segment(segment)
98+
tracks << track
99+
end
100+
tracks
101+
end
102+
103+
# Converts GeoJSON 'LineString' features.
104+
# Current default strategy is to convert each LineString into a
105+
# Track Segment, returning one Track for all LineStrings.
106+
#
107+
def line_strings_to_track_segments(geojson, opts)
83108
line_strings = line_strings_in(geojson)
84109
return nil unless line_strings.any?
85110

@@ -88,7 +113,7 @@ def line_strings_to_track(geojson, opts)
88113
coords = ls['geometry']['coordinates']
89114
segment = coords_to_segment(coords)
90115

91-
opts[:line_string_feature_to_segment]&.call(ls, segment)
116+
opts[:line_string_feature_to_segment]&.call(ls, segment) if opts[:line_string_feature_to_segment].is_a?(Proc)
92117
track.append_segment(segment)
93118
end
94119
track

tests/geojson_test.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,18 @@ def test_line_string_functionality
5454
assert_equal(58, pts_size)
5555
end
5656

57+
def test_line_string_functionality_with_feature_to_track
58+
file = File.join(File.dirname(__FILE__), 'geojson_files/line_string_data.json')
59+
gpx_file = GPX::GeoJSON.convert_to_gpx(geojson_file: file, line_string_feature_to_track: true)
60+
61+
assert_equal(3, gpx_file.tracks.size)
62+
assert_equal(1, gpx_file.tracks.first.segments.size)
63+
pts_size = gpx_file.tracks[0].segments[0].points.size +
64+
gpx_file.tracks[1].segments[0].points.size +
65+
gpx_file.tracks[2].segments[0].points.size
66+
assert_equal(58, pts_size)
67+
end
68+
5769
def test_line_string_functionality_with_lambda
5870
file = File.join(File.dirname(__FILE__), 'geojson_files/line_string_data.json')
5971
gpx_file = GPX::GeoJSON.convert_to_gpx(

0 commit comments

Comments
 (0)