ffi-geos 1.2.0 → 2.2.0
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.
- checksums.yaml +5 -5
- data/.rubocop.yml +4851 -0
- data/.travis.yml +24 -9
- data/FUNDING.yml +2 -0
- data/Gemfile +12 -16
- data/Guardfile +6 -8
- data/MIT-LICENSE +1 -1
- data/README.rdoc +2 -20
- data/Rakefile +4 -2
- data/ffi-geos.gemspec +13 -14
- data/lib/ffi-geos.rb +342 -244
- data/lib/ffi-geos/buffer_params.rb +9 -20
- data/lib/ffi-geos/coordinate_sequence.rb +351 -65
- data/lib/ffi-geos/geometry.rb +267 -191
- data/lib/ffi-geos/geometry_collection.rb +74 -12
- data/lib/ffi-geos/interrupt.rb +11 -16
- data/lib/ffi-geos/line_string.rb +157 -33
- data/lib/ffi-geos/linear_ring.rb +2 -3
- data/lib/ffi-geos/multi_line_string.rb +1 -2
- data/lib/ffi-geos/multi_point.rb +0 -1
- data/lib/ffi-geos/multi_polygon.rb +0 -1
- data/lib/ffi-geos/point.rb +70 -15
- data/lib/ffi-geos/polygon.rb +124 -21
- data/lib/ffi-geos/prepared_geometry.rb +11 -12
- data/lib/ffi-geos/strtree.rb +64 -77
- data/lib/ffi-geos/tools.rb +16 -19
- data/lib/ffi-geos/utils.rb +36 -60
- data/lib/ffi-geos/version.rb +1 -3
- data/lib/ffi-geos/wkb_reader.rb +4 -9
- data/lib/ffi-geos/wkb_writer.rb +15 -20
- data/lib/ffi-geos/wkt_reader.rb +2 -5
- data/lib/ffi-geos/wkt_writer.rb +20 -31
- data/sonar-project.properties +16 -0
- data/test/.rubocop.yml +36 -0
- data/test/coordinate_sequence_tests.rb +322 -52
- data/test/geometry_collection_tests.rb +388 -4
- data/test/geometry_tests.rb +466 -121
- data/test/interrupt_tests.rb +9 -12
- data/test/line_string_tests.rb +213 -25
- data/test/linear_ring_tests.rb +1 -3
- data/test/misc_tests.rb +28 -30
- data/test/multi_line_string_tests.rb +0 -2
- data/test/point_tests.rb +158 -2
- data/test/polygon_tests.rb +283 -2
- data/test/prepared_geometry_tests.rb +8 -11
- data/test/strtree_tests.rb +14 -15
- data/test/test_helper.rb +75 -51
- data/test/tools_tests.rb +1 -4
- data/test/utils_tests.rb +85 -76
- data/test/wkb_reader_tests.rb +18 -18
- data/test/wkb_writer_tests.rb +15 -22
- data/test/wkt_reader_tests.rb +1 -4
- data/test/wkt_writer_tests.rb +8 -17
- metadata +11 -7
@@ -1,4 +1,3 @@
|
|
1
|
-
# encoding: UTF-8
|
2
1
|
# frozen_string_literal: true
|
3
2
|
|
4
3
|
module Geos
|
@@ -8,34 +7,97 @@ module Geos
|
|
8
7
|
# Yields each Geometry in the GeometryCollection.
|
9
8
|
def each
|
10
9
|
if block_given?
|
11
|
-
|
12
|
-
yield
|
10
|
+
num_geometries.times do |n|
|
11
|
+
yield get_geometry_n(n)
|
13
12
|
end
|
14
13
|
self
|
15
14
|
else
|
16
|
-
|
17
|
-
|
15
|
+
num_geometries.times.collect { |n|
|
16
|
+
get_geometry_n(n)
|
18
17
|
}.to_enum
|
19
18
|
end
|
20
19
|
end
|
21
20
|
|
22
21
|
def get_geometry_n(n)
|
23
|
-
if n
|
22
|
+
if n.negative? || n >= num_geometries
|
24
23
|
nil
|
25
24
|
else
|
26
|
-
cast_geometry_ptr(FFIGeos.GEOSGetGeometryN_r(Geos.current_handle_pointer,
|
25
|
+
cast_geometry_ptr(FFIGeos.GEOSGetGeometryN_r(Geos.current_handle_pointer, ptr, n), auto_free: false)
|
27
26
|
end
|
28
27
|
end
|
29
|
-
|
28
|
+
alias geometry_n get_geometry_n
|
30
29
|
|
31
30
|
def [](*args)
|
32
31
|
if args.length == 1 && args.first.is_a?(Numeric) && args.first >= 0
|
33
|
-
|
32
|
+
get_geometry_n(args.first)
|
34
33
|
else
|
35
|
-
|
34
|
+
to_a[*args]
|
36
35
|
end
|
37
36
|
end
|
38
|
-
|
39
|
-
|
37
|
+
alias slice []
|
38
|
+
alias at []
|
39
|
+
|
40
|
+
def dump_points(cur_path = [])
|
41
|
+
each do |geom|
|
42
|
+
cur_path << geom.dump_points
|
43
|
+
end
|
44
|
+
cur_path
|
45
|
+
end
|
46
|
+
|
47
|
+
%w{ x y z }.each do |dimension|
|
48
|
+
%w{ max min }.each do |op|
|
49
|
+
native_method = "GEOSGeom_get#{dimension.upcase}#{op[0].upcase}#{op[1..-1]}_r"
|
50
|
+
|
51
|
+
if FFIGeos.respond_to?(native_method)
|
52
|
+
class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
|
53
|
+
def #{dimension}_#{op}
|
54
|
+
return if empty?
|
55
|
+
|
56
|
+
double_ptr = FFI::MemoryPointer.new(:double)
|
57
|
+
FFIGeos.#{native_method}(Geos.current_handle_pointer, ptr, double_ptr)
|
58
|
+
double_ptr.read_double
|
59
|
+
end
|
60
|
+
RUBY
|
61
|
+
else
|
62
|
+
class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
|
63
|
+
def #{dimension}_#{op}
|
64
|
+
unless self.empty?
|
65
|
+
self.collect(&:#{dimension}_#{op}).#{op}
|
66
|
+
end
|
67
|
+
end
|
68
|
+
RUBY
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
%w{
|
74
|
+
affine
|
75
|
+
rotate
|
76
|
+
rotate_x
|
77
|
+
rotate_y
|
78
|
+
rotate_z
|
79
|
+
scale
|
80
|
+
snap_to_grid
|
81
|
+
trans_scale
|
82
|
+
translate
|
83
|
+
}.each do |m|
|
84
|
+
class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
|
85
|
+
def #{m}!(*args)
|
86
|
+
unless self.empty?
|
87
|
+
self.num_geometries.times do |i|
|
88
|
+
self[i].#{m}!(*args)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
self
|
93
|
+
end
|
94
|
+
|
95
|
+
def #{m}(*args)
|
96
|
+
ret = self.dup.#{m}!(*args)
|
97
|
+
ret.srid = pick_srid_according_to_policy(self.srid)
|
98
|
+
ret
|
99
|
+
end
|
100
|
+
RUBY
|
101
|
+
end
|
40
102
|
end
|
41
103
|
end
|
data/lib/ffi-geos/interrupt.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
# encoding: UTF-8
|
2
1
|
# frozen_string_literal: true
|
3
2
|
|
4
3
|
module Geos
|
@@ -26,23 +25,20 @@ module Geos
|
|
26
25
|
# collector may not play nicely with GEOS and objects may get cleaned
|
27
26
|
# up in unexpected ways while interrupts are firing.
|
28
27
|
def register(method_or_block = nil, &block)
|
29
|
-
if method_or_block.nil? && !block_given?
|
30
|
-
|
31
|
-
elsif !method_or_block.nil? && block_given?
|
32
|
-
raise ArgumentError.new("Cannot use both a method and a block for Geos::Interrupt.register")
|
33
|
-
else
|
34
|
-
retval = @current_interrupt_callback
|
28
|
+
raise ArgumentError, 'Expected either a method or a block for Geos::Interrupt.register' if method_or_block.nil? && !block_given?
|
29
|
+
raise ArgumentError, 'Cannot use both a method and a block for Geos::Interrupt.register' if !method_or_block.nil? && block_given?
|
35
30
|
|
36
|
-
|
37
|
-
FFIGeos.GEOS_interruptRegisterCallback(method_or_block)
|
38
|
-
method_or_block
|
39
|
-
elsif block_given?
|
40
|
-
FFIGeos.GEOS_interruptRegisterCallback(block)
|
41
|
-
block
|
42
|
-
end
|
31
|
+
retval = @current_interrupt_callback
|
43
32
|
|
44
|
-
|
33
|
+
@current_interrupt_callback = if method_or_block
|
34
|
+
FFIGeos.GEOS_interruptRegisterCallback(method_or_block)
|
35
|
+
method_or_block
|
36
|
+
elsif block_given?
|
37
|
+
FFIGeos.GEOS_interruptRegisterCallback(block)
|
38
|
+
block
|
45
39
|
end
|
40
|
+
|
41
|
+
retval
|
46
42
|
end
|
47
43
|
|
48
44
|
# Interrupt the current operation. This method should generally be
|
@@ -72,4 +68,3 @@ module Geos
|
|
72
68
|
end
|
73
69
|
end
|
74
70
|
end
|
75
|
-
|
data/lib/ffi-geos/line_string.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
# encoding: UTF-8
|
2
1
|
# frozen_string_literal: true
|
3
2
|
|
4
3
|
module Geos
|
@@ -7,82 +6,207 @@ module Geos
|
|
7
6
|
|
8
7
|
def each
|
9
8
|
if block_given?
|
10
|
-
|
11
|
-
yield
|
9
|
+
num_points.times do |n|
|
10
|
+
yield point_n(n)
|
12
11
|
end
|
13
12
|
self
|
14
13
|
else
|
15
|
-
|
16
|
-
|
14
|
+
num_points.times.collect { |n|
|
15
|
+
point_n(n)
|
17
16
|
}.to_enum
|
18
17
|
end
|
19
18
|
end
|
20
19
|
|
21
20
|
if FFIGeos.respond_to?(:GEOSGeomGetNumPoints_r)
|
22
21
|
def num_points
|
23
|
-
FFIGeos.GEOSGeomGetNumPoints_r(Geos.current_handle_pointer,
|
22
|
+
FFIGeos.GEOSGeomGetNumPoints_r(Geos.current_handle_pointer, ptr)
|
24
23
|
end
|
25
24
|
else
|
26
25
|
def num_points
|
27
|
-
|
26
|
+
coord_seq.length
|
28
27
|
end
|
29
28
|
end
|
30
29
|
|
31
30
|
def point_n(n)
|
32
|
-
if n
|
33
|
-
|
34
|
-
|
35
|
-
cast_geometry_ptr(
|
36
|
-
FFIGeos.GEOSGeomGetPointN_r(Geos.current_handle_pointer, self.ptr, n), {
|
37
|
-
:srid_copy => self.srid
|
38
|
-
}
|
39
|
-
)
|
40
|
-
end
|
31
|
+
raise Geos::IndexBoundsError if n.negative? || n >= num_points
|
32
|
+
|
33
|
+
cast_geometry_ptr(FFIGeos.GEOSGeomGetPointN_r(Geos.current_handle_pointer, ptr, n), srid_copy: srid)
|
41
34
|
end
|
42
35
|
|
43
36
|
def [](*args)
|
44
37
|
if args.length == 1 && args.first.is_a?(Numeric) && args.first >= 0
|
45
|
-
|
38
|
+
point_n(args.first)
|
46
39
|
else
|
47
|
-
|
40
|
+
to_a[*args]
|
48
41
|
end
|
49
42
|
end
|
50
|
-
|
43
|
+
alias slice []
|
51
44
|
|
52
45
|
def offset_curve(width, options = {})
|
53
46
|
options = Constants::BUFFER_PARAM_DEFAULTS.merge(options)
|
54
47
|
|
55
|
-
cast_geometry_ptr(
|
48
|
+
cast_geometry_ptr(
|
49
|
+
FFIGeos.GEOSOffsetCurve_r(
|
56
50
|
Geos.current_handle_pointer,
|
57
|
-
|
51
|
+
ptr,
|
58
52
|
width,
|
59
53
|
options[:quad_segs],
|
60
54
|
options[:join],
|
61
55
|
options[:mitre_limit]
|
62
|
-
|
63
|
-
:
|
64
|
-
|
56
|
+
),
|
57
|
+
srid_copy: srid
|
58
|
+
)
|
65
59
|
end
|
66
60
|
|
67
61
|
if FFIGeos.respond_to?(:GEOSisClosed_r)
|
68
62
|
def closed?
|
69
|
-
bool_result(FFIGeos.GEOSisClosed_r(Geos.current_handle_pointer,
|
63
|
+
bool_result(FFIGeos.GEOSisClosed_r(Geos.current_handle_pointer, ptr))
|
70
64
|
end
|
71
65
|
end
|
72
66
|
|
73
67
|
def to_linear_ring
|
74
|
-
if
|
75
|
-
Geos.create_linear_ring(self.coord_seq, :srid => pick_srid_according_to_policy(self.srid))
|
76
|
-
else
|
77
|
-
self_cs = self.coord_seq.to_a
|
78
|
-
self_cs.push(self_cs[0])
|
68
|
+
return Geos.create_linear_ring(coord_seq, srid: pick_srid_according_to_policy(srid)) if closed?
|
79
69
|
|
80
|
-
|
81
|
-
|
70
|
+
self_cs = coord_seq.to_a
|
71
|
+
self_cs.push(self_cs[0])
|
72
|
+
|
73
|
+
Geos.create_linear_ring(self_cs, srid: pick_srid_according_to_policy(srid))
|
82
74
|
end
|
83
75
|
|
84
76
|
def to_polygon
|
85
|
-
|
77
|
+
to_linear_ring.to_polygon
|
78
|
+
end
|
79
|
+
|
80
|
+
def dump_points(cur_path = [])
|
81
|
+
cur_path.concat(to_a)
|
82
|
+
end
|
83
|
+
|
84
|
+
def snap_to_grid!(*args)
|
85
|
+
unless empty?
|
86
|
+
cs = coord_seq.snap_to_grid!(*args)
|
87
|
+
|
88
|
+
if cs.empty?
|
89
|
+
@ptr = Geos.create_empty_line_string(srid: srid).ptr
|
90
|
+
elsif cs.length <= 1
|
91
|
+
raise Geos::InvalidGeometryError, "snap_to_grid! produced an invalid number of points in for a LineString - found #{cs.length} - must be 0 or > 1"
|
92
|
+
else
|
93
|
+
@ptr = Geos.create_line_string(cs).ptr
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
self
|
98
|
+
end
|
99
|
+
|
100
|
+
def snap_to_grid(*args)
|
101
|
+
ret = dup.snap_to_grid!(*args)
|
102
|
+
ret.srid = pick_srid_according_to_policy(srid)
|
103
|
+
ret
|
104
|
+
end
|
105
|
+
|
106
|
+
def line_interpolate_point(fraction)
|
107
|
+
raise ArgumentError, 'fraction must be between 0 and 1' unless fraction.between?(0, 1)
|
108
|
+
|
109
|
+
case fraction
|
110
|
+
when 0
|
111
|
+
start_point
|
112
|
+
when 1
|
113
|
+
end_point
|
114
|
+
else
|
115
|
+
length = self.length
|
116
|
+
total_length = 0
|
117
|
+
segs = num_points - 1
|
118
|
+
|
119
|
+
segs.times do |i|
|
120
|
+
p_1 = self[i]
|
121
|
+
p_2 = self[i + 1]
|
122
|
+
|
123
|
+
seg_length = p_1.distance(p_2) / length
|
124
|
+
|
125
|
+
if fraction < total_length + seg_length
|
126
|
+
dseg = (fraction - total_length) / seg_length
|
127
|
+
|
128
|
+
args = []
|
129
|
+
args << p_1.x + ((p_2.x - p_1.x) * dseg)
|
130
|
+
args << p_1.y + ((p_2.y - p_1.y) * dseg)
|
131
|
+
args << p_1.z + ((p_2.z - p_1.z) * dseg) if has_z?
|
132
|
+
|
133
|
+
args << { srid: pick_srid_according_to_policy(srid) } unless srid.zero?
|
134
|
+
|
135
|
+
return Geos.create_point(*args)
|
136
|
+
end
|
137
|
+
|
138
|
+
total_length += seg_length
|
139
|
+
end
|
140
|
+
|
141
|
+
# if all else fails...
|
142
|
+
end_point
|
143
|
+
end
|
144
|
+
end
|
145
|
+
alias interpolate_point line_interpolate_point
|
146
|
+
|
147
|
+
%w{ max min }.each do |op|
|
148
|
+
%w{ x y }.each do |dimension|
|
149
|
+
native_method = "GEOSGeom_get#{dimension.upcase}#{op[0].upcase}#{op[1..-1]}_r"
|
150
|
+
|
151
|
+
if FFIGeos.respond_to?(native_method)
|
152
|
+
class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
|
153
|
+
def #{dimension}_#{op}
|
154
|
+
return if empty?
|
155
|
+
|
156
|
+
double_ptr = FFI::MemoryPointer.new(:double)
|
157
|
+
FFIGeos.#{native_method}(Geos.current_handle_pointer, ptr, double_ptr)
|
158
|
+
double_ptr.read_double
|
159
|
+
end
|
160
|
+
RUBY
|
161
|
+
else
|
162
|
+
class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
|
163
|
+
def #{dimension}_#{op}
|
164
|
+
unless self.empty?
|
165
|
+
self.coord_seq.#{dimension}_#{op}
|
166
|
+
end
|
167
|
+
end
|
168
|
+
RUBY
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
|
173
|
+
def z_#{op}
|
174
|
+
unless self.empty?
|
175
|
+
if self.has_z?
|
176
|
+
self.coord_seq.z_#{op}
|
177
|
+
else
|
178
|
+
0
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
RUBY
|
183
|
+
end
|
184
|
+
|
185
|
+
%w{
|
186
|
+
affine
|
187
|
+
rotate
|
188
|
+
rotate_x
|
189
|
+
rotate_y
|
190
|
+
rotate_z
|
191
|
+
scale
|
192
|
+
trans_scale
|
193
|
+
translate
|
194
|
+
}.each do |m|
|
195
|
+
class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
|
196
|
+
def #{m}!(*args)
|
197
|
+
unless self.empty?
|
198
|
+
self.coord_seq.#{m}!(*args)
|
199
|
+
end
|
200
|
+
|
201
|
+
self
|
202
|
+
end
|
203
|
+
|
204
|
+
def #{m}(*args)
|
205
|
+
ret = self.dup.#{m}!(*args)
|
206
|
+
ret.srid = pick_srid_according_to_policy(self.srid)
|
207
|
+
ret
|
208
|
+
end
|
209
|
+
RUBY
|
86
210
|
end
|
87
211
|
end
|
88
212
|
end
|
data/lib/ffi-geos/linear_ring.rb
CHANGED
@@ -1,14 +1,13 @@
|
|
1
|
-
# encoding: UTF-8
|
2
1
|
# frozen_string_literal: true
|
3
2
|
|
4
3
|
module Geos
|
5
4
|
class LinearRing < LineString
|
6
5
|
def to_polygon
|
7
|
-
Geos.create_polygon(self, :
|
6
|
+
Geos.create_polygon(self, srid: pick_srid_according_to_policy(srid))
|
8
7
|
end
|
9
8
|
|
10
9
|
def to_line_string
|
11
|
-
Geos.create_line_string(
|
10
|
+
Geos.create_line_string(coord_seq, srid: pick_srid_according_to_policy(srid))
|
12
11
|
end
|
13
12
|
end
|
14
13
|
end
|
@@ -1,4 +1,3 @@
|
|
1
|
-
# encoding: UTF-8
|
2
1
|
# frozen_string_literal: true
|
3
2
|
|
4
3
|
module Geos
|
@@ -6,7 +5,7 @@ module Geos
|
|
6
5
|
if FFIGeos.respond_to?(:GEOSisClosed_r) && Geos::GEOS_VERSION >= '3.5.0'
|
7
6
|
# Available in GEOS 3.5.0+.
|
8
7
|
def closed?
|
9
|
-
bool_result(FFIGeos.GEOSisClosed_r(Geos.current_handle_pointer,
|
8
|
+
bool_result(FFIGeos.GEOSisClosed_r(Geos.current_handle_pointer, ptr))
|
10
9
|
end
|
11
10
|
end
|
12
11
|
end
|
data/lib/ffi-geos/multi_point.rb
CHANGED
data/lib/ffi-geos/point.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
# encoding: UTF-8
|
2
1
|
# frozen_string_literal: true
|
3
2
|
|
4
3
|
module Geos
|
@@ -6,41 +5,41 @@ module Geos
|
|
6
5
|
if FFIGeos.respond_to?(:GEOSGeomGetX_r)
|
7
6
|
def get_x
|
8
7
|
double_ptr = FFI::MemoryPointer.new(:double)
|
9
|
-
FFIGeos.GEOSGeomGetX_r(Geos.current_handle_pointer,
|
8
|
+
FFIGeos.GEOSGeomGetX_r(Geos.current_handle_pointer, ptr, double_ptr)
|
10
9
|
double_ptr.read_double
|
11
10
|
end
|
12
11
|
else
|
13
12
|
def get_x
|
14
|
-
|
13
|
+
coord_seq.get_x(0)
|
15
14
|
end
|
16
15
|
end
|
17
|
-
|
16
|
+
alias x get_x
|
18
17
|
|
19
18
|
if FFIGeos.respond_to?(:GEOSGeomGetY_r)
|
20
19
|
def get_y
|
21
20
|
double_ptr = FFI::MemoryPointer.new(:double)
|
22
|
-
FFIGeos.GEOSGeomGetY_r(Geos.current_handle_pointer,
|
21
|
+
FFIGeos.GEOSGeomGetY_r(Geos.current_handle_pointer, ptr, double_ptr)
|
23
22
|
double_ptr.read_double
|
24
23
|
end
|
25
24
|
else
|
26
25
|
def get_y
|
27
|
-
|
26
|
+
coord_seq.get_y(0)
|
28
27
|
end
|
29
28
|
end
|
30
|
-
|
29
|
+
alias y get_y
|
31
30
|
|
32
31
|
if FFIGeos.respond_to?(:GEOSGeomGetZ_r)
|
33
32
|
def get_z
|
34
33
|
double_ptr = FFI::MemoryPointer.new(:double)
|
35
|
-
FFIGeos.GEOSGeomGetZ_r(Geos.current_handle_pointer,
|
34
|
+
FFIGeos.GEOSGeomGetZ_r(Geos.current_handle_pointer, ptr, double_ptr)
|
36
35
|
double_ptr.read_double
|
37
36
|
end
|
38
37
|
else
|
39
38
|
def get_z
|
40
|
-
|
39
|
+
coord_seq.get_z(0)
|
41
40
|
end
|
42
41
|
end
|
43
|
-
|
42
|
+
alias z get_z
|
44
43
|
|
45
44
|
def area
|
46
45
|
0
|
@@ -61,7 +60,7 @@ module Geos
|
|
61
60
|
def normalize!
|
62
61
|
self
|
63
62
|
end
|
64
|
-
|
63
|
+
alias normalize normalize!
|
65
64
|
|
66
65
|
%w{
|
67
66
|
convex_hull
|
@@ -70,13 +69,69 @@ module Geos
|
|
70
69
|
envelope
|
71
70
|
topology_preserve_simplify
|
72
71
|
}.each do |method|
|
73
|
-
|
72
|
+
class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
|
74
73
|
def #{method}(*args)
|
75
|
-
|
74
|
+
dup.tap do |ret|
|
76
75
|
ret.srid = pick_srid_according_to_policy(ret.srid)
|
77
|
-
|
76
|
+
end
|
78
77
|
end
|
79
|
-
|
78
|
+
RUBY
|
79
|
+
end
|
80
|
+
|
81
|
+
def dump_points(cur_path = [])
|
82
|
+
cur_path.push(dup)
|
83
|
+
end
|
84
|
+
|
85
|
+
%w{ max min }.each do |op|
|
86
|
+
%w{ x y }.each do |dimension|
|
87
|
+
class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
|
88
|
+
def #{dimension}_#{op}
|
89
|
+
unless empty?
|
90
|
+
#{dimension}
|
91
|
+
end
|
92
|
+
end
|
93
|
+
RUBY
|
94
|
+
end
|
95
|
+
|
96
|
+
class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
|
97
|
+
def z_#{op}
|
98
|
+
unless empty?
|
99
|
+
if has_z?
|
100
|
+
z
|
101
|
+
else
|
102
|
+
0
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
RUBY
|
107
|
+
end
|
108
|
+
|
109
|
+
%w{
|
110
|
+
affine
|
111
|
+
rotate
|
112
|
+
rotate_x
|
113
|
+
rotate_y
|
114
|
+
rotate_z
|
115
|
+
scale
|
116
|
+
snap_to_grid
|
117
|
+
trans_scale
|
118
|
+
translate
|
119
|
+
}.each do |m|
|
120
|
+
class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
|
121
|
+
def #{m}!(*args)
|
122
|
+
unless empty?
|
123
|
+
coord_seq.#{m}!(*args)
|
124
|
+
end
|
125
|
+
|
126
|
+
self
|
127
|
+
end
|
128
|
+
|
129
|
+
def #{m}(*args)
|
130
|
+
ret = dup.#{m}!(*args)
|
131
|
+
ret.srid = pick_srid_according_to_policy(srid)
|
132
|
+
ret
|
133
|
+
end
|
134
|
+
RUBY
|
80
135
|
end
|
81
136
|
end
|
82
137
|
end
|