rgeo 0.2.9 → 0.3.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.
Files changed (67) hide show
  1. data/History.rdoc +11 -0
  2. data/README.rdoc +3 -3
  3. data/Spatial_Programming_With_RGeo.rdoc +19 -8
  4. data/Version +1 -1
  5. data/ext/geos_c_impl/factory.c +1 -0
  6. data/ext/geos_c_impl/factory.h +1 -0
  7. data/ext/geos_c_impl/geometry.c +4 -5
  8. data/ext/geos_c_impl/geometry_collection.c +15 -0
  9. data/ext/geos_c_impl/line_string.c +10 -0
  10. data/ext/geos_c_impl/point.c +2 -0
  11. data/ext/geos_c_impl/polygon.c +4 -0
  12. data/lib/rgeo/cartesian/feature_classes.rb +23 -17
  13. data/lib/rgeo/cartesian/feature_methods.rb +20 -1
  14. data/lib/rgeo/feature.rb +1 -0
  15. data/lib/rgeo/feature/curve.rb +1 -2
  16. data/lib/rgeo/feature/geometry_collection.rb +1 -1
  17. data/lib/rgeo/feature/line.rb +1 -1
  18. data/lib/rgeo/feature/line_string.rb +1 -2
  19. data/lib/rgeo/feature/linear_ring.rb +1 -2
  20. data/lib/rgeo/feature/mixins.rb +198 -0
  21. data/lib/rgeo/feature/multi_curve.rb +1 -2
  22. data/lib/rgeo/feature/multi_line_string.rb +1 -2
  23. data/lib/rgeo/feature/multi_point.rb +1 -2
  24. data/lib/rgeo/feature/multi_polygon.rb +1 -2
  25. data/lib/rgeo/feature/multi_surface.rb +1 -2
  26. data/lib/rgeo/feature/point.rb +1 -2
  27. data/lib/rgeo/feature/polygon.rb +1 -3
  28. data/lib/rgeo/feature/surface.rb +1 -2
  29. data/lib/rgeo/feature/types.rb +27 -0
  30. data/lib/rgeo/geographic/projected_feature_classes.rb +31 -4
  31. data/lib/rgeo/geographic/projected_feature_methods.rb +2 -1
  32. data/lib/rgeo/geographic/spherical_feature_classes.rb +30 -3
  33. data/lib/rgeo/geos.rb +22 -0
  34. data/lib/rgeo/geos/factory.rb +11 -5
  35. data/lib/rgeo/geos/ffi_classes.rb +655 -0
  36. data/lib/rgeo/geos/ffi_factory.rb +503 -0
  37. data/lib/rgeo/geos/impl_additions.rb +1 -1
  38. data/lib/rgeo/geos/interface.rb +63 -8
  39. data/lib/rgeo/geos/zm_factory.rb +10 -4
  40. data/test/common/geometry_collection_tests.rb +1 -3
  41. data/test/coord_sys/tc_ogc_cs.rb +13 -2
  42. data/test/coord_sys/tc_proj4_srs_data.rb +1 -1
  43. data/test/{geos → geos_capi}/tc_factory.rb +2 -2
  44. data/test/{geos → geos_capi}/tc_geometry_collection.rb +2 -2
  45. data/test/{geos → geos_capi}/tc_line_string.rb +2 -2
  46. data/test/{geos → geos_capi}/tc_misc.rb +6 -2
  47. data/test/{geos → geos_capi}/tc_multi_line_string.rb +2 -2
  48. data/test/{geos → geos_capi}/tc_multi_point.rb +2 -2
  49. data/test/{geos → geos_capi}/tc_multi_polygon.rb +2 -2
  50. data/test/{geos → geos_capi}/tc_parsing_unparsing.rb +2 -2
  51. data/test/{geos → geos_capi}/tc_point.rb +2 -2
  52. data/test/{geos → geos_capi}/tc_polygon.rb +2 -2
  53. data/test/{geos → geos_capi}/tc_zmfactory.rb +2 -2
  54. data/test/geos_ffi/tc_factory.rb +91 -0
  55. data/test/geos_ffi/tc_geometry_collection.rb +62 -0
  56. data/test/geos_ffi/tc_line_string.rb +62 -0
  57. data/test/geos_ffi/tc_misc.rb +69 -0
  58. data/test/geos_ffi/tc_multi_line_string.rb +62 -0
  59. data/test/geos_ffi/tc_multi_point.rb +62 -0
  60. data/test/geos_ffi/tc_multi_polygon.rb +64 -0
  61. data/test/geos_ffi/tc_parsing_unparsing.rb +81 -0
  62. data/test/geos_ffi/tc_point.rb +87 -0
  63. data/test/geos_ffi/tc_polygon.rb +86 -0
  64. data/test/geos_ffi/tc_zmfactory.rb +86 -0
  65. data/test/tc_mixins.rb +188 -0
  66. data/test/tc_types.rb +77 -0
  67. metadata +54 -25
@@ -0,0 +1,503 @@
1
+ # -----------------------------------------------------------------------------
2
+ #
3
+ # FFI-GEOS factory implementation
4
+ #
5
+ # -----------------------------------------------------------------------------
6
+ # Copyright 2010 Daniel Azuma
7
+ #
8
+ # All rights reserved.
9
+ #
10
+ # Redistribution and use in source and binary forms, with or without
11
+ # modification, are permitted provided that the following conditions are met:
12
+ #
13
+ # * Redistributions of source code must retain the above copyright notice,
14
+ # this list of conditions and the following disclaimer.
15
+ # * Redistributions in binary form must reproduce the above copyright notice,
16
+ # this list of conditions and the following disclaimer in the documentation
17
+ # and/or other materials provided with the distribution.
18
+ # * Neither the name of the copyright holder, nor the names of any other
19
+ # contributors to this software, may be used to endorse or promote products
20
+ # derived from this software without specific prior written permission.
21
+ #
22
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32
+ # POSSIBILITY OF SUCH DAMAGE.
33
+ # -----------------------------------------------------------------------------
34
+ ;
35
+
36
+
37
+ module RGeo
38
+
39
+ module Geos
40
+
41
+
42
+ # This the FFI-GEOS implementation of ::RGeo::Feature::Factory.
43
+
44
+ class FFIFactory
45
+
46
+
47
+ include Feature::Factory::Instance
48
+
49
+
50
+ # Create a new factory. Returns nil if the FFI-GEOS implementation
51
+ # is not supported.
52
+ #
53
+ # See ::RGeo::Geos.factory for a list of supported options.
54
+
55
+ def initialize(opts_={})
56
+ # Main flags
57
+ @uses_lenient_multi_polygon_assertions = opts_[:lenient_multi_polygon_assertions] ||
58
+ opts_[:uses_lenient_multi_polygon_assertions]
59
+ @has_z = opts_[:has_z_coordinate]
60
+ @has_m = opts_[:has_m_coordinate]
61
+ if @has_z && @has_m
62
+ raise Error::UnsupportedOperation, "GEOS cannot support both Z and M coordinates at the same time."
63
+ end
64
+ @_has_3d = @has_z || @has_m
65
+ @buffer_resolution = opts_[:buffer_resolution].to_i
66
+ @buffer_resolution = 1 if @buffer_resolution < 1
67
+
68
+ # Interpret the generator options
69
+ wkt_generator_ = opts_[:wkt_generator]
70
+ case wkt_generator_
71
+ when :geos
72
+ @wkt_writer = ::Geos::WktWriter.new
73
+ @wkt_generator = nil
74
+ when ::Hash
75
+ @wkt_generator = WKRep::WKTGenerator.new(wkt_generator_)
76
+ @wkt_writer = nil
77
+ else
78
+ @wkt_generator = WKRep::WKTGenerator.new(:convert_case => :upper)
79
+ @wkt_writer = nil
80
+ end
81
+ wkb_generator_ = opts_[:wkb_generator]
82
+ case wkb_generator_
83
+ when :geos
84
+ @wkb_writer = ::Geos::WkbWriter.new
85
+ @wkb_generator = nil
86
+ when ::Hash
87
+ @wkb_generator = WKRep::WKBGenerator.new(wkb_generator_)
88
+ @wkb_writer = nil
89
+ else
90
+ @wkb_generator = WKRep::WKBGenerator.new
91
+ @wkb_writer = nil
92
+ end
93
+
94
+ # Coordinate system (srid, proj4, and coord_sys)
95
+ @srid = opts_[:srid]
96
+ @proj4 = opts_[:proj4]
97
+ if CoordSys::Proj4.supported?
98
+ if @proj4.kind_of?(::String) || @proj4.kind_of?(::Hash)
99
+ @proj4 = CoordSys::Proj4.create(@proj4)
100
+ end
101
+ else
102
+ @proj4 = nil
103
+ end
104
+ @coord_sys = opts_[:coord_sys]
105
+ if @coord_sys.kind_of?(::String)
106
+ @coord_sys = CoordSys::CS.create_from_wkt(@coord_sys) rescue nil
107
+ end
108
+ if (!@proj4 || !@coord_sys) && @srid && (db_ = opts_[:srs_database])
109
+ entry_ = db_.get(@srid.to_i)
110
+ if entry_
111
+ @proj4 ||= entry_.proj4
112
+ @coord_sys ||= entry_.coord_sys
113
+ end
114
+ end
115
+ @srid ||= @coord_sys.authority_code if @coord_sys
116
+ @srid = @srid.to_i
117
+
118
+ # Interpret parser options
119
+ wkt_parser_ = opts_[:wkt_parser]
120
+ case wkt_parser_
121
+ when :geos
122
+ @wkt_reader = ::Geos::WktReader.new
123
+ @wkt_parser = nil
124
+ when ::Hash
125
+ @wkt_parser = WKRep::WKTParser.new(self, wkt_parser_)
126
+ @wkt_reader = nil
127
+ else
128
+ @wkt_parser = WKRep::WKTParser.new(self)
129
+ @wkt_reader = nil
130
+ end
131
+ wkb_parser_ = opts_[:wkb_parser]
132
+ case wkb_parser_
133
+ when :geos
134
+ @wkb_reader = ::Geos::WktReader.new
135
+ @wkb_parser = nil
136
+ when ::Hash
137
+ @wkb_parser = WKRep::WKBParser.new(self, wkb_parser_)
138
+ @wkb_reader = nil
139
+ else
140
+ @wkb_parser = WKRep::WKBParser.new(self)
141
+ @wkb_reader = nil
142
+ end
143
+ end
144
+
145
+
146
+ def inspect # :nodoc:
147
+ "#<#{self.class}:0x#{object_id.to_s(16)} srid=#{srid}>"
148
+ end
149
+
150
+
151
+ # Factory equivalence test.
152
+
153
+ def eql?(rhs_)
154
+ rhs_.is_a?(self.class) && @srid == rhs_.srid &&
155
+ @has_z == rhs_.property(:has_z_coordinate) &&
156
+ @has_m == rhs_.property(:has_m_coordinate)
157
+ end
158
+ alias_method :==, :eql?
159
+
160
+
161
+ # Returns the SRID of geometries created by this factory.
162
+
163
+ def srid
164
+ @srid
165
+ end
166
+
167
+
168
+ # Returns the resolution used by buffer calculations on geometries
169
+ # created by this factory
170
+
171
+ def buffer_resolution
172
+ @buffer_resolution
173
+ end
174
+
175
+
176
+ # Returns true if this factory is lenient with MultiPolygon assertions
177
+
178
+ def lenient_multi_polygon_assertions?
179
+ @uses_lenient_multi_polygon_assertions
180
+ end
181
+
182
+
183
+ # See ::RGeo::Feature::Factory#property
184
+
185
+ def property(name_)
186
+ case name_
187
+ when :has_z_coordinate
188
+ @has_z
189
+ when :has_m_coordinate
190
+ @has_m
191
+ when :is_cartesian
192
+ true
193
+ when :buffer_resolution
194
+ @buffer_resolution
195
+ when :uses_lenient_multi_polygon_assertions
196
+ @uses_lenient_multi_polygon_assertions
197
+ else
198
+ nil
199
+ end
200
+ end
201
+
202
+
203
+ # See ::RGeo::Feature::Factory#parse_wkt
204
+
205
+ def parse_wkt(str_)
206
+ if @wkt_reader
207
+ @wkt_reader.read(str_)
208
+ else
209
+ @wkt_parser.parse(str_)
210
+ end
211
+ end
212
+
213
+
214
+ # See ::RGeo::Feature::Factory#parse_wkb
215
+
216
+ def parse_wkb(str_)
217
+ if @wkb_reader
218
+ @wkb_reader.read(str_)
219
+ else
220
+ @wkb_parser.parse(str_)
221
+ end
222
+ end
223
+
224
+
225
+ def wrap_fg_geom(fg_geom_, klass_=nil) # :nodoc:
226
+ klasses_ = nil
227
+ unless klass_.kind_of?(::Class)
228
+ is_collection_ = false
229
+ case fg_geom_.type_id
230
+ when ::Geos::GeomTypes::GEOS_POINT
231
+ inferred_klass_ = FFIPointImpl
232
+ when ::Geos::GeomTypes::GEOS_MULTIPOINT
233
+ inferred_klass_ = FFIMultiPointImpl
234
+ is_collection_ = true
235
+ when ::Geos::GeomTypes::GEOS_LINESTRING
236
+ inferred_klass_ = FFILineStringImpl
237
+ when ::Geos::GeomTypes::GEOS_LINEARRING
238
+ inferred_klass_ = FFILinearRingImpl
239
+ when ::Geos::GeomTypes::GEOS_MULTILINESTRING
240
+ inferred_klass_ = FFIMultiLineStringImpl
241
+ is_collection_ = true
242
+ when ::Geos::GeomTypes::GEOS_POLYGON
243
+ inferred_klass_ = FFIPolygonImpl
244
+ when ::Geos::GeomTypes::GEOS_MULTIPOLYGON
245
+ inferred_klass_ = FFIMultiPolygonImpl
246
+ is_collection_ = true
247
+ when ::Geos::GeomTypes::GEOS_GEOMETRYCOLLECTION
248
+ inferred_klass_ = FFIGeometryCollectionImpl
249
+ is_collection_ = true
250
+ else
251
+ inferred_klass_ = FFIGeometryImpl
252
+ end
253
+ if is_collection_ && klass_.is_a?(::Array)
254
+ klasses_ = klass_
255
+ end
256
+ klass_ = inferred_klass_
257
+ end
258
+ klass_.new(self, fg_geom_, klasses_)
259
+ end
260
+
261
+
262
+ # See ::RGeo::Feature::Factory#point
263
+
264
+ def point(x_, y_, z_=0)
265
+ cs_ = ::Geos::CoordinateSequence.new(1, 3)
266
+ cs_.set_x(0, x_)
267
+ cs_.set_y(0, y_)
268
+ cs_.set_z(0, z_)
269
+ FFIPointImpl.new(self, ::Geos::Utils.create_point(cs_), nil)
270
+ end
271
+
272
+
273
+ # See ::RGeo::Feature::Factory#line_string
274
+
275
+ def line_string(points_)
276
+ points_ = points_.to_a unless points_.kind_of?(::Array)
277
+ size_ = points_.size
278
+ return nil if size_ == 1
279
+ cs_ = ::Geos::CoordinateSequence.new(size_, 3)
280
+ points_.each_with_index do |p_, i_|
281
+ return nil unless ::RGeo::Feature::Point.check_type(p_)
282
+ cs_.set_x(i_, p_.x)
283
+ cs_.set_y(i_, p_.y)
284
+ if @has_z
285
+ cs_.set_z(i_, p_.z)
286
+ elsif @has_m
287
+ cs_.set_z(i_, p_.m)
288
+ end
289
+ end
290
+ FFILineStringImpl.new(self, ::Geos::Utils.create_line_string(cs_), nil)
291
+ end
292
+
293
+
294
+ # See ::RGeo::Feature::Factory#line
295
+
296
+ def line(start_, end_)
297
+ return nil unless ::RGeo::Feature::Point.check_type(start_) &&
298
+ ::RGeo::Feature::Point.check_type(end_)
299
+ cs_ = ::Geos::CoordinateSequence.new(2, 3)
300
+ cs_.set_x(0, start_.x)
301
+ cs_.set_x(1, end_.x)
302
+ cs_.set_y(0, start_.y)
303
+ cs_.set_y(1, end_.y)
304
+ if @has_z
305
+ cs_.set_z(0, start_.z)
306
+ cs_.set_z(1, end_.z)
307
+ elsif @has_m
308
+ cs_.set_z(0, start_.m)
309
+ cs_.set_z(1, end_.m)
310
+ end
311
+ FFILineImpl.new(self, ::Geos::Utils.create_line_string(cs_), nil)
312
+ end
313
+
314
+
315
+ # See ::RGeo::Feature::Factory#linear_ring
316
+
317
+ def linear_ring(points_)
318
+ points_ = points_.to_a unless points_.kind_of?(::Array)
319
+ fg_geom_ = _create_fg_linear_ring(points_)
320
+ fg_geom_ ? FFILinearRingImpl.new(self, fg_geom_, nil) : nil
321
+ end
322
+
323
+
324
+ # See ::RGeo::Feature::Factory#polygon
325
+
326
+ def polygon(outer_ring_, inner_rings_=nil)
327
+ inner_rings_ = inner_rings_.to_a unless inner_rings_.kind_of?(::Array)
328
+ return nil unless ::RGeo::Feature::LineString.check_type(outer_ring_)
329
+ outer_ring_ = _create_fg_linear_ring(outer_ring_.points)
330
+ inner_rings_.map! do |r_|
331
+ return nil unless ::RGeo::Feature::LineString.check_type(r_)
332
+ _create_fg_linear_ring(r_.points)
333
+ end
334
+ inner_rings_.compact!
335
+ fg_geom_ = ::Geos::Utils.create_polygon(outer_ring_, *inner_rings_)
336
+ fg_geom_ ? FFIPolygonImpl.new(self, fg_geom_, nil) : nil
337
+ end
338
+
339
+
340
+ # See ::RGeo::Feature::Factory#collection
341
+
342
+ def collection(elems_)
343
+ elems_ = elems_.to_a unless elems_.kind_of?(::Array)
344
+ klasses_ = []
345
+ fg_geoms_ = []
346
+ elems_.each do |elem_|
347
+ k_ = elem_._klasses if elem_.is_a?(FFIGeometryImpl)
348
+ elem_ = ::RGeo::Feature.cast(elem_, self, :force_new, :keep_subtype)
349
+ if elem_
350
+ klasses_ << (k_ || elem_.class)
351
+ fg_geoms_ << elem_._detach_fg_geom
352
+ end
353
+ end
354
+ fg_geom_ = ::Geos::Utils.create_collection(
355
+ ::Geos::GeomTypes::GEOS_GEOMETRYCOLLECTION, fg_geoms_)
356
+ fg_geom_ ? FFIGeometryCollectionImpl.new(self, fg_geom_, klasses_) : nil
357
+ end
358
+
359
+
360
+ # See ::RGeo::Feature::Factory#multi_point
361
+
362
+ def multi_point(elems_)
363
+ elems_ = elems_.to_a unless elems_.kind_of?(::Array)
364
+ fg_geoms_ = []
365
+ elems_.map! do |elem_|
366
+ elem_ = ::RGeo::Feature.cast(elem_, self, ::RGeo::Feature::Point,
367
+ :force_new, :keep_subtype)
368
+ return nil unless elem_
369
+ elem_._detach_fg_geom
370
+ end
371
+ klasses_ = ::Array.new(elems_.size, FFIPointImpl)
372
+ fg_geom_ = ::Geos::Utils.create_collection(
373
+ ::Geos::GeomTypes::GEOS_MULTIPOINT, elems_)
374
+ fg_geom_ ? FFIMultiPointImpl.new(self, fg_geom_, klasses_) : nil
375
+ end
376
+
377
+
378
+ # See ::RGeo::Feature::Factory#multi_line_string
379
+
380
+ def multi_line_string(elems_)
381
+ elems_ = elems_.to_a unless elems_.kind_of?(::Array)
382
+ klasses_ = []
383
+ elems_.map! do |elem_|
384
+ elem_ = ::RGeo::Feature.cast(elem_, self, ::RGeo::Feature::LineString,
385
+ :force_new, :keep_subtype)
386
+ return nil unless elem_
387
+ klasses_ << elem_.class
388
+ elem_._detach_fg_geom
389
+ end
390
+ fg_geom_ = ::Geos::Utils.create_collection(
391
+ ::Geos::GeomTypes::GEOS_MULTILINESTRING, elems_)
392
+ fg_geom_ ? FFIMultiLineStringImpl.new(self, fg_geom_, klasses_) : nil
393
+ end
394
+
395
+
396
+ # See ::RGeo::Feature::Factory#multi_polygon
397
+
398
+ def multi_polygon(elems_)
399
+ elems_ = elems_.to_a unless elems_.kind_of?(::Array)
400
+ elems_.map! do |elem_|
401
+ elem_ = ::RGeo::Feature.cast(elem_, self, ::RGeo::Feature::Polygon,
402
+ :force_new, :keep_subtype)
403
+ return nil unless elem_
404
+ elem_._detach_fg_geom
405
+ end
406
+ unless @uses_lenient_multi_polygon_assertions
407
+ (1...elems_.size).each do |i_|
408
+ (0...i_).each do |j_|
409
+ igeom_ = elems_[i_]
410
+ jgeom_ = elems_[j_]
411
+ return nil if igeom_.relate_pattern(jgeom_, "2********") ||
412
+ igeom_.relate_pattern(jgeom_, "****1****")
413
+ end
414
+ end
415
+ end
416
+ klasses_ = ::Array.new(elems_.size, FFIPolygonImpl)
417
+ fg_geom_ = ::Geos::Utils.create_collection(
418
+ ::Geos::GeomTypes::GEOS_MULTIPOLYGON, elems_)
419
+ fg_geom_ ? FFIMultiPolygonImpl.new(self, fg_geom_, klasses_) : nil
420
+ end
421
+
422
+
423
+ # See ::RGeo::Feature::Factory#proj4
424
+
425
+ def proj4
426
+ @proj4
427
+ end
428
+
429
+
430
+ # See ::RGeo::Feature::Factory#coord_sys
431
+
432
+ def coord_sys
433
+ @coord_sys
434
+ end
435
+
436
+
437
+ # See ::RGeo::Feature::Factory#override_cast
438
+
439
+ def override_cast(original_, ntype_, flags_)
440
+ false
441
+ # TODO
442
+ end
443
+
444
+
445
+ attr_reader :_has_3d # :nodoc:
446
+
447
+
448
+ def _convert_to_fg_geometry(obj_, type_=nil) # :nodoc:
449
+ if type_.nil? && obj_.factory == self
450
+ obj_
451
+ else
452
+ obj_ = Feature.cast(obj_, self, type_)
453
+ end
454
+ obj_ ? obj_.fg_geom : nil
455
+ end
456
+
457
+
458
+ def _create_fg_linear_ring(points_) # :nodoc:
459
+ size_ = points_.size
460
+ return nil if size_ == 1 || size_ == 2
461
+ if size_ > 0 && points_.first != points_.last
462
+ points_ = points_ + [points_.first]
463
+ size_ += 1
464
+ end
465
+ cs_ = ::Geos::CoordinateSequence.new(size_, 3)
466
+ points_.each_with_index do |p_, i_|
467
+ return nil unless ::RGeo::Feature::Point.check_type(p_)
468
+ cs_.set_x(i_, p_.x)
469
+ cs_.set_y(i_, p_.y)
470
+ if @has_z
471
+ cs_.set_z(i_, p_.z)
472
+ elsif @has_m
473
+ cs_.set_z(i_, p_.m)
474
+ end
475
+ end
476
+ ::Geos::Utils.create_linear_ring(cs_)
477
+ end
478
+
479
+
480
+ def _generate_wkt(geom_) # :nodoc:
481
+ if @wkt_writer
482
+ @wkt_writer.write(geom_.fg_geom)
483
+ else
484
+ @wkt_generator.generate(geom_)
485
+ end
486
+ end
487
+
488
+
489
+ def _generate_wkb(geom_) # :nodoc:
490
+ if @wkb_writer
491
+ @wkb_writer.write(geom_.fg_geom)
492
+ else
493
+ @wkb_generator.generate(geom_)
494
+ end
495
+ end
496
+
497
+
498
+ end
499
+
500
+
501
+ end
502
+
503
+ end