ffi-geos 1.2.1 → 1.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +5 -5
  2. data/.rubocop.yml +20 -0
  3. data/.travis.yml +7 -3
  4. data/Gemfile +1 -1
  5. data/Guardfile +4 -5
  6. data/ffi-geos.gemspec +1 -1
  7. data/lib/ffi-geos.rb +212 -196
  8. data/lib/ffi-geos/buffer_params.rb +9 -20
  9. data/lib/ffi-geos/coordinate_sequence.rb +342 -58
  10. data/lib/ffi-geos/geometry.rb +167 -178
  11. data/lib/ffi-geos/geometry_collection.rb +60 -12
  12. data/lib/ffi-geos/interrupt.rb +2 -4
  13. data/lib/ffi-geos/line_string.rb +146 -37
  14. data/lib/ffi-geos/linear_ring.rb +2 -3
  15. data/lib/ffi-geos/multi_line_string.rb +1 -2
  16. data/lib/ffi-geos/multi_point.rb +0 -1
  17. data/lib/ffi-geos/multi_polygon.rb +0 -1
  18. data/lib/ffi-geos/point.rb +69 -14
  19. data/lib/ffi-geos/polygon.rb +110 -21
  20. data/lib/ffi-geos/prepared_geometry.rb +11 -12
  21. data/lib/ffi-geos/strtree.rb +41 -52
  22. data/lib/ffi-geos/tools.rb +15 -18
  23. data/lib/ffi-geos/utils.rb +27 -44
  24. data/lib/ffi-geos/version.rb +1 -3
  25. data/lib/ffi-geos/wkb_reader.rb +4 -9
  26. data/lib/ffi-geos/wkb_writer.rb +14 -18
  27. data/lib/ffi-geos/wkt_reader.rb +2 -5
  28. data/lib/ffi-geos/wkt_writer.rb +17 -22
  29. data/test/.rubocop.yml +36 -0
  30. data/test/coordinate_sequence_tests.rb +263 -14
  31. data/test/geometry_collection_tests.rb +412 -1
  32. data/test/geometry_tests.rb +156 -86
  33. data/test/interrupt_tests.rb +2 -4
  34. data/test/line_string_tests.rb +212 -23
  35. data/test/linear_ring_tests.rb +1 -2
  36. data/test/misc_tests.rb +28 -29
  37. data/test/multi_line_string_tests.rb +0 -1
  38. data/test/point_tests.rb +158 -1
  39. data/test/polygon_tests.rb +284 -1
  40. data/test/prepared_geometry_tests.rb +1 -3
  41. data/test/strtree_tests.rb +9 -10
  42. data/test/test_helper.rb +49 -18
  43. data/test/tools_tests.rb +1 -3
  44. data/test/utils_tests.rb +22 -22
  45. data/test/wkb_reader_tests.rb +10 -9
  46. data/test/wkb_writer_tests.rb +5 -13
  47. data/test/wkt_reader_tests.rb +1 -2
  48. data/test/wkt_writer_tests.rb +9 -14
  49. metadata +6 -3
@@ -1,4 +1,3 @@
1
- # encoding: UTF-8
2
1
  # frozen_string_literal: true
3
2
 
4
3
  require 'test_helper'
@@ -131,8 +130,8 @@ class CoordinateSequenceTests < Minitest::Test
131
130
  end
132
131
 
133
132
  def test_to_point
134
- cs = Geos::CoordinateSequence.new([5,7])
135
- assert_equal('POINT (5 7)', write(cs.to_point, :trim => true))
133
+ cs = Geos::CoordinateSequence.new([ 5, 7 ])
134
+ assert_equal('POINT (5 7)', write(cs.to_point, trim: true))
136
135
  end
137
136
 
138
137
  def test_to_to_linear_ring
@@ -144,21 +143,21 @@ class CoordinateSequenceTests < Minitest::Test
144
143
  [ 0, 0 ]
145
144
  ])
146
145
 
147
- assert_equal('LINEARRING (0 0, 0 5, 5 5, 5 0, 0 0)', write(cs.to_linear_ring, :trim => true))
146
+ assert_equal('LINEARRING (0 0, 0 5, 5 5, 5 0, 0 0)', write(cs.to_linear_ring, trim: true))
148
147
  end
149
148
 
150
149
  def test_empty
151
150
  cs = Geos::CoordinateSequence.new
152
151
  assert_geom_empty(cs)
153
152
 
154
- cs = Geos::CoordinateSequence.new([4,1])
153
+ cs = Geos::CoordinateSequence.new([ 4, 1 ])
155
154
  refute_geom_empty(cs)
156
155
  end
157
156
 
158
157
  def test_to_empty_linear_ring
159
158
  cs = Geos::CoordinateSequence.new
160
159
 
161
- assert_equal('LINEARRING EMPTY', write(cs.to_linear_ring, :trim => true))
160
+ assert_equal('LINEARRING EMPTY', write(cs.to_linear_ring, trim: true))
162
161
  end
163
162
 
164
163
  def test_to_line_string
@@ -169,13 +168,13 @@ class CoordinateSequenceTests < Minitest::Test
169
168
  [ 5, 0 ]
170
169
  ])
171
170
 
172
- assert_equal('LINESTRING (0 0, 0 5, 5 5, 5 0)', write(cs.to_line_string, :trim => true))
171
+ assert_equal('LINESTRING (0 0, 0 5, 5 5, 5 0)', write(cs.to_line_string, trim: true))
173
172
  end
174
173
 
175
174
  def test_to_empty_line_string
176
175
  cs = Geos::CoordinateSequence.new
177
176
 
178
- assert_equal('LINESTRING EMPTY', write(cs.to_line_string, :trim => true))
177
+ assert_equal('LINESTRING EMPTY', write(cs.to_line_string, trim: true))
179
178
  end
180
179
 
181
180
  def test_to_polygon
@@ -187,21 +186,23 @@ class CoordinateSequenceTests < Minitest::Test
187
186
  [ 0, 0 ]
188
187
  ])
189
188
 
190
- assert_equal('POLYGON ((0 0, 0 5, 5 5, 5 0, 0 0))', write(cs.to_polygon, :trim => true))
189
+ assert_equal('POLYGON ((0 0, 0 5, 5 5, 5 0, 0 0))', write(cs.to_polygon, trim: true))
191
190
  end
192
191
 
193
192
  def test_to_empty_polygon
194
193
  cs = Geos::CoordinateSequence.new
195
194
 
196
- assert_equal('POLYGON EMPTY', write(cs.to_polygon, :trim => true))
195
+ assert_equal('POLYGON EMPTY', write(cs.to_polygon, trim: true))
197
196
  end
198
197
 
199
- def test_to_s
198
+ def test_to_s_2d
200
199
  cs = Geos::CoordinateSequence.new([[1, 2], [10, 11]])
201
- assert_equal("1.0 2.0, 10.0 11.0", cs.to_s)
200
+ assert_equal('1.0 2.0, 10.0 11.0', cs.to_s)
201
+ end
202
202
 
203
+ def test_to_s_3d
203
204
  cs = Geos::CoordinateSequence.new([[1, 2, 3], [10, 11, 12]])
204
- assert_equal("1.0 2.0 3.0, 10.0 11.0 12.0", cs.to_s)
205
+ assert_equal('1.0 2.0 3.0, 10.0 11.0 12.0', cs.to_s)
205
206
  end
206
207
 
207
208
  def test_get_by_proxy
@@ -265,7 +266,7 @@ class CoordinateSequenceTests < Minitest::Test
265
266
  end
266
267
 
267
268
  def test_options_hash
268
- cs = Geos::CoordinateSequence.new(:size => 10, :dimensions => 2)
269
+ cs = Geos::CoordinateSequence.new(size: 10, dimensions: 2)
269
270
 
270
271
  assert_equal(10, cs.size)
271
272
  assert_equal(2, cs.dimensions)
@@ -332,4 +333,252 @@ class CoordinateSequenceTests < Minitest::Test
332
333
  assert_geom_has_z(read('POINT (0 0 0)').coord_seq)
333
334
  refute_geom_has_z(read('POINT (0 0)').coord_seq)
334
335
  end
336
+
337
+ def test_x_max
338
+ cs = Geos::CoordinateSequence.new([ -10, -15 ], [ 0, 5 ], [ 10, 20 ])
339
+ assert_equal(10, cs.x_max)
340
+ end
341
+
342
+ def test_x_min
343
+ cs = Geos::CoordinateSequence.new([ -10, -15 ], [ 0, 5 ], [ 10, 20 ])
344
+ assert_equal(-10, cs.x_min)
345
+ end
346
+
347
+ def test_y_max
348
+ cs = Geos::CoordinateSequence.new([ -10, -15 ], [ 0, 5 ], [ 10, 20 ])
349
+ assert_equal(20, cs.y_max)
350
+ end
351
+
352
+ def test_y_min
353
+ cs = Geos::CoordinateSequence.new([ -10, -15 ], [ 0, 5 ], [ 10, 20 ])
354
+ assert_equal(-15, cs.y_min)
355
+ end
356
+
357
+ def test_z_max
358
+ cs = Geos::CoordinateSequence.new([ -10, -15 ], [ 0, 5 ], [ 10, 20 ])
359
+ assert(cs.z_max.nan?, " Expected NaN")
360
+
361
+ cs = Geos::CoordinateSequence.new([ -10, -15, -20 ], [ 0, 5, 10 ], [ 10, 20, 30 ])
362
+ assert_equal(30, cs.z_max)
363
+ end
364
+
365
+ def test_z_min
366
+ cs = Geos::CoordinateSequence.new([ -10, -15 ], [ 0, 5 ], [ 10, 20 ])
367
+ assert(cs.z_min.nan?, " Expected NaN")
368
+
369
+ cs = Geos::CoordinateSequence.new([ -10, -15, -20 ], [ 0, 5, 10 ], [ 10, 20, 30 ])
370
+ assert_equal(-20, cs.z_min)
371
+ end
372
+
373
+ def test_snap_to_grid_with_size
374
+ expected = [
375
+ [[-10.0, -15.0], [0.0, 5.0], [10.0, 20.0]],
376
+ [[-10.1, -15.1], [0.1, 5.1], [10.1, 20.1]],
377
+ [[-10.12, -15.12], [0.12, 5.12], [10.12, 20.12]],
378
+ [[-10.123, -15.123], [0.123, 5.123], [10.123, 20.123]],
379
+ [[-10.1235, -15.1235], [0.1235, 5.1235], [10.1235, 20.1235]],
380
+ [[-10.12346, -15.12346], [0.12346, 5.12346], [10.12346, 20.12346]],
381
+ [[-10.123457, -15.123457], [0.123457, 5.123457], [10.123457, 20.123457]],
382
+ [[-10.1234568, -15.1234568], [0.1234568, 5.1234568], [10.1234568, 20.1234568]],
383
+ [[-10.12345679, -15.12345679], [0.12345679, 5.12345679], [10.12345679, 20.12345679]]
384
+ ]
385
+
386
+ coordinates = [
387
+ [ -10.123456789, -15.123456789 ],
388
+ [ 0.123456789, 5.123456789 ],
389
+ [ 10.123456789, 20.123456789 ]
390
+ ]
391
+
392
+ 9.times do |i|
393
+ cs = Geos::CoordinateSequence.new(*coordinates)
394
+ cs.snap_to_grid!(10 ** -i)
395
+
396
+ # XXX - Ruby 1.8.7 sometimes sees the the float values as differing
397
+ # slightly, but not enough that it would matter for these tests.
398
+ # Test equality on the inspect Strings instead of the float values.
399
+ assert_equal(expected[i].inspect, cs.to_a.inspect)
400
+
401
+ cs = Geos::CoordinateSequence.new(*coordinates)
402
+ snapped = cs.snap_to_grid(10 ** -i)
403
+ assert_equal(coordinates, cs.to_a)
404
+ assert_equal(expected[i].inspect, snapped.to_a.inspect)
405
+ end
406
+ end
407
+
408
+ def test_snap_to_grid_with_hash
409
+ cs = Geos::CoordinateSequence.new(
410
+ [ 10, 10 ],
411
+ [ 20, 20 ],
412
+ [ 30, 30 ]
413
+ )
414
+ cs.snap_to_grid!(:size_x => 1, :size_y => 1, :offset_x => 12.5, :offset_y => 12.5)
415
+
416
+ assert_equal([
417
+ [ 9.5, 9.5 ],
418
+ [ 20.5, 20.5 ],
419
+ [ 30.5, 30.5 ]
420
+ ], cs.to_a)
421
+ end
422
+
423
+ def test_snap_to_grid_with_geometry_origin
424
+ cs = Geos::CoordinateSequence.new(
425
+ [ 10, 10 ],
426
+ [ 20, 20 ],
427
+ [ 30, 30 ]
428
+ )
429
+ cs.snap_to_grid!(:size => 1, :offset => read('LINESTRING (0 0, 25 25)'))
430
+
431
+ assert_equal([
432
+ [ 9.5, 9.5 ],
433
+ [ 20.5, 20.5 ],
434
+ [ 30.5, 30.5 ]
435
+ ], cs.to_a)
436
+ end
437
+
438
+ def test_snap_to_grid_with_z
439
+ cs = Geos::CoordinateSequence.new(
440
+ [ 10, 10, 10 ],
441
+ [ 20, 20, 20 ],
442
+ [ 30, 30, 30 ]
443
+ )
444
+ cs.snap_to_grid!(
445
+ :size_x => 1,
446
+ :size_y => 1,
447
+ :size_z => 1,
448
+
449
+ :offset_x => 12.5,
450
+ :offset_y => 12.5,
451
+ :offset_z => 12.5
452
+ )
453
+
454
+ assert_equal([
455
+ [ 9.5, 9.5, 9.5 ],
456
+ [ 20.5, 20.5, 20.5 ],
457
+ [ 30.5, 30.5, 30.5 ]
458
+ ], cs.to_a)
459
+ end
460
+
461
+ def test_snap_to_grid_remove_duplicate_points
462
+ coords = [
463
+ [-10.0, 0.0],
464
+ [-10.0, 5.0], [-10.0, 5.0],
465
+ [-10.0, 6.0], [-10.0, 6.0], [-10.0, 6.0],
466
+ [-10.0, 7.0], [-10.0, 7.0], [-10.0, 7.0],
467
+ [-10.0, 8.0], [-10.0, 8.0],
468
+ [-9.0, 8.0], [-9.0, 9.0],
469
+ [-10.0, 0.0]
470
+ ]
471
+
472
+ expected = [
473
+ [-10.0, 0.0],
474
+ [-10.0, 5.0],
475
+ [-10.0, 6.0],
476
+ [-10.0, 7.0],
477
+ [-10.0, 8.0],
478
+ [-9.0, 8.0],
479
+ [-9.0, 9.0],
480
+ [-10.0, 0.0]
481
+ ]
482
+
483
+ cs = Geos::CoordinateSequence.new(coords)
484
+ cs.snap_to_grid!
485
+
486
+ assert_equal(expected, cs.to_a)
487
+
488
+ cs = Geos::CoordinateSequence.new(coords)
489
+ cs2 = cs.snap_to_grid
490
+
491
+ assert_equal(coords, cs.to_a)
492
+ assert_equal(expected, cs2.to_a)
493
+ end
494
+
495
+ undef :affine_tester
496
+ def affine_tester(method, expected, coords, *args)
497
+ cs = Geos::CoordinateSequence.new(coords)
498
+ cs.send("#{method}!", *args)
499
+
500
+ expected.length.times do |i|
501
+ assert_in_delta(expected[i], cs.get_ordinate(0, i), TOLERANCE)
502
+ end
503
+
504
+ cs = Geos::CoordinateSequence.new(coords)
505
+ cs2 = cs.send(method, *args)
506
+
507
+ expected.length.times do |i|
508
+ assert_in_delta(coords[i], cs.get_ordinate(0, i), TOLERANCE)
509
+ assert_in_delta(expected[i], cs2.get_ordinate(0, i), TOLERANCE)
510
+ end
511
+ end
512
+
513
+ def test_rotate
514
+ affine_tester(:rotate, [ 29.0, 11.0 ], [ 1, 1 ], Math::PI / 2, [ 10.0, 20.0 ])
515
+ affine_tester(:rotate, [ -2.0, 0.0 ], [ 1, 1 ], -Math::PI / 2, [ -1.0, 2.0 ])
516
+ affine_tester(:rotate, [ 19.0, 1.0 ], [ 1, 1 ], Math::PI / 2, read('POINT(10 10)'))
517
+ affine_tester(:rotate, [ -0.5, 0.5 ], [ 1, 1 ], Math::PI / 2, read('LINESTRING(0 0, 1 0)'))
518
+ end
519
+
520
+ def test_rotate_x
521
+ affine_tester(:rotate_x, [ 1, -1, -1 ], [ 1, 1, 1 ], Math::PI)
522
+ affine_tester(:rotate_x, [ 1, -1, 1 ], [ 1, 1, 1 ], Math::PI / 2)
523
+ affine_tester(:rotate_x, [ 1, 1, -1 ], [ 1, 1, 1 ], Math::PI + Math::PI / 2)
524
+ affine_tester(:rotate_x, [ 1, 1, 1 ], [ 1, 1, 1 ], Math::PI * 2)
525
+ end
526
+
527
+ def test_rotate_y
528
+ affine_tester(:rotate_y, [ -1, 1, -1 ], [ 1, 1, 1 ], Math::PI)
529
+ affine_tester(:rotate_y, [ 1, 1, -1 ], [ 1, 1, 1 ], Math::PI / 2)
530
+ affine_tester(:rotate_y, [ -1, 1, 1 ], [ 1, 1, 1 ], Math::PI + Math::PI / 2)
531
+ affine_tester(:rotate_y, [ 1, 1, 1 ], [ 1, 1, 1 ], Math::PI * 2)
532
+ end
533
+
534
+ def test_rotate_z
535
+ affine_tester(:rotate_z, [ -1, -1 ], [ 1, 1 ], Math::PI)
536
+ affine_tester(:rotate_z, [ -1, 1 ], [ 1, 1 ], Math::PI / 2)
537
+ affine_tester(:rotate_z, [ 1, -1 ], [ 1, 1 ], Math::PI + Math::PI / 2)
538
+ affine_tester(:rotate_z, [ 1, 1 ], [ 1, 1 ], Math::PI * 2)
539
+ end
540
+
541
+ def test_scale
542
+ affine_tester(:scale, [ 5, 5 ], [ 1, 1 ], 5, 5)
543
+ affine_tester(:scale, [ 3, 2 ], [ 1, 1 ], 3, 2)
544
+ affine_tester(:scale, [ 40, 40, 40 ], [ 10, 20, -5 ], 4, 2, -8)
545
+ end
546
+
547
+ def test_scale_hash
548
+ affine_tester(:scale, [ 5, 5 ], [ 1, 1 ], :x => 5, :y => 5)
549
+ affine_tester(:scale, [ 3, 2 ], [ 1, 1 ], :x => 3, :y => 2)
550
+ affine_tester(:scale, [ 40, 40, 40 ], [ 10, 20, -5 ], :x => 4, :y => 2, :z => -8)
551
+ end
552
+
553
+ def test_trans_scale
554
+ affine_tester(:trans_scale, [ 2, 2 ], [ 1, 1 ], 1, 1, 1, 1)
555
+ affine_tester(:trans_scale, [ 3, 3 ], [ 2, 2 ], 1, 1, 1, 1)
556
+ affine_tester(:trans_scale, [ 0, 0 ], [ 1, 1 ], -1, -1, -1, -1)
557
+ affine_tester(:trans_scale, [ 1, 2 ], [ 1, 1 ], 0, 1, 1, 1)
558
+ affine_tester(:trans_scale, [ 2, 1 ], [ 1, 1 ], 1, 0, 1, 1)
559
+ affine_tester(:trans_scale, [ 0, 2 ], [ 1, 1 ], 1, 1, 0, 1)
560
+ affine_tester(:trans_scale, [ 2, 0 ], [ 1, 1 ], 1, 1, 1, 0)
561
+ affine_tester(:trans_scale, [ 3, 2 ], [ 1, 1 ], 2, 1, 1, 1)
562
+ affine_tester(:trans_scale, [ 2, 3 ], [ 1, 1 ], 1, 2, 1, 1)
563
+ affine_tester(:trans_scale, [ 4, 2 ], [ 1, 1 ], 1, 1, 2, 1)
564
+ affine_tester(:trans_scale, [ 2, 4 ], [ 1, 1 ], 1, 1, 1, 2)
565
+ affine_tester(:trans_scale, [ 15, 28 ], [ 1, 1 ], 2, 3, 5, 7)
566
+ affine_tester(:trans_scale, [ 15, 28, 1 ], [ 1, 1, 1 ], 2, 3, 5, 7)
567
+ end
568
+
569
+ def test_trans_scale_hash
570
+ affine_tester(:trans_scale, [ 2, 2 ], [ 1, 1 ], :delta_x => 1, :delta_y => 1, :x_factor => 1, :y_factor => 1)
571
+ affine_tester(:trans_scale, [ 15, 28, 1 ], [ 1, 1, 1 ], :delta_x => 2, :delta_y => 3, :x_factor => 5, :y_factor => 7)
572
+ affine_tester(:trans_scale, [ 3, 1, 1 ], [ 1, 1, 1 ], :delta_x => 2, :z_factor => 2)
573
+ end
574
+
575
+ def test_translate
576
+ affine_tester(:translate, [ 5, 12 ], [ 0, 0 ], 5, 12)
577
+ affine_tester(:translate, [ -3, -7, 3 ], [ 0, 0, 0 ], -3, -7, 3)
578
+ end
579
+
580
+ def test_translate_hash
581
+ affine_tester(:translate, [ 5, 12 ], [ 0, 0 ], :x => 5, :y => 12)
582
+ affine_tester(:translate, [ -3, -7, 3 ], [ 0, 0, 0 ], :x => -3, :y => -7, :z => 3)
583
+ end
335
584
  end
@@ -1,4 +1,3 @@
1
- # encoding: UTF-8
2
1
  # frozen_string_literal: true
3
2
 
4
3
  require 'test_helper'
@@ -84,4 +83,416 @@ class GeometryCollectionTests < Minitest::Test
84
83
  geom = read('GEOMETRYCOLLECTION (POINT(1 2), LINESTRING(1 2, 3 4))')
85
84
  assert_equal(2, geom.num_geometries)
86
85
  end
86
+
87
+ def test_x_max
88
+ geom = read('GEOMETRYCOLLECTION (
89
+ POLYGON ((0 0, 5 0, 8 9, -10 5, 0 0)),
90
+ LINESTRING (0 0, 5 0, 8 9, -10 5, 0 0),
91
+ POINT(3 12)
92
+ )')
93
+
94
+ assert_equal(8, geom.x_max)
95
+ end
96
+
97
+ def test_x_min
98
+ geom = read('GEOMETRYCOLLECTION (
99
+ POLYGON ((0 0, 5 0, 8 9, -10 5, 0 0)),
100
+ LINESTRING (0 0, 5 0, 8 9, -10 5, 0 0),
101
+ POINT(3 12)
102
+ )')
103
+
104
+ assert_equal(-10, geom.x_min)
105
+ end
106
+
107
+ def test_y_max
108
+ geom = read('GEOMETRYCOLLECTION (
109
+ POLYGON ((0 0, 5 0, 8 9, -10 5, 0 0)),
110
+ LINESTRING (0 0, 5 0, 8 9, -10 5, 0 0),
111
+ POINT(3 12)
112
+ )')
113
+
114
+ assert_equal(12, geom.y_max)
115
+ end
116
+
117
+ def test_y_min
118
+ geom = read('GEOMETRYCOLLECTION (
119
+ POLYGON ((0 0, 5 0, 8 9, -10 5, 0 0)),
120
+ LINESTRING (0 0, 5 0, 8 9, -10 5, 0 0),
121
+ POINT(3 12)
122
+ )')
123
+
124
+ assert_equal(0, geom.y_min)
125
+ end
126
+
127
+ def test_z_max
128
+ geom = read('GEOMETRYCOLLECTION (
129
+ POLYGON ((0 0, 5 0, 8 9, -10 5, 0 0)),
130
+ LINESTRING (0 0, 5 0, 8 9, -10 5, 0 0),
131
+ POINT(3 12)
132
+ )')
133
+ assert_equal(0, geom.z_max)
134
+
135
+ geom = read('GEOMETRYCOLLECTION Z (
136
+ POLYGON Z ((0 0 0, 5 0 3, 8 9 4, -10 5 3, 0 0 0)),
137
+ LINESTRING Z (0 0 0, 5 0 3, 8 9 4, -10 5 3, 0 0 0),
138
+ POINT Z (3 12 6)
139
+ )')
140
+ assert_equal(6, geom.z_max)
141
+
142
+ # GEOS lets you mix dimensionality, while PostGIS doesn't.
143
+ geom = read('GEOMETRYCOLLECTION (
144
+ POLYGON ((0 0, 5 0, 8 9, -10 5, 0 0)),
145
+ LINESTRING (0 0, 5 0, 8 9, -10 5, 0 0),
146
+ POINT(3 12 10)
147
+ )')
148
+ assert_equal(10, geom.z_max)
149
+ end
150
+
151
+ def test_z_min
152
+ geom = read('GEOMETRYCOLLECTION (
153
+ POLYGON ((0 0, 5 0, 8 9, -10 5, 0 0)),
154
+ LINESTRING (0 0, 5 0, 8 9, -10 5, 0 0),
155
+ POINT(3 12)
156
+ )')
157
+ assert_equal(0, geom.z_min)
158
+
159
+ geom = read('GEOMETRYCOLLECTION Z (
160
+ POLYGON Z ((0 0 0, 5 0 3, 8 9 4, -10 5 3, 0 0 0)),
161
+ LINESTRING Z (0 0 0, 5 0 3, 8 9 4, -10 5 3, 0 0 0),
162
+ POINT Z (3 12 6)
163
+ )')
164
+ assert_equal(0, geom.z_min)
165
+
166
+ # GEOS lets you mix dimensionality, while PostGIS doesn't.
167
+ geom = read('GEOMETRYCOLLECTION (
168
+ POLYGON ((0 0, 5 0, 8 9, -10 5, 0 0)),
169
+ LINESTRING (0 0, 5 0, 8 9, -10 5, 0 0),
170
+ POINT(3 12 -10)
171
+ )')
172
+ assert_equal(-10, geom.z_min)
173
+ end
174
+
175
+ def test_snap_to_grid
176
+ wkt = 'GEOMETRYCOLLECTION (LINESTRING (-10.12 0, -10.12 5, -10.12 5, -10.12 6, -10.12 6, -10.12 6, -10.12 7, -10.12 7, -10.12 7, -10.12 8, -10.12 8, -9 8, -9 9, -10.12 0), POLYGON ((-10.12 0, -10.12 5, -10.12 5, -10.12 6, -10.12 6, -10.12 6, -10.12 7, -10.12 7, -10.12 7, -10.12 8, -10.12 8, -9 8, -9 9, -10.12 0)), POINT (10.12 10.12))'
177
+
178
+ expected = 'GEOMETRYCOLLECTION (LINESTRING (-10 0, -10 5, -10 5, -10 6, -10 6, -10 6, -10 7, -10 7, -10 7, -10 8, -10 8, -9 8, -9 9, -10 0), POLYGON ((-10 0, -10 5, -10 5, -10 6, -10 6, -10 6, -10 7, -10 7, -10 7, -10 8, -10 8, -9 8, -9 9, -10 0)), POINT (10 10))'
179
+
180
+ simple_bang_tester(:snap_to_grid, expected, wkt, 1)
181
+ end
182
+
183
+ def test_snap_to_grid_empty
184
+ assert(read('GEOMETRYCOLLECTION EMPTY').snap_to_grid!.empty?, 'Expected an empty GeometryCollection')
185
+ end
186
+
187
+ def test_snap_to_grid_with_srid
188
+ wkt = 'GEOMETRYCOLLECTION (
189
+ LINESTRING (-10.12 0, -10.12 5, -10.12 5, -10.12 6, -10.12 6, -10.12 6, -10.12 7, -10.12 7, -10.12 7, -10.12 8, -10.12 8, -9 8, -9 9, -10.12 0),
190
+ POLYGON ((-10.12 0, -10.12 5, -10.12 5, -10.12 6, -10.12 6, -10.12 6, -10.12 7, -10.12 7, -10.12 7, -10.12 8, -10.12 8, -9 8, -9 9, -10.12 0)),
191
+ POINT (10.12 10.12)
192
+ )'
193
+
194
+ expected = 'GEOMETRYCOLLECTION (LINESTRING (-10 0, -10 5, -10 5, -10 6, -10 6, -10 6, -10 7, -10 7, -10 7, -10 8, -10 8, -9 8, -9 9, -10 0), POLYGON ((-10 0, -10 5, -10 5, -10 6, -10 6, -10 6, -10 7, -10 7, -10 7, -10 8, -10 8, -9 8, -9 9, -10 0)), POINT (10 10))'
195
+
196
+ srid_copy_tester(:snap_to_grid, expected, 0, :zero, wkt, 1)
197
+ srid_copy_tester(:snap_to_grid, expected, 4326, :lenient, wkt, 1)
198
+ srid_copy_tester(:snap_to_grid, expected, 4326, :strict, wkt, 1)
199
+ end
200
+
201
+ def test_snap_to_grid_with_illegal_result
202
+ assert_raises(Geos::InvalidGeometryError) do
203
+ read('GEOMETRYCOLLECTION (POINT (0 2), LINESTRING (0 1, 0 11), POLYGON ((0 1, 0 1, 0 6, 0 6, 0 1)))').
204
+ snap_to_grid(1)
205
+ end
206
+ end
207
+
208
+ def test_rotate
209
+ writer.rounding_precision = 3
210
+
211
+ wkt = 'GEOMETRYCOLLECTION (POINT (1 1), LINESTRING (0 0, 10 10), POLYGON ((0 0, 5 0, 5 5, 0 5, 0 0)))'
212
+
213
+ affine_tester(:rotate,
214
+ 'GEOMETRYCOLLECTION (POINT (29 11), LINESTRING (30 10, 20 20), POLYGON ((30 10, 30 15, 25 15, 25 10, 30 10)))',
215
+ wkt,
216
+ Math::PI / 2,
217
+ [ 10.0, 20.0 ]
218
+ )
219
+
220
+ affine_tester(:rotate,
221
+ 'GEOMETRYCOLLECTION (POINT (-2 0), LINESTRING (-3 1, 7 -9), POLYGON ((-3 1, -3 -4, 2 -4, 2 1, -3 1)))',
222
+ wkt,
223
+ -Math::PI / 2,
224
+ [ -1.0, 2.0 ]
225
+ )
226
+
227
+ affine_tester(:rotate,
228
+ 'GEOMETRYCOLLECTION (POINT (19 1), LINESTRING (20 0, 10 10), POLYGON ((20 0, 20 5, 15 5, 15 0, 20 0)))',
229
+ wkt,
230
+ Math::PI / 2,
231
+ read('POINT(10 10)')
232
+ )
233
+
234
+ affine_tester(:rotate,
235
+ 'GEOMETRYCOLLECTION (POINT (-0.5 0.5), LINESTRING (0.5 -0.5, -9.5 9.5), POLYGON ((0.5 -0.5, 0.5 4.5, -4.5 4.5, -4.5 -0.5, 0.5 -0.5)))',
236
+ wkt,
237
+ Math::PI / 2,
238
+ read('LINESTRING(0 0, 1 0)')
239
+ )
240
+ end
241
+
242
+ def test_rotate_x
243
+ writer.rounding_precision = 3
244
+ writer.output_dimensions = 3
245
+
246
+ wkt = 'GEOMETRYCOLLECTION Z (POINT Z (1 1 1), LINESTRING Z (1 1 1, 10 10 10), POLYGON Z ((0 0 0, 5 0 0, 5 5 0, 0 5 0, 0 0 0)))'
247
+
248
+ affine_tester(:rotate_x,
249
+ 'GEOMETRYCOLLECTION Z (POINT Z (1 -1 -1), LINESTRING Z (1 -1 -1, 10 -10 -10), POLYGON Z ((0 0 0, 5 0 0, 5 -5 0, 0 -5 0, 0 0 0)))',
250
+ wkt,
251
+ Math::PI
252
+ )
253
+
254
+ affine_tester(:rotate_x,
255
+ 'GEOMETRYCOLLECTION Z (POINT Z (1 -1 1), LINESTRING Z (1 -1 1, 10 -10 10), POLYGON Z ((0 0 0, 5 0 0, 5 0 5, 0 0 5, 0 0 0)))',
256
+ wkt,
257
+ Math::PI / 2
258
+ )
259
+
260
+ affine_tester(:rotate_x,
261
+ 'GEOMETRYCOLLECTION Z (POINT Z (1 1 -1), LINESTRING Z (1 1 -1, 10 10 -10), POLYGON Z ((0 0 0, 5 0 0, 5 0 -5, 0 0 -5, 0 0 0)))',
262
+ wkt,
263
+ Math::PI + Math::PI / 2
264
+ )
265
+
266
+ affine_tester(:rotate_x,
267
+ wkt,
268
+ wkt,
269
+ Math::PI * 2
270
+ )
271
+ end
272
+
273
+ def test_rotate_y
274
+ writer.rounding_precision = 6
275
+ writer.output_dimensions = 3
276
+
277
+ wkt = 'GEOMETRYCOLLECTION Z (POINT Z (1 1 1), LINESTRING Z (1 1 1, 10 10 10), POLYGON Z ((0 0 0, 5 0 0, 5 5 0, 0 5 0, 0 0 0)))'
278
+
279
+ affine_tester(:rotate_y,
280
+ 'GEOMETRYCOLLECTION Z (POINT Z (-1 1 -1), LINESTRING Z (-1 1 -1, -10 10 -10), POLYGON Z ((0 0 0, -5 0 0, -5 5 0, 0 5 0, 0 0 0)))',
281
+ wkt,
282
+ Math::PI
283
+ )
284
+
285
+ affine_tester(:rotate_y,
286
+ 'GEOMETRYCOLLECTION Z (POINT Z (1 1 -1), LINESTRING Z (1 1 -1, 10 10 -10), POLYGON Z ((0 0 0, 0 0 -5, 0 5 -5, 0 5 0, 0 0 0)))',
287
+ wkt,
288
+ Math::PI / 2
289
+ )
290
+
291
+ affine_tester(:rotate_y,
292
+ 'GEOMETRYCOLLECTION Z (POINT Z (-1 1 1), LINESTRING Z (-1 1 1, -10 10 10), POLYGON Z ((0 0 0, 0 0 5, 0 5 5, 0 5 0, 0 0 0)))',
293
+ wkt,
294
+ Math::PI + Math::PI / 2
295
+ )
296
+
297
+ affine_tester(:rotate_y,
298
+ wkt,
299
+ wkt,
300
+ Math::PI * 2
301
+ )
302
+ end
303
+
304
+ def test_rotate_z
305
+ writer.rounding_precision = 3
306
+
307
+ wkt = 'GEOMETRYCOLLECTION (POINT (1 1), LINESTRING (0 0, 10 10), POLYGON ((0 0, 5 0, 5 5, 0 5, 0 0)))'
308
+
309
+ affine_tester(:rotate_z,
310
+ 'GEOMETRYCOLLECTION (POINT (-1 -1), LINESTRING (0 0, -10 -10), POLYGON ((0 0, -5 0, -5 -5, 0 -5, 0 0)))',
311
+ wkt,
312
+ Math::PI
313
+ )
314
+
315
+ affine_tester(:rotate_z,
316
+ 'GEOMETRYCOLLECTION (POINT (-1 1), LINESTRING (0 0, -10 10), POLYGON ((0 0, 0 5, -5 5, -5 0, 0 0)))',
317
+ wkt,
318
+ Math::PI / 2
319
+ )
320
+
321
+ affine_tester(:rotate_z,
322
+ 'GEOMETRYCOLLECTION (POINT (1 -1), LINESTRING (0 0, 10 -10), POLYGON ((0 0, 0 -5, 5 -5, 5 0, 0 0)))',
323
+ wkt,
324
+ Math::PI + Math::PI / 2
325
+ )
326
+
327
+ affine_tester(:rotate_z,
328
+ wkt,
329
+ wkt,
330
+ Math::PI * 2
331
+ )
332
+ end
333
+
334
+ def test_scale
335
+ affine_tester(:scale,
336
+ 'GEOMETRYCOLLECTION (POINT (5 5), LINESTRING (0 0, 50 50), POLYGON ((0 0, 25 0, 25 25, 0 25, 0 0)))',
337
+ 'GEOMETRYCOLLECTION (POINT (1 1), LINESTRING (0 0, 10 10), POLYGON ((0 0, 5 0, 5 5, 0 5, 0 0)))',
338
+ 5,
339
+ 5
340
+ )
341
+
342
+ affine_tester(:scale,
343
+ 'GEOMETRYCOLLECTION (POINT (3 2), LINESTRING (0 0, 30 20), POLYGON ((0 0, 15 0, 15 10, 0 10, 0 0)))',
344
+ 'GEOMETRYCOLLECTION (POINT (1 1), LINESTRING (0 0, 10 10), POLYGON ((0 0, 5 0, 5 5, 0 5, 0 0)))',
345
+ 3,
346
+ 2
347
+ )
348
+
349
+ writer.output_dimensions = 3
350
+ affine_tester(:scale,
351
+ 'GEOMETRYCOLLECTION Z (POINT Z (4 2 -8), LINESTRING Z (4 2 -8, 40 20 -80), POLYGON Z ((0 0 0, 20 0 0, 20 10 0, 0 10 0, 0 0 0)))',
352
+ 'GEOMETRYCOLLECTION Z (POINT Z (1 1 1), LINESTRING Z (1 1 1, 10 10 10), POLYGON Z ((0 0 0, 5 0 0, 5 5 0, 0 5 0, 0 0 0)))',
353
+ 4,
354
+ 2,
355
+ -8
356
+ )
357
+ end
358
+
359
+ def test_scale_hash
360
+ affine_tester(:scale,
361
+ 'GEOMETRYCOLLECTION (POINT (5 5), LINESTRING (0 0, 50 50), POLYGON ((0 0, 25 0, 25 25, 0 25, 0 0)))',
362
+ 'GEOMETRYCOLLECTION (POINT (1 1), LINESTRING (0 0, 10 10), POLYGON ((0 0, 5 0, 5 5, 0 5, 0 0)))',
363
+ :x => 5,
364
+ :y => 5
365
+ )
366
+
367
+ affine_tester(:scale,
368
+ 'GEOMETRYCOLLECTION (POINT (3 2), LINESTRING (0 0, 30 20), POLYGON ((0 0, 15 0, 15 10, 0 10, 0 0)))',
369
+ 'GEOMETRYCOLLECTION (POINT (1 1), LINESTRING (0 0, 10 10), POLYGON ((0 0, 5 0, 5 5, 0 5, 0 0)))',
370
+ :x => 3,
371
+ :y => 2
372
+ )
373
+
374
+ writer.output_dimensions = 3
375
+ affine_tester(:scale,
376
+ 'GEOMETRYCOLLECTION Z (POINT Z (4 2 -8), LINESTRING Z (4 2 -8, 40 20 -80), POLYGON Z ((0 0 0, 20 0 0, 20 10 0, 0 10 0, 0 0 0)))',
377
+ 'GEOMETRYCOLLECTION Z (POINT Z (1 1 1), LINESTRING Z (1 1 1, 10 10 10), POLYGON Z ((0 0 0, 5 0 0, 5 5 0, 0 5 0, 0 0 0)))',
378
+ :x => 4,
379
+ :y => 2,
380
+ :z => -8
381
+ )
382
+ end
383
+
384
+ def test_trans_scale
385
+ affine_tester(:trans_scale,
386
+ 'GEOMETRYCOLLECTION (POINT (3 3), LINESTRING (2 2, 12 12), POLYGON ((2 2, 7 2, 7 7, 2 7, 2 2)))',
387
+ 'GEOMETRYCOLLECTION (POINT (2 2), LINESTRING (1 1, 11 11), POLYGON ((1 1, 6 1, 6 6, 1 6, 1 1)))',
388
+ 1, 1, 1, 1)
389
+
390
+ wkt = 'GEOMETRYCOLLECTION (POINT (1 1), LINESTRING (0 0, 10 10), POLYGON ((0 0, 5 0, 5 5, 0 5, 0 0)))'
391
+
392
+ affine_tester(:trans_scale,
393
+ 'GEOMETRYCOLLECTION (POINT (2 2), LINESTRING (1 1, 11 11), POLYGON ((1 1, 6 1, 6 6, 1 6, 1 1)))',
394
+ wkt,
395
+ 1, 1, 1, 1)
396
+
397
+ affine_tester(:trans_scale,
398
+ 'GEOMETRYCOLLECTION (POINT (0 0), LINESTRING (1 1, -9 -9), POLYGON ((1 1, -4 1, -4 -4, 1 -4, 1 1)))',
399
+ wkt,
400
+ -1, -1, -1, -1)
401
+
402
+ affine_tester(:trans_scale,
403
+ 'GEOMETRYCOLLECTION (POINT (1 2), LINESTRING (0 1, 10 11), POLYGON ((0 1, 5 1, 5 6, 0 6, 0 1)))',
404
+ wkt,
405
+ 0, 1, 1, 1)
406
+
407
+ affine_tester(:trans_scale,
408
+ 'GEOMETRYCOLLECTION (POINT (2 1), LINESTRING (1 0, 11 10), POLYGON ((1 0, 6 0, 6 5, 1 5, 1 0)))',
409
+ wkt,
410
+ 1, 0, 1, 1)
411
+
412
+ affine_tester(:trans_scale,
413
+ 'GEOMETRYCOLLECTION (POINT (3 2), LINESTRING (2 1, 12 11), POLYGON ((2 1, 7 1, 7 6, 2 6, 2 1)))',
414
+ wkt,
415
+ 2, 1, 1, 1)
416
+
417
+ affine_tester(:trans_scale,
418
+ 'GEOMETRYCOLLECTION (POINT (2 3), LINESTRING (1 2, 11 12), POLYGON ((1 2, 6 2, 6 7, 1 7, 1 2)))',
419
+ wkt,
420
+ 1, 2, 1, 1)
421
+
422
+ affine_tester(:trans_scale,
423
+ 'GEOMETRYCOLLECTION (POINT (4 2), LINESTRING (2 1, 22 11), POLYGON ((2 1, 12 1, 12 6, 2 6, 2 1)))',
424
+ wkt,
425
+ 1, 1, 2, 1)
426
+
427
+ affine_tester(:trans_scale,
428
+ 'GEOMETRYCOLLECTION (POINT (2 4), LINESTRING (1 2, 11 22), POLYGON ((1 2, 6 2, 6 12, 1 12, 1 2)))',
429
+ wkt,
430
+ 1, 1, 1, 2)
431
+
432
+ affine_tester(:trans_scale,
433
+ 'GEOMETRYCOLLECTION (POINT (15 28), LINESTRING (10 21, 60 91), POLYGON ((10 21, 35 21, 35 56, 10 56, 10 21)))',
434
+ wkt,
435
+ 2, 3, 5, 7)
436
+
437
+ writer.output_dimensions = 3
438
+ affine_tester(:trans_scale,
439
+ 'GEOMETRYCOLLECTION Z (POINT Z (15 28 1), LINESTRING Z (15 28 1, 60 91 10), POLYGON Z ((10 21 0, 35 21 0, 35 56 0, 10 56 0, 10 21 0)))',
440
+ 'GEOMETRYCOLLECTION Z (POINT Z (1 1 1), LINESTRING Z (1 1 1, 10 10 10), POLYGON Z ((0 0 0, 5 0 0, 5 5 0, 0 5 0, 0 0 0)))',
441
+ 2, 3, 5, 7)
442
+ end
443
+
444
+ def test_trans_scale_hash
445
+ affine_tester(:trans_scale,
446
+ 'GEOMETRYCOLLECTION (POINT (2 2), LINESTRING (1 1, 11 11), POLYGON ((1 1, 6 1, 6 6, 1 6, 1 1)))',
447
+ 'GEOMETRYCOLLECTION (POINT (1 1), LINESTRING (0 0, 10 10), POLYGON ((0 0, 5 0, 5 5, 0 5, 0 0)))',
448
+ :delta_x => 1, :delta_y => 1, :x_factor => 1, :y_factor => 1)
449
+
450
+ writer.output_dimensions = 3
451
+ affine_tester(:trans_scale,
452
+ 'GEOMETRYCOLLECTION Z (POINT Z (15 28 1), LINESTRING Z (15 28 1, 60 91 10), POLYGON Z ((10 21 0, 35 21 0, 35 56 0, 10 56 0, 10 21 0)))',
453
+ 'GEOMETRYCOLLECTION Z (POINT Z (1 1 1), LINESTRING Z (1 1 1, 10 10 10), POLYGON Z ((0 0 0, 5 0 0, 5 5 0, 0 5 0, 0 0 0)))',
454
+ :delta_x => 2, :delta_y => 3, :x_factor => 5, :y_factor => 7)
455
+
456
+ affine_tester(:trans_scale,
457
+ 'GEOMETRYCOLLECTION Z (POINT Z (3 1 1), LINESTRING Z (3 1 1, 12 10 10), POLYGON Z ((2 0 0, 7 0 0, 7 5 0, 2 5 0, 2 0 0)))',
458
+ 'GEOMETRYCOLLECTION Z (POINT Z (1 1 1), LINESTRING Z (1 1 1, 10 10 10), POLYGON Z ((0 0 0, 5 0 0, 5 5 0, 0 5 0, 0 0 0)))',
459
+ :delta_x => 2, :z_factor => 2)
460
+ end
461
+
462
+
463
+ def test_translate
464
+ affine_tester(:translate,
465
+ 'GEOMETRYCOLLECTION (POINT (6 13), LINESTRING (5 12, 15 22), POLYGON ((5 12, 10 12, 10 17, 5 17, 5 12)))',
466
+ 'GEOMETRYCOLLECTION (POINT (1 1), LINESTRING (0 0, 10 10), POLYGON ((0 0, 5 0, 5 5, 0 5, 0 0)))',
467
+ 5,
468
+ 12
469
+ )
470
+
471
+ writer.output_dimensions = 3
472
+ affine_tester(:translate,
473
+ 'GEOMETRYCOLLECTION Z (POINT Z (-2 -6 4), LINESTRING Z (-2 -6 4, 7 3 13), POLYGON Z ((-3 -7 3, 2 -7 3, 2 -2 3, -3 -2 3, -3 -7 3)))',
474
+ 'GEOMETRYCOLLECTION Z (POINT Z (1 1 1), LINESTRING Z (1 1 1, 10 10 10), POLYGON Z ((0 0 0, 5 0 0, 5 5 0, 0 5 0, 0 0 0)))',
475
+ -3,
476
+ -7,
477
+ 3
478
+ )
479
+ end
480
+
481
+ def test_translate_hash
482
+ affine_tester(:translate,
483
+ 'GEOMETRYCOLLECTION (POINT (6 13), LINESTRING (5 12, 15 22), POLYGON ((5 12, 10 12, 10 17, 5 17, 5 12)))',
484
+ 'GEOMETRYCOLLECTION (POINT (1 1), LINESTRING (0 0, 10 10), POLYGON ((0 0, 5 0, 5 5, 0 5, 0 0)))',
485
+ :x => 5,
486
+ :y => 12
487
+ )
488
+
489
+ writer.output_dimensions = 3
490
+ affine_tester(:translate,
491
+ 'GEOMETRYCOLLECTION Z (POINT Z (-2 -6 4), LINESTRING Z (-2 -6 4, 7 3 13), POLYGON Z ((-3 -7 3, 2 -7 3, 2 -2 3, -3 -2 3, -3 -7 3)))',
492
+ 'GEOMETRYCOLLECTION Z (POINT Z (1 1 1), LINESTRING Z (1 1 1, 10 10 10), POLYGON Z ((0 0 0, 5 0 0, 5 5 0, 0 5 0, 0 0 0)))',
493
+ :x => -3,
494
+ :y => -7,
495
+ :z => 3
496
+ )
497
+ end
87
498
  end