ffi-geos 0.0.1.beta1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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