rgeo 3.0.0.pre.rc.2 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +10 -1
  3. data/ext/geos_c_impl/analysis.c +26 -23
  4. data/ext/geos_c_impl/analysis.h +8 -5
  5. data/ext/geos_c_impl/coordinates.c +27 -21
  6. data/ext/geos_c_impl/coordinates.h +5 -2
  7. data/ext/geos_c_impl/errors.c +15 -8
  8. data/ext/geos_c_impl/errors.h +4 -1
  9. data/ext/geos_c_impl/extconf.rb +40 -30
  10. data/ext/geos_c_impl/factory.c +405 -389
  11. data/ext/geos_c_impl/factory.h +71 -49
  12. data/ext/geos_c_impl/geometry.c +485 -408
  13. data/ext/geos_c_impl/geometry.h +5 -5
  14. data/ext/geos_c_impl/geometry_collection.c +269 -198
  15. data/ext/geos_c_impl/geometry_collection.h +6 -7
  16. data/ext/geos_c_impl/globals.c +99 -21
  17. data/ext/geos_c_impl/globals.h +3 -2
  18. data/ext/geos_c_impl/line_string.c +261 -220
  19. data/ext/geos_c_impl/line_string.h +5 -6
  20. data/ext/geos_c_impl/main.c +8 -9
  21. data/ext/geos_c_impl/point.c +62 -65
  22. data/ext/geos_c_impl/point.h +4 -5
  23. data/ext/geos_c_impl/polygon.c +121 -90
  24. data/ext/geos_c_impl/polygon.h +11 -9
  25. data/ext/geos_c_impl/preface.h +4 -13
  26. data/ext/geos_c_impl/ruby_more.c +39 -37
  27. data/ext/geos_c_impl/ruby_more.h +11 -2
  28. data/lib/rgeo/cartesian/analysis.rb +5 -3
  29. data/lib/rgeo/cartesian/bounding_box.rb +74 -79
  30. data/lib/rgeo/cartesian/calculations.rb +20 -26
  31. data/lib/rgeo/cartesian/factory.rb +52 -89
  32. data/lib/rgeo/cartesian/feature_methods.rb +0 -5
  33. data/lib/rgeo/cartesian/interface.rb +6 -5
  34. data/lib/rgeo/cartesian/planar_graph.rb +10 -16
  35. data/lib/rgeo/cartesian/sweepline_intersector.rb +1 -3
  36. data/lib/rgeo/cartesian/valid_op.rb +1 -3
  37. data/lib/rgeo/coord_sys/cs/entities.rb +299 -99
  38. data/lib/rgeo/coord_sys/cs/factories.rb +0 -2
  39. data/lib/rgeo/coord_sys/cs/wkt_parser.rb +85 -37
  40. data/lib/rgeo/coord_sys.rb +1 -9
  41. data/lib/rgeo/feature/curve.rb +0 -11
  42. data/lib/rgeo/feature/factory.rb +26 -36
  43. data/lib/rgeo/feature/factory_generator.rb +6 -11
  44. data/lib/rgeo/feature/geometry.rb +41 -40
  45. data/lib/rgeo/feature/geometry_collection.rb +3 -4
  46. data/lib/rgeo/feature/line_string.rb +1 -2
  47. data/lib/rgeo/feature/linear_ring.rb +0 -1
  48. data/lib/rgeo/feature/multi_curve.rb +0 -6
  49. data/lib/rgeo/feature/multi_surface.rb +0 -1
  50. data/lib/rgeo/feature/point.rb +0 -1
  51. data/lib/rgeo/feature/polygon.rb +1 -2
  52. data/lib/rgeo/feature/surface.rb +0 -1
  53. data/lib/rgeo/feature/types.rb +73 -83
  54. data/lib/rgeo/geographic/factory.rb +93 -119
  55. data/lib/rgeo/geographic/interface.rb +62 -116
  56. data/lib/rgeo/geographic/projected_feature_methods.rb +2 -16
  57. data/lib/rgeo/geographic/projected_window.rb +36 -22
  58. data/lib/rgeo/geographic/{proj4_projector.rb → projector.rb} +3 -3
  59. data/lib/rgeo/geographic/simple_mercator_projector.rb +24 -21
  60. data/lib/rgeo/geographic/spherical_feature_methods.rb +8 -8
  61. data/lib/rgeo/geographic/spherical_math.rb +17 -20
  62. data/lib/rgeo/geographic.rb +1 -1
  63. data/lib/rgeo/geos/capi_factory.rb +70 -124
  64. data/lib/rgeo/geos/capi_feature_classes.rb +0 -29
  65. data/lib/rgeo/geos/ffi_factory.rb +90 -131
  66. data/lib/rgeo/geos/ffi_feature_methods.rb +73 -128
  67. data/lib/rgeo/geos/interface.rb +21 -36
  68. data/lib/rgeo/geos/utils.rb +3 -3
  69. data/lib/rgeo/geos/zm_factory.rb +53 -76
  70. data/lib/rgeo/geos/zm_feature_methods.rb +16 -34
  71. data/lib/rgeo/geos.rb +2 -5
  72. data/lib/rgeo/impl_helper/basic_geometry_collection_methods.rb +5 -18
  73. data/lib/rgeo/impl_helper/basic_geometry_methods.rb +1 -2
  74. data/lib/rgeo/impl_helper/basic_line_string_methods.rb +18 -42
  75. data/lib/rgeo/impl_helper/basic_point_methods.rb +1 -13
  76. data/lib/rgeo/impl_helper/basic_polygon_methods.rb +16 -25
  77. data/lib/rgeo/impl_helper/utils.rb +21 -0
  78. data/lib/rgeo/impl_helper/valid_op.rb +12 -16
  79. data/lib/rgeo/impl_helper/validity_check.rb +3 -3
  80. data/lib/rgeo/version.rb +1 -1
  81. data/lib/rgeo/wkrep/wkb_generator.rb +73 -63
  82. data/lib/rgeo/wkrep/wkb_parser.rb +33 -31
  83. data/lib/rgeo/wkrep/wkt_generator.rb +52 -45
  84. data/lib/rgeo/wkrep/wkt_parser.rb +48 -35
  85. data/lib/rgeo.rb +1 -3
  86. metadata +10 -9
@@ -78,7 +78,6 @@ module RGeo
78
78
  # Therefore, if an implementation cannot provide a suitable test for
79
79
  # their equivalence types, they must degrade to use a stronger form
80
80
  # of equivalence.
81
-
82
81
  module Geometry
83
82
  extend Type
84
83
 
@@ -225,11 +224,6 @@ module RGeo
225
224
  raise Error::UnsupportedOperation, "Method #{self.class}#empty? not defined."
226
225
  end
227
226
 
228
- def is_empty?
229
- warn "The is_empty? method is deprecated, please use the empty? counterpart, will be removed in v3" unless ENV["RGEO_SILENCE_DEPRECATION"]
230
- empty?
231
- end
232
-
233
227
  # === SFS 1.1 Description
234
228
  #
235
229
  # Returns true if this geometric object has no anomalous geometric
@@ -247,11 +241,6 @@ module RGeo
247
241
  raise Error::UnsupportedOperation, "Method #{self.class}#simple? not defined."
248
242
  end
249
243
 
250
- def is_simple?
251
- warn "The is_simple? method is deprecated, please use the simple? counterpart, will be removed in v3" unless ENV["RGEO_SILENCE_DEPRECATION"]
252
- simple?
253
- end
254
-
255
244
  # === SFS 1.2 Description
256
245
  #
257
246
  # Returns 1 (TRUE) if this geometric object has z coordinate values.
@@ -304,7 +293,7 @@ module RGeo
304
293
  # this geometry, strictly speaking, the result of comparing objects
305
294
  # from different factories is undefined.
306
295
 
307
- def equals?(another_geometry)
296
+ def equals?(_another_geometry)
308
297
  raise Error::UnsupportedOperation, "Method #{self.class}#equals? not defined."
309
298
  end
310
299
 
@@ -323,7 +312,7 @@ module RGeo
323
312
  # this geometry, strictly speaking, the result of comparing objects
324
313
  # from different factories is undefined.
325
314
 
326
- def disjoint?(another_geometry)
315
+ def disjoint?(_another_geometry)
327
316
  raise Error::UnsupportedOperation, "Method #{self.class}#disjoint? not defined."
328
317
  end
329
318
 
@@ -342,7 +331,7 @@ module RGeo
342
331
  # this geometry, strictly speaking, the result of comparing objects
343
332
  # from different factories is undefined.
344
333
 
345
- def intersects?(another_geometry)
334
+ def intersects?(_another_geometry)
346
335
  raise Error::UnsupportedOperation, "Method #{self.class}#intersects? not defined."
347
336
  end
348
337
 
@@ -361,7 +350,7 @@ module RGeo
361
350
  # this geometry, strictly speaking, the result of comparing objects
362
351
  # from different factories is undefined.
363
352
 
364
- def touches?(another_geometry)
353
+ def touches?(_another_geometry)
365
354
  raise Error::UnsupportedOperation, "Method #{self.class}#touches? not defined."
366
355
  end
367
356
 
@@ -380,7 +369,7 @@ module RGeo
380
369
  # this geometry, strictly speaking, the result of comparing objects
381
370
  # from different factories is undefined.
382
371
 
383
- def crosses?(another_geometry)
372
+ def crosses?(_another_geometry)
384
373
  raise Error::UnsupportedOperation, "Method #{self.class}#crosses? not defined."
385
374
  end
386
375
 
@@ -399,7 +388,7 @@ module RGeo
399
388
  # this geometry, strictly speaking, the result of comparing objects
400
389
  # from different factories is undefined.
401
390
 
402
- def within?(another_geometry)
391
+ def within?(_another_geometry)
403
392
  raise Error::UnsupportedOperation, "Method #{self.class}#within? not defined."
404
393
  end
405
394
 
@@ -418,7 +407,7 @@ module RGeo
418
407
  # this geometry, strictly speaking, the result of comparing objects
419
408
  # from different factories is undefined.
420
409
 
421
- def contains?(another_geometry)
410
+ def contains?(_another_geometry)
422
411
  raise Error::UnsupportedOperation, "Method #{self.class}#contains? not defined."
423
412
  end
424
413
 
@@ -437,7 +426,7 @@ module RGeo
437
426
  # this geometry, strictly speaking, the result of comparing objects
438
427
  # from different factories is undefined.
439
428
 
440
- def overlaps?(another_geometry)
429
+ def overlaps?(_another_geometry)
441
430
  raise Error::UnsupportedOperation, "Method #{self.class}#overlaps? not defined."
442
431
  end
443
432
 
@@ -463,7 +452,7 @@ module RGeo
463
452
  # this geometry, strictly speaking, the result of comparing objects
464
453
  # from different factories is undefined.
465
454
 
466
- def relate?(another_geometry, _intersection_pattern_matrix_)
455
+ def relate?(_another_geometry, _intersection_pattern_matrix_)
467
456
  raise Error::UnsupportedOperation, "Method #{self.class}#relate not defined."
468
457
  end
469
458
 
@@ -509,7 +498,7 @@ module RGeo
509
498
  # this geometry, strictly speaking, the result of measuring the
510
499
  # distance between objects from different factories is undefined.
511
500
 
512
- def distance(another_geometry)
501
+ def distance(_another_geometry)
513
502
  raise Error::UnsupportedOperation, "Method #{self.class}#distance not defined."
514
503
  end
515
504
 
@@ -555,7 +544,7 @@ module RGeo
555
544
  # this geometry, strictly speaking, the result of performing
556
545
  # operations on objects from different factories is undefined.
557
546
 
558
- def intersection(another_geometry)
547
+ def intersection(_another_geometry)
559
548
  raise Error::UnsupportedOperation, "Method #{self.class}#intersection not defined."
560
549
  end
561
550
 
@@ -573,7 +562,7 @@ module RGeo
573
562
  # this geometry, strictly speaking, the result of performing
574
563
  # operations on objects from different factories is undefined.
575
564
 
576
- def union(another_geometry)
565
+ def union(_another_geometry)
577
566
  raise Error::UnsupportedOperation, "Method #{self.class}#union not defined."
578
567
  end
579
568
 
@@ -591,7 +580,7 @@ module RGeo
591
580
  # this geometry, strictly speaking, the result of performing
592
581
  # operations on objects from different factories is undefined.
593
582
 
594
- def difference(another_geometry)
583
+ def difference(_another_geometry)
595
584
  raise Error::UnsupportedOperation, "Method #{self.class}#difference not defined."
596
585
  end
597
586
 
@@ -609,7 +598,7 @@ module RGeo
609
598
  # this geometry, strictly speaking, the result of performing
610
599
  # operations on objects from different factories is undefined.
611
600
 
612
- def sym_difference(another_geometry)
601
+ def sym_difference(_another_geometry)
613
602
  raise Error::UnsupportedOperation, "Method #{self.class}#sym_difference not defined."
614
603
  end
615
604
 
@@ -621,7 +610,7 @@ module RGeo
621
610
  # this geometry, strictly speaking, the result of comparing objects
622
611
  # from different factories is undefined.
623
612
 
624
- def rep_equals?(another_geometry)
613
+ def rep_equals?(_another_geometry)
625
614
  raise Error::UnsupportedOperation, "Method #{self.class}#rep_equals? not defined."
626
615
  end
627
616
 
@@ -657,12 +646,12 @@ module RGeo
657
646
  # representational equivalence test, this method must fall back on
658
647
  # objective equivalence.
659
648
 
660
- def eql?(rhs)
661
- if rhs.is_a?(RGeo::Feature::Instance)
649
+ def eql?(other)
650
+ if other.is_a?(RGeo::Feature::Instance)
662
651
  begin
663
- rep_equals?(rhs)
652
+ rep_equals?(other)
664
653
  rescue Error::UnsupportedOperation
665
- equal?(rhs)
654
+ equal?(other)
666
655
  end
667
656
  else
668
657
  false
@@ -683,12 +672,12 @@ module RGeo
683
672
  # test, the == operator must fall back on representational or
684
673
  # objective equivalence.
685
674
 
686
- def ==(rhs)
687
- if rhs.is_a?(RGeo::Feature::Instance)
675
+ def ==(other)
676
+ if other.is_a?(RGeo::Feature::Instance)
688
677
  begin
689
- equals?(rhs)
678
+ equals?(other)
690
679
  rescue Error::UnsupportedOperation
691
- eql?(rhs)
680
+ eql?(other)
692
681
  end
693
682
  else
694
683
  false
@@ -700,8 +689,8 @@ module RGeo
700
689
  # types is not specified; an implementation may choose to provide
701
690
  # additional capabilities as appropriate.
702
691
 
703
- def -(rhs)
704
- difference(rhs)
692
+ def -(other)
693
+ difference(other)
705
694
  end
706
695
 
707
696
  # If the given rhs is a geometry object, this operator must behave
@@ -709,8 +698,8 @@ module RGeo
709
698
  # is not specified; an implementation may choose to provide
710
699
  # additional capabilities as appropriate.
711
700
 
712
- def +(rhs)
713
- union(rhs)
701
+ def +(other)
702
+ union(other)
714
703
  end
715
704
 
716
705
  # If the given rhs is a geometry object, this operator must behave
@@ -718,8 +707,20 @@ module RGeo
718
707
  # types is not specified; an implementation may choose to provide
719
708
  # additional capabilities as appropriate.
720
709
 
721
- def *(rhs)
722
- intersection(rhs)
710
+ def *(other)
711
+ intersection(other)
712
+ end
713
+
714
+ # Convenience method to transform/project a geometry
715
+ # to a different coordinate system from the geometry itself
716
+ # instead of the cast method.
717
+ #
718
+ # @note: Not an OGC SFS method
719
+ #
720
+ # @param [RGeo::Feature::Factory] other_factory
721
+ # @return [RGeo::Feature::Geometry]
722
+ def transform(other_factory)
723
+ Feature.cast(self, factory: other_factory, project: true)
723
724
  end
724
725
  end
725
726
  end
@@ -28,7 +28,6 @@ module RGeo
28
28
  # include this module itself. Therefore, you should not depend on the
29
29
  # kind_of? method to check type. Instead, use the provided check_type
30
30
  # class method (or === operator) defined in the Type module.
31
-
32
31
  module GeometryCollection
33
32
  include Geometry
34
33
  extend Type
@@ -58,7 +57,7 @@ module RGeo
58
57
  # Also note that this method is different from GeometryCollection#[]
59
58
  # in that it does not support negative indexes.
60
59
 
61
- def geometry_n(n)
60
+ def geometry_n(_idx)
62
61
  raise Error::UnsupportedOperation, "Method #{self.class}#geometry_n not defined."
63
62
  end
64
63
 
@@ -78,7 +77,7 @@ module RGeo
78
77
  # the same way Ruby's array indexing works. Hence, geometry_n(-1)
79
78
  # returns nil, where [-1] returns the last element of the collection.
80
79
 
81
- def [](n)
80
+ def [](_idx)
82
81
  raise Error::UnsupportedOperation, "Method #{self.class}#[] not defined."
83
82
  end
84
83
 
@@ -95,7 +94,7 @@ module RGeo
95
94
  # Note that all GeometryCollection implementations must also
96
95
  # include the Enumerable mixin.
97
96
 
98
- def each(&block)
97
+ def each(&_block)
99
98
  raise Error::UnsupportedOperation, "Method #{self.class}#each not defined."
100
99
  end
101
100
 
@@ -20,7 +20,6 @@ module RGeo
20
20
  # include this module itself. Therefore, you should not depend on the
21
21
  # kind_of? method to check type. Instead, use the provided check_type
22
22
  # class method (or === operator) defined in the Type module.
23
-
24
23
  module LineString
25
24
  include Curve
26
25
  extend Type
@@ -47,7 +46,7 @@ module RGeo
47
46
  # if the given N is out of range. N is zero-based.
48
47
  # Does not support negative indexes.
49
48
 
50
- def point_n(n)
49
+ def point_n(_idx)
51
50
  raise Error::UnsupportedOperation, "Method #{self.class}#point_n not defined."
52
51
  end
53
52
 
@@ -19,7 +19,6 @@ module RGeo
19
19
  # include this module itself. Therefore, you should not depend on the
20
20
  # kind_of? method to check type. Instead, use the provided check_type
21
21
  # class method (or === operator) defined in the Type module.
22
-
23
22
  module LinearRing
24
23
  include LineString
25
24
  extend Type
@@ -37,7 +37,6 @@ module RGeo
37
37
  # include this module itself. Therefore, you should not depend on the
38
38
  # kind_of? method to check type. Instead, use the provided check_type
39
39
  # class method (or === operator) defined in the Type module.
40
-
41
40
  module MultiCurve
42
41
  include GeometryCollection
43
42
  extend Type
@@ -68,11 +67,6 @@ module RGeo
68
67
  def closed?
69
68
  raise Error::UnsupportedOperation, "Method MultiCurve#closed? not defined."
70
69
  end
71
-
72
- def is_closed?
73
- warn "The is_closed? method is deprecated, please use the closed? counterpart, will be removed in v3" unless ENV["RGEO_SILENCE_DEPRECATION"]
74
- closed?
75
- end
76
70
  end
77
71
  end
78
72
  end
@@ -28,7 +28,6 @@ module RGeo
28
28
  # include this module itself. Therefore, you should not depend on the
29
29
  # kind_of? method to check type. Instead, use the provided check_type
30
30
  # class method (or === operator) defined in the Type module.
31
-
32
31
  module MultiSurface
33
32
  include GeometryCollection
34
33
  extend Type
@@ -33,7 +33,6 @@ module RGeo
33
33
  # replace them with empty GeometryCollection objects. Therefore,
34
34
  # currently, every RGeo Point object represents an actual location
35
35
  # with real coordinates.
36
-
37
36
  module Point
38
37
  include Geometry
39
38
  extend Type
@@ -45,7 +45,6 @@ module RGeo
45
45
  # include this module itself. Therefore, you should not depend on the
46
46
  # kind_of? method to check type. Instead, use the provided check_type
47
47
  # class method (or === operator) defined in the Type module.
48
-
49
48
  module Polygon
50
49
  include Surface
51
50
  extend Type
@@ -84,7 +83,7 @@ module RGeo
84
83
  # if the given N is out of range. N is zero-based.
85
84
  # Does not support negative indexes.
86
85
 
87
- def interior_ring_n(n)
86
+ def interior_ring_n(_idx)
88
87
  raise Error::UnsupportedOperation, "Method Polygon#interior_ring_n not defined."
89
88
  end
90
89
 
@@ -34,7 +34,6 @@ module RGeo
34
34
  # class method (or === operator) defined in the Type module.
35
35
  #
36
36
  # Some implementations may support higher dimensional points.
37
-
38
37
  module Surface
39
38
  include Geometry
40
39
  extend Type
@@ -11,7 +11,6 @@ module RGeo
11
11
  # All geometry implementations MUST include this submodule.
12
12
  # This serves as a marker that may be used to test an object for
13
13
  # feature-ness.
14
-
15
14
  module Instance
16
15
  end
17
16
 
@@ -49,7 +48,6 @@ module RGeo
49
48
  # a particular object is a feature type:
50
49
  #
51
50
  # RGeo::Feature::Type === object.geometry_type # true
52
-
53
51
  module Type
54
52
  # Returns true if the given object is this type or a subtype
55
53
  # thereof, or if it is a feature object whose geometry_type is
@@ -192,92 +190,84 @@ module RGeo
192
190
  # Types are the same
193
191
  if nfactory == factory
194
192
  force_new ? obj.dup : obj
195
- else
196
- if type == Point
197
- proj = nproj = nil
198
- if project
199
- proj = factory.proj4
200
- nproj = nfactory.proj4
201
- end
202
- hasz = factory.property(:has_z_coordinate)
203
- nhasz = nfactory.property(:has_z_coordinate)
204
- if proj && nproj && CoordSys.check!(:proj4)
205
- coords = CoordSys::Proj4.transform_coords(proj, nproj, obj.x, obj.y, hasz ? obj.z : nil)
206
- coords << (hasz ? obj.z : 0.0) if nhasz && coords.size < 3
207
- else
208
- coords = [obj.x, obj.y]
209
- coords << (hasz ? obj.z : 0.0) if nhasz
210
- end
211
- coords << (factory.property(:has_m_coordinate) ? obj.m : 0.0) if nfactory.property(:has_m_coordinate)
212
- nfactory.point(*coords)
213
- elsif type == Line
214
- nfactory.line(cast(obj.start_point, nfactory, opts), cast(obj.end_point, nfactory, opts))
215
- elsif type == LinearRing
216
- nfactory.linear_ring(obj.points.map { |p| cast(p, nfactory, opts) })
217
- elsif type == LineString
218
- nfactory.line_string(obj.points.map { |p| cast(p, nfactory, opts) })
219
- elsif type == Polygon
220
- nfactory.polygon(cast(obj.exterior_ring, nfactory, opts),
221
- obj.interior_rings.map { |r| cast(r, nfactory, opts) })
222
- elsif type == MultiPoint
223
- nfactory.multi_point(obj.map { |g| cast(g, nfactory, opts) })
224
- elsif type == MultiLineString
225
- nfactory.multi_line_string(obj.map { |g| cast(g, nfactory, opts) })
226
- elsif type == MultiPolygon
227
- nfactory.multi_polygon(obj.map { |g| cast(g, nfactory, opts) })
228
- elsif type == GeometryCollection
229
- nfactory.collection(obj.map { |g| cast(g, nfactory, opts) })
230
- end
231
- end
232
- else
233
- # Types are different
234
- if ntype == Point && (type == MultiPoint || type == GeometryCollection) ||
235
- (ntype == Line || ntype == LineString || ntype == LinearRing) && (type == MultiLineString || type == GeometryCollection) ||
236
- ntype == Polygon && (type == MultiPolygon || type == GeometryCollection)
237
- if obj.num_geometries == 1
238
- cast(obj.geometry_n(0), nfactory, ntype, opts)
239
- end
240
- elsif ntype == Point
241
- raise(Error::InvalidGeometry, "Cannot cast to Point")
242
- elsif ntype == Line
243
- if type == LineString && obj.num_points == 2
244
- nfactory.line(cast(obj.point_n(0), nfactory, opts), cast(obj.point_n(1), nfactory, opts))
245
- end
246
- elsif ntype == LinearRing
247
- if type == LineString
248
- nfactory.linear_ring(obj.points.map { |p| cast(p, nfactory, opts) })
249
- end
250
- elsif ntype == LineString
251
- if type == Line || type == LinearRing
252
- nfactory.line_string(obj.points.map { |p| cast(p, nfactory, opts) })
193
+ elsif type == Point
194
+ cs = ncs = nil
195
+ if project
196
+ cs = factory.coord_sys
197
+ ncs = nfactory.coord_sys
253
198
  end
254
- elsif ntype == MultiPoint
255
- if type == Point
256
- nfactory.multi_point([cast(obj, nfactory, opts)])
257
- elsif type == GeometryCollection
258
- nfactory.multi_point(obj.map { |p| cast(p, nfactory, opts) })
259
- end
260
- elsif ntype == MultiLineString
261
- if type == Line || type == LinearRing || type == LineString
262
- nfactory.multi_line_string([cast(obj, nfactory, opts)])
263
- elsif type == GeometryCollection
264
- nfactory.multi_line_string(obj.map { |p| cast(p, nfactory, opts) })
265
- end
266
- elsif ntype == MultiPolygon
267
- if type == Polygon
268
- nfactory.multi_polygon([cast(obj, nfactory, opts)])
269
- elsif type == GeometryCollection
270
- nfactory.multi_polygon(obj.map { |p| cast(p, nfactory, opts) })
271
- end
272
- elsif ntype == GeometryCollection
273
- if type == MultiPoint || type == MultiLineString || type == MultiPolygon
274
- nfactory.collection(obj.map { |p| cast(p, nfactory, opts) })
199
+ hasz = factory.property(:has_z_coordinate)
200
+ nhasz = nfactory.property(:has_z_coordinate)
201
+ if cs && ncs
202
+ coords = cs.transform_coords(ncs, obj.x, obj.y, hasz ? obj.z : nil)
203
+ coords << (hasz ? obj.z : 0.0) if nhasz && coords.size < 3
275
204
  else
276
- nfactory.collection([cast(obj, nfactory, opts)])
205
+ coords = [obj.x, obj.y]
206
+ coords << (hasz ? obj.z : 0.0) if nhasz
277
207
  end
208
+ coords << (factory.property(:has_m_coordinate) ? obj.m : 0.0) if nfactory.property(:has_m_coordinate)
209
+ nfactory.point(*coords)
210
+ elsif type == Line
211
+ nfactory.line(cast(obj.start_point, nfactory, opts), cast(obj.end_point, nfactory, opts))
212
+ elsif type == LinearRing
213
+ nfactory.linear_ring(obj.points.map { |p| cast(p, nfactory, opts) })
214
+ elsif type == LineString
215
+ nfactory.line_string(obj.points.map { |p| cast(p, nfactory, opts) })
216
+ elsif type == Polygon
217
+ nfactory.polygon(
218
+ cast(obj.exterior_ring, nfactory, opts),
219
+ obj.interior_rings.map { |r| cast(r, nfactory, opts) }
220
+ )
221
+ elsif type == MultiPoint
222
+ nfactory.multi_point(obj.map { |g| cast(g, nfactory, opts) })
223
+ elsif type == MultiLineString
224
+ nfactory.multi_line_string(obj.map { |g| cast(g, nfactory, opts) })
225
+ elsif type == MultiPolygon
226
+ nfactory.multi_polygon(obj.map { |g| cast(g, nfactory, opts) })
227
+ elsif type == GeometryCollection
228
+ nfactory.collection(obj.map { |g| cast(g, nfactory, opts) })
229
+ end
230
+ # Types are different
231
+ elsif ntype == Point && [MultiPoint, GeometryCollection].include?(type) ||
232
+ [Line, LineString, LinearRing].include?(ntype) && [MultiLineString, GeometryCollection].include?(type) ||
233
+ ntype == Polygon && [MultiPolygon, GeometryCollection].include?(type)
234
+ cast(obj.geometry_n(0), nfactory, ntype, opts) if obj.num_geometries == 1
235
+ elsif ntype == Point
236
+ raise(Error::InvalidGeometry, "Cannot cast to Point")
237
+ elsif ntype == Line
238
+ if type == LineString && obj.num_points == 2
239
+ nfactory.line(cast(obj.point_n(0), nfactory, opts), cast(obj.point_n(1), nfactory, opts))
240
+ end
241
+ elsif ntype == LinearRing
242
+ nfactory.linear_ring(obj.points.map { |p| cast(p, nfactory, opts) }) if type == LineString
243
+ elsif ntype == LineString
244
+ nfactory.line_string(obj.points.map { |p| cast(p, nfactory, opts) }) if [Line, LinearRing].include?(type)
245
+ elsif ntype == MultiPoint
246
+ if type == Point
247
+ nfactory.multi_point([cast(obj, nfactory, opts)])
248
+ elsif type == GeometryCollection
249
+ nfactory.multi_point(obj.map { |p| cast(p, nfactory, opts) })
250
+ end
251
+ elsif ntype == MultiLineString
252
+ if [Line, LinearRing, LineString].include?(type)
253
+ nfactory.multi_line_string([cast(obj, nfactory, opts)])
254
+ elsif type == GeometryCollection
255
+ nfactory.multi_line_string(obj.map { |p| cast(p, nfactory, opts) })
256
+ end
257
+ elsif ntype == MultiPolygon
258
+ if type == Polygon
259
+ nfactory.multi_polygon([cast(obj, nfactory, opts)])
260
+ elsif type == GeometryCollection
261
+ nfactory.multi_polygon(obj.map { |p| cast(p, nfactory, opts) })
262
+ end
263
+ elsif ntype == GeometryCollection
264
+ if [MultiPoint, MultiLineString, MultiPolygon].include?(type)
265
+ nfactory.collection(obj.map { |p| cast(p, nfactory, opts) })
278
266
  else
279
- raise(RGeo::Error::InvalidGeometry, "Undefined type cast from #{type.name} to #{ntype.name}")
267
+ nfactory.collection([cast(obj, nfactory, opts)])
280
268
  end
269
+ else
270
+ raise(RGeo::Error::InvalidGeometry, "Undefined type cast from #{type.name} to #{ntype.name}")
281
271
  end
282
272
  end
283
273
  end