gpx2png 0.2.0 → 0.3.0

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/Gemfile CHANGED
@@ -2,9 +2,8 @@ source "http://rubygems.org"
2
2
 
3
3
  gem 'mini_exiftool'
4
4
  gem 'rmagick'
5
- # removed
6
- #gem 'chunky_png'
7
5
  gem 'gpx_utils'
6
+ gem 'colorize'
8
7
 
9
8
  group :development do
10
9
  gem "rspec"
@@ -3,6 +3,7 @@ GEM
3
3
  specs:
4
4
  addressable (2.3.5)
5
5
  builder (3.2.2)
6
+ colorize (0.6.0)
6
7
  diff-lcs (1.2.5)
7
8
  docile (1.1.1)
8
9
  faraday (0.8.8)
@@ -69,6 +70,7 @@ PLATFORMS
69
70
 
70
71
  DEPENDENCIES
71
72
  bundler
73
+ colorize
72
74
  gpx_utils
73
75
  jeweler
74
76
  mini_exiftool
data/README.md CHANGED
@@ -1,75 +1,11 @@
1
- gpx2exif
1
+ gpx2png
2
2
  =======
3
3
 
4
- Geotagging
5
- ----------
6
-
7
- Geotag your photos using stored GPX files. At this moment it supports only Garmin eTrex devices.
8
-
9
-
10
- Disclaimer
11
- ----------
12
-
13
- This gem add one executable which overwrite JPG files. BACKUP IS NEEDED!
14
-
15
-
16
- How to use it
17
- -------------
18
-
19
- 1. gem install gpx2exif
20
-
21
- 2. Go to path where you have JPG/JPEG photos (case insensitive) and GPX files.
22
-
23
- 3. From 0.0.1 there is 'simulation command'. Type 'geotag_simulate' and enter.
24
-
25
- 4. WARNING! it will overwrite all your photos so MAKE A BACKUP!
26
-
27
- 5. Type 'geotag_all_images' and press enter key.
28
-
29
- 6. See a nice piece of output and now you have geotagged photos :)
30
-
31
-
32
- If something is not working send me e-mail and I'll fix it.
33
-
34
-
35
- Create waypoint files
36
- ---------------------
37
-
38
- You can prepare your own list of waypoints and then store into eTrex using GPX file. At this moment there is
39
- only possible to convert data from YAML file to GPX. It is also possible to integrate with other (web)apps.
40
-
41
- How to use it
42
- -------------
43
-
44
- 1. Check samples/sample_yaml_pois.yml as a template.
45
-
46
- 2. Modify it, add yours POIs.
47
-
48
- 3. Run command
49
-
50
- generate_garmin_waypoints -y input_file.yml > output.gpx
51
-
52
- 4. You can check inter-POI distances using
53
-
54
- generate_garmin_waypoints -y input_file.yml -C
55
-
56
- Distance conflict does not mean something is wrong. POIs can be close to each other so it
57
- is a good idea to have your brain turned on ;)
58
-
59
- 5. You can change inter-POI distances using 'latlon something' distance for distance checking
60
- explained line before.
61
-
62
- generate_garmin_waypoints -y samples/sample_yaml_pois.yml -C -t 1
63
-
64
- 6. You can specify output file if you don't like using >> 'file.gpx'.
65
-
66
- generate_garmin_waypoints -y samples/sample_yaml_pois.yml -o file.gpx
67
-
68
-
69
4
  Render track with OpenStreetMap
70
5
  ---------------------
71
6
 
72
- You can "convert" your tracks to images using this command.
7
+ You can "convert" your tracks to map images using this command.
8
+
73
9
 
74
10
  How to use it
75
11
  -------------
@@ -92,13 +28,17 @@ How to use it
92
28
 
93
29
  gpx2png -g spec/fixtures/sample.gpx -z 11 -o map.png
94
30
 
95
- 4. Adding -u forces using [UMP tiles](http://ump.waw.pl/) .
31
+ 4. You can change map provider:
32
+
33
+ * OpenStreetMap - defualt
34
+ * UMP - add -u to use [UMP tiles](http://ump.waw.pl/)
35
+ * Cycle - add -u to use [UMP tiles](http://ump.waw.pl/)
96
36
 
97
37
 
98
- Contributing to gpx2xif
38
+ Contributing to gpx2png
99
39
  -------------------------------
100
40
 
101
- [![Flattr this git repo](http://api.flattr.com/button/flattr-badge-large.png)](https://flattr.com/submit/auto?user_id=bobik314&url=https://github.com/akwiatkowski/gpx2xif&title=gpx2xif&language=en_GB&tags=github&category=software)
41
+ [![Flattr this git repo](http://api.flattr.com/button/flattr-badge-large.png)](https://flattr.com/submit/auto?user_id=bobik314&url=https://github.com/akwiatkowski/gpx2png&title=gpx2png&language=en_GB&tags=github&category=software)
102
42
 
103
43
  * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
104
44
  * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
@@ -112,6 +52,6 @@ Contributing to gpx2xif
112
52
  Copyright
113
53
  ---------
114
54
 
115
- Copyright (c) 2012 Aleksander Kwiatkowski. See LICENSE.txt for
55
+ Copyright (c) 2012-2014 Aleksander Kwiatkowski. See LICENSE.txt for
116
56
  further details.
117
57
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.0
1
+ 0.3.0
@@ -6,7 +6,7 @@ require 'gpx2png/osm'
6
6
  require 'gpx2png/ump'
7
7
  require 'optparse'
8
8
 
9
- options = { }
9
+ options = {}
10
10
  OptionParser.new do |opts|
11
11
  opts.banner = "Usage: gpx2png [options]"
12
12
 
@@ -22,8 +22,8 @@ OptionParser.new do |opts|
22
22
  opts.on("-o", "--output FILE", "Output image file") do |v|
23
23
  options[:output_file] = v
24
24
  end
25
- opts.on("-u", "--ump", "Use UMP tiles rather than OSM") do
26
- options[:ump] = true
25
+ opts.on("-k", "--klass CLASS", "Use different map provider (osm, ump, cycle, transport, outdoors, landscape)") do |v|
26
+ options[:klass] = v
27
27
  end
28
28
  end.parse!
29
29
 
@@ -40,15 +40,26 @@ if options[:zoom].nil? and options[:size].nil?
40
40
  @fail = true
41
41
  end
42
42
 
43
+ klass = case options[:klass].to_s
44
+ when "ump" then
45
+ Gpx2png::Ump
46
+ when "cycle" then
47
+ Gpx2png::OpenCycle
48
+ when "transport" then
49
+ Gpx2png::Transport
50
+ when "outdoors" then
51
+ Gpx2png::Outdoors
52
+ when "landscape" then
53
+ Gpx2png::Landscape
54
+ else
55
+ Gpx2png::Osm
56
+ end
57
+
43
58
  unless @fail
44
59
  g = GpxUtils::TrackImporter.new
45
60
  g.add_file(options[:gpx])
46
61
 
47
- if options[:ump]
48
- e = Gpx2png::Ump.new
49
- else
50
- e = Gpx2png::Osm.new
51
- end
62
+ e = klass.new
52
63
  e.coords = g.coords
53
64
 
54
65
  if options[:size]
@@ -58,7 +69,7 @@ unless @fail
58
69
  else
59
70
  # constant zoom
60
71
  e.zoom = options[:zoom].to_i
61
- e.renderer_options = {crop_enabled: true}
72
+ e.renderer_options = { crop_enabled: true }
62
73
  end
63
74
 
64
75
  e.save(options[:output_file])
@@ -3,3 +3,7 @@ $:.unshift(File.dirname(__FILE__))
3
3
  require 'gpx_utils'
4
4
  require 'gpx2png/osm'
5
5
  require 'gpx2png/ump'
6
+ require 'gpx2png/opencycle'
7
+ require 'gpx2png/transport'
8
+ require 'gpx2png/landscape'
9
+ require 'gpx2png/outdoors'
@@ -1,29 +1,125 @@
1
- require 'rubygems'
2
-
3
- $:.unshift(File.dirname(__FILE__))
1
+ require 'colorize'
2
+ require 'logger'
3
+ require 'gpx2png/layer'
4
+ require 'gpx2png/calculations/base_class_methods'
5
+ require 'gpx2png/calculations/base_instance_methods'
4
6
 
5
7
  module Gpx2png
6
8
  class Base
9
+ extend Calculations::BaseClassMethods
10
+ include Calculations::BaseInstanceMethods
7
11
 
8
12
  def initialize
9
- @coords = Array.new
13
+ @layers = Array.new
14
+ _layer = Layer.new
15
+ _layer.parent = self
16
+ @layers << _layer
17
+ @single_layer = true
18
+
10
19
  @zoom = 9
11
- @verbose = true
20
+
21
+ self.class.logger.debug("Init, default zoom #{@zoom.to_s.green}")
22
+ end
23
+
24
+ def add_layer(_layer_options)
25
+ if @single_layer
26
+ self.class.logger.debug("Created #{"first".to_s.red} layer")
27
+ # turn off single layer version
28
+ @single_layer = false
29
+ # set layer options for first layer and return it
30
+ _layer = @layers.first
31
+ _layer.options = _layer_options
32
+ return _layer
33
+ else
34
+ # create new layer with options, add to list and return
35
+ _layer = Layer.new
36
+ _layer.parent = self
37
+ _layer.options = _layer_options
38
+ @layers << _layer
39
+ self.class.logger.debug("Created layer, count: #{@layers.size.to_s.red}")
40
+ return _layer
41
+ end
12
42
  end
13
43
 
14
44
  def add(lat, lon)
15
- @coords << { lat: lat, lon: lon }
45
+ if @single_layer
46
+ # add coord to first layer
47
+ _layer = @layers.first
48
+ _layer.add(lat, lon)
49
+ else
50
+ # I'm afraid Dave I can't do that
51
+ self.class.logger.fatal("After you've added first layer you can use coords only from layers")
52
+ raise StandardError
53
+ end
54
+ end
55
+
56
+ def coords=(_coords)
57
+ if @single_layer
58
+ # add coord to first layer
59
+ _layer = @layers.first
60
+ _layer.coords = _coords
61
+ else
62
+ # I'm afraid Dave I can't do that
63
+ self.class.fatal("After you've added first layer you can use coords only from layers")
64
+ raise StandardError
65
+ end
66
+ end
67
+
68
+ def color(_color)
69
+ if @single_layer
70
+ # add coord to first layer
71
+ _layer = @layers.first
72
+ _layer.color = _color
73
+ else
74
+ # I'm afraid Dave I can't do that
75
+ self.class.fatal("After you've added first layer you have to use layers")
76
+ raise StandardError
77
+ end
78
+ end
79
+
80
+ # Create image with fixed size
81
+ def fixed_size(_width, _height)
82
+ @fixed_width = _width
83
+ @fixed_height = _height
84
+ self.class.logger.debug("Map image fixed dimension set #{@fixed_width.to_s.red} x #{@fixed_height.to_s.red}")
85
+ true
16
86
  end
17
87
 
18
- attr_accessor :zoom, :color, :coords
88
+ def zoom=(_zoom)
89
+ self.class.logger.debug("Map zoom set #{_zoom.to_s.red}")
90
+ @zoom = _zoom
91
+ end
92
+
93
+ def zoom
94
+ @zoom
95
+ end
96
+
97
+ attr_accessor :layers
98
+
99
+ # Simulate download of tiles
100
+ attr_accessor :simulate_download
101
+
102
+ def self.simulate_download=(b)
103
+ logger.debug("Simulate tiles download for class #{self.to_s.blue}") if b
104
+ @@simulate_download = b
105
+ end
106
+
107
+ def simulate_download?
108
+ return true if true == self.simulate_download or (defined? @@simulate_download and true == @@simulate_download)
109
+ end
110
+
111
+ def destroy
112
+ @r.destroy
113
+ self.class.logger.debug "Image destroyed"
114
+ end
19
115
 
20
- # Some math stuff
21
- def self.rad2deg(rad)
22
- return rad * 180.0 / Math::PI
116
+ def self.logger=(_logger)
117
+ @@logger = _logger
23
118
  end
24
119
 
25
- def self.deg2rad(deg)
26
- return deg * Math::PI / 180.0
120
+ def self.logger
121
+ @@logger = Logger.new(STDOUT) unless defined? @@logger
122
+ return @@logger
27
123
  end
28
124
 
29
125
  end
@@ -0,0 +1,15 @@
1
+ module Gpx2png
2
+ module Calculations
3
+ module BaseClassMethods
4
+ # Some math stuff
5
+ def rad2deg(rad)
6
+ return rad * 180.0 / Math::PI
7
+ end
8
+
9
+ def deg2rad(deg)
10
+ return deg * Math::PI / 180.0
11
+ end
12
+
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,32 @@
1
+ module Gpx2png
2
+ module Calculations
3
+ module BaseInstanceMethods
4
+
5
+ def calculate_minmax_latlon
6
+ @layers.each do |l|
7
+ enlarge_border_coords(l)
8
+ end
9
+ # when no coords specified
10
+ @lat_min ||= -0.01
11
+ @lat_max ||= 0.01
12
+ @lon_min ||= -0.01
13
+ @lon_max ||= 0.01
14
+ end
15
+
16
+ def enlarge_border_coords(layer)
17
+ _lat_min = layer.coords.collect { |c| c[:lat] }.min
18
+ _lat_max = layer.coords.collect { |c| c[:lat] }.max
19
+ _lon_min = layer.coords.collect { |c| c[:lon] }.min
20
+ _lon_max = layer.coords.collect { |c| c[:lon] }.max
21
+
22
+ @lat_min = _lat_min if @lat_min.nil? or _lat_min < @lat_min
23
+ @lat_max = _lat_max if @lat_max.nil? or _lat_max > @lat_max
24
+ @lon_min = _lon_min if @lon_min.nil? or _lon_min < @lon_min
25
+ @lon_max = _lon_max if @lon_max.nil? or _lon_max > @lon_max
26
+
27
+ self.class.logger.debug("Border coords #{@lat_min.to_s.green},#{@lon_min.to_s.green} - #{@lat_max.to_s.green},#{@lon_max.to_s.green}")
28
+ end
29
+
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,99 @@
1
+ module Gpx2png
2
+ module Calculations
3
+ module OsmClassMethods
4
+
5
+ TILE_WIDTH = 256
6
+ TILE_HEIGHT = 256
7
+
8
+ # http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#X_and_Y
9
+ # Convert latlon deg to OSM tile coords
10
+ def convert(zoom, coord)
11
+ lat_deg, lon_deg = coord
12
+ lat_rad = deg2rad(lat_deg)
13
+ x = (((lon_deg + 180) / 360) * (2 ** zoom)).floor
14
+ y = ((1 - Math.log(Math.tan(lat_rad) + 1 / Math.cos(lat_rad)) / Math::PI) /2 * (2 ** zoom)).floor
15
+
16
+ logger.debug "Converted #{lat_deg.to_s.green},#{lat_deg.to_s.green} to [#{x.to_s.red},#{y.to_s.red}]"
17
+
18
+ return [x, y]
19
+ end
20
+
21
+ # Convert OSM tile coords to latlon deg in top-left corner
22
+ def reverse_convert(zoom, coord)
23
+ x, y = coord
24
+ n = 2 ** zoom
25
+ lon_deg = x.to_f / n.to_f * 360.0 - 180.0
26
+ lat_deg = rad2deg(Math.atan(Math.sinh(Math::PI * (1.to_f - 2.to_f * y.to_f / n.to_f))))
27
+
28
+ logger.debug "Reverse converted [#{x.to_s.red},#{y.to_s.red}] to #{lat_deg.to_s.green},#{lat_deg.to_s.green}"
29
+
30
+ return [lat_deg, lon_deg]
31
+ end
32
+
33
+ # Lazy calc proper zoom for drawing
34
+ def calc_zoom(lat_min, lat_max, lon_min, lon_max, width, height)
35
+ # because I'm lazy! :] and math is not my best side
36
+
37
+ last_zoom = 2
38
+ (5..18).each do |zoom|
39
+ # calculate drawing tile size and pixel size
40
+ tile_min = point_on_absolute_image(zoom, [lat_min, lon_min])
41
+ tile_max = point_on_absolute_image(zoom, [lat_max, lon_max])
42
+ current_pixel_x_distance = tile_max[0] - tile_min[0]
43
+ current_pixel_y_distance = tile_min[1] - tile_max[1]
44
+ if current_pixel_x_distance > width or current_pixel_y_distance > height
45
+ logger.debug "Calculated best zoom #{last_zoom.to_s.red}"
46
+ return last_zoom
47
+ end
48
+ last_zoom = zoom
49
+ end
50
+ return 18
51
+ end
52
+
53
+ # Convert latlon deg coords to image point (x,y) and OSM tile coord
54
+ # return where you should put point on tile
55
+ def point_on_image(zoom, geo_coord)
56
+ osm_tile_coord = convert(zoom, geo_coord)
57
+ top_left_corner = reverse_convert(zoom, osm_tile_coord)
58
+ bottom_right_corner = reverse_convert(zoom, [
59
+ osm_tile_coord[0] + 1, osm_tile_coord[1] + 1
60
+ ])
61
+
62
+ # some line math: y = ax + b
63
+
64
+ x_geo = geo_coord[1]
65
+ # offset
66
+ x_offset = x_geo - top_left_corner[1]
67
+ # scale
68
+ x_distance = (bottom_right_corner[1] - top_left_corner[1])
69
+ x = (TILE_WIDTH.to_f * (x_offset / x_distance)).round
70
+
71
+ y_geo = geo_coord[0]
72
+ # offset
73
+ y_offset = y_geo - top_left_corner[0]
74
+ # scale
75
+ y_distance = (bottom_right_corner[0] - top_left_corner[0])
76
+ y = (TILE_HEIGHT.to_f * (y_offset / y_distance)).round
77
+
78
+ logger.debug("Point on image: zoom #{zoom.to_s.green}, coord #{geo_coord[0].to_s.green},#{geo_coord[1].to_s.green} => [#{x.to_s.red}, #{y.to_s.red}]")
79
+
80
+ return { osm_title_coord: osm_tile_coord, pixel_offset: [x, y] }
81
+ end
82
+
83
+ # Useful for calculating distance on output image
84
+ # It is not position on output image because we don't know tile coords
85
+ # For upper-left tile
86
+ def point_on_absolute_image(zoom, geo_coord)
87
+ _p = point_on_image(zoom, geo_coord)
88
+ _x = _p[:osm_title_coord][0] * TILE_WIDTH + _p[:pixel_offset][0]
89
+ _y = _p[:osm_title_coord][1] * TILE_WIDTH + _p[:pixel_offset][1]
90
+
91
+ logger.debug("Point on abs. image: zoom #{zoom.to_s.green}, coord #{geo_coord[0].to_s.green},#{geo_coord[1].to_s.green} => [#{_x.to_s.red}, #{_y.to_s.red}]")
92
+
93
+ return [_x, _y]
94
+ end
95
+
96
+
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,197 @@
1
+ require 'gpx2png/calculations/osm_class_methods'
2
+
3
+ module Gpx2png
4
+ module Calculations
5
+ module OsmInstanceMethods
6
+
7
+ TILE_WIDTH = OsmClassMethods::TILE_WIDTH
8
+ TILE_HEIGHT = OsmClassMethods::TILE_WIDTH
9
+
10
+ attr_reader :lat_min, :lat_max, :lon_min, :lon_max
11
+ attr_reader :tile_x_distance, :tile_y_distance
12
+ # points for cropping
13
+ attr_reader :bitmap_point_x_max, :bitmap_point_x_min, :bitmap_point_y_max, :bitmap_point_y_min
14
+
15
+ def initial_calculations
16
+ calculate_minmax_latlon
17
+
18
+ # auto zoom must be here
19
+ # drawing must fit into fixed resolution
20
+ # map must be bigger than fixed resolution
21
+ if @fixed_width and @fixed_height
22
+ @new_zoom = self.class.calc_zoom(
23
+ @lat_min, @lat_max,
24
+ @lon_min, @lon_max,
25
+ @fixed_width, @fixed_height
26
+ )
27
+ self.class.logger.debug "Calculated new zoom #{@new_zoom.to_s.red} (was #{@zoom.to_s.red})"
28
+ @zoom = @new_zoom
29
+ end
30
+
31
+ @border_tiles = [
32
+ self.class.convert(@zoom, [@lat_min, @lon_min]),
33
+ self.class.convert(@zoom, [@lat_max, @lon_max])
34
+ ]
35
+
36
+ @tile_x_range = (@border_tiles[0][0])..(@border_tiles[1][0])
37
+ @tile_y_range = (@border_tiles[1][1])..(@border_tiles[0][1])
38
+
39
+ # enlarging ranges to fill up map area
40
+ # both sizes are enlarged
41
+ if @fixed_width and @fixed_height
42
+ x_axis_expand_count = ((@fixed_width - (1 + @tile_x_range.max - @tile_x_range.min) * TILE_WIDTH).to_f / (TILE_WIDTH.to_f * 2.0)).ceil
43
+ y_axis_expand_count = ((@fixed_height - (1 + @tile_y_range.max - @tile_y_range.min) * TILE_HEIGHT).to_f / (TILE_HEIGHT.to_f * 2.0)).ceil
44
+ self.class.logger.debug "Expanding #{"X".to_s.blue} tiles from both sides #{x_axis_expand_count.to_s.green}"
45
+ self.class.logger.debug "Expanding #{"Y".to_s.blue} tiles from both sides #{y_axis_expand_count.to_s.green}"
46
+ @tile_x_range = ((@tile_x_range.min - x_axis_expand_count)..(@tile_x_range.max + x_axis_expand_count))
47
+ @tile_y_range = ((@tile_y_range.min - y_axis_expand_count)..(@tile_y_range.max + y_axis_expand_count))
48
+ end
49
+
50
+ # new/full image size
51
+ @full_image_x = (1 + @tile_x_range.max - @tile_x_range.min) * TILE_WIDTH
52
+ @full_image_y = (1 + @tile_y_range.max - @tile_y_range.min) * TILE_HEIGHT
53
+ @r.x = @full_image_x
54
+ @r.y = @full_image_y
55
+
56
+ if @fixed_width and @fixed_height
57
+ calculate_for_crop_with_auto_zoom
58
+ else
59
+ calculate_for_crop
60
+ end
61
+ end
62
+
63
+ # Calculate zoom level
64
+ def auto_zoom_for(x = 0, y = 0)
65
+ # TODO
66
+ end
67
+
68
+ # Calculate some numbers for cropping operation
69
+ def calculate_for_crop
70
+ point_min = self.class.point_on_image(@zoom, [@lat_min, @lon_min])
71
+ point_max = self.class.point_on_image(@zoom, [@lat_max, @lon_max])
72
+ @bitmap_point_x_min = (point_min[:osm_title_coord][0] - @tile_x_range.min) * TILE_WIDTH + point_min[:pixel_offset][0]
73
+ @bitmap_point_x_max = (point_max[:osm_title_coord][0] - @tile_x_range.min) * TILE_WIDTH + point_max[:pixel_offset][0]
74
+ @bitmap_point_y_max = (point_min[:osm_title_coord][1] - @tile_y_range.min) * TILE_HEIGHT + point_min[:pixel_offset][1]
75
+ @bitmap_point_y_min = (point_max[:osm_title_coord][1] - @tile_y_range.min) * TILE_HEIGHT + point_max[:pixel_offset][1]
76
+
77
+ @r.set_crop(@bitmap_point_x_min, @bitmap_point_x_max, @bitmap_point_y_min, @bitmap_point_y_max)
78
+ end
79
+
80
+ # Calculate some numbers for cropping operation with autozoom
81
+ def calculate_for_crop_with_auto_zoom
82
+ point_min = self.class.point_on_image(@zoom, [@lat_min, @lon_min])
83
+ point_max = self.class.point_on_image(@zoom, [@lat_max, @lon_max])
84
+ @bitmap_point_x_min = (point_min[:osm_title_coord][0] - @tile_x_range.min) * TILE_WIDTH + point_min[:pixel_offset][0]
85
+ @bitmap_point_x_max = (point_max[:osm_title_coord][0] - @tile_x_range.min) * TILE_WIDTH + point_max[:pixel_offset][0]
86
+ @bitmap_point_y_max = (point_min[:osm_title_coord][1] - @tile_y_range.min) * TILE_HEIGHT + point_min[:pixel_offset][1]
87
+ @bitmap_point_y_min = (point_max[:osm_title_coord][1] - @tile_y_range.min) * TILE_HEIGHT + point_max[:pixel_offset][1]
88
+
89
+ bitmap_x_center = (@bitmap_point_x_min + @bitmap_point_x_max) / 2
90
+ bitmap_y_center = (@bitmap_point_y_min + @bitmap_point_y_max) / 2
91
+
92
+ @r.set_crop_fixed(bitmap_x_center, bitmap_y_center, @fixed_width, @fixed_height)
93
+ end
94
+
95
+ def expand_map
96
+ # TODO expand min and max ranges
97
+ end
98
+
99
+ # Do everything
100
+ def download_and_join_tiles
101
+ self.class.logger.info "Output image dimension #{@full_image_x.to_s.red} x #{@full_image_y.to_s.red}"
102
+ @r.new_image
103
+
104
+ # {:x, :y, :blob}
105
+ @images = Array.new
106
+
107
+
108
+ @tile_x_range.each do |x|
109
+ @tile_y_range.each do |y|
110
+ url = self.class.url(@zoom, [x, y])
111
+
112
+ # blob time
113
+ unless simulate_download?
114
+ uri = URI.parse(url)
115
+ response = Net::HTTP.get_response(uri)
116
+ blob = response.body
117
+ else
118
+ blob = @r.blank_tile(TILE_WIDTH, TILE_HEIGHT, x+y)
119
+ end
120
+
121
+ @r.add_tile(
122
+ blob,
123
+ (x - @tile_x_range.min) * TILE_WIDTH,
124
+ (y - @tile_y_range.min) * TILE_HEIGHT
125
+ )
126
+
127
+ @images << {
128
+ url: url,
129
+ x: x,
130
+ y: y
131
+ }
132
+
133
+ self.class.logger.info "processed #{(x - @tile_x_range.min).to_s.red} x #{(y - @tile_y_range.min).to_s.red} (max #{(@tile_x_range.max - @tile_x_range.min).to_s.yellow} x #{(@tile_y_range.max - @tile_y_range.min).to_s.yellow})"
134
+ end
135
+ end
136
+
137
+ # sweet, image is joined
138
+
139
+ # min/max points used for cropping
140
+ @bitmap_point_x_max = (@full_image_x / 2).round
141
+ @bitmap_point_x_min = (@full_image_x / 2).round
142
+ @bitmap_point_y_max = (@full_image_y / 2).round
143
+ @bitmap_point_y_min = (@full_image_y / 2).round
144
+
145
+ # add all coords to the map
146
+ _coords_count = 0
147
+ @layers.each do |layer|
148
+ _coords = layer.coords
149
+ _coords_count += _coords.size
150
+ (1..._coords.size).each do |i|
151
+
152
+ lat_from = _coords[i-1][:lat]
153
+ lon_from = _coords[i-1][:lon]
154
+
155
+ lat_to = _coords[i][:lat]
156
+ lon_to = _coords[i][:lon]
157
+
158
+ point_from = self.class.point_on_image(@zoom, [lat_from, lon_from])
159
+ point_to = self.class.point_on_image(@zoom, [lat_to, lon_to])
160
+ # { osm_title_coord: osm_tile_coord, pixel_offset: [x, y] }
161
+
162
+ # first point
163
+ bitmap_xa = (point_from[:osm_title_coord][0] - @tile_x_range.min) * TILE_WIDTH + point_from[:pixel_offset][0]
164
+ bitmap_ya = (point_from[:osm_title_coord][1] - @tile_y_range.min) * TILE_HEIGHT + point_from[:pixel_offset][1]
165
+ bitmap_xb = (point_to[:osm_title_coord][0] - @tile_x_range.min) * TILE_WIDTH + point_to[:pixel_offset][0]
166
+ bitmap_yb = (point_to[:osm_title_coord][1] - @tile_y_range.min) * TILE_HEIGHT + point_to[:pixel_offset][1]
167
+
168
+ @r.line(
169
+ bitmap_xa, bitmap_ya,
170
+ bitmap_xb, bitmap_yb
171
+ )
172
+ end
173
+ end
174
+ self.class.logger.info "Layers - #{@layers.size.to_s.red} with #{_coords_count.to_s.yellow} coords have been added to image"
175
+
176
+ # add points
177
+ @markers.each do |point|
178
+ lat = point[:lat]
179
+ lon = point[:lon]
180
+
181
+ p = self.class.point_on_image(@zoom, [lat, lon])
182
+ bitmap_x = (p[:osm_title_coord][0] - @tile_x_range.min) * TILE_WIDTH + p[:pixel_offset][0]
183
+ bitmap_y = (p[:osm_title_coord][1] - @tile_y_range.min) * TILE_HEIGHT + p[:pixel_offset][1]
184
+
185
+ point[:x] = bitmap_x
186
+ point[:y] = bitmap_y
187
+
188
+ @r.markers << point
189
+ end
190
+ self.class.logger.info "Markers - #{@markers.size.to_s.red} have been added to image"
191
+
192
+ end
193
+
194
+
195
+ end
196
+ end
197
+ end
@@ -0,0 +1,19 @@
1
+ require 'rubygems'
2
+ require 'gpx2png/osm'
3
+
4
+ module Gpx2png
5
+ class Landscape < Osm
6
+
7
+ # Convert OSM/UMP tile coords to url
8
+ def self.url(zoom, coord, server = '3.')
9
+ x, y = coord
10
+ url = "http://tile.thunderforest.com/landscape/#{zoom}/#{x}/#{y}.png"
11
+ return url
12
+ end
13
+
14
+ def self.licence_string
15
+ "All maps copyright Thunderforest.com and OpenStreetMap contributors"
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,36 @@
1
+ module Gpx2png
2
+ class Layer
3
+ def initialize
4
+ @coords = Array.new
5
+ @options = Hash.new
6
+ end
7
+
8
+ attr_accessor :options, :coords, :parent
9
+
10
+ def coords=(_coords)
11
+ logger.debug("Set #{_coords.size.to_s.red} for layer #{self.index.to_s.green}")
12
+ @coords = _coords
13
+ end
14
+
15
+ def coords
16
+ @coords
17
+ end
18
+
19
+ # Number of this layer
20
+ def index
21
+ if @parent
22
+ return parent.layers.index(self)
23
+ end
24
+ return nil
25
+ end
26
+
27
+ def logger
28
+ @parent.class.logger
29
+ end
30
+
31
+ def add(lat, lon)
32
+ logger.debug("Added coord #{lat.to_s.red},#{lon.to_s.red} for layer #{self.index.to_s.green}, count #{(@coords.size + 1).to_s.blue}")
33
+ @coords << { lat: lat, lon: lon }
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,19 @@
1
+ require 'rubygems'
2
+ require 'gpx2png/osm'
3
+
4
+ module Gpx2png
5
+ class OpenCycle < Osm
6
+
7
+ # Convert OSM/UMP tile coords to url
8
+ def self.url(zoom, coord, server = '3.')
9
+ x, y = coord
10
+ url = "http://tile.thunderforest.com/cycle/#{zoom}/#{x}/#{y}.png"
11
+ return url
12
+ end
13
+
14
+ def self.licence_string
15
+ "All maps copyright Thunderforest.com and OpenStreetMap contributors"
16
+ end
17
+
18
+ end
19
+ end
@@ -1,8 +1,6 @@
1
1
  require 'rubygems'
2
2
  require 'gpx2png/osm_base'
3
3
 
4
- $:.unshift(File.dirname(__FILE__))
5
-
6
4
  module Gpx2png
7
5
  class Osm < OsmBase
8
6
 
@@ -1,36 +1,16 @@
1
- require 'rubygems'
2
1
  require 'gpx2png/base'
3
2
  require 'net/http'
4
3
  require "uri"
5
-
6
- $:.unshift(File.dirname(__FILE__))
4
+ require 'gpx2png/calculations/osm_class_methods'
5
+ require 'gpx2png/calculations/osm_instance_methods'
7
6
 
8
7
  module Gpx2png
9
8
  class OsmBase < Base
10
- TILE_WIDTH = 256
11
- TILE_HEIGHT = 256
12
-
13
- # if true it will not download tiles
14
- attr_accessor :simulate_download
9
+ extend Calculations::OsmClassMethods
10
+ include Calculations::OsmInstanceMethods
15
11
 
16
- def self.simulate_download=(b)
17
- @@simulate_download = b
18
- end
19
-
20
- def simulate_download?
21
- return true if true == self.simulate_download or (defined? @@simulate_download and true == @@simulate_download)
22
- end
23
-
24
- # http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#X_and_Y
25
- # Convert latlon deg to OSM tile coords
26
- def self.convert(zoom, coord)
27
- lat_deg, lon_deg = coord
28
- lat_rad = deg2rad(lat_deg)
29
- x = (((lon_deg + 180) / 360) * (2 ** zoom)).floor
30
- y = ((1 - Math.log(Math.tan(lat_rad) + 1 / Math.cos(lat_rad)) / Math::PI) /2 * (2 ** zoom)).floor
31
-
32
- return [x, y]
33
- end
12
+ TILE_WIDTH = Calculations::OsmClassMethods::TILE_WIDTH
13
+ TILE_HEIGHT = Calculations::OsmClassMethods::TILE_HEIGHT
34
14
 
35
15
  # Convert latlon deg to OSM tile url
36
16
  # TODO add algorithm to choose from diff. servers
@@ -46,265 +26,11 @@ module Gpx2png
46
26
  return url
47
27
  end
48
28
 
49
- # Convert OSM tile coords to latlon deg in top-left corner
50
- def self.reverse_convert(zoom, coord)
51
- x, y = coord
52
- n = 2 ** zoom
53
- lon_deg = x.to_f / n.to_f * 360.0 - 180.0
54
- lat_deg = rad2deg(Math.atan(Math.sinh(Math::PI * (1.to_f - 2.to_f * y.to_f / n.to_f))))
55
- return [lat_deg, lon_deg]
56
- end
57
-
58
- # Lazy calc proper zoom for drawing
59
- def self.calc_zoom(lat_min, lat_max, lon_min, lon_max, width, height)
60
- # because I'm lazy! :] and math is not my best side
61
-
62
- last_zoom = 2
63
- (5..18).each do |zoom|
64
- # calculate drawing tile size and pixel size
65
- tile_min = point_on_absolute_image(zoom, [lat_min, lon_min])
66
- tile_max = point_on_absolute_image(zoom, [lat_max, lon_max])
67
- current_pixel_x_distance = tile_max[0] - tile_min[0]
68
- current_pixel_y_distance = tile_min[1] - tile_max[1]
69
- if current_pixel_x_distance > width or current_pixel_y_distance > height
70
- return last_zoom
71
- end
72
- last_zoom = zoom
73
- end
74
- return 18
75
- end
76
-
77
- # Convert latlon deg coords to image point (x,y) and OSM tile coord
78
- # return where you should put point on tile
79
- def self.point_on_image(zoom, geo_coord)
80
- osm_tile_coord = convert(zoom, geo_coord)
81
- top_left_corner = reverse_convert(zoom, osm_tile_coord)
82
- bottom_right_corner = reverse_convert(zoom, [
83
- osm_tile_coord[0] + 1, osm_tile_coord[1] + 1
84
- ])
85
-
86
- # some line math: y = ax + b
87
-
88
- x_geo = geo_coord[1]
89
- # offset
90
- x_offset = x_geo - top_left_corner[1]
91
- # scale
92
- x_distance = (bottom_right_corner[1] - top_left_corner[1])
93
- x = (TILE_WIDTH.to_f * (x_offset / x_distance)).round
94
-
95
- y_geo = geo_coord[0]
96
- # offset
97
- y_offset = y_geo - top_left_corner[0]
98
- # scale
99
- y_distance = (bottom_right_corner[0] - top_left_corner[0])
100
- y = (TILE_HEIGHT.to_f * (y_offset / y_distance)).round
101
-
102
- return { osm_title_coord: osm_tile_coord, pixel_offset: [x, y] }
103
- end
104
-
105
- # Useful for calculating distance on output image
106
- # It is not position on output image because we don't know tile coords
107
- # For upper-left tile
108
- def self.point_on_absolute_image(zoom, geo_coord)
109
- _p = point_on_image(zoom, geo_coord)
110
- _x = _p[:osm_title_coord][0] * TILE_WIDTH + _p[:pixel_offset][0]
111
- _y = _p[:osm_title_coord][1] * TILE_WIDTH + _p[:pixel_offset][1]
112
- return [_x, _y]
113
- end
114
-
115
- # Create image with fixed size
116
- def fixed_size(_width, _height)
117
- @fixed_width = _width
118
- @fixed_height = _height
119
- end
120
-
121
- def initial_calculations
122
- @lat_min = @coords.collect { |c| c[:lat] }.min
123
- @lat_max = @coords.collect { |c| c[:lat] }.max
124
- @lon_min = @coords.collect { |c| c[:lon] }.min
125
- @lon_max = @coords.collect { |c| c[:lon] }.max
126
-
127
- # auto zoom must be here
128
- # drawing must fit into fixed resolution
129
- # map must be bigger than fixed resolution
130
- if @fixed_width and @fixed_height
131
- @new_zoom = self.class.calc_zoom(
132
- @lat_min, @lat_max,
133
- @lon_min, @lon_max,
134
- @fixed_width, @fixed_height
135
- )
136
- puts "Calculated new zoom #{@new_zoom} (was #{@zoom})" if @verbose
137
- @zoom = @new_zoom
138
- end
139
-
140
- @border_tiles = [
141
- self.class.convert(@zoom, [@lat_min, @lon_min]),
142
- self.class.convert(@zoom, [@lat_max, @lon_max])
143
- ]
144
-
145
- @tile_x_range = (@border_tiles[0][0])..(@border_tiles[1][0])
146
- @tile_y_range = (@border_tiles[1][1])..(@border_tiles[0][1])
147
-
148
- # enlarging ranges to fill up map area
149
- # both sizes are enlarged
150
- # = ( ( (preferred size - real size) / tile width ) / 2 ).ceil
151
- if @fixed_width and @fixed_height
152
- x_axis_expand_count = ((@fixed_width - (1 + @tile_x_range.max - @tile_x_range.min) * TILE_WIDTH).to_f / (TILE_WIDTH.to_f * 2.0)).ceil
153
- y_axis_expand_count = ((@fixed_height - (1 + @tile_y_range.max - @tile_y_range.min) * TILE_HEIGHT).to_f / (TILE_HEIGHT.to_f * 2.0)).ceil
154
- puts "Expanding X tiles from both sides #{x_axis_expand_count}" if @verbose
155
- puts "Expanding Y tiles from both sides #{y_axis_expand_count}" if @verbose
156
- @tile_x_range = ((@tile_x_range.min - x_axis_expand_count)..(@tile_x_range.max + x_axis_expand_count))
157
- @tile_y_range = ((@tile_y_range.min - y_axis_expand_count)..(@tile_y_range.max + y_axis_expand_count))
158
- end
159
-
160
- # new/full image size
161
- @full_image_x = (1 + @tile_x_range.max - @tile_x_range.min) * TILE_WIDTH
162
- @full_image_y = (1 + @tile_y_range.max - @tile_y_range.min) * TILE_HEIGHT
163
- @r.x = @full_image_x
164
- @r.y = @full_image_y
165
-
166
- if @fixed_width and @fixed_height
167
- calculate_for_crop_with_auto_zoom
168
- else
169
- calculate_for_crop
170
- end
171
- end
172
-
173
- # Calculate zoom level
174
- def auto_zoom_for(x = 0, y = 0)
175
- # TODO
176
- end
177
-
178
- attr_reader :lat_min, :lat_max, :lon_min, :lon_max
179
- attr_reader :tile_x_distance, :tile_y_distance
180
- # points for cropping
181
- attr_reader :bitmap_point_x_max, :bitmap_point_x_min, :bitmap_point_y_max, :bitmap_point_y_min
182
-
183
- # Do everything
184
- def download_and_join_tiles
185
- puts "Output image dimension #{@full_image_x}x#{@full_image_y}" if @verbose
186
- @r.new_image
187
-
188
- # {:x, :y, :blob}
189
- @images = Array.new
190
-
191
-
192
- @tile_x_range.each do |x|
193
- @tile_y_range.each do |y|
194
- url = self.class.url(@zoom, [x, y])
195
-
196
- # blob time
197
- unless simulate_download?
198
- uri = URI.parse(url)
199
- response = Net::HTTP.get_response(uri)
200
- blob = response.body
201
- else
202
- blob = @r.blank_tile(TILE_WIDTH, TILE_HEIGHT, x+y)
203
- end
204
-
205
- @r.add_tile(
206
- blob,
207
- (x - @tile_x_range.min) * TILE_WIDTH,
208
- (y - @tile_y_range.min) * TILE_HEIGHT
209
- )
210
-
211
- @images << {
212
- url: url,
213
- x: x,
214
- y: y
215
- }
216
-
217
- puts "processed #{x - @tile_x_range.min}x#{y - @tile_y_range.min} (max #{@tile_x_range.max - @tile_x_range.min}x#{@tile_y_range.max - @tile_y_range.min})" if @verbose
218
- end
219
- end
220
-
221
- # sweet, image is joined
222
-
223
- # min/max points used for cropping
224
- @bitmap_point_x_max = (@full_image_x / 2).round
225
- @bitmap_point_x_min = (@full_image_x / 2).round
226
- @bitmap_point_y_max = (@full_image_y / 2).round
227
- @bitmap_point_y_min = (@full_image_y / 2).round
228
-
229
- # add some coords to the map
230
- (1...@coords.size).each do |i|
231
- lat_from = @coords[i-1][:lat]
232
- lon_from = @coords[i-1][:lon]
233
-
234
- lat_to = @coords[i][:lat]
235
- lon_to = @coords[i][:lon]
236
-
237
- point_from = self.class.point_on_image(@zoom, [lat_from, lon_from])
238
- point_to = self.class.point_on_image(@zoom, [lat_to, lon_to])
239
- # { osm_title_coord: osm_tile_coord, pixel_offset: [x, y] }
240
-
241
- # first point
242
- bitmap_xa = (point_from[:osm_title_coord][0] - @tile_x_range.min) * TILE_WIDTH + point_from[:pixel_offset][0]
243
- bitmap_ya = (point_from[:osm_title_coord][1] - @tile_y_range.min) * TILE_HEIGHT + point_from[:pixel_offset][1]
244
- bitmap_xb = (point_to[:osm_title_coord][0] - @tile_x_range.min) * TILE_WIDTH + point_to[:pixel_offset][0]
245
- bitmap_yb = (point_to[:osm_title_coord][1] - @tile_y_range.min) * TILE_HEIGHT + point_to[:pixel_offset][1]
246
-
247
- @r.line(
248
- bitmap_xa, bitmap_ya,
249
- bitmap_xb, bitmap_yb
250
- )
251
- end
252
-
253
- # add points
254
- @markers.each do |point|
255
- lat = point[:lat]
256
- lon = point[:lon]
257
-
258
- p = self.class.point_on_image(@zoom, [lat, lon])
259
- bitmap_x = (p[:osm_title_coord][0] - @tile_x_range.min) * TILE_WIDTH + p[:pixel_offset][0]
260
- bitmap_y = (p[:osm_title_coord][1] - @tile_y_range.min) * TILE_HEIGHT + p[:pixel_offset][1]
261
-
262
- point[:x] = bitmap_x
263
- point[:y] = bitmap_y
264
-
265
- @r.markers << point
266
- end
267
- end
268
-
269
- # Calculate some numbers for cropping operation
270
- def calculate_for_crop
271
- point_min = self.class.point_on_image(@zoom, [@lat_min, @lon_min])
272
- point_max = self.class.point_on_image(@zoom, [@lat_max, @lon_max])
273
- @bitmap_point_x_min = (point_min[:osm_title_coord][0] - @tile_x_range.min) * TILE_WIDTH + point_min[:pixel_offset][0]
274
- @bitmap_point_x_max = (point_max[:osm_title_coord][0] - @tile_x_range.min) * TILE_WIDTH + point_max[:pixel_offset][0]
275
- @bitmap_point_y_max = (point_min[:osm_title_coord][1] - @tile_y_range.min) * TILE_HEIGHT + point_min[:pixel_offset][1]
276
- @bitmap_point_y_min = (point_max[:osm_title_coord][1] - @tile_y_range.min) * TILE_HEIGHT + point_max[:pixel_offset][1]
277
-
278
- @r.set_crop(@bitmap_point_x_min, @bitmap_point_x_max, @bitmap_point_y_min, @bitmap_point_y_max)
279
- end
280
-
281
- # Calculate some numbers for cropping operation with autozoom
282
- def calculate_for_crop_with_auto_zoom
283
- point_min = self.class.point_on_image(@zoom, [@lat_min, @lon_min])
284
- point_max = self.class.point_on_image(@zoom, [@lat_max, @lon_max])
285
- @bitmap_point_x_min = (point_min[:osm_title_coord][0] - @tile_x_range.min) * TILE_WIDTH + point_min[:pixel_offset][0]
286
- @bitmap_point_x_max = (point_max[:osm_title_coord][0] - @tile_x_range.min) * TILE_WIDTH + point_max[:pixel_offset][0]
287
- @bitmap_point_y_max = (point_min[:osm_title_coord][1] - @tile_y_range.min) * TILE_HEIGHT + point_min[:pixel_offset][1]
288
- @bitmap_point_y_min = (point_max[:osm_title_coord][1] - @tile_y_range.min) * TILE_HEIGHT + point_max[:pixel_offset][1]
289
-
290
- bitmap_x_center = (@bitmap_point_x_min + @bitmap_point_x_max) / 2
291
- bitmap_y_center = (@bitmap_point_y_min + @bitmap_point_y_max) / 2
292
-
293
- @r.set_crop_fixed(bitmap_x_center, bitmap_y_center, @fixed_width, @fixed_height)
294
- end
295
-
296
- def expand_map
297
- # TODO expand min and max ranges
298
- end
299
-
300
29
  def self.licence_string
301
30
  "Map data OpenStreetMap (CC-by-SA 2.0)"
302
31
  end
303
32
 
304
- def destroy
305
- @r.destroy
306
- puts "Image destroyed" if @verbose
307
- end
33
+
308
34
 
309
35
  end
310
36
  end
@@ -0,0 +1,19 @@
1
+ require 'rubygems'
2
+ require 'gpx2png/osm'
3
+
4
+ module Gpx2png
5
+ class Outdoors < Osm
6
+
7
+ # Convert OSM/UMP tile coords to url
8
+ def self.url(zoom, coord, server = '3.')
9
+ x, y = coord
10
+ url = "http://tile.thunderforest.com/outdoors/#{zoom}/#{x}/#{y}.png"
11
+ return url
12
+ end
13
+
14
+ def self.licence_string
15
+ "All maps copyright Thunderforest.com and OpenStreetMap contributors"
16
+ end
17
+
18
+ end
19
+ end
@@ -1,7 +1,7 @@
1
1
  require 'rubygems'
2
2
  require 'chunky_png'
3
3
 
4
- $:.unshift(File.dirname(__FILE__))
4
+ # WARNING: deprecated
5
5
 
6
6
  # This renderer has some/a lot of features missing
7
7
  module Gpx2png
@@ -2,8 +2,6 @@ require 'rubygems'
2
2
  require 'RMagick'
3
3
  require 'gpx2png/assets/sample_marker'
4
4
 
5
- $:.unshift(File.dirname(__FILE__))
6
-
7
5
  module Gpx2png
8
6
  class RmagickRenderer
9
7
  def initialize(_options = {})
@@ -77,8 +75,6 @@ module Gpx2png
77
75
 
78
76
  # Setup crop image using CSS padding style data
79
77
  def set_crop(x_min, x_max, y_min, y_max)
80
- # puts @x, @y, @crop_margin, x_min, x_max, y_min, y_max
81
-
82
78
  @crop_t = y_min - @crop_margin
83
79
  @crop_r = (@x - x_max) - @crop_margin
84
80
  @crop_b = (@y - y_max) - @crop_margin
@@ -0,0 +1,19 @@
1
+ require 'rubygems'
2
+ require 'gpx2png/osm'
3
+
4
+ module Gpx2png
5
+ class Transport < Osm
6
+
7
+ # Convert OSM/UMP tile coords to url
8
+ def self.url(zoom, coord, server = '3.')
9
+ x, y = coord
10
+ url = "http://tile.thunderforest.com/transport/#{zoom}/#{x}/#{y}.png"
11
+ return url
12
+ end
13
+
14
+ def self.licence_string
15
+ "All maps copyright Thunderforest.com and OpenStreetMap contributors"
16
+ end
17
+
18
+ end
19
+ end
@@ -1,8 +1,6 @@
1
1
  require 'rubygems'
2
2
  require 'gpx2png/osm'
3
3
 
4
- $:.unshift(File.dirname(__FILE__))
5
-
6
4
  module Gpx2png
7
5
  class Ump < Osm
8
6
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gpx2png
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-12-22 00:00:00.000000000 Z
12
+ date: 2013-12-23 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: mini_exiftool
@@ -59,6 +59,22 @@ dependencies:
59
59
  - - ! '>='
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: colorize
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
62
78
  - !ruby/object:Gem::Dependency
63
79
  name: rspec
64
80
  requirement: !ruby/object:Gem::Requirement
@@ -142,10 +158,19 @@ files:
142
158
  - lib/gpx2png.rb
143
159
  - lib/gpx2png/assets/sample_marker.rb
144
160
  - lib/gpx2png/base.rb
161
+ - lib/gpx2png/calculations/base_class_methods.rb
162
+ - lib/gpx2png/calculations/base_instance_methods.rb
163
+ - lib/gpx2png/calculations/osm_class_methods.rb
164
+ - lib/gpx2png/calculations/osm_instance_methods.rb
165
+ - lib/gpx2png/landscape.rb
166
+ - lib/gpx2png/layer.rb
167
+ - lib/gpx2png/opencycle.rb
145
168
  - lib/gpx2png/osm.rb
146
169
  - lib/gpx2png/osm_base.rb
170
+ - lib/gpx2png/outdoors.rb
147
171
  - lib/gpx2png/renderers/chunky_png_renderer.rb
148
172
  - lib/gpx2png/renderers/rmagick_renderer.rb
173
+ - lib/gpx2png/transport.rb
149
174
  - lib/gpx2png/ump.rb
150
175
  homepage: http://github.com/akwiatkowski/gpx2png
151
176
  licenses:
@@ -162,7 +187,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
162
187
  version: '0'
163
188
  segments:
164
189
  - 0
165
- hash: 2224186545062807777
190
+ hash: 828698515099526590
166
191
  required_rubygems_version: !ruby/object:Gem::Requirement
167
192
  none: false
168
193
  requirements: