ffi-geos 0.0.1.beta1

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.
@@ -0,0 +1,33 @@
1
+
2
+ module Geos
3
+ class WkbReader
4
+ include Geos::Tools
5
+
6
+ attr_reader :ptr
7
+
8
+ def initialize(*args)
9
+ ptr = if args.first.is_a?(FFI::Pointer)
10
+ args.first
11
+ else
12
+ FFIGeos.GEOSWKBReader_create_r(Geos.current_handle, *args)
13
+ end
14
+
15
+ @ptr = FFI::AutoPointer.new(
16
+ ptr,
17
+ self.class.method(:release)
18
+ )
19
+ end
20
+
21
+ def read(wkb)
22
+ cast_geometry_ptr(FFIGeos.GEOSWKBReader_read_r(Geos.current_handle, self.ptr, wkb, wkb.bytesize))
23
+ end
24
+
25
+ def read_hex(wkb)
26
+ cast_geometry_ptr(FFIGeos.GEOSWKBReader_readHEX_r(Geos.current_handle, self.ptr, wkb, wkb.bytesize))
27
+ end
28
+
29
+ def self.release(ptr) #:nodoc:
30
+ FFIGeos.GEOSWKBReader_destroy_r(Geos.current_handle, ptr)
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,95 @@
1
+
2
+ module Geos
3
+ class WkbWriter
4
+ include Geos::Tools
5
+
6
+ attr_reader :ptr
7
+
8
+ def initialize(options = {})
9
+ options = {
10
+ :include_srid => false
11
+ }.merge(options)
12
+
13
+ ptr = FFIGeos.GEOSWKBWriter_create_r(Geos.current_handle)
14
+ @ptr = FFI::AutoPointer.new(
15
+ ptr,
16
+ self.class.method(:release)
17
+ )
18
+
19
+ set_options(options)
20
+ end
21
+
22
+ def self.release(ptr) #:nodoc:
23
+ FFIGeos.GEOSWKBWriter_destroy_r(Geos.current_handle, ptr)
24
+ end
25
+
26
+ def set_options(options = {}) #:nodoc:
27
+ [ :include_srid ].each do |k|
28
+ self.send("#{k}=", options[k]) if options.has_key?(k)
29
+ end
30
+ end
31
+ private :set_options
32
+
33
+ # Options can be set temporarily for individual writes using an options
34
+ # Hash. The only option currently available is :include_srid.
35
+ def write(geom, options = nil)
36
+ unless options.nil?
37
+ old_options = {
38
+ :include_srid => self.include_srid
39
+ }
40
+
41
+ set_options(options)
42
+ end
43
+
44
+ size_t = FFI::MemoryPointer.new(:size_t)
45
+ FFIGeos.GEOSWKBWriter_write_r(Geos.current_handle, self.ptr, geom.ptr, size_t).get_bytes(0, size_t.read_int)
46
+ ensure
47
+ set_options(old_options) unless old_options.nil?
48
+ end
49
+
50
+ def write_hex(geom, options = nil)
51
+ unless options.nil?
52
+ old_options = {
53
+ :include_srid => self.include_srid
54
+ }
55
+
56
+ set_options(options)
57
+ end
58
+
59
+ size_t = FFI::MemoryPointer.new(:size_t)
60
+ FFIGeos.GEOSWKBWriter_writeHEX_r(Geos.current_handle, self.ptr, geom.ptr, size_t).get_string(0, size_t.read_int)
61
+ ensure
62
+ set_options(old_options) unless old_options.nil?
63
+ end
64
+
65
+ def output_dimensions=(dim)
66
+ if dim < 2 || dim > 3
67
+ raise RuntimeError.new("Output dimensions must be either 2 or 3")
68
+ end
69
+ FFIGeos.GEOSWKBWriter_setOutputDimension_r(Geos.current_handle, self.ptr, dim)
70
+ end
71
+
72
+ def output_dimensions
73
+ FFIGeos.GEOSWKBWriter_getOutputDimension_r(Geos.current_handle, self.ptr)
74
+ end
75
+
76
+ def include_srid
77
+ bool_result(FFIGeos.GEOSWKBWriter_getIncludeSRID_r(Geos.current_handle, self.ptr))
78
+ end
79
+
80
+ def include_srid=(val)
81
+ FFIGeos.GEOSWKBWriter_setIncludeSRID_r(Geos.current_handle, self.ptr,
82
+ val ? 1 : 0
83
+ )
84
+ end
85
+
86
+ def byte_order
87
+ FFIGeos.GEOSWKBWriter_getByteOrder_r(Geos.current_handle, self.ptr)
88
+ end
89
+
90
+ def byte_order=(val)
91
+ check_enum_value(Geos::ByteOrders, val)
92
+ FFIGeos.GEOSWKBWriter_setByteOrder_r(Geos.current_handle, self.ptr, val)
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,29 @@
1
+
2
+ module Geos
3
+ class WktReader
4
+ include Geos::Tools
5
+
6
+ attr_reader :ptr
7
+
8
+ def initialize(*args)
9
+ ptr = if args.first.is_a?(FFI::Pointer)
10
+ args.first
11
+ else
12
+ FFIGeos.GEOSWKTReader_create_r(Geos.current_handle, *args)
13
+ end
14
+
15
+ @ptr = FFI::AutoPointer.new(
16
+ ptr,
17
+ self.class.method(:release)
18
+ )
19
+ end
20
+
21
+ def read(wkt)
22
+ cast_geometry_ptr(FFIGeos.GEOSWKTReader_read_r(Geos.current_handle, self.ptr, wkt))
23
+ end
24
+
25
+ def self.release(ptr) #:nodoc:
26
+ FFIGeos.GEOSWKTReader_destroy_r(Geos.current_handle, ptr)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,108 @@
1
+
2
+ module Geos
3
+ class WktWriter
4
+ attr_reader :ptr
5
+ attr_reader :old_3d
6
+ attr_reader :rounding_precision
7
+ attr_reader :trim
8
+
9
+ def initialize(options = {})
10
+ options = {
11
+ :trim => false,
12
+ :old_3d => false,
13
+ :rounding_precision => -1,
14
+ :output_dimensions => 2
15
+ }.merge(options)
16
+
17
+ ptr = FFIGeos.GEOSWKTWriter_create_r(Geos.current_handle)
18
+ @ptr = FFI::AutoPointer.new(
19
+ ptr,
20
+ self.class.method(:release)
21
+ )
22
+
23
+ set_options(options)
24
+ end
25
+
26
+ def self.release(ptr) #:nodoc:
27
+ FFIGeos.GEOSWKTWriter_destroy_r(Geos.current_handle, ptr)
28
+ end
29
+
30
+ def set_options(options) #:nodoc:
31
+ [ :trim, :old_3d, :rounding_precision, :output_dimensions ].each do |k|
32
+ self.send("#{k}=", options[k]) if self.respond_to?("#{k}=") && options.has_key?(k)
33
+ end
34
+ end
35
+ private :set_options
36
+
37
+ # Options can be set temporarily for individual writes using an options
38
+ # Hash. Options include :trim, :old_3d, :rounding_precision and
39
+ # :output_dimensions
40
+ def write(geom, options = nil)
41
+ unless options.nil?
42
+ old_options = {
43
+ :trim => self.trim,
44
+ :old_3d => self.old_3d,
45
+ :rounding_precision => self.rounding_precision,
46
+ :output_dimensions => self.output_dimensions
47
+ }
48
+
49
+ set_options(options)
50
+ end
51
+
52
+ FFIGeos.GEOSWKTWriter_write_r(Geos.current_handle, self.ptr, geom.ptr)
53
+ ensure
54
+ set_options(old_options) unless options.nil?
55
+ end
56
+
57
+ if FFIGeos.respond_to?(:GEOSWKTWriter_setTrim_r)
58
+ # Available in GEOS 3.3+.
59
+ def trim=(val)
60
+ @trim = !!val
61
+ FFIGeos.GEOSWKTWriter_setTrim_r(Geos.current_handle, self.ptr,
62
+ @trim ? 1 : 0
63
+ )
64
+ end
65
+ end
66
+
67
+ if FFIGeos.respond_to?(:GEOSWKTWriter_setRoundingPrecision_r)
68
+ # Available in GEOS 3.3+.
69
+ def rounding_precision=(r)
70
+ r = r.to_i
71
+ if r > 255
72
+ raise RuntimeError.new("Rounding precision cannot be greater than 255")
73
+ end
74
+
75
+ @rounding_precision = r
76
+ FFIGeos.GEOSWKTWriter_setRoundingPrecision_r(Geos.current_handle, self.ptr, @rounding_precision)
77
+ end
78
+ end
79
+
80
+ if FFIGeos.respond_to?(:GEOSWKTWriter_setOld3D_r)
81
+ # Available in GEOS 3.3+.
82
+ def old_3d=(val)
83
+ @old_3d = !!val
84
+ FFIGeos.GEOSWKTWriter_setOld3D_r(Geos.current_handle, self.ptr,
85
+ @old_3d ? 1 : 0
86
+ )
87
+ end
88
+ end
89
+
90
+ if FFIGeos.respond_to?(:GEOSWKTWriter_setOutputDimension_r)
91
+ # Available in GEOS 3.3+.
92
+ def output_dimensions=(dim)
93
+ dim = dim.to_i
94
+ if dim < 2 || dim > 3
95
+ raise RuntimeError.new("Output dimensions must be either 2 or 3")
96
+ end
97
+ FFIGeos.GEOSWKTWriter_setOutputDimension_r(Geos.current_handle, self.ptr, dim)
98
+ end
99
+ end
100
+
101
+ if FFIGeos.respond_to?(:GEOSWKTWriter_getOutputDimension_r)
102
+ # Available in GEOS 3.3+.
103
+ def output_dimensions
104
+ FFIGeos.GEOSWKTWriter_getOutputDimension_r(Geos.current_handle, self.ptr)
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,70 @@
1
+
2
+ $: << File.dirname(__FILE__)
3
+ require 'test_helper'
4
+
5
+ class CoordinateSequenceTests < Test::Unit::TestCase
6
+ include TestHelper
7
+
8
+ def setup
9
+ @cs = Geos::CoordinateSequence.new(3, 0)
10
+ end
11
+
12
+ def test_set_and_get_x
13
+ @cs.set_x(0, 10.01)
14
+ assert_in_delta(10.01, @cs.get_x(0), 0.0000001)
15
+ end
16
+
17
+ def test_set_and_get_y
18
+ @cs.set_y(0, 20.02)
19
+ assert_in_delta(20.02, @cs.get_y(0), 0.0000001)
20
+ end
21
+
22
+ def test_set_and_get_z
23
+ @cs.set_z(0, 20.02)
24
+ assert_in_delta(20.02, @cs.get_z(0), 0.0000001)
25
+ end
26
+
27
+ def test_set_and_get_ordinate
28
+ @cs.set_ordinate(0, 0, 10.01)
29
+ @cs.set_ordinate(0, 1, 20.02)
30
+ @cs.set_ordinate(0, 2, 30.03)
31
+
32
+ assert_in_delta(10.01, @cs.get_ordinate(0, 0), 0.0000001)
33
+ assert_in_delta(20.02, @cs.get_ordinate(0, 1), 0.0000001)
34
+ assert_in_delta(30.03, @cs.get_ordinate(0, 2), 0.0000001)
35
+ end
36
+
37
+ def test_length
38
+ assert_equal(3, @cs.length)
39
+ end
40
+
41
+ def test_dimensions
42
+ assert_equal(2, @cs.dimensions)
43
+ end
44
+
45
+ def test_check_bounds
46
+ assert_raise(RuntimeError) { @cs.set_x(10, 0.1) }
47
+ assert_raise(RuntimeError) { @cs.set_x(-1, 0.1) }
48
+
49
+ assert_raise(RuntimeError) { @cs.set_y(10, 0.1) }
50
+ assert_raise(RuntimeError) { @cs.set_y(-1, 0.1) }
51
+
52
+ assert_raise(RuntimeError) { @cs.set_z(10, 0.1) }
53
+ assert_raise(RuntimeError) { @cs.set_z(-1, 0.1) }
54
+
55
+ assert_raise(RuntimeError) { @cs.set_ordinate(10, 0, 0.1) }
56
+ assert_raise(RuntimeError) { @cs.set_ordinate(-1, 0, 0.1) }
57
+
58
+ assert_raise(RuntimeError) { @cs.get_x(10) }
59
+ assert_raise(RuntimeError) { @cs.get_x(-1) }
60
+
61
+ assert_raise(RuntimeError) { @cs.get_y(10) }
62
+ assert_raise(RuntimeError) { @cs.get_y(-1) }
63
+
64
+ assert_raise(RuntimeError) { @cs.get_z(10) }
65
+ assert_raise(RuntimeError) { @cs.get_z(-1) }
66
+
67
+ assert_raise(RuntimeError) { @cs.get_ordinate(10, 0) }
68
+ assert_raise(RuntimeError) { @cs.get_ordinate(-1, 0) }
69
+ end
70
+ end
@@ -0,0 +1,1499 @@
1
+
2
+ $: << File.dirname(__FILE__)
3
+ require 'test_helper'
4
+
5
+ class GeometryTests < Test::Unit::TestCase
6
+ include TestHelper
7
+
8
+ def comparison_tester(method_with_args, geom_a, geom_b, expected)
9
+ method_with_args = Array(method_with_args)
10
+ method = method_with_args.shift
11
+ args = method_with_args
12
+
13
+ geom_1 = read(geom_a)
14
+ geom_b = read(geom_b)
15
+ result = geom_1.send(method, geom_b, *args)
16
+ assert(read(expected).eql_exact?(result, TOLERANCE))
17
+ end
18
+
19
+ def self_tester(method_with_args, g, expected)
20
+ method_with_args = Array(method_with_args)
21
+ geom = read(g)
22
+ result = geom.send(*method_with_args)
23
+ assert(read(expected).eql_exact?(result, TOLERANCE))
24
+ end
25
+
26
+ def test_intersection
27
+ comparison_tester(
28
+ :intersection,
29
+ 'POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))',
30
+ 'POLYGON((5 5, 15 5, 15 15, 5 15, 5 5))',
31
+ 'POLYGON((5 10, 10 10, 10 5, 5 5, 5 10))'
32
+ )
33
+ end
34
+
35
+ def test_buffer
36
+ geom = read('POINT(0 0)')
37
+ assert_equal('POLYGON EMPTY', write(geom.buffer(0)))
38
+
39
+ assert(read('POLYGON ((
40
+ 10.0000000000000000 0.0000000000000000, 9.8078528040323043 -1.9509032201612808,
41
+ 9.2387953251128696 -3.8268343236508939, 8.3146961230254561 -5.5557023301960173,
42
+ 7.0710678118654808 -7.0710678118654702, 5.5557023301960315 -8.3146961230254472,
43
+ 3.8268343236509086 -9.2387953251128625, 1.9509032201612964 -9.8078528040323025,
44
+ 0.0000000000000162 -10.0000000000000000, -1.9509032201612646 -9.8078528040323079,
45
+ -3.8268343236508784 -9.2387953251128749, -5.5557023301960040 -8.3146961230254650,
46
+ -7.0710678118654595 -7.0710678118654924, -8.3146961230254384 -5.5557023301960431,
47
+ -9.2387953251128572 -3.8268343236509232, -9.8078528040322990 -1.9509032201613119,
48
+ -10.0000000000000000 -0.0000000000000323, -9.8078528040323114 1.9509032201612488,
49
+ -9.2387953251128820 3.8268343236508642, -8.3146961230254739 5.5557023301959898,
50
+ -7.0710678118655048 7.0710678118654453, -5.5557023301960591 8.3146961230254277,
51
+ -3.8268343236509361 9.2387953251128518, -1.9509032201613217 9.8078528040322972,
52
+ -0.0000000000000374 10.0000000000000000, 1.9509032201612482 9.8078528040323114,
53
+ 3.8268343236508673 9.2387953251128803, 5.5557023301959960 8.3146961230254686,
54
+ 7.0710678118654542 7.0710678118654959, 8.3146961230254384 5.5557023301960440,
55
+ 9.2387953251128589 3.8268343236509201, 9.8078528040323008 1.9509032201613046,
56
+ 10.0000000000000000 0.0000000000000000
57
+ ))').eql_exact?(geom.buffer(10), TOLERANCE))
58
+
59
+ assert(read("POLYGON ((
60
+ 1.0000000000000000 0.0000000000000000, 0.0000000000000016 -1.0000000000000000,
61
+ -1.0000000000000000 -0.0000000000000032, -0.0000000000000046 1.0000000000000000,
62
+ 1.0000000000000000 0.0000000000000000
63
+ ))").eql_exact?(geom.buffer(1, 1), TOLERANCE))
64
+ end
65
+
66
+ if ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:buffer_with_style)
67
+ def test_buffer_with_style
68
+ tester = lambda { |expected, g, width, style|
69
+ geom = read(g)
70
+ buffered = geom.buffer(width, style)
71
+
72
+ assert_equal(expected, write(buffered))
73
+ }
74
+
75
+ @writer.rounding_precision = 0
76
+
77
+ tester[
78
+ 'POLYGON ((100 10, 110 0, 100 -10, 0 -10, -10 0, 0 10, 100 10))',
79
+ 'LINESTRING(0 0, 100 0)',
80
+ 10, {
81
+ :quad_segs => 1,
82
+ :endcap => :round
83
+ }
84
+ ]
85
+
86
+ tester[
87
+ 'POLYGON ((100 10, 100 -10, 0 -10, 0 10, 100 10))',
88
+ 'LINESTRING(0 0, 100 0)',
89
+ 10, {
90
+ :quad_segs => 1,
91
+ :endcap => :flat
92
+ }
93
+ ]
94
+
95
+ tester[
96
+ 'POLYGON ((100 10, 110 10, 110 -10, 0 -10, -10 -10, -10 10, 100 10))',
97
+ 'LINESTRING(0 0, 100 0)',
98
+ 10, {
99
+ :quad_segs => 1,
100
+ :endcap => :square
101
+ }
102
+ ]
103
+
104
+ tester[
105
+ 'POLYGON ((90 10, 90 100, 93 107, 100 110, 107 107, 110 100, 110 0, 107 -7, 100 -10, 0 -10, -7 -7, -10 0, -7 7, 0 10, 90 10))',
106
+ 'LINESTRING(0 0, 100 0, 100 100)',
107
+ 10, {
108
+ :quad_segs => 2,
109
+ :join => :round
110
+ }
111
+ ]
112
+
113
+ tester[
114
+ 'POLYGON ((90 10, 90 100, 93 107, 100 110, 107 107, 110 100, 110 0, 100 -10, 0 -10, -7 -7, -10 0, -7 7, 0 10, 90 10))',
115
+ 'LINESTRING(0 0, 100 0, 100 100)',
116
+ 10, {
117
+ :quad_segs => 2,
118
+ :join => :bevel
119
+ }
120
+ ]
121
+
122
+ tester[
123
+ 'POLYGON ((90 10, 90 100, 93 107, 100 110, 107 107, 110 100, 110 -10, 0 -10, -7 -7, -10 0, -7 7, 0 10, 90 10))',
124
+ 'LINESTRING(0 0, 100 0, 100 100)',
125
+ 10, {
126
+ :quad_segs => 2,
127
+ :join => :mitre
128
+ }
129
+ ]
130
+
131
+ tester[
132
+ 'POLYGON ((90 10, 90 100, 93 107, 100 110, 107 107, 110 100, 109 -5, 105 -9, 0 -10, -7 -7, -10 0, -7 7, 0 10, 90 10))',
133
+ 'LINESTRING(0 0, 100 0, 100 100)',
134
+ 10, {
135
+ :quad_segs => 2,
136
+ :join => :mitre,
137
+ :mitre_limit => 1.0
138
+ }
139
+ ]
140
+ end
141
+ end
142
+
143
+ if ENV['FORCE_TESTS'] || Geos::LineString.method_defined?(:buffer_single_sided)
144
+ def test_buffer_single_sided
145
+ tester = lambda { |expected, g, width, style|
146
+ geom = read(g)
147
+ buffered = geom.buffer_single_sided(width, style)
148
+
149
+ assert_equal(expected, write(buffered))
150
+ }
151
+
152
+ @writer.rounding_precision = 0
153
+
154
+ tester[
155
+ 'LINESTRING (0 2, 10 2)',
156
+ 'LINESTRING(0 0, 10 0)',
157
+ 2, {
158
+ :quad_segs => 2,
159
+ :join => :round,
160
+ :mitre_limit => 2.0,
161
+ :left_side => true
162
+ }
163
+ ]
164
+
165
+ tester[
166
+ 'LINESTRING (10 -2, 0 -2)',
167
+ 'LINESTRING(0 0, 10 0)',
168
+ 2, {
169
+ :quad_segs => 2,
170
+ :join => :round,
171
+ :mitre_limit => 2.0
172
+ }
173
+ ]
174
+ end
175
+ end
176
+
177
+ def test_convex_hull
178
+ geom = read('POINT(0 0)')
179
+ assert(read('POINT(0 0)').eql_exact?(geom.convex_hull, TOLERANCE))
180
+
181
+ geom = read('LINESTRING(0 0, 10 10)')
182
+ assert(read('LINESTRING(0 0, 10 10)').eql_exact?(geom.convex_hull, TOLERANCE))
183
+
184
+ geom = read('POLYGON((0 0, 0 10, 5 5, 10 10, 10 0, 0 0))')
185
+ assert(read('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))').eql_exact?(geom.convex_hull, TOLERANCE))
186
+ end
187
+
188
+ def test_difference
189
+ comparison_tester(
190
+ :difference,
191
+ 'POINT(0 0)',
192
+ 'POINT(0 0)',
193
+ 'GEOMETRYCOLLECTION EMPTY'
194
+ )
195
+
196
+ comparison_tester(
197
+ :difference,
198
+ 'POINT(0 0)',
199
+ 'POINT(1 0)',
200
+ 'POINT (0 0)'
201
+ )
202
+
203
+ comparison_tester(
204
+ :difference,
205
+ 'LINESTRING(0 0, 10 0)',
206
+ 'POINT(5 0)',
207
+ 'LINESTRING (0 0, 10 0)'
208
+ )
209
+
210
+ comparison_tester(
211
+ :difference,
212
+ 'POINT(5 0)',
213
+ 'LINESTRING(0 0, 10 0)',
214
+ 'GEOMETRYCOLLECTION EMPTY'
215
+ )
216
+
217
+ comparison_tester(
218
+ :difference,
219
+ 'POINT(5 0)',
220
+ 'LINESTRING(0 1, 10 1)',
221
+ 'POINT (5 0)'
222
+ )
223
+
224
+ comparison_tester(
225
+ :difference,
226
+ 'LINESTRING(0 0, 10 0)',
227
+ 'LINESTRING(5 -10, 5 10)',
228
+ 'MULTILINESTRING ((0 0, 5 0), (5 0, 10 0))'
229
+ )
230
+
231
+ comparison_tester(
232
+ :difference,
233
+ 'LINESTRING(0 0, 10 0)',
234
+ 'LINESTRING(5 0, 20 0)',
235
+ 'LINESTRING (0 0, 5 0)'
236
+ )
237
+
238
+ comparison_tester(
239
+ :difference,
240
+ 'POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))',
241
+ 'LINESTRING(5 -10, 5 10)',
242
+ 'POLYGON ((5 0, 0 0, 0 10, 5 10, 10 10, 10 0, 5 0))'
243
+ )
244
+
245
+ comparison_tester(
246
+ :difference,
247
+ 'POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))',
248
+ 'LINESTRING(10 0, 20 0)',
249
+ 'POLYGON ((10 0, 0 0, 0 10, 10 10, 10 0))'
250
+ )
251
+
252
+ comparison_tester(
253
+ :difference,
254
+ 'POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))',
255
+ 'POLYGON((5 -5, 5 5, 15 5, 15 -5, 5 -5))',
256
+ 'POLYGON ((5 0, 0 0, 0 10, 10 10, 10 5, 5 5, 5 0))'
257
+ )
258
+ end
259
+
260
+ def test_sym_difference
261
+ comparison_tester(
262
+ :sym_difference,
263
+ 'POINT(0 0)',
264
+ 'POINT(0 0)',
265
+ 'GEOMETRYCOLLECTION EMPTY'
266
+ )
267
+
268
+ comparison_tester(
269
+ :sym_difference,
270
+ 'POINT(0 0)',
271
+ 'POINT(1 0)',
272
+ 'MULTIPOINT (0 0, 1 0)'
273
+ )
274
+
275
+ comparison_tester(
276
+ :sym_difference,
277
+ 'LINESTRING(0 0, 10 0)',
278
+ 'POINT(5 0)',
279
+ 'LINESTRING (0 0, 10 0)'
280
+ )
281
+
282
+ comparison_tester(
283
+ :sym_difference,
284
+ 'POINT(5 0)',
285
+ 'LINESTRING(0 0, 10 0)',
286
+ 'LINESTRING (0 0, 10 0)'
287
+ )
288
+
289
+ comparison_tester(
290
+ :sym_difference,
291
+ 'POINT(5 0)',
292
+ 'LINESTRING(0 1, 10 1)',
293
+ 'GEOMETRYCOLLECTION (POINT (5 0), LINESTRING (0 1, 10 1))'
294
+ )
295
+
296
+ comparison_tester(
297
+ :sym_difference,
298
+ 'LINESTRING(0 0, 10 0)',
299
+ 'LINESTRING(5 -10, 5 10)',
300
+ 'MULTILINESTRING ((0 0, 5 0), (5 0, 10 0), (5 -10, 5 0), (5 0, 5 10))'
301
+ )
302
+
303
+ comparison_tester(
304
+ :sym_difference,
305
+ 'LINESTRING(0 0, 10 0)',
306
+ 'LINESTRING(5 0, 20 0)',
307
+ 'MULTILINESTRING ((0 0, 5 0), (10 0, 20 0))'
308
+ )
309
+
310
+ comparison_tester(
311
+ :sym_difference,
312
+ 'POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))',
313
+ 'LINESTRING(5 -10, 5 10)',
314
+ 'GEOMETRYCOLLECTION (LINESTRING (5 -10, 5 0), POLYGON ((5 0, 0 0, 0 10, 5 10, 10 10, 10 0, 5 0)))'
315
+ )
316
+
317
+ comparison_tester(
318
+ :sym_difference,
319
+ 'POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))',
320
+ 'LINESTRING(10 0, 20 0)',
321
+ 'GEOMETRYCOLLECTION (LINESTRING (10 0, 20 0), POLYGON ((10 0, 0 0, 0 10, 10 10, 10 0)))'
322
+ )
323
+
324
+ comparison_tester(
325
+ :sym_difference,
326
+ 'POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))',
327
+ 'POLYGON((5 -5, 5 5, 15 5, 15 -5, 5 -5))',
328
+ 'MULTIPOLYGON (((5 0, 0 0, 0 10, 10 10, 10 5, 5 5, 5 0)), ((5 0, 10 0, 10 5, 15 5, 15 -5, 5 -5, 5 0)))'
329
+ )
330
+ end
331
+
332
+ def test_boundary
333
+ self_tester(
334
+ :boundary,
335
+ 'POINT(0 0)',
336
+ 'GEOMETRYCOLLECTION EMPTY'
337
+ )
338
+
339
+ self_tester(
340
+ :boundary,
341
+ 'LINESTRING(0 0, 10 10)',
342
+ 'MULTIPOINT (0 0, 10 10)'
343
+ )
344
+
345
+ self_tester(
346
+ :boundary,
347
+ 'POLYGON((0 0, 10 0, 10 10, 0 10, 0 0),( 5 5, 5 6, 6 6, 6 5, 5 5))',
348
+ 'MULTILINESTRING ((0 0, 10 0, 10 10, 0 10, 0 0), (5 5, 5 6, 6 6, 6 5, 5 5))'
349
+ )
350
+ end
351
+
352
+ def test_union
353
+ comparison_tester(
354
+ :union,
355
+ 'POINT(0 0)',
356
+ 'POINT(0 0)',
357
+ 'POINT (0 0)'
358
+ )
359
+
360
+ comparison_tester(
361
+ :union,
362
+ 'POINT(0 0)',
363
+ 'POINT(1 0)',
364
+ 'MULTIPOINT (0 0, 1 0)'
365
+ )
366
+
367
+ comparison_tester(
368
+ :union,
369
+ 'LINESTRING(0 0, 10 0)',
370
+ 'POINT(5 0)',
371
+ 'LINESTRING (0 0, 10 0)'
372
+ )
373
+
374
+ comparison_tester(
375
+ :union,
376
+ 'POINT(5 0)',
377
+ 'LINESTRING(0 0, 10 0)',
378
+ 'LINESTRING (0 0, 10 0)'
379
+ )
380
+
381
+ comparison_tester(
382
+ :union,
383
+ 'POINT(5 0)',
384
+ 'LINESTRING(0 1, 10 1)',
385
+ 'GEOMETRYCOLLECTION (POINT (5 0), LINESTRING (0 1, 10 1))'
386
+ )
387
+
388
+ comparison_tester(
389
+ :union,
390
+ 'LINESTRING(0 0, 10 0)',
391
+ 'LINESTRING(5 -10, 5 10)',
392
+ 'MULTILINESTRING ((0 0, 5 0), (5 0, 10 0), (5 -10, 5 0), (5 0, 5 10))'
393
+ )
394
+
395
+ comparison_tester(
396
+ :union,
397
+ 'LINESTRING(0 0, 10 0)',
398
+ 'LINESTRING(5 0, 20 0)',
399
+ 'MULTILINESTRING ((0 0, 5 0), (5 0, 10 0), (10 0, 20 0))'
400
+ )
401
+
402
+ comparison_tester(
403
+ :union,
404
+ 'POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))',
405
+ 'LINESTRING(5 -10, 5 10)',
406
+ 'GEOMETRYCOLLECTION (LINESTRING (5 -10, 5 0), POLYGON ((5 0, 0 0, 0 10, 5 10, 10 10, 10 0, 5 0)))'
407
+ )
408
+
409
+ comparison_tester(
410
+ :union,
411
+ 'POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))',
412
+ 'LINESTRING(10 0, 20 0)',
413
+ 'GEOMETRYCOLLECTION (LINESTRING (10 0, 20 0), POLYGON ((10 0, 0 0, 0 10, 10 10, 10 0)))'
414
+ )
415
+
416
+ comparison_tester(
417
+ :union,
418
+ 'POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))',
419
+ 'POLYGON((5 -5, 5 5, 15 5, 15 -5, 5 -5))',
420
+ 'POLYGON ((5 0, 0 0, 0 10, 10 10, 10 5, 15 5, 15 -5, 5 -5, 5 0))'
421
+ )
422
+ end
423
+
424
+ if ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:union_cascaded)
425
+ def test_union_cascaded
426
+ self_tester(
427
+ :union_cascaded,
428
+ 'MULTIPOLYGON(
429
+ ((0 0, 1 0, 1 1, 0 1, 0 0)),
430
+ ((10 10, 10 14, 14 14, 14 10, 10 10),
431
+ (11 11, 11 12, 12 12, 12 11, 11 11)),
432
+ ((0 0, 11 0, 11 11, 0 11, 0 0))
433
+ ))',
434
+ 'POLYGON ((
435
+ 1 0, 0 0, 0 1, 0 11, 10 11,
436
+ 10 14, 14 14, 14 10, 11 10,
437
+ 11 0, 1 0
438
+ ), (11 11, 12 11, 12 12, 11 12, 11 11))'
439
+ )
440
+ end
441
+ end
442
+
443
+ if ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:unary_union)
444
+ def test_unary_union
445
+ self_tester(
446
+ :unary_union,
447
+ 'MULTIPOLYGON(
448
+ ((0 0, 1 0, 1 1, 0 1, 0 0)),
449
+ ((10 10, 10 14, 14 14, 14 10, 10 10),
450
+ (11 11, 11 12, 12 12, 12 11, 11 11)),
451
+ ((0 0, 11 0, 11 11, 0 11, 0 0))
452
+ ))',
453
+ 'POLYGON ((
454
+ 1 0, 0 0, 0 1, 0 11, 10 11,
455
+ 10 14, 14 14, 14 10, 11 10,
456
+ 11 0, 1 0
457
+ ), (11 11, 12 11, 12 12, 11 12, 11 11))'
458
+ )
459
+ end
460
+ end
461
+
462
+ def test_union_without_arguments
463
+ self_tester(
464
+ :union,
465
+ 'MULTIPOLYGON(
466
+ ((0 0, 1 0, 1 1, 0 1, 0 0)),
467
+ ((10 10, 10 14, 14 14, 14 10, 10 10),
468
+ (11 11, 11 12, 12 12, 12 11, 11 11)),
469
+ ((0 0, 11 0, 11 11, 0 11, 0 0))
470
+ ))',
471
+ 'POLYGON ((
472
+ 1 0, 0 0, 0 1, 0 11, 10 11,
473
+ 10 14, 14 14, 14 10, 11 10,
474
+ 11 0, 1 0
475
+ ), (11 11, 12 11, 12 12, 11 12, 11 11))'
476
+ )
477
+ end
478
+
479
+ def test_point_on_surface
480
+ self_tester(
481
+ :point_on_surface,
482
+ 'POINT(0 0)',
483
+ 'POINT(0 0)'
484
+ )
485
+
486
+ self_tester(
487
+ :point_on_surface,
488
+ 'LINESTRING(0 0, 5 5, 10 10)',
489
+ 'POINT (5 5)'
490
+ )
491
+
492
+ self_tester(
493
+ :point_on_surface,
494
+ 'POLYGON((0 0, 0 10, 5 5, 10 10, 10 0, 0 0))',
495
+ 'POINT (2.5 5)'
496
+ )
497
+ end
498
+
499
+ def test_centroid
500
+ self_tester(
501
+ :centroid,
502
+ 'POINT(0 0)',
503
+ 'POINT (0 0)'
504
+ )
505
+
506
+ self_tester(
507
+ :centroid,
508
+ 'LINESTRING(0 0, 10 10)',
509
+ 'POINT (5 5)'
510
+ )
511
+
512
+ self_tester(
513
+ :centroid,
514
+ 'POLYGON((0 0, 0 10, 5 5, 10 10, 10 0, 0 0))',
515
+ 'POINT (5 3.888888888888888888)'
516
+ )
517
+ end
518
+
519
+ def test_envelope
520
+ self_tester(
521
+ :envelope,
522
+ 'POINT(0 0)',
523
+ 'POINT (0 0)'
524
+ )
525
+
526
+ self_tester(
527
+ :envelope,
528
+ 'LINESTRING(0 0, 10 10)',
529
+ 'POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))'
530
+ )
531
+ end
532
+
533
+ def test_relate
534
+ tester = lambda { |expected, geom_a, geom_b|
535
+ assert_equal(expected, geom_a.relate(geom_b))
536
+ }
537
+
538
+ geom_a = read('POINT(0 0)')
539
+ geom_b = read('POINT(0 0)')
540
+ tester['0FFFFFFF2', geom_a, geom_b]
541
+
542
+ geom_a = read('POINT(0 0)')
543
+ geom_b = read('POINT(1 0)')
544
+ tester['FF0FFF0F2', geom_a, geom_b]
545
+
546
+ geom_a = read('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))')
547
+ geom_b = read('POINT(1 0)')
548
+ tester['FF20F1FF2', geom_a, geom_b]
549
+ end
550
+
551
+ def test_relate_pattern
552
+ tester = lambda { |pattern, geom_a, geom_b, expected|
553
+ assert_equal(expected, geom_a.relate_pattern(geom_b, pattern))
554
+ }
555
+
556
+ geom_a = read('POINT(0 0)')
557
+ geom_b = read('POINT(0 0)')
558
+ tester['0FFFFFFF2', geom_a, geom_b, true]
559
+ tester['0*******T', geom_a, geom_b, true]
560
+ tester['0*******1', geom_a, geom_b, false]
561
+
562
+ geom_a = read('POINT(0 0)')
563
+ geom_b = read('POINT(1 0)')
564
+ tester['FF0FFF0F2', geom_a, geom_b, true]
565
+ tester['F*******2', geom_a, geom_b, true]
566
+ tester['T*******2', geom_a, geom_b, false]
567
+
568
+ geom_a = read('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))')
569
+ geom_b = read('POINT(1 0)')
570
+ tester['FF20F1FF2', geom_a, geom_b, true]
571
+ tester['F****T**T', geom_a, geom_b, true]
572
+ tester['T*******2', geom_a, geom_b, false]
573
+ end
574
+
575
+ if ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:relate_boundary_node_rule)
576
+ def test_relate_boundary_node_rule
577
+ geom_a = read('LINESTRING(0 0, 2 4, 5 5, 0 0)')
578
+ geom_b = read('POINT(0 0)')
579
+
580
+ ret = geom_a.relate_boundary_node_rule(geom_b, :ogc)
581
+ assert_equal('0F1FFFFF2', ret)
582
+
583
+ ret = geom_a.relate_boundary_node_rule(geom_b, :endpoint)
584
+ assert_equal('FF10FFFF2', ret)
585
+
586
+ assert_raise(TypeError) do
587
+ geom_a.relate_boundary_node_rule(geom_b, :gibberish)
588
+ end
589
+ end
590
+ end
591
+
592
+ def test_line_merge
593
+ self_tester(
594
+ :line_merge,
595
+ 'MULTILINESTRING(
596
+ (0 0, 10 10),
597
+ (10 10, 10 0),
598
+ (5 0, 10 0),
599
+ (5 -5, 5 0)
600
+ )',
601
+ 'LINESTRING (0 0, 10 10, 10 0, 5 0, 5 -5)'
602
+ )
603
+ end
604
+
605
+ def test_simplify
606
+ self_tester(
607
+ [ :simplify, 2 ],
608
+ 'LINESTRING(0 0, 3 4, 5 10, 10 0, 10 9, 5 11, 0 9)',
609
+ 'LINESTRING (0 0, 5 10, 10 0, 10 9, 0 9)'
610
+ )
611
+ end
612
+
613
+ def test_topology_preserve_simplify
614
+ self_tester(
615
+ [ :topology_preserve_simplify, 2 ],
616
+ 'LINESTRING(0 0, 3 4, 5 10, 10 0, 10 9, 5 11, 0 9)',
617
+ 'LINESTRING (0 0, 5 10, 10 0, 10 9, 5 11, 0 9)'
618
+ )
619
+ end
620
+
621
+ if ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:extract_unique_points)
622
+ def test_extract_unique_points
623
+ writer.rounding_precision = 0
624
+
625
+ geom = read('GEOMETRYCOLLECTION (
626
+ MULTIPOLYGON (
627
+ ((0 0, 1 0, 1 1, 0 1, 0 0)),
628
+ ((10 10, 10 14, 14 14, 14 10, 10 10),
629
+ (11 11, 11 12, 12 12, 12 11, 11 11))
630
+ ),
631
+ POLYGON ((0 0, 1 0, 1 1, 0 1, 0 0)),
632
+ MULTILINESTRING ((0 0, 2 3), (10 10, 3 4)),
633
+ LINESTRING (0 0, 2 3),
634
+ MULTIPOINT (0 0, 2 3),
635
+ POINT (9 0),
636
+ POINT(1 0)),
637
+ LINESTRING EMPTY
638
+ ')
639
+
640
+ assert_equal(
641
+ 'MULTIPOINT (0 0, 1 0, 1 1, 0 1, 10 10, 10 14, 14 14, 14 10, 11 11, 11 12, 12 12, 12 11, 2 3, 3 4, 9 0)',
642
+ write(geom.extract_unique_points)
643
+ )
644
+ end
645
+ end
646
+
647
+ def test_relationships
648
+ tester = lambda { |geom_a, geom_b, tests|
649
+ tests.each do |test|
650
+ expected, method, args = test
651
+ if ENV['FORCE_TESTS'] || geom_a.respond_to?(method)
652
+ value = geom_a.send(method, *([ geom_b ] + Array(args)))
653
+ assert_equal(expected, value)
654
+ end
655
+ end
656
+ }
657
+
658
+ tester[read('POINT(0 0)'), read('POINT(0 0)'), [
659
+ [false, :disjoint?],
660
+ [false, :touches?],
661
+ [true, :intersects?],
662
+ [false, :crosses?],
663
+ [true, :within?],
664
+ [true, :contains?],
665
+ [false, :overlaps?],
666
+ [true, :eql?],
667
+ [true, :eql_exact?, TOLERANCE],
668
+ [true, :covers?],
669
+ [true, :covered_by?]
670
+ ]]
671
+
672
+ tester[read('POINT(0 0)'), read('LINESTRING(0 0, 10 0)'), [
673
+ [false, :disjoint?],
674
+ [true, :touches?],
675
+ [true, :intersects?],
676
+ [false, :crosses?],
677
+ [false, :within?],
678
+ [false, :contains?],
679
+ [false, :overlaps?],
680
+ [false, :eql?],
681
+ [false, :eql_exact?, TOLERANCE],
682
+ [false, :covers?],
683
+ [true, :covered_by?]
684
+ ]]
685
+
686
+ tester[read('POINT(5 0)'), read('LINESTRING(0 0, 10 0)'), [
687
+ [false, :disjoint?],
688
+ [false, :touches?],
689
+ [true, :intersects?],
690
+ [false, :crosses?],
691
+ [true, :within?],
692
+ [false, :contains?],
693
+ [false, :overlaps?],
694
+ [false, :eql?],
695
+ [false, :eql_exact?, TOLERANCE],
696
+ [false, :covers?],
697
+ [true, :covered_by?]
698
+ ]]
699
+
700
+ tester[read('LINESTRING(5 -5, 5 5)'), read('LINESTRING(0 0, 10 0)'), [
701
+ [false, :disjoint?],
702
+ [false, :touches?],
703
+ [true, :intersects?],
704
+ [true, :crosses?],
705
+ [false, :within?],
706
+ [false, :contains?],
707
+ [false, :overlaps?],
708
+ [false, :eql?],
709
+ [false, :eql_exact?, TOLERANCE],
710
+ [false, :covers?],
711
+ [false, :covered_by?]
712
+ ]]
713
+
714
+ tester[read('LINESTRING(5 0, 15 0)'), read('LINESTRING(0 0, 10 0)'), [
715
+ [false, :disjoint?],
716
+ [false, :touches?],
717
+ [true, :intersects?],
718
+ [false, :crosses?],
719
+ [false, :within?],
720
+ [false, :contains?],
721
+ [true, :overlaps?],
722
+ [false, :eql?],
723
+ [false, :eql_exact?, TOLERANCE],
724
+ [false, :covers?],
725
+ [false, :covered_by?]
726
+ ]]
727
+
728
+ tester[read('LINESTRING(0 0, 5 0, 10 0)'), read('LINESTRING(0 0, 10 0)'), [
729
+ [false, :disjoint?],
730
+ [false, :touches?],
731
+ [true, :intersects?],
732
+ [false, :crosses?],
733
+ [true, :within?],
734
+ [true, :contains?],
735
+ [false, :overlaps?],
736
+ [true, :eql?],
737
+ [false, :eql_exact?, TOLERANCE],
738
+ [true, :covers?],
739
+ [true, :covered_by?]
740
+ ]]
741
+
742
+ tester[read('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))'), read('POLYGON((5 -5, 5 5, 15 5, 15 -5, 5 -5))'), [
743
+ [false, :disjoint?],
744
+ [false, :touches?],
745
+ [true, :intersects?],
746
+ [false, :crosses?],
747
+ [false, :within?],
748
+ [false, :contains?],
749
+ [true, :overlaps?],
750
+ [false, :eql?],
751
+ [false, :eql_exact?, TOLERANCE],
752
+ [false, :covers?],
753
+ [false, :covered_by?]
754
+ ]]
755
+
756
+ tester[read('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))'), read('POINT(15 15)'), [
757
+ [true, :disjoint?],
758
+ [false, :touches?],
759
+ [false, :intersects?],
760
+ [false, :crosses?],
761
+ [false, :within?],
762
+ [false, :contains?],
763
+ [false, :overlaps?],
764
+ [false, :eql?],
765
+ [false, :eql_exact?, TOLERANCE],
766
+ [false, :covers?],
767
+ [false, :covered_by?]
768
+ ]]
769
+ end
770
+
771
+ def test_empty
772
+ assert(!read('POINT(0 0)').empty?)
773
+ assert(read('POINT EMPTY').empty?)
774
+ assert(!read('LINESTRING(0 0, 10 0)').empty?)
775
+ assert(read('LINESTRING EMPTY').empty?)
776
+ assert(!read('POLYGON((0 0, 10 0, 10 10, 0 0))').empty?)
777
+ assert(read('POLYGON EMPTY').empty?)
778
+ assert(!read('GEOMETRYCOLLECTION(POINT(0 0))').empty?)
779
+ assert(read('GEOMETRYCOLLECTION EMPTY').empty?)
780
+ end
781
+
782
+ def test_valid
783
+ assert(read('POINT(0 0)').valid?)
784
+ assert(!read('POINT(0 NaN)').valid?)
785
+ assert(!read('POINT(0 nan)').valid?)
786
+ end
787
+
788
+ if ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:valid_reason)
789
+ def test_valid_reason
790
+ assert_equal("Valid Geometry", read('POINT(0 0)').valid_reason)
791
+ assert_equal("Invalid Coordinate[0 nan]", read('POINT(0 NaN)').valid_reason)
792
+ assert_equal("Invalid Coordinate[0 nan]", read('POINT(0 nan)').valid_reason)
793
+ assert_equal("Self-intersection[2.5 5]", read('POLYGON((0 0, 0 5, 5 5, 5 10, 0 0))').valid_reason)
794
+ end
795
+ end
796
+
797
+ if ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:valid_detail)
798
+ def test_valid_detail
799
+ tester = lambda { |detail, location, geom, flags|
800
+ ret = read(geom).valid_detail(flags)
801
+ assert_equal(detail, ret[:detail])
802
+ assert_equal(location, write(ret[:location]))
803
+ }
804
+
805
+ writer.rounding_precision = 0
806
+
807
+ assert_nil(read('POINT(0 0)').valid_detail)
808
+ tester["Invalid Coordinate", 'POINT (0 nan)', 'POINT(0 NaN)', 0]
809
+ tester["Self-intersection", 'POINT (2 5)', 'POLYGON((0 0, 0 5, 5 5, 5 10, 0 0))', 0]
810
+
811
+ tester["Ring Self-intersection", 'POINT (0 0)', 'POLYGON((0 0, -10 10, 10 10, 0 0, 4 5, -4 5, 0 0)))', 0]
812
+
813
+ assert_nil(read('POLYGON((0 0, -10 10, 10 10, 0 0, 4 5, -4 5, 0 0)))').valid_detail(
814
+ :allow_selftouching_ring_forming_hole
815
+ ))
816
+ end
817
+ end
818
+
819
+ def test_simple
820
+ assert(read('POINT(0 0)').simple?)
821
+ assert(read('LINESTRING(0 0, 10 0)').simple?)
822
+ assert(!read('LINESTRING(0 0, 10 0, 5 5, 5 -5)').simple?)
823
+ end
824
+
825
+ def test_ring
826
+ assert(!read('POINT(0 0)').ring?)
827
+ assert(!read('LINESTRING(0 0, 10 0, 5 5, 5 -5)').ring?)
828
+ assert(read('LINESTRING(0 0, 10 0, 5 5, 0 0)').ring?)
829
+ end
830
+
831
+ def test_has_z
832
+ assert(!read('POINT(0 0)').has_z?)
833
+ assert(read('POINT(0 0 0)').has_z?)
834
+ end
835
+
836
+ if ENV['FORCE_TESTS'] || Geos::LineString.method_defined?(:closed?)
837
+ def test_closed
838
+ assert(read('LINESTRING(0 0, 1 1, 2 2, 0 0)').closed?)
839
+ assert(!read('LINESTRING(0 0, 1 1, 2 2)').closed?)
840
+ assert(read('LINEARRING(0 0, 1 1, 2 2, 0 0)').closed?)
841
+ end
842
+ end
843
+
844
+ def test_num_geometries
845
+ tester = lambda { |expected, g|
846
+ geom = read(g)
847
+ assert_equal(expected, geom.num_geometries)
848
+ }
849
+
850
+ tester[1, 'POINT(0 0)']
851
+ tester[2, 'MULTIPOINT (0 1, 2 3)']
852
+ tester[1, 'LINESTRING (0 0, 2 3)']
853
+ tester[2, 'MULTILINESTRING ((0 1, 2 3), (10 10, 3 4))']
854
+ tester[1, 'POLYGON ((0 0, 1 0, 1 1, 0 1, 0 0))']
855
+ tester[2, 'MULTIPOLYGON(
856
+ ((0 0, 1 0, 1 1, 0 1, 0 0)),
857
+ ((10 10, 10 14, 14 14, 14 10, 10 10),
858
+ (11 11, 11 12, 12 12, 12 11, 11 11)))'
859
+ ]
860
+ tester[6, 'GEOMETRYCOLLECTION (
861
+ MULTIPOLYGON (
862
+ ((0 0, 1 0, 1 1, 0 1, 0 0)),
863
+ ((10 10, 10 14, 14 14, 14 10, 10 10),
864
+ (11 11, 11 12, 12 12, 12 11, 11 11))
865
+ ),
866
+ POLYGON ((0 0, 1 0, 1 1, 0 1, 0 0)),
867
+ MULTILINESTRING ((0 0, 2 3), (10 10, 3 4)),
868
+ LINESTRING (0 0, 2 3),
869
+ MULTIPOINT (0 0, 2 3),
870
+ POINT (9 0))'
871
+ ]
872
+ end
873
+
874
+ # get_geometry_n is segfaulting in the binary GEOS build
875
+ if defined?(Geos::FFIGeos)
876
+ def test_get_geometry_n
877
+ tester = lambda { |expected, g, n|
878
+ geom = read(g)
879
+ result = geom.get_geometry_n(n)
880
+
881
+ if expected.nil?
882
+ assert_nil(result)
883
+ else
884
+ assert(result.eql_exact?(read(expected), TOLERANCE))
885
+ end
886
+ }
887
+
888
+ tester['POINT(0 1)', 'MULTIPOINT (0 1, 2 3)', 0]
889
+ tester['POINT(2 3)', 'MULTIPOINT (0 1, 2 3)', 1]
890
+ tester[nil, 'MULTIPOINT (0 1, 2 3)', 2]
891
+ end
892
+ end
893
+
894
+ def test_num_interior_rings
895
+ tester = lambda { |expected, g|
896
+ geom = read(g)
897
+ assert_equal(expected, geom.num_interior_rings)
898
+ }
899
+
900
+ tester[0, 'POLYGON ((0 0, 1 0, 1 1, 0 1, 0 0))']
901
+ tester[1, 'POLYGON (
902
+ (10 10, 10 14, 14 14, 14 10, 10 10),
903
+ (11 11, 11 12, 12 12, 12 11, 11 11)
904
+ )']
905
+ tester[2, 'POLYGON (
906
+ (10 10, 10 14, 14 14, 14 10, 10 10),
907
+ (11 11, 11 12, 12 12, 12 11, 11 11),
908
+ (13 11, 13 12, 13.5 12, 13.5 11, 13 11))'
909
+ ]
910
+
911
+ assert_raise(NoMethodError) do
912
+ tester[0, 'POINT (0 0)']
913
+ end
914
+ end
915
+
916
+ def test_interior_ring_n
917
+ tester = lambda { |expected, g, n|
918
+ geom = read(g)
919
+ result = geom.interior_ring_n(n)
920
+
921
+ if expected.nil?
922
+ assert_nil(result)
923
+ else
924
+ assert(result.eql_exact?(read(expected), TOLERANCE))
925
+ end
926
+ }
927
+
928
+ tester[
929
+ 'LINEARRING(11 11, 11 12, 12 12, 12 11, 11 11)',
930
+ 'POLYGON(
931
+ (10 10, 10 14, 14 14, 14 10, 10 10),
932
+ (11 11, 11 12, 12 12, 12 11, 11 11)
933
+ )',
934
+ 0
935
+ ]
936
+
937
+ tester[
938
+ 'LINEARRING (11 11, 11 12, 12 12, 12 11, 11 11)',
939
+ 'POLYGON (
940
+ (10 10, 10 14, 14 14, 14 10, 10 10),
941
+ (11 11, 11 12, 12 12, 12 11, 11 11),
942
+ (13 11, 13 12, 13.5 12, 13.5 11, 13 11)
943
+ )',
944
+ 0
945
+ ]
946
+
947
+ tester[
948
+ 'LINEARRING (13 11, 13 12, 13.5 12, 13.5 11, 13 11)',
949
+ 'POLYGON (
950
+ (10 10, 10 14, 14 14, 14 10, 10 10),
951
+ (11 11, 11 12, 12 12, 12 11, 11 11),
952
+ (13 11, 13 12, 13.5 12, 13.5 11, 13 11)
953
+ )',
954
+ 1
955
+ ]
956
+
957
+ assert_raise(RuntimeError) do
958
+ tester[
959
+ nil,
960
+ 'POLYGON ((0 0, 1 0, 1 1, 0 1, 0 0))',
961
+ 0
962
+ ]
963
+ end
964
+
965
+ assert_raise(NoMethodError) do
966
+ tester[
967
+ nil,
968
+ 'POINT (0 0)',
969
+ 0
970
+ ]
971
+ end
972
+ end
973
+
974
+ def test_exterior_ring
975
+ tester = lambda { |expected, g|
976
+ geom = read(g)
977
+ result = geom.exterior_ring
978
+
979
+ if expected.nil?
980
+ assert_nil(result)
981
+ else
982
+ assert(result.eql_exact?(read(expected), TOLERANCE))
983
+ end
984
+ }
985
+
986
+ tester[
987
+ 'LINEARRING (10 10, 10 14, 14 14, 14 10, 10 10)',
988
+ 'POLYGON (
989
+ (10 10, 10 14, 14 14, 14 10, 10 10),
990
+ (11 11, 11 12, 12 12, 12 11, 11 11)
991
+ )'
992
+ ]
993
+
994
+ assert_raise(NoMethodError) do
995
+ tester[
996
+ nil,
997
+ 'POINT (0 0)'
998
+ ]
999
+ end
1000
+ end
1001
+
1002
+ if ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:num_coordinates)
1003
+ def test_num_coordinates
1004
+ tester = lambda { |expected, g|
1005
+ geom = read(g)
1006
+ result = geom.num_coordinates
1007
+
1008
+ assert_equal(expected, result)
1009
+ }
1010
+
1011
+ tester[1, 'POINT(0 0)']
1012
+ tester[2, 'MULTIPOINT (0 1, 2 3)']
1013
+ tester[2, 'LINESTRING (0 0, 2 3)']
1014
+ tester[4, 'MULTILINESTRING ((0 1, 2 3), (10 10, 3 4))']
1015
+ tester[5, 'POLYGON ((0 0, 1 0, 1 1, 0 1, 0 0))']
1016
+ tester[15, 'MULTIPOLYGON (
1017
+ ((0 0, 1 0, 1 1, 0 1, 0 0)),
1018
+ ((10 10, 10 14, 14 14, 14 10, 10 10),
1019
+ (11 11, 11 12, 12 12, 12 11, 11 11))
1020
+ )']
1021
+ tester[29, 'GEOMETRYCOLLECTION (
1022
+ MULTIPOLYGON (
1023
+ ((0 0, 1 0, 1 1, 0 1, 0 0)),
1024
+ ((10 10, 10 14, 14 14, 14 10, 10 10),
1025
+ (11 11, 11 12, 12 12, 12 11, 11 11))
1026
+ ),
1027
+ POLYGON ((0 0, 1 0, 1 1, 0 1, 0 0)),
1028
+ MULTILINESTRING ((0 0, 2 3), (10 10, 3 4)),
1029
+ LINESTRING (0 0, 2 3),
1030
+ MULTIPOINT (0 0, 2 3),
1031
+ POINT (9 0)
1032
+ )']
1033
+ end
1034
+ end
1035
+
1036
+ def test_coord_seq
1037
+ tester = lambda { |expected, g|
1038
+ geom = read(g)
1039
+ cs = geom.coord_seq
1040
+ expected.each_with_index do |c, i|
1041
+ assert_equal(c[0], cs.get_x(i))
1042
+ assert_equal(c[1], cs.get_y(i))
1043
+ end
1044
+ }
1045
+
1046
+ tester[[[0, 0]], 'POINT(0 0)']
1047
+ tester[[[0, 0], [2, 3]], 'LINESTRING (0 0, 2 3)']
1048
+ tester[[[0, 0], [0, 5], [5, 5], [5, 0], [0, 0]], 'LINEARRING(0 0, 0 5, 5 5, 5 0, 0 0)']
1049
+ end
1050
+
1051
+ if ENV['FORCE_TESTS'] || Geos::LineString.method_defined?(:num_points)
1052
+ def test_num_points
1053
+ assert_equal(4, read('LINESTRING (0 0, 1 0, 1 1, 0 1)').num_points)
1054
+
1055
+ assert_raise(NoMethodError) do
1056
+ read('POINT (0 0)').num_points
1057
+ end
1058
+ end
1059
+ end
1060
+
1061
+ if ENV['FORCE_TESTS'] || Geos::Point.method_defined?(:get_x)
1062
+ def test_get_x_and_get_y
1063
+ geom = read('POINT (1 2)')
1064
+ assert_equal(1, geom.get_x)
1065
+ assert_equal(2, geom.get_y)
1066
+
1067
+ assert_equal(1, geom.x)
1068
+ assert_equal(2, geom.y)
1069
+
1070
+ assert_raise(NoMethodError) do
1071
+ read('LINESTRING (0 0, 1 1)').get_x
1072
+ end
1073
+ end
1074
+ end
1075
+
1076
+ def test_dimensions
1077
+ tester = lambda { |expected, g|
1078
+ geom = read(g)
1079
+ result = geom.dimensions
1080
+
1081
+ assert_equal(expected, result)
1082
+ }
1083
+
1084
+ types = {
1085
+ :dontcare => -3,
1086
+ :non_empty => -2,
1087
+ :empty => -1,
1088
+ :point => 0,
1089
+ :curve => 1,
1090
+ :surface => 2
1091
+ }
1092
+
1093
+ tester[types[:point], 'POINT(0 0)']
1094
+ tester[types[:point], 'MULTIPOINT (0 1, 2 3)']
1095
+ tester[types[:curve], 'LINESTRING (0 0, 2 3)']
1096
+ tester[types[:curve], 'MULTILINESTRING ((0 1, 2 3), (10 10, 3 4))']
1097
+ tester[types[:surface], 'POLYGON ((0 0, 1 0, 1 1, 0 1, 0 0))']
1098
+ tester[types[:surface], 'MULTIPOLYGON (
1099
+ ((0 0, 1 0, 1 1, 0 1, 0 0)),
1100
+ ((10 10, 10 14, 14 14, 14 10, 10 10),
1101
+ (11 11, 11 12, 12 12, 12 11, 11 11)))'
1102
+ ]
1103
+ tester[types[:surface], 'GEOMETRYCOLLECTION (
1104
+ MULTIPOLYGON (
1105
+ ((0 0, 1 0, 1 1, 0 1, 0 0)),
1106
+ ((10 10, 10 14, 14 14, 14 10, 10 10),
1107
+ (11 11, 11 12, 12 12, 12 11, 11 11))
1108
+ ),
1109
+ POLYGON ((0 0, 1 0, 1 1, 0 1, 0 0)),
1110
+ MULTILINESTRING ((0 0, 2 3), (10 10, 3 4)),
1111
+ LINESTRING (0 0, 2 3),
1112
+ MULTIPOINT (0 0, 2 3),
1113
+ POINT (9 0)
1114
+ )']
1115
+ end
1116
+
1117
+ if ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:project)
1118
+ def test_project_and_project_normalized
1119
+ geom_a = read('POINT(1 2)')
1120
+ geom_b = read('POINT(3 4)')
1121
+
1122
+ # The method only accept lineal geometries
1123
+ assert_raise(RuntimeError) do
1124
+ geom_a.project(geom_b)
1125
+ end
1126
+
1127
+ geom_a = read('LINESTRING(0 0, 10 0)')
1128
+ geom_b = read('POINT(0 0)')
1129
+ assert_equal(0, geom_a.project(geom_b))
1130
+ assert_equal(0, geom_a.project(geom_b, true))
1131
+
1132
+ geom_b = read('POINT(10 0)')
1133
+ assert_equal(10, geom_a.project(geom_b))
1134
+ assert_equal(1, geom_a.project(geom_b, true))
1135
+
1136
+ geom_b = read('POINT(5 0)')
1137
+ assert_equal(5, geom_a.project(geom_b))
1138
+ assert_equal(0.5, geom_a.project(geom_b, true))
1139
+
1140
+ geom_a = read('MULTILINESTRING((0 0, 10 0),(20 10, 20 20))')
1141
+ geom_b = read('POINT(20 0)')
1142
+ assert_equal(10, geom_a.project(geom_b))
1143
+ assert_equal(0.5, geom_a.project(geom_b, true))
1144
+
1145
+ geom_b = read('POINT(20 5)')
1146
+ assert_equal(10, geom_a.project(geom_b))
1147
+ assert_equal(0.5, geom_a.project(geom_b, true))
1148
+ end
1149
+ end
1150
+
1151
+ if ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:interpolate)
1152
+ def test_interpolate
1153
+ tester = lambda { |expected, g, d, normalize|
1154
+ geom = read(g)
1155
+ assert_equal(expected, write(geom.interpolate(d, normalize)))
1156
+ }
1157
+
1158
+ writer.trim = true
1159
+
1160
+ tester['POINT (0 0)', 'LINESTRING(0 0, 10 0)', 0, false]
1161
+ tester['POINT (0 0)', 'LINESTRING(0 0, 10 0)', 0, true]
1162
+
1163
+ tester['POINT (5 0)', 'LINESTRING(0 0, 10 0)', 5, false]
1164
+ tester['POINT (5 0)', 'LINESTRING(0 0, 10 0)', 0.5, true]
1165
+
1166
+ tester['POINT (10 0)', 'LINESTRING(0 0, 10 0)', 20, false]
1167
+ tester['POINT (10 0)', 'LINESTRING(0 0, 10 0)', 2, true]
1168
+
1169
+ assert_raise(RuntimeError) do
1170
+ read('POINT(1 2)').interpolate(0)
1171
+ end
1172
+ end
1173
+ end
1174
+
1175
+ if ENV['FORCE_TESTS'] || Geos::LineString.method_defined?(:point_n)
1176
+ def test_point_n
1177
+ writer.rounding_precision = 0
1178
+
1179
+ tester = lambda { |expected, geom, n|
1180
+ assert_equal(expected, write(geom.point_n(n)))
1181
+ }
1182
+
1183
+ geom = read('LINESTRING (10 10, 10 14, 14 14, 14 10)')
1184
+ tester['POINT (10 10)', geom, 0]
1185
+ tester['POINT (10 14)', geom, 1]
1186
+ tester['POINT (14 14)', geom, 2]
1187
+ tester['POINT (14 10)', geom, 3]
1188
+
1189
+ assert_raise(RuntimeError) do
1190
+ tester['POINT (0 0)', geom, 4]
1191
+ end
1192
+
1193
+ geom = read('LINEARRING (11 11, 11 12, 12 11, 11 11)')
1194
+ tester['POINT (11 11)', geom, 0]
1195
+ tester['POINT (11 12)', geom, 1]
1196
+ tester['POINT (12 11)', geom, 2]
1197
+ tester['POINT (11 11)', geom, 3]
1198
+
1199
+ assert_raise(NoMethodError) do
1200
+ tester[nil, read('POINT (0 0)'), 0]
1201
+ end
1202
+ end
1203
+ end
1204
+
1205
+ if ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:start_point)
1206
+ def test_start_and_end_points
1207
+ writer.rounding_precision = 0
1208
+
1209
+ tester = lambda { |expected, method, geom|
1210
+ assert_equal(expected, write(geom.send(method)))
1211
+ }
1212
+
1213
+ geom = read('LINESTRING (10 10, 10 14, 14 14, 14 10)')
1214
+ tester['POINT (10 10)', :start_point, geom]
1215
+ tester['POINT (14 10)', :end_point, geom]
1216
+
1217
+ geom = read('LINEARRING (11 11, 11 12, 12 11, 11 11)')
1218
+ tester['POINT (11 11)', :start_point, geom]
1219
+ tester['POINT (11 11)', :end_point, geom]
1220
+ end
1221
+ end
1222
+
1223
+ def test_area
1224
+ tester = lambda { |expected, g|
1225
+ assert_in_delta(expected, read(g).area, TOLERANCE)
1226
+ }
1227
+
1228
+ tester[1.0, 'POLYGON ((0 0, 1 0, 1 1, 0 1, 0 0))']
1229
+ tester[0.0, 'POINT (0 0)']
1230
+ tester[0.0, 'LINESTRING (0 0 , 10 0)']
1231
+ end
1232
+
1233
+ def test_length
1234
+ tester = lambda { |expected, g|
1235
+ assert_in_delta(expected, read(g).length, TOLERANCE)
1236
+ }
1237
+
1238
+ tester[4.0, 'POLYGON ((0 0, 1 0, 1 1, 0 1, 0 0))']
1239
+ tester[0.0, 'POINT (0 0)']
1240
+ tester[10.0, 'LINESTRING (0 0 , 10 0)']
1241
+ end
1242
+
1243
+ def test_distance
1244
+ tester = lambda { |expected, g1, g2|
1245
+ geom_1 = read(g1)
1246
+ geom_2 = read(g2)
1247
+ assert_in_delta(expected, geom_1.distance(geom_2), TOLERANCE)
1248
+ }
1249
+
1250
+ g = 'POLYGON ((0 0, 1 0, 1 1, 0 1, 0 0))'
1251
+ tester[0.0, g, 'POINT(0.5 0.5)']
1252
+ tester[1.0, g, 'POINT (-1 0)']
1253
+ tester[2.0, g, 'LINESTRING (3 0 , 10 0)']
1254
+ end
1255
+
1256
+ if ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:hausdorff_distance)
1257
+ def test_hausdorff_distance
1258
+ tester = lambda { |expected, g1, g2|
1259
+ geom_1 = read(g1)
1260
+ geom_2 = read(g2)
1261
+ assert_in_delta(expected, geom_1.hausdorff_distance(geom_2), TOLERANCE)
1262
+ }
1263
+
1264
+ geom_a = 'POLYGON ((0 0, 1 0, 1 1, 0 1, 0 0))'
1265
+
1266
+ tester[10.0498756211209, geom_a, 'POINT(0 10)']
1267
+ tester[2.23606797749979, geom_a, 'POINT(-1 0)']
1268
+ tester[9.0, geom_a, 'LINESTRING (3 0 , 10 0)']
1269
+ end
1270
+ end
1271
+
1272
+ if ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:snap)
1273
+ def test_snap
1274
+ tester = lambda { |expected, g1, g2, tolerance|
1275
+ geom_a = read(g1)
1276
+ geom_b = read(g2)
1277
+ assert(read(expected).eql_exact?(geom_a.snap(geom_b, tolerance), TOLERANCE))
1278
+ }
1279
+
1280
+ writer.trim = true
1281
+
1282
+ geom = 'POLYGON ((0 0, 1 0, 1 1, 0 1, 0 0))'
1283
+ tester['POLYGON ((0 0, 1 0, 1 1, 0 1, 0 0))', geom, 'POINT(0.1 0)', 0]
1284
+ tester['POLYGON ((0.1 0, 1 0, 1 1, 0 1, 0.1 0))', geom, 'POINT(0.1 0)', 0.5]
1285
+ end
1286
+ end
1287
+
1288
+ if ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:polygonize)
1289
+ def test_polygonize
1290
+ writer.rounding_precision = 0
1291
+
1292
+ geom_a = read(
1293
+ 'GEOMETRYCOLLECTION(
1294
+ LINESTRING(0 0, 10 10),
1295
+ LINESTRING(185 221, 100 100),
1296
+ LINESTRING(185 221, 88 275, 180 316),
1297
+ LINESTRING(185 221, 292 281, 180 316),
1298
+ LINESTRING(189 98, 83 187, 185 221),
1299
+ LINESTRING(189 98, 325 168, 185 221)
1300
+ )'
1301
+ )
1302
+
1303
+ polygonized = geom_a.polygonize
1304
+ assert_equal(2, polygonized.length)
1305
+ assert_equal(
1306
+ 'POLYGON ((185 221, 88 275, 180 316, 292 281, 185 221))',
1307
+ write(polygonized[0])
1308
+ )
1309
+ assert_equal(
1310
+ 'POLYGON ((189 98, 83 187, 185 221, 325 168, 189 98))',
1311
+ write(polygonized[1])
1312
+ )
1313
+ end
1314
+ end
1315
+
1316
+ if ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:polygonize_cut_edges)
1317
+ def test_polygonize_cut_edges
1318
+ writer.rounding_precision = 0
1319
+
1320
+ geom_a = read(
1321
+ 'GEOMETRYCOLLECTION(
1322
+ LINESTRING(0 0, 10 10),
1323
+ LINESTRING(185 221, 100 100),
1324
+ LINESTRING(185 221, 88 275, 180 316),
1325
+ LINESTRING(185 221, 292 281, 180 316),
1326
+ LINESTRING(189 98, 83 187, 185 221),
1327
+ LINESTRING(189 98, 325 168, 185 221)
1328
+ )'
1329
+ )
1330
+
1331
+ cut_edges = geom_a.polygonize_cut_edges
1332
+ assert_equal(0, cut_edges.length)
1333
+ end
1334
+ end
1335
+
1336
+ if ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:polygonize_full)
1337
+ def test_polygonize_full
1338
+ writer.rounding_precision = 0
1339
+
1340
+ geom_a = read(
1341
+ 'GEOMETRYCOLLECTION(
1342
+ LINESTRING(0 0, 10 10),
1343
+ LINESTRING(185 221, 100 100),
1344
+ LINESTRING(185 221, 88 275, 180 316),
1345
+ LINESTRING(185 221, 292 281, 180 316),
1346
+ LINESTRING(189 98, 83 187, 185 221),
1347
+ LINESTRING(189 98, 325 168, 185 221)
1348
+ )')
1349
+
1350
+ polygonized = geom_a.polygonize_full
1351
+
1352
+ assert(polygonized[:rings].is_a?(Array))
1353
+ assert(polygonized[:cuts].is_a?(Array))
1354
+ assert(polygonized[:dangles].is_a?(Array))
1355
+ assert(polygonized[:invalid_rings].is_a?(Array))
1356
+
1357
+ assert_equal(2, polygonized[:rings].length)
1358
+ assert_equal(0, polygonized[:cuts].length)
1359
+ assert_equal(2, polygonized[:dangles].length)
1360
+ assert_equal(0, polygonized[:invalid_rings].length)
1361
+
1362
+ assert_equal(
1363
+ 'POLYGON ((185 221, 88 275, 180 316, 292 281, 185 221))',
1364
+ write(polygonized[:rings][0])
1365
+ )
1366
+
1367
+ assert_equal(
1368
+ 'POLYGON ((189 98, 83 187, 185 221, 325 168, 189 98))',
1369
+ write(polygonized[:rings][1])
1370
+ )
1371
+
1372
+ assert_equal(
1373
+ 'LINESTRING (185 221, 100 100)',
1374
+ write(polygonized[:dangles][0])
1375
+ )
1376
+
1377
+ assert_equal(
1378
+ 'LINESTRING (0 0, 10 10)',
1379
+ write(polygonized[:dangles][1])
1380
+ )
1381
+
1382
+ geom_b = geom_a.union(read('POINT(0 0)'))
1383
+ polygonized = geom_b.polygonize_full
1384
+
1385
+ assert_equal(2, polygonized[:dangles].length)
1386
+ assert_equal(0, polygonized[:invalid_rings].length)
1387
+
1388
+ assert_equal(
1389
+ 'LINESTRING (132 146, 100 100)',
1390
+ write(polygonized[:dangles][0])
1391
+ )
1392
+
1393
+ assert_equal(
1394
+ 'LINESTRING (0 0, 10 10)',
1395
+ write(polygonized[:dangles][1])
1396
+ )
1397
+ end
1398
+
1399
+ def test_polygonize_with_bad_arguments
1400
+ assert_raise(ArgumentError) do
1401
+ geom = read('POINT(0 0)')
1402
+
1403
+ geom.polygonize(geom, 'gibberish')
1404
+ end
1405
+ end
1406
+ end
1407
+
1408
+ if ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:shared_paths)
1409
+ def test_shared_paths
1410
+ writer.rounding_precision = 0
1411
+
1412
+ geom_a = read('LINESTRING(0 0, 50 0)')
1413
+ geom_b = read('MULTILINESTRING((5 0, 15 0),(40 0, 30 0))')
1414
+
1415
+ paths = geom_a.shared_paths(geom_b)
1416
+ assert_equal(2, paths.length)
1417
+ assert_equal(
1418
+ 'MULTILINESTRING ((5 0, 15 0))',
1419
+ write(paths[0])
1420
+ )
1421
+ assert_equal(
1422
+ 'MULTILINESTRING ((30 0, 40 0))',
1423
+ write(paths[1])
1424
+ )
1425
+ end
1426
+ end
1427
+
1428
+ if ENV['FORCE_TESTS'] || Geos::LineString.method_defined?(:select)
1429
+ def test_line_string_enumerable
1430
+ @writer.trim = true
1431
+ geom = read('LINESTRING(0 0, 1 1, 2 2, 3 3, 10 0, 2 2)')
1432
+
1433
+ assert_equal(2, geom.select { |point| point == read('POINT(2 2)') }.length)
1434
+ end
1435
+ end
1436
+
1437
+ if ENV['FORCE_TESTS'] || Geos::GeometryCollection.method_defined?(:detect)
1438
+ def test_geometry_collection_enumerable
1439
+ @writer.trim = true
1440
+ geom = read('GEOMETRYCOLLECTION(
1441
+ LINESTRING(0 0, 1 1, 2 2, 3 3, 10 0, 2 2),
1442
+ POINT(10 20),
1443
+ POLYGON((0 0, 0 5, 5 5, 5 0, 0 0)),
1444
+ POINT(10 20)
1445
+ )')
1446
+
1447
+ assert_equal(2, geom.select { |point| point == read('POINT(10 20)') }.length)
1448
+ end
1449
+ end
1450
+
1451
+ if ENV['FORCE_TESTS'] || Geos::LineString.method_defined?(:[])
1452
+ def test_line_string_array
1453
+ @writer.trim = true
1454
+ geom = read('LINESTRING(0 0, 1 1, 2 2, 3 3, 4 4)')
1455
+
1456
+ assert_equal('POINT (0 0)', write(geom[0]))
1457
+ assert_equal('POINT (4 4)', write(geom[-1]))
1458
+
1459
+ assert_equal([
1460
+ 'POINT (0 0)',
1461
+ 'POINT (1 1)'
1462
+ ], geom[0, 2].collect { |g| write(g) })
1463
+
1464
+ assert_equal(nil, geom[0, -1])
1465
+ assert_equal([], geom[-1, 0])
1466
+ assert_equal([
1467
+ 'POINT (1 1)',
1468
+ 'POINT (2 2)'
1469
+ ], geom[1..2].collect { |g| write(g) })
1470
+ end
1471
+ end
1472
+
1473
+ if ENV['FORCE_TESTS'] || Geos::GeometryCollection.method_defined?(:[])
1474
+ def test_geometry_collection_array
1475
+ @writer.trim = true
1476
+ geom = read('GEOMETRYCOLLECTION(
1477
+ LINESTRING(0 0, 1 1, 2 2, 3 3),
1478
+ POINT(10 20),
1479
+ POLYGON((0 0, 0 5, 5 5, 5 0, 0 0)),
1480
+ POINT(10 20)
1481
+ )')
1482
+
1483
+ assert_equal('LINESTRING (0 0, 1 1, 2 2, 3 3)', write(geom[0]))
1484
+ assert_equal('POINT (10 20)', write(geom[-1]))
1485
+
1486
+ assert_equal([
1487
+ 'LINESTRING (0 0, 1 1, 2 2, 3 3)',
1488
+ 'POINT (10 20)'
1489
+ ], geom[0, 2].collect { |g| write(g) })
1490
+
1491
+ assert_equal(nil, geom[0, -1])
1492
+ assert_equal([], geom[-1, 0])
1493
+ assert_equal([
1494
+ 'POINT (10 20)',
1495
+ 'POLYGON ((0 0, 0 5, 5 5, 5 0, 0 0))'
1496
+ ], geom[1..2].collect { |g| write(g) })
1497
+ end
1498
+ end
1499
+ end