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/README.rdoc +7 -5
- data/VERSION +1 -1
- data/ffi-geos.gemspec +85 -0
- data/lib/buffer_params.rb +81 -0
- data/lib/ffi-geos.rb +273 -20
- data/lib/geometry.rb +22 -51
- data/lib/line_string.rb +5 -11
- data/lib/prepared_geometry.rb +30 -0
- data/lib/tools.rb +8 -0
- data/lib/utils.rb +22 -14
- data/test/geometry_tests.rb +125 -105
- data/test/prepared_geometry_tests.rb +56 -10
- data/test/utils_tests.rb +16 -11
- metadata +6 -4
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.
|
77
|
-
#
|
78
|
-
#
|
79
|
-
#
|
80
|
-
def buffer(width,
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
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
|
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
|
-
|
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
|
-
|
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
|
37
|
-
options =
|
38
|
-
|
39
|
-
|
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
|
|
data/lib/prepared_geometry.rb
CHANGED
@@ -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
|
-
#
|
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(
|
93
|
+
create_empty_collection(:multi_point)
|
88
94
|
end
|
89
95
|
|
90
96
|
def create_empty_multi_line_string
|
91
|
-
create_empty_collection(
|
97
|
+
create_empty_collection(:multi_line_string)
|
92
98
|
end
|
93
99
|
|
94
100
|
def create_empty_multi_polygon
|
95
|
-
create_empty_collection(
|
101
|
+
create_empty_collection(:multi_polygon)
|
96
102
|
end
|
97
103
|
|
98
104
|
def create_empty_geometry_collection
|
99
|
-
create_empty_collection(
|
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
|
112
|
+
when GEOS_MULTIPOINT, :multi_point
|
105
113
|
Geos::Point
|
106
|
-
when
|
114
|
+
when GEOS_MULTILINESTRING, :multi_line_string
|
107
115
|
Geos::LineString
|
108
|
-
when
|
116
|
+
when GEOS_MULTIPOLYGON, :multi_polygon
|
109
117
|
Geos::Polygon
|
110
|
-
when
|
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(
|
137
|
+
create_collection(:multi_point, *geoms)
|
130
138
|
end
|
131
139
|
|
132
140
|
def create_multi_line_string(*geoms)
|
133
|
-
create_collection(
|
141
|
+
create_collection(:multi_line_string, *geoms)
|
134
142
|
end
|
135
143
|
|
136
144
|
def create_multi_polygon(*geoms)
|
137
|
-
create_collection(
|
145
|
+
create_collection(:multi_polygon, *geoms)
|
138
146
|
end
|
139
147
|
|
140
148
|
def create_geometry_collection(*geoms)
|
141
|
-
create_collection(
|
149
|
+
create_collection(:geometry_collection, *geoms)
|
142
150
|
end
|
143
151
|
end
|
144
152
|
end
|
data/test/geometry_tests.rb
CHANGED
@@ -33,142 +33,148 @@ class GeometryTests < Test::Unit::TestCase
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def test_buffer
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
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
|
-
|
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
|
-
|
73
|
-
}
|
43
|
+
tester['POLYGON EMPTY', 'POINT(0 0)', 0]
|
74
44
|
|
75
|
-
|
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
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
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
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
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
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
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
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
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
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
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
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
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
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
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?(:
|
144
|
-
def
|
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.
|
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 =>
|
142
|
+
:quad_segs => 0,
|
159
143
|
:join => :round,
|
160
|
-
:mitre_limit => 2
|
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 =>
|
175
|
+
:quad_segs => 1,
|
170
176
|
:join => :round,
|
171
|
-
:mitre_limit => 2
|
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)
|