]> git.openstreetmap.org Git - rails.git/blob - test/lib/bounding_box_test.rb
eff48655cc495c992639a6d69670d67dd0e2246e
[rails.git] / test / lib / bounding_box_test.rb
1 require 'test_helper'
2
3 class BoundingBoxTest < ActiveSupport::TestCase
4   def setup
5     @size_error_message = "The maximum bbox size is 0.25, and your request was too large. Either request a smaller area, or use planet.osm"
6     @malformed_error_message = "The parameter bbox is required, and must be of the form min_lon,min_lat,max_lon,max_lat"
7     @lon_order_error_message = "The minimum longitude must be less than the maximum longitude, but it wasn't"
8     @lat_order_error_message = "The minimum latitude must be less than the maximum latitude, but it wasn't"
9     @bbox_out_of_limits_error_message = "The latitudes must be between -90.0 and 90.0, and longitudes between -180.0 and 180.0"
10     @nil_error_message = "Should not contain nil"
11
12     @bbox_from_nils = BoundingBox.new(nil, nil, nil, nil)
13     @bbox_expand = BoundingBox.new(0, 0, 0, 0)
14     @bbox_expand_ten = BoundingBox.new(10, 10, 10, 10)
15     @bbox_expand_minus_two = BoundingBox.new(-2, -2, -2, -2)
16     @bbox_from_string = BoundingBox.from_s("1,2,3,4")
17     @min_lon = 1.0
18     @min_lat = 2.0
19     @max_lon = 3.0
20     @max_lat = 4.0
21
22     @bad_positive_boundary_bbox  = %w(181,91,0,0 0,0,181,91)
23     @bad_negative_boundary_bbox  = %w(-181,-91,0,0 0,0,-181,-91)
24     @bad_big_bbox       = %w(-0.1,-0.1,1.1,1.1  10,10,11,11)
25     @bad_malformed_bbox = %w(-0.1  hello 10N2W10.1N2.1W)
26     @bad_lat_mixed_bbox  = %w(0,0.1,0.1,0  -0.1,80,0.1,70  0.24,54.34,0.25,54.33)
27     @bad_lon_mixed_bbox  = %w(80,-0.1,70,0.1  54.34,0.24,54.33,0.25)
28     @bad_limit_bbox = %w(-180.1,-90,180,90 -180,-90.1,180,90 -180,-90,180.1,90 -180,-90,180,90.1)
29     @good_bbox         = %w(-0.1,-0.1,0.1,0.1  51.1,-0.1,51.2,0 -0.1,%20-0.1,%200.1,%200.1
30                             -0.1edcd,-0.1d,0.1,0.1  -0.1E,-0.1E,0.1S,0.1N S0.1,W0.1,N0.1,E0.1)
31
32     @expand_min_lon_array = %w(2,10,10,10 1,10,10,10 0,10,10,10 -1,10,10,10 -2,10,10,10 -8,10,10,10)
33     @expand_min_lat_array = %w(10,2,10,10 10,1,10,10 10,0,10,10 10,-1,10,10 10,-2,10,10 10,-8,10,10)
34     @expand_max_lon_array = %w(-2,-2,-1,-2 -2,-2,0,-2 -2,-2,1,-2 -2,-2,2,-2)
35     @expand_max_lat_array = %w(-2,-2,-2,-1 -2,-2,-2,0 -2,-2,-2,1 -2,-2,-2,2)
36     @expand_min_lon_margin_response = [[2, 10, 10, 10], [-7, 10, 10, 10], [-7, 10, 10, 10], [-7, 10, 10, 10], [-7, 10, 10, 10], [-25, 10, 10, 10]]
37     @expand_min_lat_margin_response = [[10, 2, 10, 10], [10, -7, 10, 10], [10, -7, 10, 10], [10, -7, 10, 10], [10, -7, 10, 10], [10, -25, 10, 10]]
38     @expand_max_lon_margin_response = [[-2, -2, -1, -2], [-2, -2, 1, -2], [-2, -2, 1, -2], [-2, -2, 5, -2]]
39     @expand_max_lat_margin_response = [[-2, -2, -2, -1], [-2, -2, -2, 1], [-2, -2, -2, 1], [-2, -2, -2, 5]]
40   end
41
42   def test_good_bbox_from_string
43     @good_bbox.each do |string|
44       bbox = BoundingBox.from_s(string)
45       array = string.split(',').collect(&:to_f)
46       check_bbox(bbox, array)
47     end
48   end
49
50   def test_bbox_from_s_malformed
51     @bad_malformed_bbox.each do |bbox_string|
52       bbox = BoundingBox.from_s(bbox_string)
53       assert_nil bbox
54     end
55   end
56
57   def test_good_bbox_from_params
58     @good_bbox.each do |string|
59       bbox = BoundingBox.from_bbox_params(:bbox => string)
60       array = string.split(',').collect(&:to_f)
61       check_bbox(bbox, array)
62     end
63   end
64
65   def test_good_bbox_from_lon_lat_params
66     @good_bbox.each do |string|
67       array = string.split(',')
68       bbox = BoundingBox.from_lon_lat_params(:minlon => array[0], :minlat => array[1], :maxlon => array[2], :maxlat => array[3])
69       check_bbox(bbox, array.collect(&:to_f))
70     end
71   end
72
73   def test_bbox_from_params_malformed
74     @bad_malformed_bbox.each do |bbox_string|
75       exception = assert_raise(OSM::APIBadUserInput) { BoundingBox.from_bbox_params(:bbox => bbox_string) }
76       assert_equal(@malformed_error_message, exception.message)
77     end
78   end
79
80   def test_good_bbox_from_new
81     @good_bbox.each do |string|
82       array = string.split(',')
83       bbox = BoundingBox.new(array[0], array[1], array[2], array[3])
84       check_bbox(bbox, array.collect(&:to_f))
85     end
86   end
87
88   def test_creation_from_new_with_nils
89     check_bbox(@bbox_from_nils, [nil, nil, nil, nil])
90   end
91
92   def test_expand_min_lon_boundary
93     @bbox_expand.expand!(BoundingBox.new(-1810000000, 0, 0, 0))
94     check_expand(@bbox_expand, "-1800000000,0,0,0")
95   end
96
97   def test_expand_min_lat_boundary
98     @bbox_expand.expand!(BoundingBox.new(0, -910000000, 0, 0))
99     check_expand(@bbox_expand, "0,-900000000,0,0")
100   end
101
102   def test_expand_max_lon_boundary
103     @bbox_expand.expand!(BoundingBox.new(0, 0, 1810000000, 0))
104     check_expand(@bbox_expand, "0,0,1800000000,0")
105   end
106
107   def test_expand_max_lat_boundary
108     @bbox_expand.expand!(BoundingBox.new(0, 0, 0, 910000000))
109     check_expand(@bbox_expand, "0,0,0,900000000")
110   end
111
112   def test_expand_min_lon_without_margin
113     @expand_min_lon_array.each { |array_string| check_expand(@bbox_expand_ten, array_string) }
114   end
115
116   def test_expand_min_lon_with_margin
117     @expand_min_lon_array.each_with_index do |array_string, index|
118       check_expand(@bbox_expand_ten, array_string, 1, @expand_min_lon_margin_response[index])
119     end
120   end
121
122   def test_expand_min_lat_without_margin
123     @expand_min_lat_array.each { |array_string| check_expand(@bbox_expand_ten, array_string) }
124   end
125
126   def test_expand_min_lat_with_margin
127     @expand_min_lat_array.each_with_index do |array_string, index|
128       check_expand(@bbox_expand_ten, array_string, 1, @expand_min_lat_margin_response[index])
129     end
130   end
131
132   def test_expand_max_lon_without_margin
133     @expand_max_lon_array.each { |array_string| check_expand(@bbox_expand_minus_two, array_string) }
134   end
135
136   def test_expand_max_lon_with_margin
137     @expand_max_lon_array.each_with_index do |array_string, index|
138       check_expand(@bbox_expand_minus_two, array_string, 1, @expand_max_lon_margin_response[index])
139     end
140   end
141
142   def test_expand_max_lat_without_margin
143     @expand_max_lat_array.each { |array_string| check_expand(@bbox_expand_minus_two, array_string) }
144   end
145
146   def test_expand_max_lat_with_margin
147     bbox = @bbox_expand
148     @expand_max_lat_array.each_with_index do |array_string, index|
149       check_expand(@bbox_expand_minus_two, array_string, 1, @expand_max_lat_margin_response[index])
150     end
151   end
152
153   def test_good_bbox_boundaries
154     @good_bbox.each do |bbox_string|
155       assert_nothing_raised(OSM::APIBadBoundingBox) { BoundingBox.from_s(bbox_string).check_boundaries }
156     end
157   end
158
159   def test_from_params_with_positive_out_of_boundary
160     @bad_positive_boundary_bbox.each do |bbox_string|
161       bbox = BoundingBox.from_bbox_params(:bbox => bbox_string)
162       array = bbox.to_a
163       assert_equal 180, [array[0], array[2]].max
164       assert_equal 90, [array[1], array[3]].max
165     end
166   end
167
168   def test_from_params_with_negative_out_of_boundary
169     @bad_negative_boundary_bbox.each do |bbox_string|
170       bbox = BoundingBox.from_bbox_params(:bbox => bbox_string)
171       array = bbox.to_a
172       assert_equal -180, [array[0], array[2]].min
173       assert_equal -90, [array[1], array[3]].min
174     end
175   end
176
177   def test_boundaries_mixed_lon
178     @bad_lon_mixed_bbox.each do |bbox_string|
179       exception = assert_raise(OSM::APIBadBoundingBox) { BoundingBox.from_s(bbox_string).check_boundaries }
180       assert_equal(@lon_order_error_message, exception.message)
181     end
182   end
183
184   def test_boundaries_mixed_lat
185     @bad_lat_mixed_bbox.each do |bbox_string|
186       exception = assert_raise(OSM::APIBadBoundingBox) { BoundingBox.from_s(bbox_string).check_boundaries }
187       assert_equal(@lat_order_error_message, exception.message)
188     end
189   end
190
191   def test_boundaries_out_of_limits
192     @bad_limit_bbox.each do |bbox_string|
193       exception = assert_raise(OSM::APIBadBoundingBox) { BoundingBox.from_s(bbox_string).check_boundaries }
194       assert_equal(@bbox_out_of_limits_error_message, exception.message)
195     end
196   end
197
198   def test_good_bbox_size
199     @good_bbox.each do |bbox_string|
200       assert_nothing_raised(OSM::APIBadBoundingBox) { BoundingBox.from_s(bbox_string).check_size }
201     end
202   end
203
204   def test_size_to_big
205     @bad_big_bbox.each do |bbox_string|
206       bbox = nil
207       assert_nothing_raised(OSM::APIBadBoundingBox) { bbox = BoundingBox.from_bbox_params(:bbox => bbox_string).check_boundaries }
208       exception = assert_raise(OSM::APIBadBoundingBox) { bbox.check_size }
209       assert_equal(@size_error_message, exception.message)
210     end
211   end
212
213   def test_bbox_area
214     @good_bbox.each do |string|
215       bbox = BoundingBox.from_s(string)
216       array = string.split(',')
217       assert_equal ((array[2].to_f - array[0].to_f) * (array[3].to_f - array[1].to_f)), bbox.area
218     end
219   end
220
221   def test_complete
222     assert !@bbox_from_nils.complete?, "should contain a nil"
223     assert @bbox_from_string.complete?, "should not contain a nil"
224   end
225
226   def test_centre_lon
227     @good_bbox.each do |bbox_string|
228       array = bbox_string.split(',')
229       assert_equal ((array[0].to_f + array[2].to_f) / 2.0), BoundingBox.from_s(bbox_string).centre_lon
230     end
231   end
232
233   def test_centre_lat
234     @good_bbox.each do |bbox_string|
235       array = bbox_string.split(',')
236       assert_equal ((array[1].to_f + array[3].to_f) / 2.0), BoundingBox.from_s(bbox_string).centre_lat
237     end
238   end
239
240   def test_width
241     @good_bbox.each do |bbox_string|
242       array = bbox_string.split(',')
243       assert_equal (array[2].to_f - array[0].to_f), BoundingBox.from_s(bbox_string).width
244     end
245   end
246
247   def test_height
248     @good_bbox.each do |bbox_string|
249       array = bbox_string.split(',')
250       assert_equal (array[3].to_f - array[1].to_f), BoundingBox.from_s(bbox_string).height
251     end
252   end
253
254   def test_slippy_width
255     assert_in_delta 5.68888888888889, @bbox_from_string.slippy_width(2), 0.000000000000001
256   end
257
258   def test_slippy_height
259     assert_in_delta 5.69698684268433, @bbox_from_string.slippy_height(2), 0.000000000000001
260   end
261
262   def test_add_bounds_to_no_underscore
263     bounds = @bbox_from_string.add_bounds_to({})
264     assert_equal 4, bounds.size
265     assert_equal @min_lon.to_s, bounds['minlon']
266     assert_equal @min_lat.to_s, bounds['minlat']
267     assert_equal @max_lon.to_s, bounds['maxlon']
268     assert_equal @max_lat.to_s, bounds['maxlat']
269   end
270
271   def test_add_bounds_to_with_underscore
272     bounds = @bbox_from_string.add_bounds_to({}, '_')
273     assert_equal 4, bounds.size
274     assert_equal @min_lon.to_s, bounds['min_lon']
275     assert_equal @min_lat.to_s, bounds['min_lat']
276     assert_equal @max_lon.to_s, bounds['max_lon']
277     assert_equal @max_lat.to_s, bounds['max_lat']
278   end
279
280   def test_to_scaled
281     bbox = @bbox_from_string.to_scaled
282     assert_equal @min_lon * GeoRecord::SCALE, bbox.min_lon
283     assert_equal @min_lat * GeoRecord::SCALE, bbox.min_lat
284     assert_equal @max_lon * GeoRecord::SCALE, bbox.max_lon
285     assert_equal @max_lat * GeoRecord::SCALE, bbox.max_lat
286   end
287
288   def test_to_unscaled
289     scale = GeoRecord::SCALE
290     bbox = BoundingBox.new(1.0 * scale, 2.0 * scale, 3.0 * scale, 4.0 * scale).to_unscaled
291     check_bbox(bbox, [@min_lon, @min_lat, @max_lon, @max_lat])
292   end
293
294   def test_to_a
295     assert_equal [1.0, 2.0, 3.0, 4.0], @bbox_from_string.to_a
296   end
297
298   def test_to_string
299     assert_equal "#{@min_lon},#{@min_lat},#{@max_lon},#{@max_lat}", @bbox_from_string.to_s
300   end
301
302   private
303
304   def check_expand(bbox, array_string, margin = 0, result = nil)
305     array = array_string.split(',').collect(&:to_f)
306     result = array unless result
307     bbox.expand!(BoundingBox.new(array[0], array[1], array[2], array[3]), margin)
308     check_bbox(bbox, result)
309   end
310
311   def check_bbox(bbox, result)
312     assert_equal result[0], bbox.min_lon, 'min_lon'
313     assert_equal result[1], bbox.min_lat, 'min_lat'
314     assert_equal result[2], bbox.max_lon, 'max_lon'
315     assert_equal result[3], bbox.max_lat, 'max_lat'
316   end
317 end