ffi-geos 0.0.1.beta1 → 0.0.1.beta2

Sign up to get free protection for your applications and to get access to all the features.
data/lib/geometry.rb CHANGED
@@ -71,60 +71,27 @@ module Geos
71
71
  # :call-seq:
72
72
  # buffer(width)
73
73
  # buffer(width, options)
74
+ # buffer(width, buffer_params)
74
75
  # buffer(width, quad_segs)
75
76
  #
76
- # Calls buffer on the Geometry. Calling with an options Hash is equivalent
77
- # to calling buffer_with_style.
78
- #
79
- # By default, quad_segs is set to 8.
80
- def buffer(width, *args)
81
- quad_segs, options = if args.length <= 0
82
- [ 8, nil ]
83
- else
84
- if args.first.is_a?(Hash)
85
- [ args.first[:quad_segs] || 8, args.first ]
86
- else
87
- [ args.first, args[1] ]
88
- end
89
- end
90
-
91
- if options
92
- if options.is_a?(Hash)
93
- self.buffer_with_style(width, options)
77
+ # Calls buffer on the Geometry. Options can be passed as either a
78
+ # BufferParams object, as an equivalent Hash or as a quad_segs value. By
79
+ # default, the default values found in Geos::Constants::BUFFER_PARAMS_DEFAULTS
80
+ # are used.
81
+ def buffer(width, options = nil)
82
+ options ||= {}
83
+ params = case options
84
+ when Hash
85
+ Geos::BufferParams.new(options)
86
+ when Geos::BufferParams
87
+ options
88
+ when Numeric
89
+ Geos::BufferParams.new(:quad_segs => options)
94
90
  else
95
- raise RuntimeError.new("Expected an options Hash")
96
- end
97
- else
98
- cast_geometry_ptr(FFIGeos.GEOSBuffer_r(Geos.current_handle, self.ptr, width, quad_segs))
91
+ raise ArgumentError.new("Expected Geos::BufferParams, a Hash or a Numeric")
99
92
  end
100
- end
101
93
 
102
- # Options:
103
- #
104
- # * :quad_segs - defaults to 8.
105
- # * :endcap - defaults :round.
106
- # * :join - defaults to :round.
107
- # * :mitre_limit - defaults to 5.0.
108
- def buffer_with_style(width, options = {})
109
- options = {
110
- :quad_segs => 8,
111
- :endcap => :round,
112
- :join => :round,
113
- :mitre_limit => 5.0
114
- }.merge(options)
115
-
116
- check_enum_value(Geos::BufferCapStyles, options[:endcap]) if options[:endcap]
117
- check_enum_value(Geos::BufferJoinStyles, options[:join]) if options[:join]
118
-
119
- cast_geometry_ptr(FFIGeos.GEOSBufferWithStyle_r(
120
- Geos.current_handle,
121
- self.ptr,
122
- width,
123
- options[:quad_segs],
124
- options[:endcap],
125
- options[:join],
126
- options[:mitre_limit]
127
- ))
94
+ cast_geometry_ptr(FFIGeos.GEOSBufferWithParams_r(Geos.current_handle, self.ptr, params.ptr, width))
128
95
  end
129
96
 
130
97
  def convex_hull
@@ -426,10 +393,14 @@ module Geos
426
393
  }.read_double
427
394
  end
428
395
 
429
- def hausdorff_distance(geom)
396
+ def hausdorff_distance(geom, densify_frac = nil)
430
397
  check_geometry(geom)
431
398
  FFI::MemoryPointer.new(:double).tap { |ret|
432
- FFIGeos.GEOSHausdorffDistance_r(Geos.current_handle, self.ptr, geom.ptr, ret)
399
+ if densify_frac
400
+ FFIGeos.GEOSHausdorffDistanceDensify_r(Geos.current_handle, self.ptr, geom.ptr, densify_frac, ret)
401
+ else
402
+ FFIGeos.GEOSHausdorffDistance_r(Geos.current_handle, self.ptr, geom.ptr, ret)
403
+ end
433
404
  }.read_double
434
405
  end
435
406
 
data/lib/line_string.rb CHANGED
@@ -33,22 +33,16 @@ module Geos
33
33
  end
34
34
  alias :slice :[]
35
35
 
36
- def buffer_single_sided(width, options = {})
37
- options = {
38
- :quad_segs => 8,
39
- :join => :round,
40
- :mitre_limit => 5.0,
41
- :left_side => false
42
- }.merge(options)
43
-
44
- cast_geometry_ptr(FFIGeos.GEOSSingleSidedBuffer_r(
36
+ def offset_curve(width, options = {})
37
+ options = Constants::BUFFER_PARAM_DEFAULTS.merge(options)
38
+
39
+ cast_geometry_ptr(FFIGeos.GEOSOffsetCurve_r(
45
40
  Geos.current_handle,
46
41
  self.ptr,
47
42
  width,
48
43
  options[:quad_segs],
49
44
  options[:join],
50
- options[:mitre_limit],
51
- options[:left_side] ? 1 : 0
45
+ options[:mitre_limit]
52
46
  ))
53
47
  end
54
48
 
@@ -29,14 +29,44 @@ module Geos
29
29
  bool_result(FFIGeos.GEOSPreparedContainsProperly_r(Geos.current_handle, self.ptr, geom.ptr))
30
30
  end
31
31
 
32
+ def covered_by?(geom)
33
+ check_geometry(geom)
34
+ bool_result(FFIGeos.GEOSPreparedCoveredBy_r(Geos.current_handle, self.ptr, geom.ptr))
35
+ end
36
+
32
37
  def covers?(geom)
33
38
  check_geometry(geom)
34
39
  bool_result(FFIGeos.GEOSPreparedCovers_r(Geos.current_handle, self.ptr, geom.ptr))
35
40
  end
36
41
 
42
+ def crosses?(geom)
43
+ check_geometry(geom)
44
+ bool_result(FFIGeos.GEOSPreparedCrosses_r(Geos.current_handle, self.ptr, geom.ptr))
45
+ end
46
+
47
+ def disjoint?(geom)
48
+ check_geometry(geom)
49
+ bool_result(FFIGeos.GEOSPreparedDisjoint_r(Geos.current_handle, self.ptr, geom.ptr))
50
+ end
51
+
37
52
  def intersects?(geom)
38
53
  check_geometry(geom)
39
54
  bool_result(FFIGeos.GEOSPreparedIntersects_r(Geos.current_handle, self.ptr, geom.ptr))
40
55
  end
56
+
57
+ def overlaps?(geom)
58
+ check_geometry(geom)
59
+ bool_result(FFIGeos.GEOSPreparedOverlaps_r(Geos.current_handle, self.ptr, geom.ptr))
60
+ end
61
+
62
+ def touches?(geom)
63
+ check_geometry(geom)
64
+ bool_result(FFIGeos.GEOSPreparedTouches_r(Geos.current_handle, self.ptr, geom.ptr))
65
+ end
66
+
67
+ def within?(geom)
68
+ check_geometry(geom)
69
+ bool_result(FFIGeos.GEOSPreparedWithin_r(Geos.current_handle, self.ptr, geom.ptr))
70
+ end
41
71
  end
42
72
  end
data/lib/tools.rb CHANGED
@@ -50,5 +50,13 @@ module Geos
50
50
  def check_enum_value(enum, value)
51
51
  raise TypeError.new("Couldn't find valid #{enum.tag} value: #{value}") unless enum[value]
52
52
  end
53
+
54
+ def symbol_for_enum(enum, value)
55
+ if value.is_a?(Symbol)
56
+ value
57
+ else
58
+ enum[value]
59
+ end
60
+ end
53
61
  end
54
62
  end
data/lib/utils.rb CHANGED
@@ -3,9 +3,14 @@ module Geos
3
3
  module Utils
4
4
  class << self
5
5
  include Geos::Tools
6
+ include Geos::GeomTypes
6
7
 
7
8
  if FFIGeos.respond_to?(:GEOSOrientationIndex_r)
8
- # Available in GEOS 3.3+.
9
+ # * -1 if reaching P takes a counter-clockwise (left) turn
10
+ # * 1 if reaching P takes a clockwise (right) turn
11
+ # * 0 if P is collinear with A-B
12
+ #
13
+ # Available in GEOS 3.3.0+.
9
14
  def orientation_index(ax, ay, bx, by, px, py)
10
15
  FFIGeos.GEOSOrientationIndex_r(
11
16
  Geos.current_handle,
@@ -15,7 +20,7 @@ module Geos
15
20
  end
16
21
 
17
22
  if FFIGeos.respond_to?(:GEOSRelatePatternMatch_r)
18
- # Available in GEOS 3.3+.
23
+ # Available in GEOS 3.3.0+.
19
24
  def relate_match(mat, pat)
20
25
  bool_result(FFIGeos.GEOSRelatePatternMatch_r(Geos.current_handle, mat, pat))
21
26
  end
@@ -80,34 +85,37 @@ module Geos
80
85
  end
81
86
 
82
87
  def create_empty_collection(t)
88
+ check_enum_value(Geos::GeometryTypes, t)
83
89
  cast_geometry_ptr(FFIGeos.GEOSGeom_createEmptyCollection_r(Geos.current_handle, t))
84
90
  end
85
91
 
86
92
  def create_empty_multi_point
87
- create_empty_collection(Geos::GeomTypes::GEOS_MULTIPOINT)
93
+ create_empty_collection(:multi_point)
88
94
  end
89
95
 
90
96
  def create_empty_multi_line_string
91
- create_empty_collection(Geos::GeomTypes::GEOS_MULTILINESTRING)
97
+ create_empty_collection(:multi_line_string)
92
98
  end
93
99
 
94
100
  def create_empty_multi_polygon
95
- create_empty_collection(Geos::GeomTypes::GEOS_MULTIPOLYGON)
101
+ create_empty_collection(:multi_polygon)
96
102
  end
97
103
 
98
104
  def create_empty_geometry_collection
99
- create_empty_collection(Geos::GeomTypes::GEOS_GEOMETRYCOLLECTION)
105
+ create_empty_collection(:geometry_collection)
100
106
  end
101
107
 
102
108
  def create_collection(t, *geoms)
109
+ check_enum_value(Geos::GeometryTypes, t)
110
+
103
111
  klass = case t
104
- when Geos::GeomTypes::GEOS_MULTIPOINT
112
+ when GEOS_MULTIPOINT, :multi_point
105
113
  Geos::Point
106
- when Geos::GeomTypes::GEOS_MULTILINESTRING
114
+ when GEOS_MULTILINESTRING, :multi_line_string
107
115
  Geos::LineString
108
- when Geos::GeomTypes::GEOS_MULTIPOLYGON
116
+ when GEOS_MULTIPOLYGON, :multi_polygon
109
117
  Geos::Polygon
110
- when Geos::GeomTypes::GEOS_GEOMETRYCOLLECTION
118
+ when GEOS_GEOMETRYCOLLECTION, :geometry_collection
111
119
  Geos::Geometry
112
120
  end
113
121
 
@@ -126,19 +134,19 @@ module Geos
126
134
  end
127
135
 
128
136
  def create_multi_point(*geoms)
129
- create_collection(Geos::GeomTypes::GEOS_MULTIPOINT, *geoms)
137
+ create_collection(:multi_point, *geoms)
130
138
  end
131
139
 
132
140
  def create_multi_line_string(*geoms)
133
- create_collection(Geos::GeomTypes::GEOS_MULTILINESTRING, *geoms)
141
+ create_collection(:multi_line_string, *geoms)
134
142
  end
135
143
 
136
144
  def create_multi_polygon(*geoms)
137
- create_collection(Geos::GeomTypes::GEOS_MULTIPOLYGON, *geoms)
145
+ create_collection(:multi_polygon, *geoms)
138
146
  end
139
147
 
140
148
  def create_geometry_collection(*geoms)
141
- create_collection(Geos::GeomTypes::GEOS_GEOMETRYCOLLECTION, *geoms)
149
+ create_collection(:geometry_collection, *geoms)
142
150
  end
143
151
  end
144
152
  end
@@ -33,142 +33,148 @@ class GeometryTests < Test::Unit::TestCase
33
33
  end
34
34
 
35
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
36
+ tester = lambda { |expected, geom, *args|
37
+ width, params = args
38
+ assert_equal(expected, write(read(geom).buffer(width, params)))
39
+ }
65
40
 
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)
41
+ @writer.rounding_precision = 0
71
42
 
72
- assert_equal(expected, write(buffered))
73
- }
43
+ tester['POLYGON EMPTY', 'POINT(0 0)', 0]
74
44
 
75
- @writer.rounding_precision = 0
45
+ tester[
46
+ 'POLYGON ((10 0, 10 -2, 9 -4, 8 -6, 7 -7, 6 -8, 4 -9, 2 -10, 0 -10, -2 -10, -4 -9, -6 -8, -7 -7, -8 -6, -9 -4, -10 -2, -10 -0, -10 2, -9 4, -8 6, -7 7, -6 8, -4 9, -2 10, -0 10, 2 10, 4 9, 6 8, 7 7, 8 6, 9 4, 10 2, 10 0))',
47
+ 'POINT(0 0)',
48
+ 10
49
+ ]
76
50
 
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
- ]
51
+ # One segment per quadrant
52
+ tester[
53
+ 'POLYGON ((10 0, 0 -10, -10 -0, -0 10, 10 0))',
54
+ 'POINT(0 0)',
55
+ 10,
56
+ { :quad_segs => 1 }
57
+ ]
85
58
 
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
- ]
59
+ # End cap styles
60
+ tester[
61
+ 'POLYGON ((100 10, 110 0, 100 -10, 0 -10, -10 0, 0 10, 100 10))',
62
+ 'LINESTRING(0 0, 100 0)',
63
+ 10,
64
+ { :quad_segs => 1, :endcap => :round }
65
+ ]
94
66
 
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
- ]
67
+ tester[
68
+ 'POLYGON ((100 10, 100 -10, 0 -10, 0 10, 100 10))',
69
+ 'LINESTRING(0 0, 100 0)',
70
+ 10,
71
+ { :quad_segs => 1, :endcap => :flat }
72
+ ]
103
73
 
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
- ]
74
+ tester[
75
+ 'POLYGON ((100 10, 110 10, 110 -10, 0 -10, -10 -10, -10 10, 100 10))',
76
+ 'LINESTRING(0 0, 100 0)',
77
+ 10,
78
+ { :quad_segs => 1, :endcap => :square }
79
+ ]
112
80
 
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
- ]
81
+ # Join styles
82
+ tester[
83
+ '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))',
84
+ 'LINESTRING(0 0, 100 0, 100 100)',
85
+ 10,
86
+ { :quad_segs => 2, :join => :round }
87
+ ]
121
88
 
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
- ]
89
+ tester[
90
+ '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))',
91
+ 'LINESTRING(0 0, 100 0, 100 100)',
92
+ 10,
93
+ { :quad_segs => 2, :join => :bevel }
94
+ ]
130
95
 
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
96
+ tester[
97
+ '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))',
98
+ 'LINESTRING(0 0, 100 0, 100 100)',
99
+ 10,
100
+ { :quad_segs => 2, :join => :mitre }
101
+ ]
102
+
103
+ tester[
104
+ '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))',
105
+ 'LINESTRING(0 0, 100 0, 100 100)',
106
+ 10,
107
+ { :quad_segs => 2, :join => :mitre, :mitre_limit => 1.0 }
108
+ ]
109
+
110
+ # Single-sided buffering
111
+ tester[
112
+ 'POLYGON ((100 0, 0 0, 0 10, 100 10, 100 0))',
113
+ 'LINESTRING(0 0, 100 0)',
114
+ 10,
115
+ { :single_sided => true }
116
+ ]
117
+
118
+ tester[
119
+ 'POLYGON ((0 0, 100 0, 100 -10, 0 -10, 0 0))',
120
+ 'LINESTRING(0 0, 100 0)',
121
+ -10,
122
+ { :single_sided => true }
123
+ ]
141
124
  end
142
125
 
143
- if ENV['FORCE_TESTS'] || Geos::LineString.method_defined?(:buffer_single_sided)
144
- def test_buffer_single_sided
126
+ if ENV['FORCE_TESTS'] || Geos::LineString.method_defined?(:offset_curve)
127
+ def test_offset_curve
145
128
  tester = lambda { |expected, g, width, style|
146
129
  geom = read(g)
147
- buffered = geom.buffer_single_sided(width, style)
130
+ buffered = geom.offset_curve(width, style)
148
131
 
149
132
  assert_equal(expected, write(buffered))
150
133
  }
151
134
 
152
135
  @writer.rounding_precision = 0
153
136
 
137
+ # straight left
154
138
  tester[
155
139
  'LINESTRING (0 2, 10 2)',
156
- 'LINESTRING(0 0, 10 0)',
140
+ 'LINESTRING (0 0, 10 0)',
157
141
  2, {
158
- :quad_segs => 2,
142
+ :quad_segs => 0,
159
143
  :join => :round,
160
- :mitre_limit => 2.0,
161
- :left_side => true
144
+ :mitre_limit => 2
162
145
  }
163
146
  ]
164
147
 
148
+ # straight right
165
149
  tester[
166
150
  'LINESTRING (10 -2, 0 -2)',
167
- 'LINESTRING(0 0, 10 0)',
151
+ 'LINESTRING (0 0, 10 0)',
152
+ -2, {
153
+ :quad_segs => 0,
154
+ :join => :round,
155
+ :mitre_limit => 2
156
+ }
157
+ ]
158
+
159
+ # outside curve
160
+ tester[
161
+ 'LINESTRING (12 10, 12 0, 10 -2, 0 -2)',
162
+ 'LINESTRING (0 0, 10 0, 10 10)',
163
+ -2, {
164
+ :quad_segs => 1,
165
+ :join => :round,
166
+ :mitre_limit => 2
167
+ }
168
+ ]
169
+
170
+ # inside curve
171
+ tester[
172
+ 'LINESTRING (0 2, 8 2, 8 10)',
173
+ 'LINESTRING (0 0, 10 0, 10 10)',
168
174
  2, {
169
- :quad_segs => 2,
175
+ :quad_segs => 1,
170
176
  :join => :round,
171
- :mitre_limit => 2.0
177
+ :mitre_limit => 2
172
178
  }
173
179
  ]
174
180
  end
@@ -1267,6 +1273,20 @@ class GeometryTests < Test::Unit::TestCase
1267
1273
  tester[2.23606797749979, geom_a, 'POINT(-1 0)']
1268
1274
  tester[9.0, geom_a, 'LINESTRING (3 0 , 10 0)']
1269
1275
  end
1276
+
1277
+ def test_hausdorff_distance_with_densify_fract
1278
+ tester = lambda { |expected, g1, g2|
1279
+ geom_1 = read(g1)
1280
+ geom_2 = read(g2)
1281
+ assert_in_delta(expected, geom_1.hausdorff_distance(geom_2, 0.001), TOLERANCE)
1282
+ }
1283
+
1284
+ geom_a = 'POLYGON ((0 0, 1 0, 1 1, 0 1, 0 0))'
1285
+
1286
+ tester[10.0498756211209, geom_a, 'POINT(0 10)']
1287
+ tester[2.23606797749979, geom_a, 'POINT(-1 0)']
1288
+ tester[9.0, geom_a, 'LINESTRING (3 0 , 10 0)']
1289
+ end
1270
1290
  end
1271
1291
 
1272
1292
  if ENV['FORCE_TESTS'] || Geos::Geometry.method_defined?(:snap)