rgeo 0.3.13 → 0.3.14

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/History.rdoc +8 -0
  2. data/README.rdoc +4 -4
  3. data/Version +1 -1
  4. data/ext/geos_c_impl/extconf.rb +1 -0
  5. data/ext/geos_c_impl/factory.c +118 -5
  6. data/ext/geos_c_impl/factory.h +24 -1
  7. data/ext/geos_c_impl/geometry.c +42 -53
  8. data/ext/geos_c_impl/geometry_collection.c +137 -54
  9. data/ext/geos_c_impl/geometry_collection.h +9 -0
  10. data/ext/geos_c_impl/line_string.c +88 -45
  11. data/ext/geos_c_impl/point.c +31 -17
  12. data/ext/geos_c_impl/polygon.c +50 -22
  13. data/ext/geos_c_impl/polygon.h +9 -0
  14. data/ext/geos_c_impl/preface.h +10 -0
  15. data/lib/rgeo/cartesian/factory.rb +9 -1
  16. data/lib/rgeo/coord_sys/cs/entities.rb +10 -1
  17. data/lib/rgeo/coord_sys/proj4.rb +1 -1
  18. data/lib/rgeo/feature/types.rb +29 -5
  19. data/lib/rgeo/geographic/factory.rb +5 -0
  20. data/lib/rgeo/geographic/projected_feature_classes.rb +3 -47
  21. data/lib/rgeo/geographic/projected_feature_methods.rb +69 -0
  22. data/lib/rgeo/geographic/spherical_feature_classes.rb +1 -74
  23. data/lib/rgeo/geographic/spherical_feature_methods.rb +84 -0
  24. data/lib/rgeo/geographic/spherical_math.rb +3 -3
  25. data/lib/rgeo/geos.rb +17 -9
  26. data/lib/rgeo/geos/{factory.rb → capi_factory.rb} +36 -15
  27. data/lib/rgeo/geos/{impl_additions.rb → capi_feature_classes.rb} +127 -16
  28. data/lib/rgeo/geos/ffi_factory.rb +55 -41
  29. data/lib/rgeo/geos/ffi_feature_classes.rb +168 -0
  30. data/lib/rgeo/geos/{ffi_classes.rb → ffi_feature_methods.rb} +56 -57
  31. data/lib/rgeo/geos/interface.rb +5 -5
  32. data/lib/rgeo/geos/utils.rb +7 -0
  33. data/lib/rgeo/geos/zm_factory.rb +40 -12
  34. data/lib/rgeo/geos/zm_feature_classes.rb +165 -0
  35. data/lib/rgeo/geos/{zm_impl.rb → zm_feature_methods.rb} +33 -52
  36. data/lib/rgeo/impl_helper/basic_geometry_collection_methods.rb +8 -0
  37. data/lib/rgeo/impl_helper/basic_line_string_methods.rb +8 -0
  38. data/lib/rgeo/impl_helper/basic_point_methods.rb +5 -0
  39. data/lib/rgeo/impl_helper/basic_polygon_methods.rb +8 -0
  40. data/test/common/factory_tests.rb +8 -2
  41. data/test/common/geometry_collection_tests.rb +23 -0
  42. data/test/common/line_string_tests.rb +25 -0
  43. data/test/common/multi_line_string_tests.rb +7 -0
  44. data/test/common/multi_point_tests.rb +7 -0
  45. data/test/common/multi_polygon_tests.rb +7 -0
  46. data/test/common/point_tests.rb +21 -0
  47. data/test/common/polygon_tests.rb +15 -0
  48. data/test/coord_sys/tc_proj4.rb +8 -1
  49. data/test/geos_capi/tc_misc.rb +1 -1
  50. data/test/tc_mixins.rb +1 -1
  51. metadata +9 -7
@@ -39,12 +39,10 @@ module RGeo
39
39
  module Geos
40
40
 
41
41
 
42
- class FFIGeometryImpl # :nodoc:
42
+ module FFIGeometryMethods # :nodoc:
43
43
 
44
44
  include Feature::Instance
45
45
 
46
- Feature::MixinCollection::GLOBAL.for_type(Feature::Geometry).include_in_class(self)
47
-
48
46
 
49
47
  def initialize(factory_, fg_geom_, klasses_)
50
48
  @factory = factory_
@@ -143,7 +141,7 @@ module RGeo
143
141
  if fg_geom_.type_id == ::Geos::GeomTypes::GEOS_POINT && fg_geom_.empty?
144
142
  fg_geom_ = ::Geos::Utils.create_geometry_collection
145
143
  end
146
- @factory.wrap_fg_geom(fg_geom_)
144
+ @factory._wrap_fg_geom(fg_geom_, nil)
147
145
  end
148
146
 
149
147
 
@@ -151,7 +149,7 @@ module RGeo
151
149
  if self.class == FFIGeometryCollectionImpl
152
150
  nil
153
151
  else
154
- @factory.wrap_fg_geom(@fg_geom.boundary)
152
+ @factory._wrap_fg_geom(@fg_geom.boundary, nil)
155
153
  end
156
154
  end
157
155
 
@@ -286,18 +284,18 @@ module RGeo
286
284
 
287
285
 
288
286
  def buffer(distance_)
289
- @factory.wrap_fg_geom(@fg_geom.buffer(distance_, @factory.buffer_resolution))
287
+ @factory._wrap_fg_geom(@fg_geom.buffer(distance_, @factory.buffer_resolution), nil)
290
288
  end
291
289
 
292
290
 
293
291
  def convex_hull
294
- @factory.wrap_fg_geom(@fg_geom.convex_hull)
292
+ @factory._wrap_fg_geom(@fg_geom.convex_hull, nil)
295
293
  end
296
294
 
297
295
 
298
296
  def intersection(rhs_)
299
297
  fg_ = factory._convert_to_fg_geometry(rhs_)
300
- fg_ ? @factory.wrap_fg_geom(@fg_geom.intersection(fg_)) : nil
298
+ fg_ ? @factory._wrap_fg_geom(@fg_geom.intersection(fg_), nil) : nil
301
299
  end
302
300
 
303
301
  alias_method :*, :intersection
@@ -305,7 +303,7 @@ module RGeo
305
303
 
306
304
  def union(rhs_)
307
305
  fg_ = factory._convert_to_fg_geometry(rhs_)
308
- fg_ ? @factory.wrap_fg_geom(@fg_geom.union(fg_)) : nil
306
+ fg_ ? @factory._wrap_fg_geom(@fg_geom.union(fg_), nil) : nil
309
307
  end
310
308
 
311
309
  alias_method :+, :union
@@ -313,7 +311,7 @@ module RGeo
313
311
 
314
312
  def difference(rhs_)
315
313
  fg_ = factory._convert_to_fg_geometry(rhs_)
316
- fg_ ? @factory.wrap_fg_geom(@fg_geom.difference(fg_)) : nil
314
+ fg_ ? @factory._wrap_fg_geom(@fg_geom.difference(fg_), nil) : nil
317
315
  end
318
316
 
319
317
  alias_method :-, :difference
@@ -321,7 +319,7 @@ module RGeo
321
319
 
322
320
  def sym_difference(rhs_)
323
321
  fg_ = factory._convert_to_fg_geometry(rhs_)
324
- fg_ ? @factory.wrap_fg_geom(@fg_geom.sym_difference(fg_)) : nil
322
+ fg_ ? @factory._wrap_fg_geom(@fg_geom.sym_difference(fg_), nil) : nil
325
323
  end
326
324
 
327
325
 
@@ -355,9 +353,7 @@ module RGeo
355
353
  end
356
354
 
357
355
 
358
- class FFIPointImpl < FFIGeometryImpl # :nodoc:
359
-
360
- Feature::MixinCollection::GLOBAL.for_type(Feature::Point).include_in_class(self)
356
+ module FFIPointMethods # :nodoc:
361
357
 
362
358
 
363
359
  def x
@@ -399,14 +395,15 @@ module RGeo
399
395
  end
400
396
 
401
397
 
402
- end
398
+ def hash
399
+ @hash ||= Utils.ffi_coord_seq_hash(@fg_geom.coord_seq, [@factory, geometry_type].hash)
400
+ end
403
401
 
404
402
 
405
- class FFILineStringImpl < FFIGeometryImpl # :nodoc:
403
+ end
406
404
 
407
405
 
408
- Feature::MixinCollection::GLOBAL.for_type(Feature::Curve).include_in_class(self)
409
- Feature::MixinCollection::GLOBAL.for_type(Feature::LineString).include_in_class(self)
406
+ module FFILineStringMethods # :nodoc:
410
407
 
411
408
 
412
409
  def geometry_type
@@ -475,13 +472,15 @@ module RGeo
475
472
  end
476
473
 
477
474
 
478
- end
475
+ def hash
476
+ @hash ||= Utils.ffi_coord_seq_hash(@fg_geom.coord_seq, [@factory, geometry_type].hash)
477
+ end
479
478
 
480
479
 
481
- class FFILinearRingImpl < FFILineStringImpl # :nodoc:
480
+ end
482
481
 
483
482
 
484
- Feature::MixinCollection::GLOBAL.for_type(Feature::LinearRing).include_in_class(self)
483
+ module FFILinearRingMethods # :nodoc:
485
484
 
486
485
 
487
486
  def geometry_type
@@ -492,10 +491,7 @@ module RGeo
492
491
  end
493
492
 
494
493
 
495
- class FFILineImpl < FFILineStringImpl # :nodoc:
496
-
497
-
498
- Feature::MixinCollection::GLOBAL.for_type(Feature::Line).include_in_class(self)
494
+ module FFILineMethods # :nodoc:
499
495
 
500
496
 
501
497
  def geometry_type
@@ -506,11 +502,7 @@ module RGeo
506
502
  end
507
503
 
508
504
 
509
- class FFIPolygonImpl < FFIGeometryImpl # :nodoc:
510
-
511
-
512
- Feature::MixinCollection::GLOBAL.for_type(Feature::Surface).include_in_class(self)
513
- Feature::MixinCollection::GLOBAL.for_type(Feature::Polygon).include_in_class(self)
505
+ module FFIPolygonMethods # :nodoc:
514
506
 
515
507
 
516
508
  def geometry_type
@@ -524,17 +516,17 @@ module RGeo
524
516
 
525
517
 
526
518
  def centroid
527
- @factory.wrap_fg_geom(@fg_geom.centroid, FFIPointImpl)
519
+ @factory._wrap_fg_geom(@fg_geom.centroid, FFIPointImpl)
528
520
  end
529
521
 
530
522
 
531
523
  def point_on_surface
532
- @factory.wrap_fg_geom(@fg_geom.point_on_surface, FFIPointImpl)
524
+ @factory._wrap_fg_geom(@fg_geom.point_on_surface, FFIPointImpl)
533
525
  end
534
526
 
535
527
 
536
528
  def exterior_ring
537
- @factory.wrap_fg_geom(@fg_geom.exterior_ring, FFILinearRingImpl)
529
+ @factory._wrap_fg_geom(@fg_geom.exterior_ring, FFILinearRingImpl)
538
530
  end
539
531
 
540
532
 
@@ -545,7 +537,7 @@ module RGeo
545
537
 
546
538
  def interior_ring_n(n_)
547
539
  if n_ >= 0 && n_ < @fg_geom.num_interior_rings
548
- @factory.wrap_fg_geom(@fg_geom.interior_ring_n(n_), FFILinearRingImpl)
540
+ @factory._wrap_fg_geom(@fg_geom.interior_ring_n(n_), FFILinearRingImpl)
549
541
  else
550
542
  nil
551
543
  end
@@ -554,7 +546,7 @@ module RGeo
554
546
 
555
547
  def interior_rings
556
548
  ::Array.new(@fg_geom.num_interior_rings) do |n_|
557
- @factory.wrap_fg_geom(@fg_geom.interior_ring_n(n_), FFILinearRingImpl)
549
+ @factory._wrap_fg_geom(@fg_geom.interior_ring_n(n_), FFILinearRingImpl)
558
550
  end
559
551
  end
560
552
 
@@ -576,13 +568,21 @@ module RGeo
576
568
  end
577
569
 
578
570
 
579
- end
571
+ def hash
572
+ @hash ||= begin
573
+ hash_ = Utils.ffi_coord_seq_hash(@fg_geom.exterior_ring.coord_seq,
574
+ [@factory, geometry_type].hash)
575
+ @fg_geom.interior_rings.inject(hash_) do |h_, r_|
576
+ Utils.ffi_coord_seq_hash(r_.coord_seq, h_)
577
+ end
578
+ end
579
+ end
580
580
 
581
581
 
582
- class FFIGeometryCollectionImpl < FFIGeometryImpl # :nodoc:
582
+ end
583
583
 
584
584
 
585
- Feature::MixinCollection::GLOBAL.for_type(Feature::GeometryCollection).include_in_class(self)
585
+ module FFIGeometryCollectionMethods # :nodoc:
586
586
 
587
587
 
588
588
  def geometry_type
@@ -612,7 +612,7 @@ module RGeo
612
612
 
613
613
  def geometry_n(n_)
614
614
  if n_ >= 0 && n_ < @fg_geom.num_geometries
615
- @factory.wrap_fg_geom(@fg_geom.get_geometry_n(n_),
615
+ @factory._wrap_fg_geom(@fg_geom.get_geometry_n(n_),
616
616
  @_klasses ? @_klasses[n_] : nil)
617
617
  else
618
618
  nil
@@ -623,7 +623,7 @@ module RGeo
623
623
  def [](n_)
624
624
  n_ += @fg_geom.num_geometries if n_ < 0
625
625
  if n_ >= 0 && n_ < @fg_geom.num_geometries
626
- @factory.wrap_fg_geom(@fg_geom.get_geometry_n(n_),
626
+ @factory._wrap_fg_geom(@fg_geom.get_geometry_n(n_),
627
627
  @_klasses ? @_klasses[n_] : nil)
628
628
  else
629
629
  nil
@@ -631,10 +631,20 @@ module RGeo
631
631
  end
632
632
 
633
633
 
634
+ def hash
635
+ @hash ||= begin
636
+ hash_ = [@factory, geometry_type].hash
637
+ (0...num_geometries).inject(hash_) do |h_, i_|
638
+ (1664525 * h_ + geometry_n(i_).hash).hash
639
+ end
640
+ end
641
+ end
642
+
643
+
634
644
  def each
635
645
  if block_given?
636
646
  @fg_geom.num_geometries.times do |n_|
637
- yield @factory.wrap_fg_geom(@fg_geom.get_geometry_n(n_),
647
+ yield @factory._wrap_fg_geom(@fg_geom.get_geometry_n(n_),
638
648
  @_klasses ? @_klasses[n_] : nil)
639
649
  end
640
650
  self
@@ -649,10 +659,7 @@ module RGeo
649
659
  end
650
660
 
651
661
 
652
- class FFIMultiPointImpl < FFIGeometryCollectionImpl # :nodoc:
653
-
654
-
655
- Feature::MixinCollection::GLOBAL.for_type(Feature::MultiPoint).include_in_class(self)
662
+ module FFIMultiPointMethods # :nodoc:
656
663
 
657
664
 
658
665
  def geometry_type
@@ -663,11 +670,7 @@ module RGeo
663
670
  end
664
671
 
665
672
 
666
- class FFIMultiLineStringImpl < FFIGeometryCollectionImpl # :nodoc:
667
-
668
-
669
- Feature::MixinCollection::GLOBAL.for_type(Feature::MultiCurve).include_in_class(self)
670
- Feature::MixinCollection::GLOBAL.for_type(Feature::MultiLineString).include_in_class(self)
673
+ module FFIMultiLineStringMethods # :nodoc:
671
674
 
672
675
 
673
676
  def geometry_type
@@ -692,11 +695,7 @@ module RGeo
692
695
  end
693
696
 
694
697
 
695
- class FFIMultiPolygonImpl < FFIGeometryCollectionImpl # :nodoc:
696
-
697
-
698
- Feature::MixinCollection::GLOBAL.for_type(Feature::MultiSurface).include_in_class(self)
699
- Feature::MixinCollection::GLOBAL.for_type(Feature::MultiPolygon).include_in_class(self)
698
+ module FFIMultiPolygonMethods # :nodoc:
700
699
 
701
700
 
702
701
  def geometry_type
@@ -710,12 +709,12 @@ module RGeo
710
709
 
711
710
 
712
711
  def centroid
713
- @factory.wrap_fg_geom(@fg_geom.centroid, FFIPointImpl)
712
+ @factory._wrap_fg_geom(@fg_geom.centroid, FFIPointImpl)
714
713
  end
715
714
 
716
715
 
717
716
  def point_on_surface
718
- @factory.wrap_fg_geom(@fg_geom.point_on_surface, FFIPointImpl)
717
+ @factory._wrap_fg_geom(@fg_geom.point_on_surface, FFIPointImpl)
719
718
  end
720
719
 
721
720
 
@@ -67,9 +67,9 @@ module RGeo
67
67
  # the given factory is a CAPI GEOS factory.
68
68
 
69
69
  def is_capi_geos?(object_)
70
- Factory === object_ || GeometryImpl === object_ ||
71
- ZMFactory === object_ && Factory === object_.z_factory ||
72
- ZMGeometryImpl === object_ && GeometryImpl === object_.z_geometry
70
+ CAPIFactory === object_ || CAPIGeometryImpl === object_ ||
71
+ ZMFactory === object_ && CAPIFactory === object_.z_factory ||
72
+ ZMGeometryImpl === object_ && CAPIGeometryImpl === object_.z_geometry
73
73
  end
74
74
 
75
75
 
@@ -87,7 +87,7 @@ module RGeo
87
87
  # factory is a GEOS factory. Does not distinguish between CAPI and FFI.
88
88
 
89
89
  def is_geos?(object_)
90
- Factory === object_ || GeometryImpl === object_ ||
90
+ CAPIFactory === object_ || CAPIGeometryImpl === object_ ||
91
91
  FFIFactory === object_ || FFIGeometryImpl === object_ ||
92
92
  ZMFactory === object_ || ZMGeometryImpl === object_
93
93
  end
@@ -204,7 +204,7 @@ module RGeo
204
204
  elsif native_interface_ == :ffi
205
205
  FFIFactory.new(opts_)
206
206
  else
207
- Factory.create(opts_)
207
+ CAPIFactory.create(opts_)
208
208
  end
209
209
  else
210
210
  nil
@@ -85,6 +85,13 @@ module RGeo
85
85
  end
86
86
 
87
87
 
88
+ def ffi_coord_seq_hash(cs_, hash_=0)
89
+ (0...cs_.length).inject(hash_) do |h_, i_|
90
+ [hash_, cs_.get_x(i_), cs_.get_y(i_), cs_.get_z(i_)].hash
91
+ end
92
+ end
93
+
94
+
88
95
  def _init
89
96
  if FFI_SUPPORTED
90
97
  @ffi_supports_prepared_level_1 = ::Geos::FFIGeos.respond_to?(:GEOSPreparedContains_r)
@@ -46,6 +46,23 @@ module RGeo
46
46
  include Feature::Factory::Instance
47
47
 
48
48
 
49
+ # :stopdoc:
50
+
51
+ TYPE_KLASSES = {
52
+ Feature::Point => ZMPointImpl,
53
+ Feature::LineString => ZMLineStringImpl,
54
+ Feature::Line => ZMLineImpl,
55
+ Feature::LinearRing => ZMLinearRingImpl,
56
+ Feature::Polygon => ZMPolygonImpl,
57
+ Feature::GeometryCollection => ZMGeometryCollectionImpl,
58
+ Feature::MultiPoint => ZMMultiPointImpl,
59
+ Feature::MultiLineString => ZMMultiLineStringImpl,
60
+ Feature::MultiPolygon => ZMMultiPolygonImpl,
61
+ }.freeze
62
+
63
+ # :startdoc:
64
+
65
+
49
66
  class << self
50
67
 
51
68
 
@@ -86,8 +103,8 @@ module RGeo
86
103
  @zfactory = FFIFactory.new(config_.merge(:has_z_coordinate => true))
87
104
  @mfactory = FFIFactory.new(config_.merge(:has_m_coordinate => true))
88
105
  else
89
- @zfactory = Factory.create(config_.merge(:has_z_coordinate => true))
90
- @mfactory = Factory.create(config_.merge(:has_m_coordinate => true))
106
+ @zfactory = CAPIFactory.create(config_.merge(:has_z_coordinate => true))
107
+ @mfactory = CAPIFactory.create(config_.merge(:has_m_coordinate => true))
91
108
  end
92
109
 
93
110
  wkt_generator_ = opts_[:wkt_generator]
@@ -270,6 +287,11 @@ module RGeo
270
287
  alias_method :==, :eql?
271
288
 
272
289
 
290
+ def hash
291
+ @hash ||= [@zfactory, @mfactory].hash
292
+ end
293
+
294
+
273
295
  # See ::RGeo::Feature::Factory#property
274
296
 
275
297
  def property(name_)
@@ -299,63 +321,63 @@ module RGeo
299
321
  # See ::RGeo::Feature::Factory#point
300
322
 
301
323
  def point(x_, y_, z_=0, m_=0)
302
- ZMPointImpl.create(self, @zfactory.point(x_, y_, z_), @mfactory.point(x_, y_, m_))
324
+ _create_feature(ZMPointImpl, @zfactory.point(x_, y_, z_), @mfactory.point(x_, y_, m_))
303
325
  end
304
326
 
305
327
 
306
328
  # See ::RGeo::Feature::Factory#line_string
307
329
 
308
330
  def line_string(points_)
309
- ZMLineStringImpl.create(self, @zfactory.line_string(points_), @mfactory.line_string(points_))
331
+ _create_feature(ZMLineStringImpl, @zfactory.line_string(points_), @mfactory.line_string(points_))
310
332
  end
311
333
 
312
334
 
313
335
  # See ::RGeo::Feature::Factory#line
314
336
 
315
337
  def line(start_, end_)
316
- ZMLineStringImpl.create(self, @zfactory.line(start_, end_), @mfactory.line(start_, end_))
338
+ _create_feature(ZMLineImpl, @zfactory.line(start_, end_), @mfactory.line(start_, end_))
317
339
  end
318
340
 
319
341
 
320
342
  # See ::RGeo::Feature::Factory#linear_ring
321
343
 
322
344
  def linear_ring(points_)
323
- ZMLineStringImpl.create(self, @zfactory.linear_ring(points_), @mfactory.linear_ring(points_))
345
+ _create_feature(ZMLinearRingImpl, @zfactory.linear_ring(points_), @mfactory.linear_ring(points_))
324
346
  end
325
347
 
326
348
 
327
349
  # See ::RGeo::Feature::Factory#polygon
328
350
 
329
351
  def polygon(outer_ring_, inner_rings_=nil)
330
- ZMPolygonImpl.create(self, @zfactory.polygon(outer_ring_, inner_rings_), @mfactory.polygon(outer_ring_, inner_rings_))
352
+ _create_feature(ZMPolygonImpl, @zfactory.polygon(outer_ring_, inner_rings_), @mfactory.polygon(outer_ring_, inner_rings_))
331
353
  end
332
354
 
333
355
 
334
356
  # See ::RGeo::Feature::Factory#collection
335
357
 
336
358
  def collection(elems_)
337
- ZMGeometryCollectionImpl.create(self, @zfactory.collection(elems_), @mfactory.collection(elems_))
359
+ _create_feature(ZMGeometryCollectionImpl, @zfactory.collection(elems_), @mfactory.collection(elems_))
338
360
  end
339
361
 
340
362
 
341
363
  # See ::RGeo::Feature::Factory#multi_point
342
364
 
343
365
  def multi_point(elems_)
344
- ZMGeometryCollectionImpl.create(self, @zfactory.multi_point(elems_), @mfactory.multi_point(elems_))
366
+ _create_feature(ZMMultiPointImpl, @zfactory.multi_point(elems_), @mfactory.multi_point(elems_))
345
367
  end
346
368
 
347
369
 
348
370
  # See ::RGeo::Feature::Factory#multi_line_string
349
371
 
350
372
  def multi_line_string(elems_)
351
- ZMMultiLineStringImpl.create(self, @zfactory.multi_line_string(elems_), @mfactory.multi_line_string(elems_))
373
+ _create_feature(ZMMultiLineStringImpl, @zfactory.multi_line_string(elems_), @mfactory.multi_line_string(elems_))
352
374
  end
353
375
 
354
376
 
355
377
  # See ::RGeo::Feature::Factory#multi_polygon
356
378
 
357
379
  def multi_polygon(elems_)
358
- ZMMultiPolygonImpl.create(self, @zfactory.multi_polygon(elems_), @mfactory.multi_polygon(elems_))
380
+ _create_feature(ZMMultiPolygonImpl, @zfactory.multi_polygon(elems_), @mfactory.multi_polygon(elems_))
359
381
  end
360
382
 
361
383
 
@@ -383,7 +405,7 @@ module RGeo
383
405
  type_ = original_.geometry_type
384
406
  ntype_ = type_ if keep_subtype_ && type_.include?(ntype_)
385
407
  case original_
386
- when ZMGeometryImpl
408
+ when ZMGeometryMethods
387
409
  # Optimization if we're just changing factories, but to
388
410
  # another ZM factory.
389
411
  if original_.factory != self && ntype_ == type_ &&
@@ -410,6 +432,12 @@ module RGeo
410
432
  end
411
433
 
412
434
 
435
+ def _create_feature(klass_, zgeometry_, mgeometry_) # :nodoc:
436
+ klass_ ||= TYPE_KLASSES[zgeometry_.geometry_type] || ZMGeometryImpl
437
+ zgeometry_ && mgeometry_ ? klass_.new(self, zgeometry_, mgeometry_) : nil
438
+ end
439
+
440
+
413
441
  def _marshal_wkb_generator # :nodoc:
414
442
  unless defined?(@marshal_wkb_generator)
415
443
  @marshal_wkb_generator = ::RGeo::WKRep::WKBGenerator.new(