rgeo-dschee 0.5.4

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.
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