rgeo 0.2.9 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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