ffi-geos 0.0.1.beta1 → 0.0.1.beta2
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.
- 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)
|