rgeo 1.1.2 → 2.2.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 +144 -0
  3. data/ext/geos_c_impl/analysis.c +78 -0
  4. data/ext/geos_c_impl/analysis.h +42 -0
  5. data/ext/geos_c_impl/errors.c +35 -0
  6. data/ext/geos_c_impl/errors.h +22 -0
  7. data/ext/geos_c_impl/extconf.rb +6 -3
  8. data/ext/geos_c_impl/factory.c +14 -5
  9. data/ext/geos_c_impl/factory.h +5 -1
  10. data/ext/geos_c_impl/geometry.c +20 -2
  11. data/ext/geos_c_impl/geometry_collection.c +0 -17
  12. data/ext/geos_c_impl/main.c +5 -2
  13. data/ext/geos_c_impl/preface.h +3 -0
  14. data/lib/rgeo.rb +11 -13
  15. data/lib/rgeo/cartesian.rb +13 -23
  16. data/lib/rgeo/cartesian/analysis.rb +44 -20
  17. data/lib/rgeo/cartesian/bounding_box.rb +83 -79
  18. data/lib/rgeo/cartesian/calculations.rb +40 -38
  19. data/lib/rgeo/cartesian/factory.rb +134 -169
  20. data/lib/rgeo/cartesian/feature_classes.rb +2 -18
  21. data/lib/rgeo/cartesian/feature_methods.rb +37 -39
  22. data/lib/rgeo/cartesian/interface.rb +11 -9
  23. data/lib/rgeo/coord_sys.rb +9 -8
  24. data/lib/rgeo/coord_sys/cs/entities.rb +345 -303
  25. data/lib/rgeo/coord_sys/cs/factories.rb +30 -28
  26. data/lib/rgeo/coord_sys/cs/wkt_parser.rb +128 -126
  27. data/lib/rgeo/coord_sys/srs_database/{interface.rb → entry.rb} +26 -32
  28. data/lib/rgeo/coord_sys/srs_database/sr_org.rb +19 -17
  29. data/lib/rgeo/coord_sys/srs_database/url_reader.rb +21 -19
  30. data/lib/rgeo/error.rb +7 -1
  31. data/lib/rgeo/feature.rb +40 -51
  32. data/lib/rgeo/feature/curve.rb +2 -0
  33. data/lib/rgeo/feature/factory.rb +15 -13
  34. data/lib/rgeo/feature/factory_generator.rb +7 -5
  35. data/lib/rgeo/feature/geometry.rb +31 -29
  36. data/lib/rgeo/feature/geometry_collection.rb +6 -4
  37. data/lib/rgeo/feature/line.rb +2 -0
  38. data/lib/rgeo/feature/line_string.rb +3 -1
  39. data/lib/rgeo/feature/linear_ring.rb +12 -0
  40. data/lib/rgeo/feature/multi_curve.rb +2 -0
  41. data/lib/rgeo/feature/multi_line_string.rb +2 -0
  42. data/lib/rgeo/feature/multi_point.rb +2 -0
  43. data/lib/rgeo/feature/multi_polygon.rb +2 -0
  44. data/lib/rgeo/feature/multi_surface.rb +2 -0
  45. data/lib/rgeo/feature/point.rb +2 -0
  46. data/lib/rgeo/feature/polygon.rb +3 -1
  47. data/lib/rgeo/feature/surface.rb +2 -0
  48. data/lib/rgeo/feature/types.rb +107 -103
  49. data/lib/rgeo/geographic.rb +27 -37
  50. data/lib/rgeo/geographic/factory.rb +154 -199
  51. data/lib/rgeo/geographic/interface.rb +141 -137
  52. data/lib/rgeo/geographic/proj4_projector.rb +28 -23
  53. data/lib/rgeo/geographic/projected_feature_classes.rb +2 -18
  54. data/lib/rgeo/geographic/projected_feature_methods.rb +64 -54
  55. data/lib/rgeo/geographic/projected_window.rb +4 -2
  56. data/lib/rgeo/geographic/simple_mercator_projector.rb +41 -39
  57. data/lib/rgeo/geographic/spherical_feature_classes.rb +3 -18
  58. data/lib/rgeo/geographic/spherical_feature_methods.rb +90 -67
  59. data/lib/rgeo/geographic/spherical_math.rb +81 -87
  60. data/lib/rgeo/geos.rb +40 -53
  61. data/lib/rgeo/geos/capi_factory.rb +111 -136
  62. data/lib/rgeo/geos/capi_feature_classes.rb +22 -36
  63. data/lib/rgeo/geos/ffi_factory.rb +276 -297
  64. data/lib/rgeo/geos/ffi_feature_classes.rb +2 -20
  65. data/lib/rgeo/geos/ffi_feature_methods.rb +177 -169
  66. data/lib/rgeo/geos/interface.rb +25 -23
  67. data/lib/rgeo/geos/utils.rb +47 -39
  68. data/lib/rgeo/geos/zm_factory.rb +171 -185
  69. data/lib/rgeo/geos/zm_feature_classes.rb +2 -20
  70. data/lib/rgeo/geos/zm_feature_methods.rb +76 -72
  71. data/lib/rgeo/impl_helper.rb +8 -18
  72. data/lib/rgeo/impl_helper/basic_geometry_collection_methods.rb +84 -75
  73. data/lib/rgeo/impl_helper/basic_geometry_methods.rb +21 -23
  74. data/lib/rgeo/impl_helper/basic_line_string_methods.rb +95 -48
  75. data/lib/rgeo/impl_helper/basic_point_methods.rb +29 -25
  76. data/lib/rgeo/impl_helper/basic_polygon_methods.rb +68 -27
  77. data/lib/rgeo/impl_helper/math.rb +2 -0
  78. data/lib/rgeo/impl_helper/utils.rb +9 -15
  79. data/lib/rgeo/version.rb +3 -1
  80. data/lib/rgeo/wkrep.rb +24 -34
  81. data/lib/rgeo/wkrep/wkb_generator.rb +87 -84
  82. data/lib/rgeo/wkrep/wkb_parser.rb +93 -93
  83. data/lib/rgeo/wkrep/wkt_generator.rb +67 -63
  84. data/lib/rgeo/wkrep/wkt_parser.rb +172 -168
  85. metadata +30 -36
  86. data/lib/rgeo/feature/mixins.rb +0 -143
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # -----------------------------------------------------------------------------
2
4
  #
3
5
  # GEOS implementation additions written in Ruby
@@ -16,60 +18,54 @@ module RGeo
16
18
  # Marshal support
17
19
 
18
20
  def marshal_dump # :nodoc:
19
- factory_ = factory
20
- [factory_, factory_._write_for_marshal(self)]
21
+ my_factory = factory
22
+ [my_factory, my_factory.write_for_marshal(self)]
21
23
  end
22
24
 
23
25
  def marshal_load(data_) # :nodoc:
24
- obj_ = data_[0]._read_for_marshal(data_[1])
25
- _steal(obj_)
26
+ obj = data_[0].read_for_marshal(data_[1])
27
+ _steal(obj)
26
28
  end
27
29
 
28
30
  # Psych support
29
31
 
30
- def encode_with(coder_) # :nodoc:
31
- factory_ = factory
32
- coder_["factory"] = factory_
33
- str_ = factory_._write_for_psych(self)
34
- str_ = str_.encode("US-ASCII") if str_.respond_to?(:encode)
35
- coder_["wkt"] = str_
32
+ def encode_with(coder) # :nodoc:
33
+ my_factory = factory
34
+ coder["factory"] = my_factory
35
+ str = my_factory.write_for_psych(self)
36
+ str = str.encode("US-ASCII") if str.respond_to?(:encode)
37
+ coder["wkt"] = str
36
38
  end
37
39
 
38
- def init_with(coder_) # :nodoc:
39
- obj_ = coder_["factory"]._read_for_psych(coder_["wkt"])
40
- _steal(obj_)
40
+ def init_with(coder) # :nodoc:
41
+ obj = coder["factory"].read_for_psych(coder["wkt"])
42
+ _steal(obj)
41
43
  end
42
44
 
43
45
  def as_text
44
- str_ = _as_text
45
- str_.force_encoding("US-ASCII") if str_.respond_to?(:force_encoding)
46
- str_
46
+ str = _as_text
47
+ str.force_encoding("US-ASCII") if str.respond_to?(:force_encoding)
48
+ str
47
49
  end
48
50
  alias to_s as_text
49
51
  end
50
52
 
51
53
  module CAPIGeometryCollectionMethods # :nodoc:
52
- include ::Enumerable
54
+ include Enumerable
53
55
  end
54
56
 
55
57
  class CAPIGeometryImpl # :nodoc:
56
58
  include CAPIGeometryMethods
57
-
58
- Feature::MixinCollection::GLOBAL.for_type(Feature::Geometry).include_in_class(self, true)
59
59
  end
60
60
 
61
61
  class CAPIPointImpl # :nodoc:
62
62
  include CAPIGeometryMethods
63
63
  include CAPIPointMethods
64
-
65
- Feature::MixinCollection::GLOBAL.for_type(Feature::Point).include_in_class(self, true)
66
64
  end
67
65
 
68
66
  class CAPILineStringImpl # :nodoc:
69
67
  include CAPIGeometryMethods
70
68
  include CAPILineStringMethods
71
-
72
- Feature::MixinCollection::GLOBAL.for_type(Feature::LineString).include_in_class(self, true)
73
69
  end
74
70
 
75
71
  class CAPILinearRingImpl # :nodoc:
@@ -77,53 +73,43 @@ module RGeo
77
73
  include CAPILineStringMethods
78
74
  include CAPILinearRingMethods
79
75
 
80
- Feature::MixinCollection::GLOBAL.for_type(Feature::LinearRing).include_in_class(self, true)
76
+ def ccw?
77
+ RGeo::Cartesian::Analysis.ccw?(self)
78
+ end
81
79
  end
82
80
 
83
81
  class CAPILineImpl # :nodoc:
84
82
  include CAPIGeometryMethods
85
83
  include CAPILineStringMethods
86
84
  include CAPILineMethods
87
-
88
- Feature::MixinCollection::GLOBAL.for_type(Feature::Line).include_in_class(self, true)
89
85
  end
90
86
 
91
87
  class CAPIPolygonImpl # :nodoc:
92
88
  include CAPIGeometryMethods
93
89
  include CAPIPolygonMethods
94
-
95
- Feature::MixinCollection::GLOBAL.for_type(Feature::Polygon).include_in_class(self, true)
96
90
  end
97
91
 
98
92
  class CAPIGeometryCollectionImpl # :nodoc:
99
93
  include CAPIGeometryMethods
100
94
  include CAPIGeometryCollectionMethods
101
-
102
- Feature::MixinCollection::GLOBAL.for_type(Feature::GeometryCollection).include_in_class(self, true)
103
95
  end
104
96
 
105
97
  class CAPIMultiPointImpl # :nodoc:
106
98
  include CAPIGeometryMethods
107
99
  include CAPIGeometryCollectionMethods
108
100
  include CAPIMultiPointMethods
109
-
110
- Feature::MixinCollection::GLOBAL.for_type(Feature::MultiPoint).include_in_class(self, true)
111
101
  end
112
102
 
113
103
  class CAPIMultiLineStringImpl # :nodoc:
114
104
  include CAPIGeometryMethods
115
105
  include CAPIGeometryCollectionMethods
116
106
  include CAPIMultiLineStringMethods
117
-
118
- Feature::MixinCollection::GLOBAL.for_type(Feature::MultiLineString).include_in_class(self, true)
119
107
  end
120
108
 
121
109
  class CAPIMultiPolygonImpl # :nodoc:
122
110
  include CAPIGeometryMethods
123
111
  include CAPIGeometryCollectionMethods
124
112
  include CAPIMultiPolygonMethods
125
-
126
- Feature::MixinCollection::GLOBAL.for_type(Feature::MultiPolygon).include_in_class(self, true)
127
113
  end
128
114
  end
129
115
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # -----------------------------------------------------------------------------
2
4
  #
3
5
  # FFI-GEOS factory implementation
@@ -10,45 +12,46 @@ module RGeo
10
12
 
11
13
  class FFIFactory
12
14
  include Feature::Factory::Instance
15
+ include ImplHelper::Utils
13
16
 
14
17
  # Create a new factory. Returns nil if the FFI-GEOS implementation
15
18
  # is not supported.
16
19
  #
17
20
  # See RGeo::Geos.factory for a list of supported options.
18
21
 
19
- def initialize(opts_ = {})
22
+ def initialize(opts = {})
20
23
  # Main flags
21
- @uses_lenient_multi_polygon_assertions = opts_[:uses_lenient_assertions] ||
22
- opts_[:lenient_multi_polygon_assertions] || opts_[:uses_lenient_multi_polygon_assertions]
23
- @has_z = opts_[:has_z_coordinate] ? true : false
24
- @has_m = opts_[:has_m_coordinate] ? true : false
24
+ @uses_lenient_multi_polygon_assertions = opts[:uses_lenient_assertions] ||
25
+ opts[:lenient_multi_polygon_assertions] || opts[:uses_lenient_multi_polygon_assertions]
26
+ @has_z = opts[:has_z_coordinate] ? true : false
27
+ @has_m = opts[:has_m_coordinate] ? true : false
25
28
  if @has_z && @has_m
26
29
  raise Error::UnsupportedOperation, "GEOS cannot support both Z and M coordinates at the same time."
27
30
  end
28
31
  @_has_3d = @has_z || @has_m
29
- @buffer_resolution = opts_[:buffer_resolution].to_i
32
+ @buffer_resolution = opts[:buffer_resolution].to_i
30
33
  @buffer_resolution = 1 if @buffer_resolution < 1
31
- @_auto_prepare = opts_[:auto_prepare] == :disabled ? false : true
34
+ @_auto_prepare = opts[:auto_prepare] == :disabled ? false : true
32
35
 
33
36
  # Interpret the generator options
34
- wkt_generator_ = opts_[:wkt_generator]
37
+ wkt_generator_ = opts[:wkt_generator]
35
38
  case wkt_generator_
36
39
  when :geos
37
40
  @wkt_writer = ::Geos::WktWriter.new
38
41
  @wkt_generator = nil
39
- when ::Hash
42
+ when Hash
40
43
  @wkt_generator = WKRep::WKTGenerator.new(wkt_generator_)
41
44
  @wkt_writer = nil
42
45
  else
43
46
  @wkt_generator = WKRep::WKTGenerator.new(convert_case: :upper)
44
47
  @wkt_writer = nil
45
48
  end
46
- wkb_generator_ = opts_[:wkb_generator]
49
+ wkb_generator_ = opts[:wkb_generator]
47
50
  case wkb_generator_
48
51
  when :geos
49
52
  @wkb_writer = ::Geos::WkbWriter.new
50
53
  @wkb_generator = nil
51
- when ::Hash
54
+ when Hash
52
55
  @wkb_generator = WKRep::WKBGenerator.new(wkb_generator_)
53
56
  @wkb_writer = nil
54
57
  else
@@ -57,53 +60,49 @@ module RGeo
57
60
  end
58
61
 
59
62
  # Coordinate system (srid, proj4, and coord_sys)
60
- @srid = opts_[:srid]
61
- @proj4 = opts_[:proj4]
63
+ @srid = opts[:srid]
64
+ @proj4 = opts[:proj4]
62
65
  if @proj4 && CoordSys.check!(:proj4)
63
- if @proj4.is_a?(::String) || @proj4.is_a?(::Hash)
66
+ if @proj4.is_a?(String) || @proj4.is_a?(Hash)
64
67
  @proj4 = CoordSys::Proj4.create(@proj4)
65
68
  end
66
69
  else
67
70
  @proj4 = nil
68
71
  end
69
- @coord_sys = opts_[:coord_sys]
70
- if @coord_sys.is_a?(::String)
71
- @coord_sys = begin
72
- CoordSys::CS.create_from_wkt(@coord_sys)
73
- rescue
74
- nil
75
- end
76
- end
77
- if (!@proj4 || !@coord_sys) && @srid && (db_ = opts_[:srs_database])
78
- entry_ = db_.get(@srid.to_i)
79
- if entry_
80
- @proj4 ||= entry_.proj4
81
- @coord_sys ||= entry_.coord_sys
72
+ @coord_sys = opts[:coord_sys]
73
+ if @coord_sys.is_a?(String)
74
+ @coord_sys = CoordSys::CS.create_from_wkt(@coord_sys)
75
+ end
76
+ if (!@proj4 || !@coord_sys) && @srid && (db = opts[:srs_database])
77
+ entry = db.get(@srid.to_i)
78
+ if entry
79
+ @proj4 ||= entry.proj4
80
+ @coord_sys ||= entry.coord_sys
82
81
  end
83
82
  end
84
83
  @srid ||= @coord_sys.authority_code if @coord_sys
85
84
  @srid = @srid.to_i
86
85
 
87
86
  # Interpret parser options
88
- wkt_parser_ = opts_[:wkt_parser]
89
- case wkt_parser_
87
+ wkt_parser = opts[:wkt_parser]
88
+ case wkt_parser
90
89
  when :geos
91
90
  @wkt_reader = ::Geos::WktReader.new
92
91
  @wkt_parser = nil
93
- when ::Hash
94
- @wkt_parser = WKRep::WKTParser.new(self, wkt_parser_)
92
+ when Hash
93
+ @wkt_parser = WKRep::WKTParser.new(self, wkt_parser)
95
94
  @wkt_reader = nil
96
95
  else
97
96
  @wkt_parser = WKRep::WKTParser.new(self)
98
97
  @wkt_reader = nil
99
98
  end
100
- wkb_parser_ = opts_[:wkb_parser]
101
- case wkb_parser_
99
+ wkb_parser = opts[:wkb_parser]
100
+ case wkb_parser
102
101
  when :geos
103
102
  @wkb_reader = ::Geos::WkbReader.new
104
103
  @wkb_parser = nil
105
- when ::Hash
106
- @wkb_parser = WKRep::WKBParser.new(self, wkb_parser_)
104
+ when Hash
105
+ @wkb_parser = WKRep::WKBParser.new(self, wkb_parser)
107
106
  @wkb_reader = nil
108
107
  else
109
108
  @wkb_parser = WKRep::WKBParser.new(self)
@@ -119,12 +118,12 @@ module RGeo
119
118
 
120
119
  # Factory equivalence test.
121
120
 
122
- def eql?(rhs_)
123
- rhs_.is_a?(self.class) && @srid == rhs_.srid &&
124
- @has_z == rhs_.property(:has_z_coordinate) &&
125
- @has_m == rhs_.property(:has_m_coordinate) &&
126
- @buffer_resolution == rhs_.property(:buffer_resolution) &&
127
- @proj4.eql?(rhs_.proj4)
121
+ def eql?(rhs)
122
+ rhs.is_a?(self.class) && @srid == rhs.srid &&
123
+ @has_z == rhs.property(:has_z_coordinate) &&
124
+ @has_m == rhs.property(:has_m_coordinate) &&
125
+ @buffer_resolution == rhs.property(:buffer_resolution) &&
126
+ @proj4.eql?(rhs.proj4)
128
127
  end
129
128
  alias == eql?
130
129
 
@@ -137,100 +136,100 @@ module RGeo
137
136
  # Marshal support
138
137
 
139
138
  def marshal_dump # :nodoc:
140
- hash_ = {
139
+ hash = {
141
140
  "hasz" => @has_z,
142
141
  "hasm" => @has_m,
143
142
  "srid" => @srid,
144
143
  "bufr" => @buffer_resolution,
145
- "wktg" => @wkt_generator._properties,
146
- "wkbg" => @wkb_generator._properties,
147
- "wktp" => @wkt_parser._properties,
148
- "wkbp" => @wkb_parser._properties,
144
+ "wktg" => @wkt_generator.properties,
145
+ "wkbg" => @wkb_generator.properties,
146
+ "wktp" => @wkt_parser.properties,
147
+ "wkbp" => @wkb_parser.properties,
149
148
  "lmpa" => @uses_lenient_multi_polygon_assertions,
150
149
  "apre" => @_auto_prepare
151
150
  }
152
- hash_["proj4"] = @proj4.marshal_dump if @proj4
153
- hash_["cs"] = @coord_sys.to_wkt if @coord_sys
154
- hash_
151
+ hash["proj4"] = @proj4.marshal_dump if @proj4
152
+ hash["cs"] = @coord_sys.to_wkt if @coord_sys
153
+ hash
155
154
  end
156
155
 
157
- def marshal_load(data_) # :nodoc:
158
- if (proj4_data_ = data_["proj4"]) && CoordSys.check!(:proj4)
159
- proj4_ = CoordSys::Proj4.allocate
160
- proj4_.marshal_load(proj4_data_)
156
+ def marshal_load(data) # :nodoc:
157
+ if (proj4_data = data["proj4"]) && CoordSys.check!(:proj4)
158
+ proj4 = CoordSys::Proj4.allocate
159
+ proj4.marshal_load(proj4_data)
161
160
  else
162
- proj4_ = nil
161
+ proj4 = nil
163
162
  end
164
- if (coord_sys_data_ = data_["cs"])
165
- coord_sys_ = CoordSys::CS.create_from_wkt(coord_sys_data_)
163
+ if (coord_sys_data = data["cs"])
164
+ coord_sys = CoordSys::CS.create_from_wkt(coord_sys_data)
166
165
  else
167
- coord_sys_ = nil
166
+ coord_sys = nil
168
167
  end
169
168
  initialize(
170
- has_z_coordinate: data_["hasz"],
171
- has_m_coordinate: data_["hasm"],
172
- srid: data_["srid"],
173
- buffer_resolution: data_["bufr"],
174
- wkt_generator: ImplHelper::Utils.symbolize_hash(data_["wktg"]),
175
- wkb_generator: ImplHelper::Utils.symbolize_hash(data_["wkbg"]),
176
- wkt_parser: ImplHelper::Utils.symbolize_hash(data_["wktp"]),
177
- wkb_parser: ImplHelper::Utils.symbolize_hash(data_["wkbp"]),
178
- uses_lenient_multi_polygon_assertions: data_["lmpa"],
179
- auto_prepare: (data_["apre"] ? :simple : :disabled),
180
- proj4: proj4_,
181
- coord_sys: coord_sys_
169
+ has_z_coordinate: data["hasz"],
170
+ has_m_coordinate: data["hasm"],
171
+ srid: data["srid"],
172
+ buffer_resolution: data["bufr"],
173
+ wkt_generator: symbolize_hash(data["wktg"]),
174
+ wkb_generator: symbolize_hash(data["wkbg"]),
175
+ wkt_parser: symbolize_hash(data["wktp"]),
176
+ wkb_parser: symbolize_hash(data["wkbp"]),
177
+ uses_lenient_multi_polygon_assertions: data["lmpa"],
178
+ auto_prepare: (data["apre"] ? :simple : :disabled),
179
+ proj4: proj4,
180
+ coord_sys: coord_sys
182
181
  )
183
182
  end
184
183
 
185
184
  # Psych support
186
185
 
187
- def encode_with(coder_) # :nodoc:
188
- coder_["has_z_coordinate"] = @has_z
189
- coder_["has_m_coordinate"] = @has_m
190
- coder_["srid"] = @srid
191
- coder_["buffer_resolution"] = @buffer_resolution
192
- coder_["lenient_multi_polygon_assertions"] = @uses_lenient_multi_polygon_assertions
193
- coder_["wkt_generator"] = @wkt_generator._properties
194
- coder_["wkb_generator"] = @wkb_generator._properties
195
- coder_["wkt_parser"] = @wkt_parser._properties
196
- coder_["wkb_parser"] = @wkb_parser._properties
197
- coder_["auto_prepare"] = @_auto_prepare ? "simple" : "disabled"
186
+ def encode_with(coder) # :nodoc:
187
+ coder["has_z_coordinate"] = @has_z
188
+ coder["has_m_coordinate"] = @has_m
189
+ coder["srid"] = @srid
190
+ coder["buffer_resolution"] = @buffer_resolution
191
+ coder["lenient_multi_polygon_assertions"] = @uses_lenient_multi_polygon_assertions
192
+ coder["wkt_generator"] = @wkt_generator.properties
193
+ coder["wkb_generator"] = @wkb_generator.properties
194
+ coder["wkt_parser"] = @wkt_parser.properties
195
+ coder["wkb_parser"] = @wkb_parser.properties
196
+ coder["auto_prepare"] = @_auto_prepare ? "simple" : "disabled"
198
197
  if @proj4
199
- str_ = @proj4.original_str || @proj4.canonical_str
200
- coder_["proj4"] = @proj4.radians? ? { "proj4" => str_, "radians" => true } : str_
198
+ str = @proj4.original_str || @proj4.canonical_str
199
+ coder["proj4"] = @proj4.radians? ? { "proj4" => str, "radians" => true } : str
201
200
  end
202
- coder_["coord_sys"] = @coord_sys.to_wkt if @coord_sys
201
+ coder["coord_sys"] = @coord_sys.to_wkt if @coord_sys
203
202
  end
204
203
 
205
- def init_with(coder_) # :nodoc:
206
- if (proj4_data_ = coder_["proj4"])
204
+ def init_with(coder) # :nodoc:
205
+ if (proj4_data = coder["proj4"])
207
206
  CoordSys.check!(:proj4)
208
- if proj4_data_.is_a?(::Hash)
209
- proj4_ = CoordSys::Proj4.create(proj4_data_["proj4"], radians: proj4_data_["radians"])
207
+ if proj4_data.is_a?(Hash)
208
+ proj4 = CoordSys::Proj4.create(proj4_data["proj4"], radians: proj4_data["radians"])
210
209
  else
211
- proj4_ = CoordSys::Proj4.create(proj4_data_.to_s)
210
+ proj4 = CoordSys::Proj4.create(proj4_data.to_s)
212
211
  end
213
212
  else
214
- proj4_ = nil
213
+ proj4 = nil
215
214
  end
216
- if (coord_sys_data_ = coder_["cs"])
217
- coord_sys_ = CoordSys::CS.create_from_wkt(coord_sys_data_.to_s)
215
+ if (coord_sys_data = coder["cs"])
216
+ coord_sys = CoordSys::CS.create_from_wkt(coord_sys_data.to_s)
218
217
  else
219
- coord_sys_ = nil
218
+ coord_sys = nil
220
219
  end
221
220
  initialize(
222
- has_z_coordinate: coder_["has_z_coordinate"],
223
- has_m_coordinate: coder_["has_m_coordinate"],
224
- srid: coder_["srid"],
225
- buffer_resolution: coder_["buffer_resolution"],
226
- wkt_generator: ImplHelper::Utils.symbolize_hash(coder_["wkt_generator"]),
227
- wkb_generator: ImplHelper::Utils.symbolize_hash(coder_["wkb_generator"]),
228
- wkt_parser: ImplHelper::Utils.symbolize_hash(coder_["wkt_parser"]),
229
- wkb_parser: ImplHelper::Utils.symbolize_hash(coder_["wkb_parser"]),
230
- auto_prepare: coder_["auto_prepare"] == "disabled" ? :disabled : :simple,
231
- uses_lenient_multi_polygon_assertions: coder_["lenient_multi_polygon_assertions"],
232
- proj4: proj4_,
233
- coord_sys: coord_sys_
221
+ has_z_coordinate: coder["has_z_coordinate"],
222
+ has_m_coordinate: coder["has_m_coordinate"],
223
+ srid: coder["srid"],
224
+ buffer_resolution: coder["buffer_resolution"],
225
+ wkt_generator: symbolize_hash(coder["wkt_generator"]),
226
+ wkb_generator: symbolize_hash(coder["wkb_generator"]),
227
+ wkt_parser: symbolize_hash(coder["wkt_parser"]),
228
+ wkb_parser: symbolize_hash(coder["wkb_parser"]),
229
+ auto_prepare: coder["auto_prepare"] == "disabled" ? :disabled : :simple,
230
+ uses_lenient_multi_polygon_assertions: coder["lenient_multi_polygon_assertions"],
231
+ proj4: proj4,
232
+ coord_sys: coord_sys
234
233
  )
235
234
  end
236
235
 
@@ -268,181 +267,170 @@ module RGeo
268
267
  end
269
268
  end
270
269
 
271
- # Create a feature that wraps the given ffi-geos geometry object
272
-
273
- def wrap_fg_geom(fg_geom_)
274
- _wrap_fg_geom(fg_geom_, nil)
275
- end
276
-
277
270
  # See RGeo::Feature::Factory#parse_wkt
278
271
 
279
- def parse_wkt(str_)
272
+ def parse_wkt(str)
280
273
  if @wkt_reader
281
- _wrap_fg_geom(@wkt_reader.read(str_), nil)
274
+ wrap_fg_geom(@wkt_reader.read(str), nil)
282
275
  else
283
- @wkt_parser.parse(str_)
276
+ @wkt_parser.parse(str)
284
277
  end
285
278
  end
286
279
 
287
280
  # See RGeo::Feature::Factory#parse_wkb
288
281
 
289
- def parse_wkb(str_)
282
+ def parse_wkb(str)
290
283
  if @wkb_reader
291
- _wrap_fg_geom(@wkb_reader.read(str_), nil)
284
+ wrap_fg_geom(@wkb_reader.read(str), nil)
292
285
  else
293
- @wkb_parser.parse(str_)
286
+ @wkb_parser.parse(str)
294
287
  end
295
288
  end
296
289
 
297
290
  # See RGeo::Feature::Factory#point
298
291
 
299
- def point(x_, y_, z_ = 0)
300
- cs_ = ::Geos::CoordinateSequence.new(1, 3)
301
- cs_.set_x(0, x_)
302
- cs_.set_y(0, y_)
303
- cs_.set_z(0, z_)
304
- FFIPointImpl.new(self, ::Geos::Utils.create_point(cs_), nil)
292
+ def point(x, y, z = 0)
293
+ cs = ::Geos::CoordinateSequence.new(1, 3)
294
+ cs.set_x(0, x)
295
+ cs.set_y(0, y)
296
+ cs.set_z(0, z)
297
+ FFIPointImpl.new(self, ::Geos::Utils.create_point(cs), nil)
305
298
  end
306
299
 
307
300
  # See RGeo::Feature::Factory#line_string
308
301
 
309
- def line_string(points_)
310
- points_ = points_.to_a unless points_.is_a?(::Array)
311
- size_ = points_.size
312
- return nil if size_ == 1
313
- cs_ = ::Geos::CoordinateSequence.new(size_, 3)
314
- points_.each_with_index do |p_, i_|
315
- return nil unless RGeo::Feature::Point.check_type(p_)
316
- cs_.set_x(i_, p_.x)
317
- cs_.set_y(i_, p_.y)
302
+ def line_string(points)
303
+ points = points.to_a unless points.is_a?(Array)
304
+ size = points.size
305
+ raise(Error::InvalidGeometry, "Must have more than one point") if size == 1
306
+ cs = ::Geos::CoordinateSequence.new(size, 3)
307
+ points.each_with_index do |p, i|
308
+ raise(Error::InvalidGeometry, "Invalid point: #{p}") unless RGeo::Feature::Point.check_type(p)
309
+ cs.set_x(i, p.x)
310
+ cs.set_y(i, p.y)
318
311
  if @has_z
319
- cs_.set_z(i_, p_.z)
312
+ cs.set_z(i, p.z)
320
313
  elsif @has_m
321
- cs_.set_z(i_, p_.m)
314
+ cs.set_z(i, p.m)
322
315
  end
323
316
  end
324
- FFILineStringImpl.new(self, ::Geos::Utils.create_line_string(cs_), nil)
317
+ FFILineStringImpl.new(self, ::Geos::Utils.create_line_string(cs), nil)
325
318
  end
326
319
 
327
320
  # See RGeo::Feature::Factory#line
328
321
 
329
- def line(start_, end_)
330
- return nil unless RGeo::Feature::Point.check_type(start_) &&
331
- RGeo::Feature::Point.check_type(end_)
332
- cs_ = ::Geos::CoordinateSequence.new(2, 3)
333
- cs_.set_x(0, start_.x)
334
- cs_.set_x(1, end_.x)
335
- cs_.set_y(0, start_.y)
336
- cs_.set_y(1, end_.y)
322
+ def line(start, stop)
323
+ return unless RGeo::Feature::Point.check_type(start) &&
324
+ RGeo::Feature::Point.check_type(stop)
325
+ cs = ::Geos::CoordinateSequence.new(2, 3)
326
+ cs.set_x(0, start.x)
327
+ cs.set_x(1, stop.x)
328
+ cs.set_y(0, start.y)
329
+ cs.set_y(1, stop.y)
337
330
  if @has_z
338
- cs_.set_z(0, start_.z)
339
- cs_.set_z(1, end_.z)
331
+ cs.set_z(0, start.z)
332
+ cs.set_z(1, stop.z)
340
333
  elsif @has_m
341
- cs_.set_z(0, start_.m)
342
- cs_.set_z(1, end_.m)
334
+ cs.set_z(0, start.m)
335
+ cs.set_z(1, stop.m)
343
336
  end
344
- FFILineImpl.new(self, ::Geos::Utils.create_line_string(cs_), nil)
337
+ FFILineImpl.new(self, ::Geos::Utils.create_line_string(cs), nil)
345
338
  end
346
339
 
347
340
  # See RGeo::Feature::Factory#linear_ring
348
341
 
349
- def linear_ring(points_)
350
- points_ = points_.to_a unless points_.is_a?(::Array)
351
- fg_geom_ = _create_fg_linear_ring(points_)
352
- fg_geom_ ? FFILinearRingImpl.new(self, fg_geom_, nil) : nil
342
+ def linear_ring(points)
343
+ points = points.to_a unless points.is_a?(Array)
344
+ fg_geom = create_fg_linear_ring(points)
345
+ FFILinearRingImpl.new(self, fg_geom, nil)
353
346
  end
354
347
 
355
348
  # See RGeo::Feature::Factory#polygon
356
349
 
357
- def polygon(outer_ring_, inner_rings_ = nil)
358
- inner_rings_ = inner_rings_.to_a unless inner_rings_.is_a?(::Array)
359
- return nil unless RGeo::Feature::LineString.check_type(outer_ring_)
360
- outer_ring_ = _create_fg_linear_ring(outer_ring_.points)
361
- inner_rings_ = inner_rings_.map do |r_|
362
- return nil unless RGeo::Feature::LineString.check_type(r_)
363
- _create_fg_linear_ring(r_.points)
364
- end
365
- inner_rings_.compact!
366
- fg_geom_ = ::Geos::Utils.create_polygon(outer_ring_, *inner_rings_)
367
- fg_geom_ ? FFIPolygonImpl.new(self, fg_geom_, nil) : nil
350
+ def polygon(outer_ring, inner_rings = nil)
351
+ inner_rings = inner_rings.to_a unless inner_rings.is_a?(Array)
352
+ return unless RGeo::Feature::LineString.check_type(outer_ring)
353
+ outer_ring = create_fg_linear_ring(outer_ring.points)
354
+ inner_rings = inner_rings.map do |r|
355
+ return unless RGeo::Feature::LineString.check_type(r)
356
+ create_fg_linear_ring(r.points)
357
+ end
358
+ inner_rings.compact!
359
+ fg_geom = ::Geos::Utils.create_polygon(outer_ring, *inner_rings)
360
+ FFIPolygonImpl.new(self, fg_geom, nil)
368
361
  end
369
362
 
370
363
  # See RGeo::Feature::Factory#collection
371
364
 
372
- def collection(elems_)
373
- elems_ = elems_.to_a unless elems_.is_a?(::Array)
374
- klasses_ = []
375
- fg_geoms_ = []
376
- elems_.each do |elem_|
377
- k_ = elem_._klasses if elem_.factory.is_a?(FFIFactory)
378
- elem_ = RGeo::Feature.cast(elem_, self, :force_new, :keep_subtype)
379
- if elem_
380
- klasses_ << (k_ || elem_.class)
381
- fg_geoms_ << elem_._detach_fg_geom
365
+ def collection(elems)
366
+ elems = elems.to_a unless elems.is_a?(Array)
367
+ klasses = []
368
+ my_fg_geoms = []
369
+ elems.each do |elem|
370
+ k = elem._klasses if elem.factory.is_a?(FFIFactory)
371
+ elem = RGeo::Feature.cast(elem, self, :force_new, :keep_subtype)
372
+ if elem
373
+ klasses << (k || elem.class)
374
+ my_fg_geoms << elem.detach_fg_geom
382
375
  end
383
376
  end
384
- fg_geom_ = ::Geos::Utils.create_collection(
385
- ::Geos::GeomTypes::GEOS_GEOMETRYCOLLECTION, fg_geoms_)
386
- fg_geom_ ? FFIGeometryCollectionImpl.new(self, fg_geom_, klasses_) : nil
377
+ fg_geom = ::Geos::Utils.create_collection(::Geos::GeomTypes::GEOS_GEOMETRYCOLLECTION, my_fg_geoms)
378
+ FFIGeometryCollectionImpl.new(self, fg_geom, klasses)
387
379
  end
388
380
 
389
381
  # See RGeo::Feature::Factory#multi_point
390
382
 
391
- def multi_point(elems_)
392
- elems_ = elems_.to_a unless elems_.is_a?(::Array)
393
- elems_ = elems_.map do |elem_|
394
- elem_ = RGeo::Feature.cast(elem_, self, RGeo::Feature::Point,
383
+ def multi_point(elems)
384
+ elems = elems.to_a unless elems.is_a?(Array)
385
+ elems = elems.map do |elem|
386
+ elem = RGeo::Feature.cast(elem, self, RGeo::Feature::Point,
395
387
  :force_new, :keep_subtype)
396
- return nil unless elem_
397
- elem_._detach_fg_geom
388
+ return unless elem
389
+ elem.detach_fg_geom
398
390
  end
399
- klasses_ = ::Array.new(elems_.size, FFIPointImpl)
400
- fg_geom_ = ::Geos::Utils.create_collection(
401
- ::Geos::GeomTypes::GEOS_MULTIPOINT, elems_)
402
- fg_geom_ ? FFIMultiPointImpl.new(self, fg_geom_, klasses_) : nil
391
+ klasses = Array.new(elems.size, FFIPointImpl)
392
+ fg_geom = ::Geos::Utils.create_collection(::Geos::GeomTypes::GEOS_MULTIPOINT, elems)
393
+ FFIMultiPointImpl.new(self, fg_geom, klasses)
403
394
  end
404
395
 
405
396
  # See RGeo::Feature::Factory#multi_line_string
406
397
 
407
- def multi_line_string(elems_)
408
- elems_ = elems_.to_a unless elems_.is_a?(::Array)
409
- klasses_ = []
410
- elems_ = elems_.map do |elem_|
411
- elem_ = RGeo::Feature.cast(elem_, self, RGeo::Feature::LineString,
412
- :force_new, :keep_subtype)
413
- return nil unless elem_
414
- klasses_ << elem_.class
415
- elem_._detach_fg_geom
398
+ def multi_line_string(elems)
399
+ elems = elems.to_a unless elems.is_a?(Array)
400
+ klasses = []
401
+ elems = elems.map do |elem|
402
+ elem = RGeo::Feature.cast(elem, self, RGeo::Feature::LineString, :force_new, :keep_subtype)
403
+ raise(RGeo::Error::InvalidGeometry, "Parse error") unless elem
404
+ klasses << elem.class
405
+ elem.detach_fg_geom
416
406
  end
417
- fg_geom_ = ::Geos::Utils.create_collection(
418
- ::Geos::GeomTypes::GEOS_MULTILINESTRING, elems_)
419
- fg_geom_ ? FFIMultiLineStringImpl.new(self, fg_geom_, klasses_) : nil
407
+ fg_geom = ::Geos::Utils.create_collection(::Geos::GeomTypes::GEOS_MULTILINESTRING, elems)
408
+ FFIMultiLineStringImpl.new(self, fg_geom, klasses)
420
409
  end
421
410
 
422
411
  # See RGeo::Feature::Factory#multi_polygon
423
412
 
424
- def multi_polygon(elems_)
425
- elems_ = elems_.to_a unless elems_.is_a?(::Array)
426
- elems_ = elems_.map do |elem_|
427
- elem_ = RGeo::Feature.cast(elem_, self, RGeo::Feature::Polygon,
428
- :force_new, :keep_subtype)
429
- return nil unless elem_
430
- elem_._detach_fg_geom
413
+ def multi_polygon(elems)
414
+ elems = elems.to_a unless elems.is_a?(Array)
415
+ elems = elems.map do |elem|
416
+ elem = RGeo::Feature.cast(elem, self, RGeo::Feature::Polygon, :force_new, :keep_subtype)
417
+ raise(RGeo::Error::InvalidGeometry, "Could not cast to polygon: #{elem}") unless elem
418
+ elem.detach_fg_geom
431
419
  end
432
420
  unless @uses_lenient_multi_polygon_assertions
433
- (1...elems_.size).each do |i_|
434
- (0...i_).each do |j_|
435
- igeom_ = elems_[i_]
436
- jgeom_ = elems_[j_]
437
- return nil if igeom_.relate_pattern(jgeom_, "2********") ||
438
- igeom_.relate_pattern(jgeom_, "****1****")
421
+ (1...elems.size).each do |i|
422
+ (0...i).each do |j|
423
+ igeom = elems[i]
424
+ jgeom = elems[j]
425
+ if igeom.relate_pattern(jgeom, "2********") || igeom.relate_pattern(jgeom, "****1****")
426
+ raise(RGeo::Error::InvalidGeometry, "Invalid relate pattern: #{jgeom}")
427
+ end
439
428
  end
440
429
  end
441
430
  end
442
- klasses_ = ::Array.new(elems_.size, FFIPolygonImpl)
443
- fg_geom_ = ::Geos::Utils.create_collection(
444
- ::Geos::GeomTypes::GEOS_MULTIPOLYGON, elems_)
445
- fg_geom_ ? FFIMultiPolygonImpl.new(self, fg_geom_, klasses_) : nil
431
+ klasses = Array.new(elems.size, FFIPolygonImpl)
432
+ fg_geom = ::Geos::Utils.create_collection(::Geos::GeomTypes::GEOS_MULTIPOLYGON, elems)
433
+ FFIMultiPolygonImpl.new(self, fg_geom, klasses)
446
434
  end
447
435
 
448
436
  # See RGeo::Feature::Factory#proj4
@@ -455,138 +443,129 @@ module RGeo
455
443
 
456
444
  # See RGeo::Feature::Factory#override_cast
457
445
 
458
- def override_cast(_original_, _ntype_, _flags_)
446
+ def override_cast(original, ntype, flags)
459
447
  false
460
448
  # TODO
461
449
  end
462
450
 
463
- attr_reader :_has_3d # :nodoc:
464
- attr_reader :_auto_prepare # :nodoc:
465
-
466
- def _wrap_fg_geom(fg_geom_, klass_) # :nodoc:
467
- klasses_ = nil
451
+ # Create a feature that wraps the given ffi-geos geometry object
452
+ def wrap_fg_geom(fg_geom, klass = nil)
453
+ klasses = nil
468
454
 
469
455
  # We don't allow "empty" points, so replace such objects with
470
456
  # an empty collection.
471
- if fg_geom_.type_id == ::Geos::GeomTypes::GEOS_POINT && fg_geom_.empty?
472
- fg_geom_ = ::Geos::Utils.create_geometry_collection
473
- klass_ = FFIGeometryCollectionImpl
457
+ if fg_geom.type_id == ::Geos::GeomTypes::GEOS_POINT && fg_geom.empty?
458
+ fg_geom = ::Geos::Utils.create_geometry_collection
459
+ klass = FFIGeometryCollectionImpl
474
460
  end
475
461
 
476
- unless klass_.is_a?(::Class)
477
- is_collection_ = false
478
- case fg_geom_.type_id
462
+ unless klass.is_a?(::Class)
463
+ is_collection = false
464
+ case fg_geom.type_id
479
465
  when ::Geos::GeomTypes::GEOS_POINT
480
- inferred_klass_ = FFIPointImpl
466
+ inferred_klass = FFIPointImpl
481
467
  when ::Geos::GeomTypes::GEOS_MULTIPOINT
482
- inferred_klass_ = FFIMultiPointImpl
483
- is_collection_ = true
468
+ inferred_klass = FFIMultiPointImpl
469
+ is_collection = true
484
470
  when ::Geos::GeomTypes::GEOS_LINESTRING
485
- inferred_klass_ = FFILineStringImpl
471
+ inferred_klass = FFILineStringImpl
486
472
  when ::Geos::GeomTypes::GEOS_LINEARRING
487
- inferred_klass_ = FFILinearRingImpl
473
+ inferred_klass = FFILinearRingImpl
488
474
  when ::Geos::GeomTypes::GEOS_MULTILINESTRING
489
- inferred_klass_ = FFIMultiLineStringImpl
490
- is_collection_ = true
475
+ inferred_klass = FFIMultiLineStringImpl
476
+ is_collection = true
491
477
  when ::Geos::GeomTypes::GEOS_POLYGON
492
- inferred_klass_ = FFIPolygonImpl
478
+ inferred_klass = FFIPolygonImpl
493
479
  when ::Geos::GeomTypes::GEOS_MULTIPOLYGON
494
- inferred_klass_ = FFIMultiPolygonImpl
495
- is_collection_ = true
480
+ inferred_klass = FFIMultiPolygonImpl
481
+ is_collection = true
496
482
  when ::Geos::GeomTypes::GEOS_GEOMETRYCOLLECTION
497
- inferred_klass_ = FFIGeometryCollectionImpl
498
- is_collection_ = true
483
+ inferred_klass = FFIGeometryCollectionImpl
484
+ is_collection = true
499
485
  else
500
- inferred_klass_ = FFIGeometryImpl
486
+ inferred_klass = FFIGeometryImpl
501
487
  end
502
- klasses_ = klass_ if is_collection_ && klass_.is_a?(::Array)
503
- klass_ = inferred_klass_
488
+ klasses = klass if is_collection && klass.is_a?(Array)
489
+ klass = inferred_klass
504
490
  end
505
- klass_.new(self, fg_geom_, klasses_)
491
+ klass.new(self, fg_geom, klasses)
506
492
  end
507
493
 
508
- def _convert_to_fg_geometry(obj_, type_ = nil) # :nodoc:
509
- if type_.nil? && obj_.factory == self
510
- obj_
511
- else
512
- obj_ = Feature.cast(obj_, self, type_)
513
- end
514
- obj_ ? obj_.fg_geom : nil
515
- end
494
+ attr_reader :_has_3d # :nodoc:
495
+ attr_reader :_auto_prepare # :nodoc:
516
496
 
517
- def _create_fg_linear_ring(points_) # :nodoc:
518
- size_ = points_.size
519
- return nil if size_ == 1 || size_ == 2
520
- if size_ > 0 && points_.first != points_.last
521
- points_ += [points_.first]
522
- size_ += 1
523
- end
524
- cs_ = ::Geos::CoordinateSequence.new(size_, 3)
525
- points_.each_with_index do |p_, i_|
526
- return nil unless RGeo::Feature::Point.check_type(p_)
527
- cs_.set_x(i_, p_.x)
528
- cs_.set_y(i_, p_.y)
529
- if @has_z
530
- cs_.set_z(i_, p_.z)
531
- elsif @has_m
532
- cs_.set_z(i_, p_.m)
533
- end
497
+ def convert_to_fg_geometry(obj, type = nil)
498
+ if type && obj.factory != self
499
+ obj = Feature.cast(obj, self, type)
534
500
  end
535
- ::Geos::Utils.create_linear_ring(cs_)
501
+ obj&.fg_geom
536
502
  end
537
503
 
538
- def _generate_wkt(geom_) # :nodoc:
504
+ def generate_wkt(geom)
539
505
  if @wkt_writer
540
- @wkt_writer.write(geom_.fg_geom)
506
+ @wkt_writer.write(geom.fg_geom)
541
507
  else
542
- @wkt_generator.generate(geom_)
508
+ @wkt_generator.generate(geom)
543
509
  end
544
510
  end
545
511
 
546
- def _generate_wkb(geom_) # :nodoc:
512
+ def generate_wkb(geom)
547
513
  if @wkb_writer
548
- @wkb_writer.write(geom_.fg_geom)
514
+ @wkb_writer.write(geom.fg_geom)
549
515
  else
550
- @wkb_generator.generate(geom_)
516
+ @wkb_generator.generate(geom)
551
517
  end
552
518
  end
553
519
 
554
- def _write_for_marshal(geom_) # :nodoc:
520
+ def write_for_marshal(geom)
555
521
  if Utils.ffi_supports_set_output_dimension || !@_has_3d
556
- unless defined?(@marshal_wkb_writer)
557
- @marshal_wkb_writer = ::Geos::WkbWriter.new
558
- @marshal_wkb_writer.output_dimensions = 3 if @_has_3d
559
- end
560
- @marshal_wkb_writer.write(geom_.fg_geom)
522
+ wkb_writer = ::Geos::WkbWriter.new
523
+ wkb_writer.output_dimensions = 3 if @_has_3d
524
+ wkb_writer.write(geom.fg_geom)
561
525
  else
562
- Utils.marshal_wkb_generator.generate(geom_)
526
+ Utils.marshal_wkb_generator.generate(geom)
563
527
  end
564
528
  end
565
529
 
566
- def _read_for_marshal(str_) # :nodoc:
567
- unless defined?(@marshal_wkb_reader)
568
- @marshal_wkb_reader = ::Geos::WkbReader.new
569
- end
570
- @marshal_wkb_reader.read(str_)
530
+ def read_for_marshal(str)
531
+ ::Geos::WkbReader.new.read(str)
571
532
  end
572
533
 
573
- def _write_for_psych(geom_) # :nodoc:
534
+ def write_for_psych(geom)
574
535
  if Utils.ffi_supports_set_output_dimension || !@_has_3d
575
- unless defined?(@psych_wkt_writer)
576
- @psych_wkt_writer = ::Geos::WktWriter.new
577
- @psych_wkt_writer.output_dimensions = 3 if @_has_3d
578
- end
579
- @psych_wkt_writer.write(geom_.fg_geom)
536
+ wkt_writer = ::Geos::WktWriter.new
537
+ wkt_writer.output_dimensions = 3 if @_has_3d
538
+ wkt_writer.write(geom.fg_geom)
580
539
  else
581
- Utils.psych_wkt_generator.generate(geom_)
540
+ Utils.psych_wkt_generator.generate(geom)
582
541
  end
583
542
  end
584
543
 
585
- def _read_for_psych(str_) # :nodoc:
586
- unless defined?(@psych_wkt_reader)
587
- @psych_wkt_reader = ::Geos::WktReader.new
544
+ def read_for_psych(str)
545
+ ::Geos::WktReader.new.read(str)
546
+ end
547
+
548
+ private
549
+
550
+ def create_fg_linear_ring(points)
551
+ size = points.size
552
+ return if size == 1 || size == 2
553
+ if size > 0 && points.first != points.last
554
+ points += [points.first]
555
+ size += 1
556
+ end
557
+ cs = ::Geos::CoordinateSequence.new(size, 3)
558
+ points.each_with_index do |p, i|
559
+ return unless RGeo::Feature::Point.check_type(p)
560
+ cs.set_x(i, p.x)
561
+ cs.set_y(i, p.y)
562
+ if @has_z
563
+ cs.set_z(i, p.z)
564
+ elsif @has_m
565
+ cs.set_z(i, p.m)
566
+ end
588
567
  end
589
- @psych_wkt_reader.read(str_)
568
+ ::Geos::Utils.create_linear_ring(cs)
590
569
  end
591
570
  end
592
571
  end