rgeo-dschee 0.5.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (176) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +29 -0
  3. data/ext/geos_c_impl/coordinates.c +65 -0
  4. data/ext/geos_c_impl/coordinates.h +2 -0
  5. data/ext/geos_c_impl/extconf.rb +43 -0
  6. data/ext/geos_c_impl/factory.c +995 -0
  7. data/ext/geos_c_impl/factory.h +238 -0
  8. data/ext/geos_c_impl/geometry.c +1093 -0
  9. data/ext/geos_c_impl/geometry.h +23 -0
  10. data/ext/geos_c_impl/geometry_collection.c +757 -0
  11. data/ext/geos_c_impl/geometry_collection.h +46 -0
  12. data/ext/geos_c_impl/line_string.c +675 -0
  13. data/ext/geos_c_impl/line_string.h +32 -0
  14. data/ext/geos_c_impl/main.c +40 -0
  15. data/ext/geos_c_impl/point.c +236 -0
  16. data/ext/geos_c_impl/point.h +30 -0
  17. data/ext/geos_c_impl/polygon.c +359 -0
  18. data/ext/geos_c_impl/polygon.h +43 -0
  19. data/ext/geos_c_impl/preface.h +38 -0
  20. data/ext/proj4_c_impl/extconf.rb +62 -0
  21. data/ext/proj4_c_impl/main.c +315 -0
  22. data/lib/rgeo.rb +89 -0
  23. data/lib/rgeo/cartesian.rb +25 -0
  24. data/lib/rgeo/cartesian/analysis.rb +77 -0
  25. data/lib/rgeo/cartesian/bounding_box.rb +398 -0
  26. data/lib/rgeo/cartesian/calculations.rb +113 -0
  27. data/lib/rgeo/cartesian/factory.rb +347 -0
  28. data/lib/rgeo/cartesian/feature_classes.rb +100 -0
  29. data/lib/rgeo/cartesian/feature_methods.rb +88 -0
  30. data/lib/rgeo/cartesian/interface.rb +135 -0
  31. data/lib/rgeo/coord_sys.rb +43 -0
  32. data/lib/rgeo/coord_sys/cs/entities.rb +1315 -0
  33. data/lib/rgeo/coord_sys/cs/factories.rb +148 -0
  34. data/lib/rgeo/coord_sys/cs/wkt_parser.rb +272 -0
  35. data/lib/rgeo/coord_sys/proj4.rb +293 -0
  36. data/lib/rgeo/coord_sys/srs_database/interface.rb +115 -0
  37. data/lib/rgeo/coord_sys/srs_database/proj4_data.rb +140 -0
  38. data/lib/rgeo/coord_sys/srs_database/sr_org.rb +62 -0
  39. data/lib/rgeo/coord_sys/srs_database/url_reader.rb +63 -0
  40. data/lib/rgeo/error.rb +27 -0
  41. data/lib/rgeo/feature.rb +54 -0
  42. data/lib/rgeo/feature/curve.rb +111 -0
  43. data/lib/rgeo/feature/factory.rb +278 -0
  44. data/lib/rgeo/feature/factory_generator.rb +96 -0
  45. data/lib/rgeo/feature/geometry.rb +624 -0
  46. data/lib/rgeo/feature/geometry_collection.rb +95 -0
  47. data/lib/rgeo/feature/line.rb +26 -0
  48. data/lib/rgeo/feature/line_string.rb +60 -0
  49. data/lib/rgeo/feature/linear_ring.rb +26 -0
  50. data/lib/rgeo/feature/mixins.rb +143 -0
  51. data/lib/rgeo/feature/multi_curve.rb +71 -0
  52. data/lib/rgeo/feature/multi_line_string.rb +26 -0
  53. data/lib/rgeo/feature/multi_point.rb +33 -0
  54. data/lib/rgeo/feature/multi_polygon.rb +57 -0
  55. data/lib/rgeo/feature/multi_surface.rb +73 -0
  56. data/lib/rgeo/feature/point.rb +84 -0
  57. data/lib/rgeo/feature/polygon.rb +97 -0
  58. data/lib/rgeo/feature/surface.rb +79 -0
  59. data/lib/rgeo/feature/types.rb +284 -0
  60. data/lib/rgeo/geographic.rb +40 -0
  61. data/lib/rgeo/geographic/factory.rb +450 -0
  62. data/lib/rgeo/geographic/interface.rb +489 -0
  63. data/lib/rgeo/geographic/proj4_projector.rb +58 -0
  64. data/lib/rgeo/geographic/projected_feature_classes.rb +107 -0
  65. data/lib/rgeo/geographic/projected_feature_methods.rb +212 -0
  66. data/lib/rgeo/geographic/projected_window.rb +383 -0
  67. data/lib/rgeo/geographic/simple_mercator_projector.rb +110 -0
  68. data/lib/rgeo/geographic/spherical_feature_classes.rb +100 -0
  69. data/lib/rgeo/geographic/spherical_feature_methods.rb +134 -0
  70. data/lib/rgeo/geographic/spherical_math.rb +188 -0
  71. data/lib/rgeo/geos.rb +89 -0
  72. data/lib/rgeo/geos/capi_factory.rb +470 -0
  73. data/lib/rgeo/geos/capi_feature_classes.rb +129 -0
  74. data/lib/rgeo/geos/ffi_factory.rb +592 -0
  75. data/lib/rgeo/geos/ffi_feature_classes.rb +83 -0
  76. data/lib/rgeo/geos/ffi_feature_methods.rb +574 -0
  77. data/lib/rgeo/geos/interface.rb +202 -0
  78. data/lib/rgeo/geos/utils.rb +74 -0
  79. data/lib/rgeo/geos/zm_factory.rb +405 -0
  80. data/lib/rgeo/geos/zm_feature_classes.rb +80 -0
  81. data/lib/rgeo/geos/zm_feature_methods.rb +344 -0
  82. data/lib/rgeo/impl_helper.rb +19 -0
  83. data/lib/rgeo/impl_helper/basic_geometry_collection_methods.rb +185 -0
  84. data/lib/rgeo/impl_helper/basic_geometry_methods.rb +61 -0
  85. data/lib/rgeo/impl_helper/basic_line_string_methods.rb +146 -0
  86. data/lib/rgeo/impl_helper/basic_point_methods.rb +104 -0
  87. data/lib/rgeo/impl_helper/basic_polygon_methods.rb +87 -0
  88. data/lib/rgeo/impl_helper/math.rb +14 -0
  89. data/lib/rgeo/impl_helper/utils.rb +29 -0
  90. data/lib/rgeo/version.rb +3 -0
  91. data/lib/rgeo/wkrep.rb +37 -0
  92. data/lib/rgeo/wkrep/wkb_generator.rb +201 -0
  93. data/lib/rgeo/wkrep/wkb_parser.rb +251 -0
  94. data/lib/rgeo/wkrep/wkt_generator.rb +207 -0
  95. data/lib/rgeo/wkrep/wkt_parser.rb +415 -0
  96. data/lib/rgeo/yaml.rb +23 -0
  97. data/test/cartesian_analysis_test.rb +65 -0
  98. data/test/cartesian_bbox_test.rb +123 -0
  99. data/test/common/factory_tests.rb +78 -0
  100. data/test/common/geometry_collection_tests.rb +237 -0
  101. data/test/common/line_string_tests.rb +330 -0
  102. data/test/common/multi_line_string_tests.rb +182 -0
  103. data/test/common/multi_point_tests.rb +200 -0
  104. data/test/common/multi_polygon_tests.rb +191 -0
  105. data/test/common/point_tests.rb +370 -0
  106. data/test/common/polygon_tests.rb +261 -0
  107. data/test/coord_sys/ogc_cs_test.rb +342 -0
  108. data/test/coord_sys/proj4_srs_data_test.rb +41 -0
  109. data/test/coord_sys/proj4_test.rb +150 -0
  110. data/test/coord_sys/sr_org_test.rb +32 -0
  111. data/test/coord_sys/url_reader_test.rb +42 -0
  112. data/test/geos_capi/factory_test.rb +31 -0
  113. data/test/geos_capi/geometry_collection_test.rb +24 -0
  114. data/test/geos_capi/line_string_test.rb +24 -0
  115. data/test/geos_capi/misc_test.rb +116 -0
  116. data/test/geos_capi/multi_line_string_test.rb +24 -0
  117. data/test/geos_capi/multi_point_test.rb +24 -0
  118. data/test/geos_capi/multi_polygon_test.rb +39 -0
  119. data/test/geos_capi/parsing_unparsing_test.rb +40 -0
  120. data/test/geos_capi/point_test.rb +72 -0
  121. data/test/geos_capi/polygon_test.rb +154 -0
  122. data/test/geos_capi/zmfactory_test.rb +57 -0
  123. data/test/geos_ffi/factory_test.rb +31 -0
  124. data/test/geos_ffi/geometry_collection_test.rb +24 -0
  125. data/test/geos_ffi/line_string_test.rb +24 -0
  126. data/test/geos_ffi/misc_test.rb +63 -0
  127. data/test/geos_ffi/multi_line_string_test.rb +24 -0
  128. data/test/geos_ffi/multi_point_test.rb +24 -0
  129. data/test/geos_ffi/multi_polygon_test.rb +33 -0
  130. data/test/geos_ffi/parsing_unparsing_test.rb +41 -0
  131. data/test/geos_ffi/point_test.rb +77 -0
  132. data/test/geos_ffi/polygon_test.rb +46 -0
  133. data/test/geos_ffi/zmfactory_test.rb +58 -0
  134. data/test/mixins_test.rb +141 -0
  135. data/test/oneoff_test.rb +26 -0
  136. data/test/projected_geographic/factory_test.rb +25 -0
  137. data/test/projected_geographic/geometry_collection_test.rb +24 -0
  138. data/test/projected_geographic/line_string_test.rb +24 -0
  139. data/test/projected_geographic/multi_line_string_test.rb +26 -0
  140. data/test/projected_geographic/multi_point_test.rb +30 -0
  141. data/test/projected_geographic/multi_polygon_test.rb +25 -0
  142. data/test/projected_geographic/point_test.rb +51 -0
  143. data/test/projected_geographic/polygon_test.rb +24 -0
  144. data/test/simple_cartesian/calculations_test.rb +99 -0
  145. data/test/simple_cartesian/factory_test.rb +27 -0
  146. data/test/simple_cartesian/geometry_collection_test.rb +30 -0
  147. data/test/simple_cartesian/line_string_test.rb +31 -0
  148. data/test/simple_cartesian/multi_line_string_test.rb +28 -0
  149. data/test/simple_cartesian/multi_point_test.rb +31 -0
  150. data/test/simple_cartesian/multi_polygon_test.rb +31 -0
  151. data/test/simple_cartesian/point_test.rb +50 -0
  152. data/test/simple_cartesian/polygon_test.rb +28 -0
  153. data/test/simple_mercator/factory_test.rb +25 -0
  154. data/test/simple_mercator/geometry_collection_test.rb +24 -0
  155. data/test/simple_mercator/line_string_test.rb +24 -0
  156. data/test/simple_mercator/multi_line_string_test.rb +26 -0
  157. data/test/simple_mercator/multi_point_test.rb +29 -0
  158. data/test/simple_mercator/multi_polygon_test.rb +25 -0
  159. data/test/simple_mercator/point_test.rb +55 -0
  160. data/test/simple_mercator/polygon_test.rb +24 -0
  161. data/test/simple_mercator/window_test.rb +173 -0
  162. data/test/spherical_geographic/calculations_test.rb +167 -0
  163. data/test/spherical_geographic/factory_test.rb +27 -0
  164. data/test/spherical_geographic/geometry_collection_test.rb +31 -0
  165. data/test/spherical_geographic/line_string_test.rb +31 -0
  166. data/test/spherical_geographic/multi_line_string_test.rb +29 -0
  167. data/test/spherical_geographic/multi_point_test.rb +31 -0
  168. data/test/spherical_geographic/multi_polygon_test.rb +31 -0
  169. data/test/spherical_geographic/point_test.rb +78 -0
  170. data/test/spherical_geographic/polygon_test.rb +28 -0
  171. data/test/types_test.rb +42 -0
  172. data/test/wkrep/wkb_generator_test.rb +185 -0
  173. data/test/wkrep/wkb_parser_test.rb +293 -0
  174. data/test/wkrep/wkt_generator_test.rb +294 -0
  175. data/test/wkrep/wkt_parser_test.rb +412 -0
  176. metadata +386 -0
@@ -0,0 +1,83 @@
1
+ # -----------------------------------------------------------------------------
2
+ #
3
+ # FFI-GEOS geometry implementation
4
+ #
5
+ # -----------------------------------------------------------------------------
6
+
7
+ module RGeo
8
+ module Geos
9
+ class FFIGeometryImpl # :nodoc:
10
+ include FFIGeometryMethods
11
+
12
+ Feature::MixinCollection::GLOBAL.for_type(Feature::Geometry).include_in_class(self, true)
13
+ end
14
+
15
+ class FFIPointImpl # :nodoc:
16
+ include FFIGeometryMethods
17
+ include FFIPointMethods
18
+
19
+ Feature::MixinCollection::GLOBAL.for_type(Feature::Point).include_in_class(self, true)
20
+ end
21
+
22
+ class FFILineStringImpl # :nodoc:
23
+ include FFIGeometryMethods
24
+ include FFILineStringMethods
25
+
26
+ Feature::MixinCollection::GLOBAL.for_type(Feature::LineString).include_in_class(self, true)
27
+ end
28
+
29
+ class FFILinearRingImpl # :nodoc:
30
+ include FFIGeometryMethods
31
+ include FFILineStringMethods
32
+ include FFILinearRingMethods
33
+
34
+ Feature::MixinCollection::GLOBAL.for_type(Feature::LinearRing).include_in_class(self, true)
35
+ end
36
+
37
+ class FFILineImpl # :nodoc:
38
+ include FFIGeometryMethods
39
+ include FFILineStringMethods
40
+ include FFILineMethods
41
+
42
+ Feature::MixinCollection::GLOBAL.for_type(Feature::Line).include_in_class(self, true)
43
+ end
44
+
45
+ class FFIPolygonImpl # :nodoc:
46
+ include FFIGeometryMethods
47
+ include FFIPolygonMethods
48
+
49
+ Feature::MixinCollection::GLOBAL.for_type(Feature::Polygon).include_in_class(self, true)
50
+ end
51
+
52
+ class FFIGeometryCollectionImpl # :nodoc:
53
+ include FFIGeometryMethods
54
+ include FFIGeometryCollectionMethods
55
+
56
+ Feature::MixinCollection::GLOBAL.for_type(Feature::GeometryCollection).include_in_class(self, true)
57
+ end
58
+
59
+ class FFIMultiPointImpl # :nodoc:
60
+ include FFIGeometryMethods
61
+ include FFIGeometryCollectionMethods
62
+ include FFIMultiPointMethods
63
+
64
+ Feature::MixinCollection::GLOBAL.for_type(Feature::MultiPoint).include_in_class(self, true)
65
+ end
66
+
67
+ class FFIMultiLineStringImpl # :nodoc:
68
+ include FFIGeometryMethods
69
+ include FFIGeometryCollectionMethods
70
+ include FFIMultiLineStringMethods
71
+
72
+ Feature::MixinCollection::GLOBAL.for_type(Feature::MultiLineString).include_in_class(self, true)
73
+ end
74
+
75
+ class FFIMultiPolygonImpl # :nodoc:
76
+ include FFIGeometryMethods
77
+ include FFIGeometryCollectionMethods
78
+ include FFIMultiPolygonMethods
79
+
80
+ Feature::MixinCollection::GLOBAL.for_type(Feature::MultiPolygon).include_in_class(self, true)
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,574 @@
1
+ # -----------------------------------------------------------------------------
2
+ #
3
+ # FFI-GEOS geometry implementation
4
+ #
5
+ # -----------------------------------------------------------------------------
6
+
7
+ module RGeo
8
+ module Geos
9
+ module FFIGeometryMethods # :nodoc:
10
+ include Feature::Instance
11
+
12
+ def initialize(factory_, fg_geom_, klasses_)
13
+ @factory = factory_
14
+ @fg_geom = fg_geom_
15
+ @_fg_prep = factory_._auto_prepare ? 1 : 0
16
+ @_klasses = klasses_
17
+ fg_geom_.srid = factory_.srid
18
+ end
19
+
20
+ def inspect
21
+ "#<#{self.class}:0x#{object_id.to_s(16)} #{as_text.inspect}>"
22
+ end
23
+
24
+ # Marshal support
25
+
26
+ def marshal_dump # :nodoc:
27
+ [@factory, @factory._write_for_marshal(self)]
28
+ end
29
+
30
+ def marshal_load(data_) # :nodoc:
31
+ @factory = data_[0]
32
+ @fg_geom = @factory._read_for_marshal(data_[1])
33
+ @fg_geom.srid = @factory.srid
34
+ @_fg_prep = @factory._auto_prepare ? 1 : 0
35
+ @_klasses = nil
36
+ end
37
+
38
+ # Psych support
39
+
40
+ def encode_with(coder_) # :nodoc:
41
+ coder_["factory"] = @factory
42
+ str_ = @factory._write_for_psych(self)
43
+ str_ = str_.encode("US-ASCII") if str_.respond_to?(:encode)
44
+ coder_["wkt"] = str_
45
+ end
46
+
47
+ def init_with(coder_) # :nodoc:
48
+ @factory = coder_["factory"]
49
+ @fg_geom = @factory._read_for_psych(coder_["wkt"])
50
+ @fg_geom.srid = @factory.srid
51
+ @_fg_prep = @factory._auto_prepare ? 1 : 0
52
+ @_klasses = nil
53
+ end
54
+
55
+ attr_reader :factory
56
+ attr_reader :fg_geom
57
+
58
+ attr_reader :_klasses # :nodoc:
59
+
60
+ def initialize_copy(orig_)
61
+ @factory = orig_.factory
62
+ @fg_geom = orig_.fg_geom.clone
63
+ @fg_geom.srid = orig_.fg_geom.srid
64
+ @_fg_prep = @factory._auto_prepare ? 1 : 0
65
+ @_klasses = orig_._klasses
66
+ end
67
+
68
+ def srid
69
+ @fg_geom.srid
70
+ end
71
+
72
+ def dimension
73
+ Utils.ffi_compute_dimension(@fg_geom)
74
+ end
75
+
76
+ def geometry_type
77
+ Feature::Geometry
78
+ end
79
+
80
+ def prepared?
81
+ !@_fg_prep.is_a?(::Integer)
82
+ end
83
+
84
+ def prepare!
85
+ if @_fg_prep.is_a?(::Integer)
86
+ @_fg_prep = ::Geos::PreparedGeometry.new(@fg_geom)
87
+ end
88
+ self
89
+ end
90
+
91
+ def envelope
92
+ @factory._wrap_fg_geom(@fg_geom.envelope, nil)
93
+ end
94
+
95
+ def boundary
96
+ if self.class == FFIGeometryCollectionImpl
97
+ nil
98
+ else
99
+ @factory._wrap_fg_geom(@fg_geom.boundary, nil)
100
+ end
101
+ end
102
+
103
+ def as_text
104
+ str_ = @factory._generate_wkt(self)
105
+ str_.force_encoding("US-ASCII") if str_.respond_to?(:force_encoding)
106
+ str_
107
+ end
108
+ alias_method :to_s, :as_text
109
+
110
+ def as_binary
111
+ @factory._generate_wkb(self)
112
+ end
113
+
114
+ def is_empty?
115
+ @fg_geom.empty?
116
+ end
117
+
118
+ def is_simple?
119
+ @fg_geom.simple?
120
+ end
121
+
122
+ def equals?(rhs_)
123
+ return false unless rhs_.is_a?(::RGeo::Feature::Instance)
124
+ fg_ = factory._convert_to_fg_geometry(rhs_)
125
+ if !fg_
126
+ false
127
+ # GEOS has a bug where empty geometries are not spatially equal
128
+ # to each other. Work around this case first.
129
+ elsif fg_.empty? && @fg_geom.empty?
130
+ true
131
+ else
132
+ @fg_geom.eql?(fg_)
133
+ end
134
+ end
135
+ alias_method :==, :equals?
136
+
137
+ def disjoint?(rhs_)
138
+ fg_ = factory._convert_to_fg_geometry(rhs_)
139
+ if fg_
140
+ prep_ = _request_prepared if Utils.ffi_supports_prepared_level_2
141
+ prep_ ? prep_.disjoint?(fg_) : @fg_geom.disjoint?(fg_)
142
+ else
143
+ false
144
+ end
145
+ end
146
+
147
+ def intersects?(rhs_)
148
+ fg_ = factory._convert_to_fg_geometry(rhs_)
149
+ if fg_
150
+ prep_ = _request_prepared if Utils.ffi_supports_prepared_level_1
151
+ prep_ ? prep_.intersects?(fg_) : @fg_geom.intersects?(fg_)
152
+ else
153
+ false
154
+ end
155
+ end
156
+
157
+ def touches?(rhs_)
158
+ fg_ = factory._convert_to_fg_geometry(rhs_)
159
+ if fg_
160
+ prep_ = _request_prepared if Utils.ffi_supports_prepared_level_2
161
+ prep_ ? prep_.touches?(fg_) : @fg_geom.touches?(fg_)
162
+ else
163
+ false
164
+ end
165
+ end
166
+
167
+ def crosses?(rhs_)
168
+ fg_ = factory._convert_to_fg_geometry(rhs_)
169
+ if fg_
170
+ prep_ = _request_prepared if Utils.ffi_supports_prepared_level_2
171
+ prep_ ? prep_.crosses?(fg_) : @fg_geom.crosses?(fg_)
172
+ else
173
+ false
174
+ end
175
+ end
176
+
177
+ def within?(rhs_)
178
+ fg_ = factory._convert_to_fg_geometry(rhs_)
179
+ if fg_
180
+ prep_ = _request_prepared if Utils.ffi_supports_prepared_level_2
181
+ prep_ ? prep_.within?(fg_) : @fg_geom.within?(fg_)
182
+ else
183
+ false
184
+ end
185
+ end
186
+
187
+ def contains?(rhs_)
188
+ fg_ = factory._convert_to_fg_geometry(rhs_)
189
+ if fg_
190
+ prep_ = _request_prepared if Utils.ffi_supports_prepared_level_1
191
+ prep_ ? prep_.contains?(fg_) : @fg_geom.contains?(fg_)
192
+ else
193
+ false
194
+ end
195
+ end
196
+
197
+ def overlaps?(rhs_)
198
+ fg_ = factory._convert_to_fg_geometry(rhs_)
199
+ if fg_
200
+ prep_ = _request_prepared if Utils.ffi_supports_prepared_level_2
201
+ prep_ ? prep_.overlaps?(fg_) : @fg_geom.overlaps?(fg_)
202
+ else
203
+ false
204
+ end
205
+ end
206
+
207
+ def relate?(rhs_, pattern_)
208
+ fg_ = factory._convert_to_fg_geometry(rhs_)
209
+ fg_ ? @fg_geom.relate_pattern(fg_, pattern_) : nil
210
+ end
211
+ alias_method :relate, :relate? # DEPRECATED
212
+
213
+ def distance(rhs_)
214
+ fg_ = factory._convert_to_fg_geometry(rhs_)
215
+ fg_ ? @fg_geom.distance(fg_) : nil
216
+ end
217
+
218
+ def buffer(distance_)
219
+ @factory._wrap_fg_geom(@fg_geom.buffer(distance_, @factory.buffer_resolution), nil)
220
+ end
221
+
222
+ def convex_hull
223
+ @factory._wrap_fg_geom(@fg_geom.convex_hull, nil)
224
+ end
225
+
226
+ def intersection(rhs_)
227
+ fg_ = factory._convert_to_fg_geometry(rhs_)
228
+ fg_ ? @factory._wrap_fg_geom(@fg_geom.intersection(fg_), nil) : nil
229
+ end
230
+
231
+ alias_method :*, :intersection
232
+
233
+ def union(rhs_)
234
+ fg_ = factory._convert_to_fg_geometry(rhs_)
235
+ fg_ ? @factory._wrap_fg_geom(@fg_geom.union(fg_), nil) : nil
236
+ end
237
+
238
+ alias_method :+, :union
239
+
240
+ def difference(rhs_)
241
+ fg_ = factory._convert_to_fg_geometry(rhs_)
242
+ fg_ ? @factory._wrap_fg_geom(@fg_geom.difference(fg_), nil) : nil
243
+ end
244
+
245
+ alias_method :-, :difference
246
+
247
+ def sym_difference(rhs_)
248
+ fg_ = factory._convert_to_fg_geometry(rhs_)
249
+ fg_ ? @factory._wrap_fg_geom(@fg_geom.sym_difference(fg_), nil) : nil
250
+ end
251
+
252
+ def eql?(rhs_)
253
+ rep_equals?(rhs_)
254
+ end
255
+
256
+ def _detach_fg_geom # :nodoc:
257
+ fg_ = @fg_geom
258
+ @fg_geom = nil
259
+ fg_
260
+ end
261
+
262
+ def _request_prepared # :nodoc:
263
+ case @_fg_prep
264
+ when 0
265
+ nil
266
+ when 1
267
+ @_fg_prep = 2
268
+ nil
269
+ when 2
270
+ @_fg_prep = ::Geos::PreparedGeometry.new(@fg_geom)
271
+ else
272
+ @_fg_prep
273
+ end
274
+ end
275
+ end
276
+
277
+ module FFIPointMethods # :nodoc:
278
+ def x
279
+ @fg_geom.coord_seq.get_x(0)
280
+ end
281
+
282
+ def y
283
+ @fg_geom.coord_seq.get_y(0)
284
+ end
285
+
286
+ def z
287
+ @fg_geom.coord_seq.get_z(0) if @factory.property(:has_z_coordinate)
288
+ end
289
+
290
+ def m
291
+ @fg_geom.coord_seq.get_z(0) if @factory.property(:has_m_coordinate)
292
+ end
293
+
294
+ def geometry_type
295
+ Feature::Point
296
+ end
297
+
298
+ def rep_equals?(rhs_)
299
+ rhs_.class == self.class && rhs_.factory.eql?(@factory) &&
300
+ Utils.ffi_coord_seqs_equal?(rhs_.fg_geom.coord_seq, @fg_geom.coord_seq, @factory._has_3d)
301
+ end
302
+
303
+ def hash
304
+ @hash ||= Utils.ffi_coord_seq_hash(@fg_geom.coord_seq, [@factory, geometry_type].hash)
305
+ end
306
+
307
+ def coordinates
308
+ [x, y].tap do |coords|
309
+ coords << z if @factory.property(:has_z_coordinate)
310
+ coords << m if @factory.property(:has_m_coordinate)
311
+ end
312
+ end
313
+ end
314
+
315
+ module FFILineStringMethods # :nodoc:
316
+ def geometry_type
317
+ Feature::LineString
318
+ end
319
+
320
+ def length
321
+ @fg_geom.length
322
+ end
323
+
324
+ def num_points
325
+ @fg_geom.num_points
326
+ end
327
+
328
+ def point_n(n_)
329
+ if n_ >= 0 && n_ < @fg_geom.num_points
330
+ coord_seq_ = @fg_geom.coord_seq
331
+ x_ = coord_seq_.get_x(n_)
332
+ y_ = coord_seq_.get_y(n_)
333
+ extra_ = @factory._has_3d ? [coord_seq_.get_z(n_)] : []
334
+ @factory.point(x_, y_, *extra_)
335
+ end
336
+ end
337
+
338
+ def start_point
339
+ point_n(0)
340
+ end
341
+
342
+ def end_point
343
+ point_n(@fg_geom.num_points - 1)
344
+ end
345
+
346
+ def points
347
+ coord_seq_ = @fg_geom.coord_seq
348
+ has_3d_ = @factory._has_3d
349
+ ::Array.new(@fg_geom.num_points) do |n_|
350
+ x_ = coord_seq_.get_x(n_)
351
+ y_ = coord_seq_.get_y(n_)
352
+ extra_ = has_3d_ ? [coord_seq_.get_z(n_)] : []
353
+ @factory.point(x_, y_, *extra_)
354
+ end
355
+ end
356
+
357
+ def is_closed?
358
+ @fg_geom.closed?
359
+ end
360
+
361
+ def is_ring?
362
+ @fg_geom.ring?
363
+ end
364
+
365
+ def rep_equals?(rhs_)
366
+ rhs_.class == self.class && rhs_.factory.eql?(@factory) &&
367
+ Utils.ffi_coord_seqs_equal?(rhs_.fg_geom.coord_seq, @fg_geom.coord_seq, @factory._has_3d)
368
+ end
369
+
370
+ def hash
371
+ @hash ||= Utils.ffi_coord_seq_hash(@fg_geom.coord_seq, [@factory, geometry_type].hash)
372
+ end
373
+
374
+ def coordinates
375
+ points.map(&:coordinates)
376
+ end
377
+ end
378
+
379
+ module FFILinearRingMethods # :nodoc:
380
+ def geometry_type
381
+ Feature::LinearRing
382
+ end
383
+ end
384
+
385
+ module FFILineMethods # :nodoc:
386
+ def geometry_type
387
+ Feature::Line
388
+ end
389
+ end
390
+
391
+ module FFIPolygonMethods # :nodoc:
392
+ def geometry_type
393
+ Feature::Polygon
394
+ end
395
+
396
+ def area
397
+ @fg_geom.area
398
+ end
399
+
400
+ def centroid
401
+ @factory._wrap_fg_geom(@fg_geom.centroid, FFIPointImpl)
402
+ end
403
+
404
+ def point_on_surface
405
+ @factory._wrap_fg_geom(@fg_geom.point_on_surface, FFIPointImpl)
406
+ end
407
+
408
+ def exterior_ring
409
+ @factory._wrap_fg_geom(@fg_geom.exterior_ring, FFILinearRingImpl)
410
+ end
411
+
412
+ def num_interior_rings
413
+ @fg_geom.num_interior_rings
414
+ end
415
+
416
+ def interior_ring_n(n_)
417
+ if n_ >= 0 && n_ < @fg_geom.num_interior_rings
418
+ @factory._wrap_fg_geom(@fg_geom.interior_ring_n(n_), FFILinearRingImpl)
419
+ end
420
+ end
421
+
422
+ def interior_rings
423
+ ::Array.new(@fg_geom.num_interior_rings) do |n_|
424
+ @factory._wrap_fg_geom(@fg_geom.interior_ring_n(n_), FFILinearRingImpl)
425
+ end
426
+ end
427
+
428
+ def rep_equals?(rhs_)
429
+ if rhs_.class == self.class && rhs_.factory.eql?(@factory) &&
430
+ rhs_.exterior_ring.rep_equals?(exterior_ring)
431
+ sn_ = @fg_geom.num_interior_rings
432
+ rn_ = rhs_.num_interior_rings
433
+ if sn_ == rn_
434
+ sn_.times do |i_|
435
+ return false unless interior_ring_n(i_).rep_equals?(rhs_.interior_ring_n(i_))
436
+ end
437
+ return true
438
+ end
439
+ end
440
+ false
441
+ end
442
+
443
+ def hash
444
+ @hash ||= begin
445
+ hash_ = Utils.ffi_coord_seq_hash(@fg_geom.exterior_ring.coord_seq,
446
+ [@factory, geometry_type].hash)
447
+ @fg_geom.interior_rings.inject(hash_) do |h_, r_|
448
+ Utils.ffi_coord_seq_hash(r_.coord_seq, h_)
449
+ end
450
+ end
451
+ end
452
+
453
+ def coordinates
454
+ ([exterior_ring] + interior_rings).map(&:coordinates)
455
+ end
456
+ end
457
+
458
+ module FFIGeometryCollectionMethods # :nodoc:
459
+ def geometry_type
460
+ Feature::GeometryCollection
461
+ end
462
+
463
+ def rep_equals?(rhs_)
464
+ if rhs_.class == self.class && rhs_.factory.eql?(@factory)
465
+ size_ = @fg_geom.num_geometries
466
+ if size_ == rhs_.num_geometries
467
+ size_.times do |n_|
468
+ return false unless geometry_n(n_).rep_equals?(rhs_.geometry_n(n_))
469
+ end
470
+ return true
471
+ end
472
+ end
473
+ false
474
+ end
475
+
476
+ def num_geometries
477
+ @fg_geom.num_geometries
478
+ end
479
+ alias_method :size, :num_geometries
480
+
481
+ def geometry_n(n_)
482
+ if n_ >= 0 && n_ < @fg_geom.num_geometries
483
+ @factory._wrap_fg_geom(@fg_geom.get_geometry_n(n_),
484
+ @_klasses ? @_klasses[n_] : nil)
485
+ end
486
+ end
487
+
488
+ def [](n_)
489
+ n_ += @fg_geom.num_geometries if n_ < 0
490
+ if n_ >= 0 && n_ < @fg_geom.num_geometries
491
+ @factory._wrap_fg_geom(@fg_geom.get_geometry_n(n_),
492
+ @_klasses ? @_klasses[n_] : nil)
493
+ end
494
+ end
495
+
496
+ def hash
497
+ @hash ||= begin
498
+ hash_ = [@factory, geometry_type].hash
499
+ (0...num_geometries).inject(hash_) do |h_, i_|
500
+ (1_664_525 * h_ + geometry_n(i_).hash).hash
501
+ end
502
+ end
503
+ end
504
+
505
+ def each
506
+ if block_given?
507
+ @fg_geom.num_geometries.times do |n_|
508
+ yield @factory._wrap_fg_geom(@fg_geom.get_geometry_n(n_),
509
+ @_klasses ? @_klasses[n_] : nil)
510
+ end
511
+ self
512
+ else
513
+ enum_for
514
+ end
515
+ end
516
+
517
+ include ::Enumerable
518
+ end
519
+
520
+ module FFIMultiPointMethods # :nodoc:
521
+ def geometry_type
522
+ Feature::MultiPoint
523
+ end
524
+
525
+ def coordinates
526
+ each.map(&:coordinates)
527
+ end
528
+ end
529
+
530
+ module FFIMultiLineStringMethods # :nodoc:
531
+ def geometry_type
532
+ Feature::MultiLineString
533
+ end
534
+
535
+ def length
536
+ @fg_geom.length
537
+ end
538
+
539
+ def is_closed?
540
+ size_ = num_geometries
541
+ size_.times do |n_|
542
+ return false unless @fg_geom.get_geometry_n(n_).closed?
543
+ end
544
+ true
545
+ end
546
+
547
+ def coordinates
548
+ each.map(&:coordinates)
549
+ end
550
+ end
551
+
552
+ module FFIMultiPolygonMethods # :nodoc:
553
+ def geometry_type
554
+ Feature::MultiPolygon
555
+ end
556
+
557
+ def area
558
+ @fg_geom.area
559
+ end
560
+
561
+ def centroid
562
+ @factory._wrap_fg_geom(@fg_geom.centroid, FFIPointImpl)
563
+ end
564
+
565
+ def point_on_surface
566
+ @factory._wrap_fg_geom(@fg_geom.point_on_surface, FFIPointImpl)
567
+ end
568
+
569
+ def coordinates
570
+ each.map(&:coordinates)
571
+ end
572
+ end
573
+ end
574
+ end