ffi-geos 0.0.6 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +21 -3
- data/ffi-geos.gemspec +2 -0
- data/lib/ffi-geos.rb +90 -13
- data/lib/ffi-geos/coordinate_sequence.rb +29 -14
- data/lib/ffi-geos/geometry.rb +77 -42
- data/lib/ffi-geos/geometry_collection.rb +6 -2
- data/lib/ffi-geos/line_string.rb +13 -3
- data/lib/ffi-geos/linear_ring.rb +3 -0
- data/lib/ffi-geos/point.rb +60 -2
- data/lib/ffi-geos/polygon.rb +13 -2
- data/lib/ffi-geos/tools.rb +35 -2
- data/lib/ffi-geos/utils.rb +120 -62
- data/lib/ffi-geos/version.rb +1 -1
- data/lib/ffi-geos/wkb_reader.rb +8 -4
- data/lib/ffi-geos/wkt_reader.rb +4 -2
- data/test/coordinate_sequence_tests.rb +81 -27
- data/test/geometry_collection_tests.rb +79 -0
- data/test/geometry_tests.rb +235 -249
- data/test/line_string_tests.rb +167 -0
- data/test/linear_ring_tests.rb +24 -0
- data/test/misc_tests.rb +3 -3
- data/test/point_tests.rb +62 -1
- data/test/polygon_tests.rb +36 -0
- data/test/prepared_geometry_tests.rb +4 -4
- data/test/strtree_tests.rb +6 -6
- data/test/test_helper.rb +48 -1
- data/test/utils_tests.rb +116 -34
- data/test/wkb_reader_tests.rb +24 -4
- data/test/wkb_writer_tests.rb +5 -5
- data/test/wkt_reader_tests.rb +10 -5
- data/test/wkt_writer_tests.rb +3 -3
- metadata +43 -3
data/README.rdoc
CHANGED
@@ -9,15 +9,21 @@
|
|
9
9
|
|
10
10
|
Ruby versions known to work:
|
11
11
|
|
12
|
-
* Ruby MRI 1.8.7 and 1.9.
|
12
|
+
* Ruby MRI 1.8.7, 1.9.2 and 1.9.3 x86_64, OSX 10.6.5+
|
13
13
|
* Ruby MRI 1.8.7 and 1.9.2, i386, linux
|
14
|
-
* Ruby MRI 1.8.7, x86_64, linux
|
15
|
-
* JRuby 1.6
|
14
|
+
* Ruby MRI 1.8.7, 1.9.2 and 1.9.3, x86_64, linux
|
15
|
+
* JRuby 1.6, x86_64 OSX 10.6.5+
|
16
|
+
|
17
|
+
=== JRuby Notes
|
16
18
|
|
17
19
|
Note that versions of JRuby prior to version 1.6.3 have problems in their ffi
|
18
20
|
implementation when dealing with AutoPointers that can lead to segfaults during
|
19
21
|
garbage collection.
|
20
22
|
|
23
|
+
JRuby 1.7.0 is exhibiting some strange and sporadic memory problems that are
|
24
|
+
difficult to lock down. Unit tests show that the errors do not occur 100% of
|
25
|
+
the time, so it has been difficult to trace the root cause of the errors.
|
26
|
+
|
21
27
|
== Features
|
22
28
|
|
23
29
|
ffi-geos supports all of the features found in the binary SWIG-based GEOS
|
@@ -54,6 +60,13 @@ Ruby bindings along with the following enhancements and additions:
|
|
54
60
|
|
55
61
|
== New Methods and Additions (not exhaustive)
|
56
62
|
|
63
|
+
* SRIDs can be copied on many operations. GEOS doesn't usually copy SRIDs
|
64
|
+
around, but for the sake of convenience, we do. The default behaviour for
|
65
|
+
SRID copying can be set via the Geos.srid_copy_policy= method. The default
|
66
|
+
behaviour is to use 0 values as before, but you can optionally allow for
|
67
|
+
copying in either a lenient or a strict sort of manner. See the documentation
|
68
|
+
for Geos.srid_copy_policy= for details.
|
69
|
+
|
57
70
|
=== Geos
|
58
71
|
|
59
72
|
* Geos.create_multi_point
|
@@ -149,3 +162,8 @@ Ruby bindings along with the following enhancements and additions:
|
|
149
162
|
|
150
163
|
* Charlie Savage for the original SWIG-based GEOS bindings implementation and
|
151
164
|
some fixes for MinGW.
|
165
|
+
|
166
|
+
== License
|
167
|
+
|
168
|
+
This gem is licensed under an MIT-style license. See the +MIT-LICENSE+ file for
|
169
|
+
details.
|
data/ffi-geos.gemspec
CHANGED
data/lib/ffi-geos.rb
CHANGED
@@ -59,15 +59,19 @@ module Geos
|
|
59
59
|
end
|
60
60
|
|
61
61
|
def self.find_lib(lib)
|
62
|
-
|
63
|
-
|
64
|
-
|
62
|
+
if ENV['GEOS_LIBRARY_PATH'] && File.file?(ENV['GEOS_LIBRARY_PATH'])
|
63
|
+
ENV['GEOS_LIBRARY_PATH']
|
64
|
+
else
|
65
|
+
Dir.glob(search_paths.map { |path|
|
66
|
+
File.expand_path(File.join(path, "#{lib}.#{FFI::Platform::LIBSUFFIX}"))
|
67
|
+
}).first
|
68
|
+
end
|
65
69
|
end
|
66
70
|
|
67
71
|
def self.geos_library_path
|
68
72
|
@geos_library_path ||= begin
|
69
73
|
# On MingW the libraries have version numbers
|
70
|
-
find_lib('
|
74
|
+
find_lib('{lib,}geos_c{,-?}')
|
71
75
|
end
|
72
76
|
end
|
73
77
|
|
@@ -79,8 +83,6 @@ module Geos
|
|
79
83
|
|
80
84
|
extend ::FFI::Library
|
81
85
|
|
82
|
-
ffi_lib(geos_library_path)
|
83
|
-
|
84
86
|
Geos::DimensionTypes = enum(:dimension_type, [
|
85
87
|
:dontcare, -3,
|
86
88
|
:non_empty, -2,
|
@@ -626,6 +628,11 @@ module Geos
|
|
626
628
|
:int, :pointer, :pointer, :pointer
|
627
629
|
],
|
628
630
|
|
631
|
+
:GEOSGeomGetZ_r => [
|
632
|
+
# -1 on exception, *handle, *geom, *point
|
633
|
+
:int, :pointer, :pointer, :pointer
|
634
|
+
],
|
635
|
+
|
629
636
|
:GEOSGeomGetPointN_r => [
|
630
637
|
# *point, *handle, *geom, n
|
631
638
|
:pointer, :pointer, :pointer, :int
|
@@ -940,15 +947,25 @@ module Geos
|
|
940
947
|
#### /Algorithms ####
|
941
948
|
}
|
942
949
|
|
943
|
-
|
944
|
-
|
945
|
-
|
946
|
-
|
947
|
-
|
950
|
+
begin
|
951
|
+
ffi_lib(geos_library_path)
|
952
|
+
|
953
|
+
FFI_LAYOUT.each do |fun, ary|
|
954
|
+
ret = ary.shift
|
955
|
+
begin
|
956
|
+
self.class_eval do
|
957
|
+
attach_function(fun, ary, ret)
|
958
|
+
end
|
959
|
+
rescue FFI::NotFoundError
|
960
|
+
# that's okay
|
948
961
|
end
|
949
|
-
rescue FFI::NotFoundError
|
950
|
-
# that's okay
|
951
962
|
end
|
963
|
+
|
964
|
+
# Checks to see if we actually have the GEOS library loaded.
|
965
|
+
FFIGeos.GEOSversion
|
966
|
+
|
967
|
+
rescue LoadError, NoMethodError
|
968
|
+
raise LoadError.new("Couldn't load the GEOS CAPI library.")
|
952
969
|
end
|
953
970
|
end
|
954
971
|
|
@@ -989,6 +1006,54 @@ module Geos
|
|
989
1006
|
Thread.current[:ffi_geos_handle].ptr
|
990
1007
|
end
|
991
1008
|
|
1009
|
+
def srid_copy_policy
|
1010
|
+
Thread.current[:ffi_geos_srid_copy_policy] ||= srid_copy_policy_default
|
1011
|
+
end
|
1012
|
+
|
1013
|
+
# Sets the SRID copying behaviour. This value can be one of the values
|
1014
|
+
# found in Geos::Constants::SRID_COPY_POLICIES and are local to the
|
1015
|
+
# current thread. A special value of +:default+ can also be used, which
|
1016
|
+
# will use a global default that can be set with srid_copy_policy_default=.
|
1017
|
+
# Setting this value will cause all future threads to use this global
|
1018
|
+
# default rather than the true default value which is set to +:zero+ for
|
1019
|
+
# the sake of backwards compatibility with
|
1020
|
+
#
|
1021
|
+
# The available values for +policy+ are:
|
1022
|
+
#
|
1023
|
+
# * +:default+ - use the value set with srid_copy_policy_default=,
|
1024
|
+
# which itself is +:zero+.
|
1025
|
+
# * +:zero+ - set all SRIDs to 0. The only exception to this is when
|
1026
|
+
# cloning a Geometry, in which the SRID is always copied as per the
|
1027
|
+
# previous behaviour.
|
1028
|
+
# * +:lenient+ - when copying SRIDs, use the SRID of the object that the
|
1029
|
+
# operation is being performed on, even if operation involves multiple
|
1030
|
+
# Geometry objects that may have different SRIDs.
|
1031
|
+
# * +:strict+ - when copying SRIDs, raise a Geos::MixedSRIDsError exception
|
1032
|
+
# if an operation is performed on mixed SRIDs. This setting
|
1033
|
+
def srid_copy_policy=(policy)
|
1034
|
+
if policy == :default
|
1035
|
+
Thread.current[:ffi_geos_srid_copy_policy] = srid_copy_policy_default
|
1036
|
+
elsif Geos::Constants::SRID_COPY_POLICIES.include?(policy)
|
1037
|
+
Thread.current[:ffi_geos_srid_copy_policy] = policy
|
1038
|
+
else
|
1039
|
+
raise ArgumentError.new("Invalid SRID policy #{policy} (must be one of #{Geos::Constants::SRID_COPY_POLICIES})")
|
1040
|
+
end
|
1041
|
+
end
|
1042
|
+
|
1043
|
+
def srid_copy_policy_default
|
1044
|
+
@srid_copy_policy_default ||= :zero
|
1045
|
+
end
|
1046
|
+
|
1047
|
+
def srid_copy_policy_default=(policy)
|
1048
|
+
if policy == :default
|
1049
|
+
@srid_copy_policy_default = :zero
|
1050
|
+
elsif Geos::Constants::SRID_COPY_POLICIES.include?(policy)
|
1051
|
+
@srid_copy_policy_default = policy
|
1052
|
+
else
|
1053
|
+
raise ArgumentError.new("Invalid SRID policy #{policy} (must be one of #{Geos::Constants::SRID_COPY_POLICIES})")
|
1054
|
+
end
|
1055
|
+
end
|
1056
|
+
|
992
1057
|
%w{
|
993
1058
|
create_point
|
994
1059
|
create_line_string
|
@@ -1070,6 +1135,18 @@ module Geos
|
|
1070
1135
|
:join => :round,
|
1071
1136
|
:mitre_limit => 5.0
|
1072
1137
|
}.freeze
|
1138
|
+
|
1139
|
+
SRID_COPY_POLICIES = [
|
1140
|
+
:zero,
|
1141
|
+
:lenient,
|
1142
|
+
:strict
|
1143
|
+
].freeze
|
1144
|
+
end
|
1145
|
+
|
1146
|
+
class MixedSRIDsError < RuntimeError
|
1147
|
+
def initialize(srid_a, srid_b)
|
1148
|
+
super("Operation on mixed SRIDs (#{srid_a} vs. #{srid_b})")
|
1149
|
+
end
|
1073
1150
|
end
|
1074
1151
|
|
1075
1152
|
include GeomTypes
|
@@ -95,12 +95,10 @@ module Geos
|
|
95
95
|
|
96
96
|
@ptr = FFI::AutoPointer.new(
|
97
97
|
ptr,
|
98
|
-
|
98
|
+
self.class.method(:release)
|
99
99
|
)
|
100
100
|
|
101
|
-
|
102
|
-
@ptr.autorelease = false
|
103
|
-
end
|
101
|
+
@ptr.autorelease = auto_free
|
104
102
|
|
105
103
|
@x = CoordinateAccessor.new(self, 0)
|
106
104
|
@y = CoordinateAccessor.new(self, 1)
|
@@ -120,9 +118,10 @@ module Geos
|
|
120
118
|
FFIGeos.GEOSCoordSeq_clone_r(Geos.current_handle, source.ptr),
|
121
119
|
self.class.method(:release)
|
122
120
|
)
|
123
|
-
end
|
124
121
|
|
125
|
-
|
122
|
+
@x = CoordinateAccessor.new(self, 0)
|
123
|
+
@y = CoordinateAccessor.new(self, 1)
|
124
|
+
@z = CoordinateAccessor.new(self, 2)
|
126
125
|
end
|
127
126
|
|
128
127
|
def self.release(ptr) #:nodoc:
|
@@ -144,6 +143,22 @@ module Geos
|
|
144
143
|
end
|
145
144
|
end
|
146
145
|
|
146
|
+
def [](*args)
|
147
|
+
if args.length == 1 && args.first.is_a?(Numeric) && args.first >= 0
|
148
|
+
i = args.first
|
149
|
+
ary = [ self.get_x(i), self.get_y(i) ]
|
150
|
+
ary << self.get_z(i) if self.has_z?
|
151
|
+
ary
|
152
|
+
else
|
153
|
+
self.to_a[*args]
|
154
|
+
end
|
155
|
+
end
|
156
|
+
alias :slice :[]
|
157
|
+
|
158
|
+
def has_z?
|
159
|
+
self.dimensions == 3
|
160
|
+
end
|
161
|
+
|
147
162
|
# Sets the x value of a coordinate. Can also be set via #x[]=.
|
148
163
|
def set_x(idx, val)
|
149
164
|
self.check_bounds(idx)
|
@@ -215,20 +230,20 @@ module Geos
|
|
215
230
|
}.read_int
|
216
231
|
end
|
217
232
|
|
218
|
-
def to_point
|
219
|
-
Geos.create_point(self)
|
233
|
+
def to_point(options = {})
|
234
|
+
Geos.create_point(self, :srid => options[:srid])
|
220
235
|
end
|
221
236
|
|
222
|
-
def to_linear_ring
|
223
|
-
Geos.create_linear_ring(self)
|
237
|
+
def to_linear_ring(options = {})
|
238
|
+
Geos.create_linear_ring(self, :srid => options[:srid])
|
224
239
|
end
|
225
240
|
|
226
|
-
def to_line_string
|
227
|
-
Geos.create_line_string(self)
|
241
|
+
def to_line_string(options = {})
|
242
|
+
Geos.create_line_string(self, :srid => options[:srid])
|
228
243
|
end
|
229
244
|
|
230
|
-
def to_polygon
|
231
|
-
Geos.create_polygon(self)
|
245
|
+
def to_polygon(options = {})
|
246
|
+
Geos.create_polygon(self, :srid => options[:srid])
|
232
247
|
end
|
233
248
|
|
234
249
|
def to_s
|
data/lib/ffi-geos/geometry.rb
CHANGED
@@ -10,12 +10,10 @@ module Geos
|
|
10
10
|
def initialize(ptr, auto_free = true)
|
11
11
|
@ptr = FFI::AutoPointer.new(
|
12
12
|
ptr,
|
13
|
-
|
13
|
+
self.class.method(:release)
|
14
14
|
)
|
15
15
|
|
16
|
-
|
17
|
-
@ptr.autorelease = false
|
18
|
-
end
|
16
|
+
@ptr.autorelease = auto_free
|
19
17
|
end
|
20
18
|
|
21
19
|
def initialize_copy(source)
|
@@ -28,9 +26,6 @@ module Geos
|
|
28
26
|
self.srid = source.srid
|
29
27
|
end
|
30
28
|
|
31
|
-
def self.no_release(ptr) #:nodoc:
|
32
|
-
end
|
33
|
-
|
34
29
|
def self.release(ptr) #:nodoc:
|
35
30
|
FFIGeos.GEOSGeom_destroy_r(Geos.current_handle, ptr)
|
36
31
|
end
|
@@ -80,7 +75,9 @@ module Geos
|
|
80
75
|
|
81
76
|
def intersection(geom)
|
82
77
|
check_geometry(geom)
|
83
|
-
cast_geometry_ptr(FFIGeos.GEOSIntersection_r(Geos.current_handle, self.ptr, geom.ptr)
|
78
|
+
cast_geometry_ptr(FFIGeos.GEOSIntersection_r(Geos.current_handle, self.ptr, geom.ptr), {
|
79
|
+
:srid_copy => pick_srid_from_geoms(self.srid, geom.srid)
|
80
|
+
})
|
84
81
|
end
|
85
82
|
|
86
83
|
if FFIGeos.respond_to?(:GEOSBufferWithParams_r)
|
@@ -110,7 +107,7 @@ module Geos
|
|
110
107
|
raise ArgumentError.new("Expected Geos::BufferParams, a Hash or a Numeric")
|
111
108
|
end
|
112
109
|
|
113
|
-
cast_geometry_ptr(FFIGeos.GEOSBufferWithParams_r(Geos.current_handle, self.ptr, params.ptr, width))
|
110
|
+
cast_geometry_ptr(FFIGeos.GEOSBufferWithParams_r(Geos.current_handle, self.ptr, params.ptr, width), :srid_copy => self.srid)
|
114
111
|
end
|
115
112
|
else
|
116
113
|
def buffer(width, options = nil)
|
@@ -126,26 +123,31 @@ module Geos
|
|
126
123
|
raise ArgumentError.new("Expected Geos::BufferParams, a Hash or a Numeric")
|
127
124
|
end
|
128
125
|
|
129
|
-
cast_geometry_ptr(FFIGeos.GEOSBuffer_r(Geos.current_handle, self.ptr, width, quad_segs))
|
126
|
+
cast_geometry_ptr(FFIGeos.GEOSBuffer_r(Geos.current_handle, self.ptr, width, quad_segs), :srid_copy => self.srid)
|
130
127
|
end
|
131
128
|
end
|
132
129
|
|
133
130
|
def convex_hull
|
134
|
-
cast_geometry_ptr(FFIGeos.GEOSConvexHull_r(Geos.current_handle, self.ptr))
|
131
|
+
cast_geometry_ptr(FFIGeos.GEOSConvexHull_r(Geos.current_handle, self.ptr), :srid_copy => self.srid)
|
135
132
|
end
|
136
133
|
|
137
134
|
def difference(geom)
|
138
135
|
check_geometry(geom)
|
139
|
-
cast_geometry_ptr(FFIGeos.GEOSDifference_r(Geos.current_handle, self.ptr, geom.ptr)
|
136
|
+
cast_geometry_ptr(FFIGeos.GEOSDifference_r(Geos.current_handle, self.ptr, geom.ptr), {
|
137
|
+
:srid_copy => pick_srid_from_geoms(self.srid, geom.srid)
|
138
|
+
})
|
140
139
|
end
|
141
140
|
|
142
141
|
def sym_difference(geom)
|
143
142
|
check_geometry(geom)
|
144
|
-
cast_geometry_ptr(FFIGeos.GEOSSymDifference_r(Geos.current_handle, self.ptr, geom.ptr)
|
143
|
+
cast_geometry_ptr(FFIGeos.GEOSSymDifference_r(Geos.current_handle, self.ptr, geom.ptr), {
|
144
|
+
:srid_copy => pick_srid_from_geoms(self.srid, geom.srid)
|
145
|
+
})
|
145
146
|
end
|
147
|
+
alias :symmetric_difference :sym_difference
|
146
148
|
|
147
149
|
def boundary
|
148
|
-
cast_geometry_ptr(FFIGeos.GEOSBoundary_r(Geos.current_handle, self.ptr))
|
150
|
+
cast_geometry_ptr(FFIGeos.GEOSBoundary_r(Geos.current_handle, self.ptr), :srid_copy => self.srid)
|
149
151
|
end
|
150
152
|
|
151
153
|
# Calling without a geom argument is equivalent to calling unary_union when
|
@@ -154,7 +156,9 @@ module Geos
|
|
154
156
|
def union(geom = nil)
|
155
157
|
if geom
|
156
158
|
check_geometry(geom)
|
157
|
-
cast_geometry_ptr(FFIGeos.GEOSUnion_r(Geos.current_handle, self.ptr, geom.ptr)
|
159
|
+
cast_geometry_ptr(FFIGeos.GEOSUnion_r(Geos.current_handle, self.ptr, geom.ptr), {
|
160
|
+
:srid_copy => pick_srid_from_geoms(self.srid, geom.srid)
|
161
|
+
})
|
158
162
|
else
|
159
163
|
if self.respond_to?(:unary_union)
|
160
164
|
self.unary_union
|
@@ -165,27 +169,32 @@ module Geos
|
|
165
169
|
end
|
166
170
|
|
167
171
|
def union_cascaded
|
168
|
-
cast_geometry_ptr(FFIGeos.GEOSUnionCascaded_r(Geos.current_handle, self.ptr)
|
172
|
+
cast_geometry_ptr(FFIGeos.GEOSUnionCascaded_r(Geos.current_handle, self.ptr), {
|
173
|
+
:srid_copy => self.srid
|
174
|
+
})
|
169
175
|
end
|
170
176
|
|
171
177
|
if FFIGeos.respond_to?(:GEOSUnaryUnion_r)
|
172
178
|
# Available in GEOS 3.3+
|
173
179
|
def unary_union
|
174
|
-
cast_geometry_ptr(FFIGeos.GEOSUnaryUnion_r(Geos.current_handle, self.ptr)
|
180
|
+
cast_geometry_ptr(FFIGeos.GEOSUnaryUnion_r(Geos.current_handle, self.ptr), {
|
181
|
+
:srid_copy => self.srid
|
182
|
+
})
|
175
183
|
end
|
176
184
|
end
|
177
185
|
|
178
186
|
def point_on_surface
|
179
|
-
cast_geometry_ptr(FFIGeos.GEOSPointOnSurface_r(Geos.current_handle, self.ptr))
|
187
|
+
cast_geometry_ptr(FFIGeos.GEOSPointOnSurface_r(Geos.current_handle, self.ptr), :srid_copy => self.srid)
|
180
188
|
end
|
189
|
+
alias :representative_point :point_on_surface
|
181
190
|
|
182
191
|
def centroid
|
183
|
-
cast_geometry_ptr(FFIGeos.GEOSGetCentroid_r(Geos.current_handle, self.ptr))
|
192
|
+
cast_geometry_ptr(FFIGeos.GEOSGetCentroid_r(Geos.current_handle, self.ptr), :srid_copy => self.srid)
|
184
193
|
end
|
185
194
|
alias :center :centroid
|
186
195
|
|
187
196
|
def envelope
|
188
|
-
cast_geometry_ptr(FFIGeos.GEOSEnvelope_r(Geos.current_handle, self.ptr))
|
197
|
+
cast_geometry_ptr(FFIGeos.GEOSEnvelope_r(Geos.current_handle, self.ptr), :srid_copy => self.srid)
|
189
198
|
end
|
190
199
|
|
191
200
|
# Returns the Dimensionally Extended Nine-Intersection Model (DE-9IM)
|
@@ -211,19 +220,19 @@ module Geos
|
|
211
220
|
end
|
212
221
|
|
213
222
|
def line_merge
|
214
|
-
cast_geometry_ptr(FFIGeos.GEOSLineMerge_r(Geos.current_handle, self.ptr))
|
223
|
+
cast_geometry_ptr(FFIGeos.GEOSLineMerge_r(Geos.current_handle, self.ptr), :srid_copy => self.srid)
|
215
224
|
end
|
216
225
|
|
217
226
|
def simplify(tolerance)
|
218
|
-
cast_geometry_ptr(FFIGeos.GEOSSimplify_r(Geos.current_handle, self.ptr, tolerance))
|
227
|
+
cast_geometry_ptr(FFIGeos.GEOSSimplify_r(Geos.current_handle, self.ptr, tolerance), :srid_copy => self.srid)
|
219
228
|
end
|
220
229
|
|
221
230
|
def topology_preserve_simplify(tolerance)
|
222
|
-
cast_geometry_ptr(FFIGeos.GEOSTopologyPreserveSimplify_r(Geos.current_handle, self.ptr, tolerance))
|
231
|
+
cast_geometry_ptr(FFIGeos.GEOSTopologyPreserveSimplify_r(Geos.current_handle, self.ptr, tolerance), :srid_copy => self.srid)
|
223
232
|
end
|
224
233
|
|
225
234
|
def extract_unique_points
|
226
|
-
cast_geometry_ptr(FFIGeos.GEOSGeom_extractUniquePoints_r(Geos.current_handle, self.ptr))
|
235
|
+
cast_geometry_ptr(FFIGeos.GEOSGeom_extractUniquePoints_r(Geos.current_handle, self.ptr), :srid_copy => self.srid)
|
227
236
|
end
|
228
237
|
alias :unique_points :extract_unique_points
|
229
238
|
|
@@ -311,11 +320,21 @@ module Geos
|
|
311
320
|
bool_result(FFIGeos.GEOSEquals_r(Geos.current_handle, self.ptr, geom.ptr))
|
312
321
|
end
|
313
322
|
alias :== :eql?
|
323
|
+
alias :equals? :eql?
|
314
324
|
|
315
325
|
def eql_exact?(geom, tolerance)
|
316
326
|
check_geometry(geom)
|
317
327
|
bool_result(FFIGeos.GEOSEqualsExact_r(Geos.current_handle, self.ptr, geom.ptr, tolerance))
|
318
328
|
end
|
329
|
+
alias :equals_exact? :eql_exact?
|
330
|
+
alias :exactly_equals? :eql_exact?
|
331
|
+
|
332
|
+
def eql_almost?(geom, decimal = 6)
|
333
|
+
check_geometry(geom)
|
334
|
+
bool_result(FFIGeos.GEOSEqualsExact_r(Geos.current_handle, self.ptr, geom.ptr, 0.5 * 10 ** (-decimal)))
|
335
|
+
end
|
336
|
+
alias :equals_almost? :eql_almost?
|
337
|
+
alias :almost_equals? :eql_almost?
|
319
338
|
|
320
339
|
def empty?
|
321
340
|
bool_result(FFIGeos.GEOSisEmpty_r(Geos.current_handle, self.ptr))
|
@@ -348,7 +367,9 @@ module Geos
|
|
348
367
|
if !valid
|
349
368
|
{
|
350
369
|
:detail => detail.read_pointer.read_string,
|
351
|
-
:location => cast_geometry_ptr(location.read_pointer
|
370
|
+
:location => cast_geometry_ptr(location.read_pointer, {
|
371
|
+
:srid_copy => self.srid
|
372
|
+
})
|
352
373
|
}
|
353
374
|
end
|
354
375
|
end
|
@@ -390,7 +411,7 @@ module Geos
|
|
390
411
|
FFIGeos.GEOSInterpolate_r(Geos.current_handle, self.ptr, d)
|
391
412
|
end
|
392
413
|
|
393
|
-
cast_geometry_ptr(ret)
|
414
|
+
cast_geometry_ptr(ret, :srid_copy => self.srid)
|
394
415
|
end
|
395
416
|
|
396
417
|
def interpolate_normalized(d)
|
@@ -398,23 +419,31 @@ module Geos
|
|
398
419
|
end
|
399
420
|
|
400
421
|
def start_point
|
401
|
-
cast_geometry_ptr(FFIGeos.GEOSGeomGetStartPoint_r(Geos.current_handle, self.ptr))
|
422
|
+
cast_geometry_ptr(FFIGeos.GEOSGeomGetStartPoint_r(Geos.current_handle, self.ptr), :srid_copy => self.srid)
|
402
423
|
end
|
403
424
|
|
404
425
|
def end_point
|
405
|
-
cast_geometry_ptr(FFIGeos.GEOSGeomGetEndPoint_r(Geos.current_handle, self.ptr))
|
426
|
+
cast_geometry_ptr(FFIGeos.GEOSGeomGetEndPoint_r(Geos.current_handle, self.ptr), :srid_copy => self.srid)
|
406
427
|
end
|
407
428
|
|
408
429
|
def area
|
409
|
-
|
410
|
-
|
411
|
-
|
430
|
+
if self.empty?
|
431
|
+
0
|
432
|
+
else
|
433
|
+
FFI::MemoryPointer.new(:double).tap { |ret|
|
434
|
+
FFIGeos.GEOSArea_r(Geos.current_handle, self.ptr, ret)
|
435
|
+
}.read_double
|
436
|
+
end
|
412
437
|
end
|
413
438
|
|
414
439
|
def length
|
415
|
-
|
416
|
-
|
417
|
-
|
440
|
+
if self.empty?
|
441
|
+
0
|
442
|
+
else
|
443
|
+
FFI::MemoryPointer.new(:double).tap { |ret|
|
444
|
+
FFIGeos.GEOSLength_r(Geos.current_handle, self.ptr, ret)
|
445
|
+
}.read_double
|
446
|
+
end
|
418
447
|
end
|
419
448
|
|
420
449
|
def distance(geom)
|
@@ -437,13 +466,17 @@ module Geos
|
|
437
466
|
|
438
467
|
def snap(geom, tolerance)
|
439
468
|
check_geometry(geom)
|
440
|
-
cast_geometry_ptr(FFIGeos.GEOSSnap_r(Geos.current_handle, self.ptr, geom.ptr, tolerance)
|
469
|
+
cast_geometry_ptr(FFIGeos.GEOSSnap_r(Geos.current_handle, self.ptr, geom.ptr, tolerance), {
|
470
|
+
:srid_copy => pick_srid_from_geoms(self.srid, geom.srid)
|
471
|
+
})
|
441
472
|
end
|
442
473
|
alias :snap_to :snap
|
443
474
|
|
444
475
|
def shared_paths(geom)
|
445
476
|
check_geometry(geom)
|
446
|
-
cast_geometry_ptr(FFIGeos.GEOSSharedPaths_r(Geos.current_handle, self.ptr, geom.ptr)
|
477
|
+
cast_geometry_ptr(FFIGeos.GEOSSharedPaths_r(Geos.current_handle, self.ptr, geom.ptr), {
|
478
|
+
:srid_copy => pick_srid_from_geoms(self.srid, geom.srid)
|
479
|
+
}).to_a
|
447
480
|
end
|
448
481
|
|
449
482
|
# Returns a Hash with the following structure:
|
@@ -460,12 +493,14 @@ module Geos
|
|
460
493
|
invalid_rings = FFI::MemoryPointer.new(:pointer)
|
461
494
|
|
462
495
|
rings = cast_geometry_ptr(
|
463
|
-
FFIGeos.GEOSPolygonize_full_r(Geos.current_handle, self.ptr, cuts, dangles, invalid_rings)
|
496
|
+
FFIGeos.GEOSPolygonize_full_r(Geos.current_handle, self.ptr, cuts, dangles, invalid_rings), {
|
497
|
+
:srid_copy => self.srid
|
498
|
+
}
|
464
499
|
)
|
465
500
|
|
466
|
-
cuts = cast_geometry_ptr(cuts.read_pointer)
|
467
|
-
dangles = cast_geometry_ptr(dangles.read_pointer)
|
468
|
-
invalid_rings = cast_geometry_ptr(invalid_rings.read_pointer)
|
501
|
+
cuts = cast_geometry_ptr(cuts.read_pointer, :srid_copy => self.srid)
|
502
|
+
dangles = cast_geometry_ptr(dangles.read_pointer, :srid_copy => self.srid)
|
503
|
+
invalid_rings = cast_geometry_ptr(invalid_rings.read_pointer, :srid_copy => self.srid)
|
469
504
|
|
470
505
|
{
|
471
506
|
:rings => rings.to_a,
|
@@ -479,14 +514,14 @@ module Geos
|
|
479
514
|
ary = FFI::MemoryPointer.new(:pointer)
|
480
515
|
ary.write_array_of_pointer([ self.ptr ])
|
481
516
|
|
482
|
-
cast_geometry_ptr(FFIGeos.GEOSPolygonize_r(Geos.current_handle, ary, 1)).to_a
|
517
|
+
cast_geometry_ptr(FFIGeos.GEOSPolygonize_r(Geos.current_handle, ary, 1), :srid_copy => self.srid).to_a
|
483
518
|
end
|
484
519
|
|
485
520
|
def polygonize_cut_edges
|
486
521
|
ary = FFI::MemoryPointer.new(:pointer)
|
487
522
|
ary.write_array_of_pointer([ self.ptr ])
|
488
523
|
|
489
|
-
cast_geometry_ptr(FFIGeos.GEOSPolygonizer_getCutEdges_r(Geos.current_handle, ary, 1)).to_a
|
524
|
+
cast_geometry_ptr(FFIGeos.GEOSPolygonizer_getCutEdges_r(Geos.current_handle, ary, 1), :srid_copy => self.srid).to_a
|
490
525
|
end
|
491
526
|
|
492
527
|
def to_prepared
|