map_print 1.0.1 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +9 -2
- data/bin/map_print +6 -1
- data/lib/map_print/geo_json_handler.rb +51 -37
- data/lib/map_print/legend_handler.rb +67 -2
- data/lib/map_print/pdf_handler.rb +6 -2
- data/lib/map_print/scalebar_handler.rb +6 -9
- data/lib/map_print/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bcc0124c6e8b0ca5bae918c8306ff3057f8d400e
|
4
|
+
data.tar.gz: 0c47173c8d8a2079d54a6775ee738f3f9a50a233
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2a3fc9ee3d584924d37ac49a68319a9827f9c4b3a00718c5f77d81ee969b0ddacec7ba30626fca03fb04e527c68ee206c2cf3cc0fd5f0d4ff2a16f5c129f17da
|
7
|
+
data.tar.gz: 36f8e4882219e98149d3750d778e25292d277198a13b21c5e4b0f6c39d50486627105d2bba0bdfe1a6dc63967fb6dfee58892b3b854632f3f37df37dbbac1c26
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -27,7 +27,7 @@ Or install it yourself as:
|
|
27
27
|
|
28
28
|
### Executable
|
29
29
|
|
30
|
-
`map_print print --south-west="-35.026862,-58.425003" --north-east="-29.980172,-52.959305" --zoom="10" --output="output.png"`
|
30
|
+
`map_print print --south-west="-35.026862,-58.425003" --north-east="-29.980172,-52.959305" --width=500 --height=800 --zoom="10" --output="output.png"`
|
31
31
|
|
32
32
|
Indicating southwest and northeast to determine the bounding box. Set the zoom at which the tiles should be requested.
|
33
33
|
|
@@ -210,7 +210,14 @@ map_configuration = {
|
|
210
210
|
padding: {top: 5, right: 5, bottom: 5, left: 5},
|
211
211
|
bar_height: 10,
|
212
212
|
background_color: 'black',
|
213
|
-
background_opacity: 0.4
|
213
|
+
background_opacity: 0.4,
|
214
|
+
text_style: {
|
215
|
+
fill_color: '#ffffff',
|
216
|
+
color: '#000000',
|
217
|
+
font: 'Arial',
|
218
|
+
pointsize: '16',
|
219
|
+
gravity: 'NorthWest'
|
220
|
+
}
|
214
221
|
}
|
215
222
|
}
|
216
223
|
```
|
data/bin/map_print
CHANGED
@@ -10,8 +10,10 @@ class MapPrintCommand < Thor
|
|
10
10
|
|
11
11
|
method_option :south_west, type: :string, required: true
|
12
12
|
method_option :north_east, type: :string, required: true
|
13
|
-
method_option :
|
13
|
+
method_option :width, type: :numeric, required: true
|
14
|
+
method_option :height, type: :numeric, required: true
|
14
15
|
method_option :zoom, type: :numeric, default: 10
|
16
|
+
method_option :output, type: :string, required: true
|
15
17
|
|
16
18
|
method_option :provider, type: :string, default: 'osm',
|
17
19
|
enum: ['osm', 'bing']
|
@@ -25,8 +27,11 @@ class MapPrintCommand < Thor
|
|
25
27
|
south_west = MapPrint::LatLng.new(*south_west_coordinate)
|
26
28
|
north_east = MapPrint::LatLng.new(*north_east_coordinate)
|
27
29
|
|
30
|
+
png_options = {height: options[:height], width: options[:width]}
|
31
|
+
|
28
32
|
map_options = {
|
29
33
|
format: 'png',
|
34
|
+
png_options: png_options,
|
30
35
|
map: {
|
31
36
|
sw: {
|
32
37
|
lat: south_west.lat,
|
@@ -38,30 +38,33 @@ module MapPrint
|
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
|
-
def
|
41
|
+
def validate_feature(geometry, properties)
|
42
42
|
raise NoGeometryPresent.new("No geometry present for this feature") if geometry.nil?
|
43
43
|
case geometry['type']
|
44
|
+
when 'Point'
|
45
|
+
if properties.nil? || properties['image'].nil?
|
46
|
+
raise NoPointImage.new("Missing image in point geometry")
|
47
|
+
end
|
48
|
+
when 'MultiPoint', 'MultiLineString', 'MultiPolygon', 'GeometryCollection'
|
49
|
+
raise FeatureNotImplemented.new("Please consider contributing!")
|
50
|
+
else
|
51
|
+
Logger.warn "Feature type '#{geometry['type']}' not implemented!"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def feature(geometry, properties={})
|
56
|
+
validate_feature(geometry, properties)
|
57
|
+
case geometry['type']
|
44
58
|
when 'Feature'
|
45
59
|
feature(geometry['geometry'], geometry['properties'])
|
46
60
|
when 'FeatureCollection'
|
47
61
|
feature_collection(geometry['features'])
|
48
62
|
when 'Point'
|
49
|
-
raise NoPointImage.new("Missing image in point geometry") unless properties && properties['image']
|
50
63
|
point(geometry, properties['image'])
|
51
64
|
when 'LineString'
|
52
65
|
line_string(geometry, properties)
|
53
66
|
when 'Polygon'
|
54
67
|
polygon(geometry, properties)
|
55
|
-
when 'MultiPoint'
|
56
|
-
raise FeatureNotImplemented.new("Please consider contributing!")
|
57
|
-
when 'MultiLineString'
|
58
|
-
raise FeatureNotImplemented.new("Please consider contributing!")
|
59
|
-
when 'MultiPolygon'
|
60
|
-
raise FeatureNotImplemented.new("Please consider contributing!")
|
61
|
-
when 'GeometryCollection'
|
62
|
-
raise FeatureNotImplemented.new("Please consider contributing!")
|
63
|
-
else
|
64
|
-
Logger.warn "Feature type '#{geometry['type']}' not implemented!"
|
65
68
|
end
|
66
69
|
rescue GeoJSONHandlerError => ex
|
67
70
|
Logger.warn ex
|
@@ -77,7 +80,7 @@ module MapPrint
|
|
77
80
|
x = get_x(point['coordinates'][0])
|
78
81
|
y = get_y(point['coordinates'][1])
|
79
82
|
|
80
|
-
if
|
83
|
+
if point_inside_map?(x, y)
|
81
84
|
point_image = MiniMagick::Image.open(image_path)
|
82
85
|
x -= point_image.width / 2
|
83
86
|
y -= point_image.height / 2
|
@@ -92,17 +95,7 @@ module MapPrint
|
|
92
95
|
end
|
93
96
|
|
94
97
|
def line_string(geometry, properties)
|
95
|
-
|
96
|
-
coords = geometry['coordinates']
|
97
|
-
coords = coords.first if coords.first.first.is_a?(Array)
|
98
|
-
points = coords.map do |coord|
|
99
|
-
x = get_x(coord[0])
|
100
|
-
y = get_y(coord[1])
|
101
|
-
if 0 <= x && x <= @width && 0 <= y && y <= @height
|
102
|
-
Logger.warn "Line coordinate outside map's boundaries!\ngeometry: #{geometry.inspect}\nproperties: #{properties.inspect}"
|
103
|
-
end
|
104
|
-
"#{x},#{y}"
|
105
|
-
end
|
98
|
+
points = generate_drawable_points(geometry, properties)
|
106
99
|
|
107
100
|
draw_command = (0..(points.length - 2)).map do |i|
|
108
101
|
"line #{points[i]} #{points[i+1]}"
|
@@ -115,17 +108,7 @@ module MapPrint
|
|
115
108
|
end
|
116
109
|
|
117
110
|
def polygon(geometry, properties)
|
118
|
-
|
119
|
-
coords = geometry['coordinates']
|
120
|
-
coords = coords.first if coords.first.first.is_a?(Array)
|
121
|
-
points = coords.map do |coord|
|
122
|
-
x = get_x(coord[0])
|
123
|
-
y = get_y(coord[1])
|
124
|
-
if 0 <= x && x <= @width && 0 <= y && y <= @height
|
125
|
-
Logger.warn "Polygon coordinate outside map's boundaries!\ngeometry: #{geometry.inspect}\nproperties: #{properties.inspect}"
|
126
|
-
end
|
127
|
-
"#{x},#{y}"
|
128
|
-
end
|
111
|
+
points = generate_drawable_points(geometry, properties)
|
129
112
|
|
130
113
|
@image.combine_options do |c|
|
131
114
|
c.density 300
|
@@ -133,20 +116,29 @@ module MapPrint
|
|
133
116
|
end
|
134
117
|
end
|
135
118
|
|
136
|
-
def
|
119
|
+
def stroke_options(properties)
|
137
120
|
options = ''
|
138
121
|
if properties['stroke'] || properties['stroke'].nil?
|
139
122
|
options += "stroke #{properties['color'] || '#0033ff'} "
|
140
123
|
options += "stroke-width #{properties['weight'] || 5} "
|
141
124
|
options += "stroke-opacity #{properties['opacity'] || 0.5} "
|
142
125
|
end
|
126
|
+
options
|
127
|
+
end
|
143
128
|
|
144
|
-
|
129
|
+
def fill_options(properties, line)
|
130
|
+
options = ''
|
131
|
+
if properties['fill'] != false || !line
|
145
132
|
options += "fill #{properties['fillColor'] || '#0033ff'} "
|
146
133
|
options += "fill-opacity #{properties['fillOpacity'] || 0.2} "
|
147
134
|
options += "fill-rule #{properties['fillRule'] || 'evenodd'} "
|
148
135
|
end
|
136
|
+
options
|
137
|
+
end
|
149
138
|
|
139
|
+
def draw_options(properties, line=true)
|
140
|
+
options = stroke_options(properties)
|
141
|
+
options += fill_options(properties, line)
|
150
142
|
options += "stroke-dasharray #{properties['dashArray']} " if properties['dashArray']
|
151
143
|
options += "stroke-linecap #{properties['lineCap']} " if properties['lineCap']
|
152
144
|
options += "stroke-linejoin #{properties['lineJoin']} " if properties['lineJoin']
|
@@ -160,5 +152,27 @@ module MapPrint
|
|
160
152
|
def get_y(lat)
|
161
153
|
@height * (@top_lat - lat) / @total_lat;
|
162
154
|
end
|
155
|
+
|
156
|
+
def point_inside_map?(x, y)
|
157
|
+
0 <= x && x <= @width && 0 <= y && y <= @height
|
158
|
+
end
|
159
|
+
|
160
|
+
def consider_outside_boundaries(x, y, geometry, properties)
|
161
|
+
if !point_inside_map?(x, y)
|
162
|
+
Logger.warn "Coordinate outside map's boundaries!\ngeometry: #{geometry.inspect}\nproperties: #{properties.inspect}"
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def generate_drawable_points(geometry, properties)
|
167
|
+
properties ||= {}
|
168
|
+
coords = geometry['coordinates']
|
169
|
+
coords = coords.first if coords.first.first.is_a?(Array)
|
170
|
+
coords.map do |coord|
|
171
|
+
x = get_x(coord[0])
|
172
|
+
y = get_y(coord[1])
|
173
|
+
consider_outside_boundaries(x, y, geometry, properties)
|
174
|
+
"#{x},#{y}"
|
175
|
+
end
|
176
|
+
end
|
163
177
|
end
|
164
178
|
end
|
@@ -6,12 +6,21 @@ module MapPrint
|
|
6
6
|
include PngHandlers::Texts
|
7
7
|
include Validations::Size
|
8
8
|
|
9
|
+
OVERFLOW = {
|
10
|
+
expand: 'expand',
|
11
|
+
compact: 'compact',
|
12
|
+
hidden: 'hidden'
|
13
|
+
}
|
14
|
+
VERTICAL = 'vertical'
|
15
|
+
HORIZONTAL = 'horizontal'
|
16
|
+
|
9
17
|
def initialize(legend)
|
10
18
|
@legend = legend
|
11
19
|
validate_data!
|
20
|
+
overflow_option_adjustments
|
12
21
|
@x_step = @legend[:size][:width] / @legend[:columns]
|
13
22
|
@y_step = @legend[:size][:height] / @legend[:rows]
|
14
|
-
@elements_in_block = @legend[:orientation] ==
|
23
|
+
@elements_in_block = @legend[:orientation] == VERTICAL ? @legend[:rows] : @legend[:columns]
|
15
24
|
@legend[:textbox_style] ||= {}
|
16
25
|
|
17
26
|
if @legend[:textbox_size]
|
@@ -73,7 +82,7 @@ module MapPrint
|
|
73
82
|
end
|
74
83
|
|
75
84
|
def get_next_x_y(x, y, z)
|
76
|
-
if @legend[:orientation] ==
|
85
|
+
if @legend[:orientation] == VERTICAL
|
77
86
|
y, x = next_step(y, x, @y_step, @x_step, z)
|
78
87
|
else
|
79
88
|
x, y = next_step(x, y, @x_step, @y_step, z)
|
@@ -92,5 +101,61 @@ module MapPrint
|
|
92
101
|
|
93
102
|
return small_step_value, big_step_value
|
94
103
|
end
|
104
|
+
|
105
|
+
def overflow_hidden?
|
106
|
+
@legend[:overflow].nil? || @legend[:overflow].downcase == OVERFLOW[:hidden]
|
107
|
+
end
|
108
|
+
|
109
|
+
def overflow_expand?
|
110
|
+
@legend[:overflow].downcase == OVERFLOW[:expand]
|
111
|
+
end
|
112
|
+
|
113
|
+
def overflow_compact?
|
114
|
+
@legend[:overflow].downcase == OVERFLOW[:compact]
|
115
|
+
end
|
116
|
+
|
117
|
+
def vertical_orientation?
|
118
|
+
@legend[:orientation] == VERTICAL
|
119
|
+
end
|
120
|
+
|
121
|
+
def horizontal_orientation?
|
122
|
+
@legend[:orientation] == HORIZONTAL
|
123
|
+
end
|
124
|
+
|
125
|
+
def available_legend_spots
|
126
|
+
@legend[:columns] * @legend[:rows]
|
127
|
+
end
|
128
|
+
|
129
|
+
def overflow_option_adjustments
|
130
|
+
return unless @legend[:elements].size > available_legend_spots
|
131
|
+
case
|
132
|
+
when overflow_hidden?
|
133
|
+
@legend[:elements] = @legend[:elements][0..(available_legend_spots-1)]
|
134
|
+
when overflow_expand?
|
135
|
+
expand_adjustments
|
136
|
+
when overflow_compact?
|
137
|
+
compact_adjustments
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def expand_adjustments
|
142
|
+
if vertical_orientation?
|
143
|
+
column_width = @legend[:size][:width] / @legend[:columns]
|
144
|
+
compact_adjustments
|
145
|
+
@legend[:size][:width] = @legend[:columns] * column_width
|
146
|
+
elsif horizontal_orientation?
|
147
|
+
row_height = @legend[:size][:height] / @legend[:rows]
|
148
|
+
compact_adjustments
|
149
|
+
@legend[:size][:height] = @legend[:rows] * row_height
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def compact_adjustments
|
154
|
+
if vertical_orientation?
|
155
|
+
@legend[:columns] = (@legend[:elements].size / @legend[:rows].to_f).ceil
|
156
|
+
elsif horizontal_orientation?
|
157
|
+
@legend[:rows] = (@legend[:elements].size / @legend[:columns].to_f).ceil
|
158
|
+
end
|
159
|
+
end
|
95
160
|
end
|
96
161
|
end
|
@@ -19,12 +19,12 @@ module MapPrint
|
|
19
19
|
|
20
20
|
scalebar_image = @context.print_scalebar
|
21
21
|
if scalebar_image
|
22
|
-
|
22
|
+
print_image(scalebar_image.path, @context.scalebar[:position])
|
23
23
|
end
|
24
24
|
|
25
25
|
legend_image = @context.print_legend
|
26
26
|
if legend_image
|
27
|
-
|
27
|
+
print_image(legend_image.path, @context.legend[:position])
|
28
28
|
end
|
29
29
|
|
30
30
|
@pdf.render_file(@context.output_path)
|
@@ -42,5 +42,9 @@ module MapPrint
|
|
42
42
|
position = @context.map[:position] || {}
|
43
43
|
@pdf.image map_image.path, at: [position[:x] || 0, @pdf.bounds.top - (position[:y] || 0)], fit: size.values
|
44
44
|
end
|
45
|
+
|
46
|
+
def print_image(image_path, position)
|
47
|
+
@pdf.image image_path, at: [position[:x], @pdf.bounds.top - position[:y]]
|
48
|
+
end
|
45
49
|
end
|
46
50
|
end
|
@@ -54,20 +54,17 @@ module MapPrint
|
|
54
54
|
quarter = (size[:width] - @padding_left - @padding_right) / 4
|
55
55
|
|
56
56
|
y_position = size[:height] - (@scalebar[:bar_height] || 10) - @padding_bottom
|
57
|
+
orig_y = size[:height] - @padding_bottom
|
57
58
|
image.combine_options do |c|
|
58
59
|
c.density 300
|
59
60
|
c.stroke 'black'
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
c.fill 'white'
|
65
|
-
c.draw "rectangle #{@padding_left + 2*quarter},#{size[:height] - @padding_bottom} #{@padding_left + 3*quarter},#{y_position}"
|
66
|
-
c.fill 'black'
|
67
|
-
c.draw "rectangle #{@padding_left + 3*quarter},#{size[:height] - @padding_bottom} #{@padding_left + 4*quarter},#{y_position}"
|
61
|
+
(0..3).each do |i|
|
62
|
+
c.fill (i % 2 == 0 ? 'white' : 'black')
|
63
|
+
c.draw "rectangle #{@padding_left + i*quarter},#{orig_y} #{@padding_left + (i+1)*quarter},#{y_position}"
|
64
|
+
end
|
68
65
|
end
|
69
66
|
|
70
|
-
text_options = { pointsize: 4, gravity: 'NorthWest' }
|
67
|
+
text_options = { pointsize: 4, gravity: 'NorthWest' }.merge(@scalebar[:text_style] || {})
|
71
68
|
draw_text(image, "0", "#{@padding_left},#{@padding_top}", text_options)
|
72
69
|
draw_text(image, (pixels_for_distance/4).round(-2).to_s, "#{-quarter + @padding_left - @padding_right},#{@padding_top}", text_options.merge(gravity: 'North'))
|
73
70
|
draw_text(image, (pixels_for_distance/2).round(-2).to_s, "#{@padding_left - @padding_right},#{@padding_top}", text_options.merge(gravity: 'North'))
|
data/lib/map_print/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: map_print
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andreas Fast
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-04-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|