rgeo 2.3.1 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +6 -0
  3. data/README.md +23 -14
  4. data/ext/geos_c_impl/analysis.c +30 -25
  5. data/ext/geos_c_impl/analysis.h +8 -7
  6. data/ext/geos_c_impl/coordinates.c +27 -21
  7. data/ext/geos_c_impl/coordinates.h +5 -2
  8. data/ext/geos_c_impl/errors.c +19 -10
  9. data/ext/geos_c_impl/errors.h +11 -4
  10. data/ext/geos_c_impl/extconf.rb +42 -28
  11. data/ext/geos_c_impl/factory.c +540 -451
  12. data/ext/geos_c_impl/factory.h +105 -95
  13. data/ext/geos_c_impl/geometry.c +593 -387
  14. data/ext/geos_c_impl/geometry.h +10 -5
  15. data/ext/geos_c_impl/geometry_collection.c +306 -339
  16. data/ext/geos_c_impl/geometry_collection.h +6 -20
  17. data/ext/geos_c_impl/globals.c +169 -0
  18. data/ext/geos_c_impl/globals.h +46 -0
  19. data/ext/geos_c_impl/line_string.c +271 -231
  20. data/ext/geos_c_impl/line_string.h +5 -8
  21. data/ext/geos_c_impl/main.c +16 -16
  22. data/ext/geos_c_impl/point.c +65 -67
  23. data/ext/geos_c_impl/point.h +4 -7
  24. data/ext/geos_c_impl/polygon.c +137 -135
  25. data/ext/geos_c_impl/polygon.h +11 -11
  26. data/ext/geos_c_impl/preface.h +16 -10
  27. data/ext/geos_c_impl/ruby_more.c +67 -0
  28. data/ext/geos_c_impl/ruby_more.h +25 -0
  29. data/lib/rgeo/cartesian/analysis.rb +5 -3
  30. data/lib/rgeo/cartesian/bounding_box.rb +74 -79
  31. data/lib/rgeo/cartesian/calculations.rb +64 -33
  32. data/lib/rgeo/cartesian/factory.rb +57 -102
  33. data/lib/rgeo/cartesian/feature_classes.rb +68 -46
  34. data/lib/rgeo/cartesian/feature_methods.rb +67 -25
  35. data/lib/rgeo/cartesian/interface.rb +6 -41
  36. data/lib/rgeo/cartesian/planar_graph.rb +373 -0
  37. data/lib/rgeo/cartesian/sweepline_intersector.rb +147 -0
  38. data/lib/rgeo/cartesian/valid_op.rb +69 -0
  39. data/lib/rgeo/cartesian.rb +3 -0
  40. data/lib/rgeo/coord_sys/cs/entities.rb +303 -99
  41. data/lib/rgeo/coord_sys/cs/factories.rb +0 -2
  42. data/lib/rgeo/coord_sys/cs/wkt_parser.rb +90 -42
  43. data/lib/rgeo/coord_sys.rb +1 -20
  44. data/lib/rgeo/error.rb +15 -0
  45. data/lib/rgeo/feature/curve.rb +0 -11
  46. data/lib/rgeo/feature/factory.rb +26 -36
  47. data/lib/rgeo/feature/factory_generator.rb +6 -14
  48. data/lib/rgeo/feature/geometry.rb +146 -66
  49. data/lib/rgeo/feature/geometry_collection.rb +16 -9
  50. data/lib/rgeo/feature/line_string.rb +4 -5
  51. data/lib/rgeo/feature/linear_ring.rb +0 -1
  52. data/lib/rgeo/feature/multi_curve.rb +0 -6
  53. data/lib/rgeo/feature/multi_surface.rb +3 -4
  54. data/lib/rgeo/feature/point.rb +4 -5
  55. data/lib/rgeo/feature/polygon.rb +1 -2
  56. data/lib/rgeo/feature/surface.rb +3 -4
  57. data/lib/rgeo/feature/types.rb +69 -85
  58. data/lib/rgeo/geographic/factory.rb +98 -125
  59. data/lib/rgeo/geographic/interface.rb +69 -166
  60. data/lib/rgeo/geographic/projected_feature_classes.rb +21 -9
  61. data/lib/rgeo/geographic/projected_feature_methods.rb +67 -42
  62. data/lib/rgeo/geographic/projected_window.rb +36 -22
  63. data/lib/rgeo/geographic/{proj4_projector.rb → projector.rb} +3 -5
  64. data/lib/rgeo/geographic/simple_mercator_projector.rb +26 -25
  65. data/lib/rgeo/geographic/spherical_feature_classes.rb +29 -9
  66. data/lib/rgeo/geographic/spherical_feature_methods.rb +86 -9
  67. data/lib/rgeo/geographic/spherical_math.rb +17 -20
  68. data/lib/rgeo/geographic.rb +1 -1
  69. data/lib/rgeo/geos/capi_factory.rb +87 -158
  70. data/lib/rgeo/geos/capi_feature_classes.rb +50 -36
  71. data/lib/rgeo/geos/ffi_factory.rb +105 -173
  72. data/lib/rgeo/geos/ffi_feature_classes.rb +34 -10
  73. data/lib/rgeo/geos/ffi_feature_methods.rb +105 -127
  74. data/lib/rgeo/geos/interface.rb +20 -59
  75. data/lib/rgeo/geos/utils.rb +5 -5
  76. data/lib/rgeo/geos/zm_factory.rb +53 -95
  77. data/lib/rgeo/geos/zm_feature_methods.rb +30 -33
  78. data/lib/rgeo/geos.rb +8 -8
  79. data/lib/rgeo/impl_helper/basic_geometry_collection_methods.rb +9 -22
  80. data/lib/rgeo/impl_helper/basic_geometry_methods.rb +1 -2
  81. data/lib/rgeo/impl_helper/basic_line_string_methods.rb +28 -56
  82. data/lib/rgeo/impl_helper/basic_point_methods.rb +2 -14
  83. data/lib/rgeo/impl_helper/basic_polygon_methods.rb +17 -26
  84. data/lib/rgeo/impl_helper/utils.rb +21 -0
  85. data/lib/rgeo/impl_helper/valid_op.rb +350 -0
  86. data/lib/rgeo/impl_helper/validity_check.rb +139 -0
  87. data/lib/rgeo/impl_helper.rb +1 -0
  88. data/lib/rgeo/version.rb +1 -1
  89. data/lib/rgeo/wkrep/wkb_generator.rb +73 -63
  90. data/lib/rgeo/wkrep/wkb_parser.rb +33 -31
  91. data/lib/rgeo/wkrep/wkt_generator.rb +52 -45
  92. data/lib/rgeo/wkrep/wkt_parser.rb +48 -35
  93. data/lib/rgeo.rb +1 -3
  94. metadata +50 -13
  95. data/lib/rgeo/coord_sys/srs_database/entry.rb +0 -107
  96. data/lib/rgeo/coord_sys/srs_database/sr_org.rb +0 -64
  97. data/lib/rgeo/coord_sys/srs_database/url_reader.rb +0 -65
@@ -19,8 +19,40 @@ module RGeo
19
19
  # adding the geometries to it. You may then query it for the bounds,
20
20
  # or use it to determine whether it encloses other geometries or
21
21
  # bounding boxes.
22
-
23
22
  class BoundingBox
23
+ # Returns the bounding box's factory.
24
+ attr_reader :factory
25
+
26
+ # Returns true if this bounding box tracks Z coordinates.
27
+ attr_reader :has_z
28
+
29
+ # Returns true if this bounding box tracks M coordinates.
30
+ attr_reader :has_m
31
+
32
+ # Returns the minimum X, or nil if this bounding box is empty.
33
+ attr_reader :min_x
34
+
35
+ # Returns the maximum X, or nil if this bounding box is empty.
36
+ attr_reader :max_x
37
+
38
+ # Returns the minimum Y, or nil if this bounding box is empty.
39
+ attr_reader :min_y
40
+
41
+ # Returns the maximum Y, or nil if this bounding box is empty.
42
+ attr_reader :max_y
43
+
44
+ # Returns the minimum Z, or nil if this bounding box is empty.
45
+ attr_reader :min_z
46
+
47
+ # Returns the maximum Z, or nil if this bounding box is empty.
48
+ attr_reader :max_z
49
+
50
+ # Returns the minimum M, or nil if this bounding box is empty.
51
+ attr_reader :min_m
52
+
53
+ # Returns the maximum M, or nil if this bounding box is empty.
54
+ attr_reader :max_m
55
+
24
56
  # Create a bounding box given two corner points.
25
57
  # The bounding box will be given the factory of the first point.
26
58
  # You may also provide the same options available to
@@ -69,19 +101,15 @@ module RGeo
69
101
  end
70
102
  end
71
103
 
72
- def eql?(rhs) # :nodoc:
73
- rhs.is_a?(BoundingBox) && @factory == rhs.factory &&
74
- @min_x == rhs.min_x && @max_x == rhs.max_x &&
75
- @min_y == rhs.min_y && @max_y == rhs.max_y &&
76
- @min_z == rhs.min_z && @max_z == rhs.max_z &&
77
- @min_m == rhs.min_m && @max_m == rhs.max_m
104
+ def eql?(other) # :nodoc:
105
+ other.is_a?(BoundingBox) && @factory == other.factory &&
106
+ @min_x == other.min_x && @max_x == other.max_x &&
107
+ @min_y == other.min_y && @max_y == other.max_y &&
108
+ @min_z == other.min_z && @max_z == other.max_z &&
109
+ @min_m == other.min_m && @max_m == other.max_m
78
110
  end
79
111
  alias == eql?
80
112
 
81
- # Returns the bounding box's factory.
82
-
83
- attr_reader :factory
84
-
85
113
  # Returns true if this bounding box is still empty.
86
114
 
87
115
  def empty?
@@ -105,22 +133,6 @@ module RGeo
105
133
  @min_x && (@min_x == @max_x || @min_y == @max_y)
106
134
  end
107
135
 
108
- # Returns true if this bounding box tracks Z coordinates.
109
-
110
- attr_reader :has_z
111
-
112
- # Returns true if this bounding box tracks M coordinates.
113
-
114
- attr_reader :has_m
115
-
116
- # Returns the minimum X, or nil if this bounding box is empty.
117
-
118
- attr_reader :min_x
119
-
120
- # Returns the maximum X, or nil if this bounding box is empty.
121
-
122
- attr_reader :max_x
123
-
124
136
  # Returns the midpoint X, or nil if this bounding box is empty.
125
137
 
126
138
  def center_x
@@ -133,14 +145,6 @@ module RGeo
133
145
  @max_x ? @max_x - @min_x : 0
134
146
  end
135
147
 
136
- # Returns the minimum Y, or nil if this bounding box is empty.
137
-
138
- attr_reader :min_y
139
-
140
- # Returns the maximum Y, or nil if this bounding box is empty.
141
-
142
- attr_reader :max_y
143
-
144
148
  # Returns the midpoint Y, or nil if this bounding box is empty.
145
149
 
146
150
  def center_y
@@ -153,14 +157,6 @@ module RGeo
153
157
  @max_y ? @max_y - @min_y : 0
154
158
  end
155
159
 
156
- # Returns the minimum Z, or nil if this bounding box is empty.
157
-
158
- attr_reader :min_z
159
-
160
- # Returns the maximum Z, or nil if this bounding box is empty.
161
-
162
- attr_reader :max_z
163
-
164
160
  # Returns the midpoint Z, or nil if this bounding box is empty or has no Z.
165
161
 
166
162
  def center_z
@@ -170,16 +166,12 @@ module RGeo
170
166
  # Returns the Z span, 0 if this bounding box is empty, or nil if it has no Z.
171
167
 
172
168
  def z_span
173
- @has_z ? (@max_z ? @max_z - @min_z : 0) : nil
174
- end
169
+ return unless @has_z
175
170
 
176
- # Returns the minimum M, or nil if this bounding box is empty.
177
-
178
- attr_reader :min_m
171
+ return 0 unless @max_z
179
172
 
180
- # Returns the maximum M, or nil if this bounding box is empty.
181
-
182
- attr_reader :max_m
173
+ @max_z - @min_z
174
+ end
183
175
 
184
176
  # Returns the midpoint M, or nil if this bounding box is empty or has no M.
185
177
 
@@ -190,31 +182,37 @@ module RGeo
190
182
  # Returns the M span, 0 if this bounding box is empty, or nil if it has no M.
191
183
 
192
184
  def m_span
193
- @has_m ? (@max_m ? @max_m - @min_m : 0) : nil
185
+ return unless @has_m
186
+
187
+ return 0 unless @max_m
188
+
189
+ @max_m - @min_m
194
190
  end
195
191
 
196
192
  # Returns a point representing the minimum extent in all dimensions,
197
193
  # or nil if this bounding box is empty.
198
194
 
199
195
  def min_point
200
- if @min_x
201
- extras = []
202
- extras << @min_z if @has_z
203
- extras << @min_m if @has_m
204
- @factory.point(@min_x, @min_y, *extras)
205
- end
196
+ return unless @min_x
197
+
198
+ extras = []
199
+ extras << @min_z if @has_z
200
+ extras << @min_m if @has_m
201
+
202
+ @factory.point(@min_x, @min_y, *extras)
206
203
  end
207
204
 
208
205
  # Returns a point representing the maximum extent in all dimensions,
209
206
  # or nil if this bounding box is empty.
210
207
 
211
208
  def max_point
212
- if @min_x
213
- extras = []
214
- extras << @max_z if @has_z
215
- extras << @max_m if @has_m
216
- @factory.point(@max_x, @max_y, *extras)
217
- end
209
+ return unless @min_x
210
+
211
+ extras = []
212
+ extras << @max_z if @has_z
213
+ extras << @max_m if @has_m
214
+
215
+ @factory.point(@max_x, @max_y, *extras)
218
216
  end
219
217
 
220
218
  # Adjusts the extents of this bounding box to encompass the given
@@ -280,21 +278,18 @@ module RGeo
280
278
  # have M. Default is false.
281
279
 
282
280
  def contains?(rhs, opts = {})
283
- if Feature::Geometry === rhs
284
- contains?(BoundingBox.new(@factory).add(rhs))
285
- elsif rhs.empty?
286
- true
287
- elsif empty?
288
- false
289
- elsif @min_x > rhs.min_x || @max_x < rhs.max_x || @min_y > rhs.min_y || @max_y < rhs.max_y
290
- false
291
- elsif @has_m && rhs.has_m && !opts[:ignore_m] && (@min_m > rhs.min_m || @max_m < rhs.max_m)
292
- false
293
- elsif @has_z && rhs.has_z && !opts[:ignore_z] && (@min_z > rhs.min_z || @max_z < rhs.max_z)
294
- false
295
- else
296
- true
297
- end
281
+ return contains?(BoundingBox.new(@factory).add(rhs)) if Feature::Geometry === rhs
282
+
283
+ return true if rhs.empty?
284
+
285
+ return false if empty?
286
+
287
+ cmp_xymz =
288
+ (@min_x > rhs.min_x || @max_x < rhs.max_x || @min_y > rhs.min_y || @max_y < rhs.max_y) ||
289
+ (@has_m && rhs.has_m && !opts[:ignore_m] && (@min_m > rhs.min_m || @max_m < rhs.max_m)) ||
290
+ (@has_z && rhs.has_z && !opts[:ignore_z] && (@min_z > rhs.min_z || @max_z < rhs.max_z))
291
+
292
+ !cmp_xymz
298
293
  end
299
294
 
300
295
  # Returns this bounding box subdivided, as an array of bounding boxes.
@@ -23,17 +23,14 @@ module RGeo
23
23
  @lensq = @dx * @dx + @dy * @dy
24
24
  end
25
25
 
26
- attr_reader :s
27
- attr_reader :e
28
- attr_reader :dx
29
- attr_reader :dy
26
+ attr_reader :s, :e, :dx, :dy
30
27
 
31
28
  def to_s
32
29
  "#{@s} - #{@e}"
33
30
  end
34
31
 
35
- def eql?(rhs)
36
- rhs.is_a?(Segment) && @s == rhs.s && @e == rhs.e
32
+ def eql?(other)
33
+ other.is_a?(Segment) && @s == other.s && @e == other.e
37
34
  end
38
35
  alias == eql?
39
36
 
@@ -45,23 +42,23 @@ module RGeo
45
42
  # a positive value if the point is to the right, or
46
43
  # 0 if the point is collinear to the segment.
47
44
 
48
- def side(p)
49
- px = p.x
50
- py = p.y
45
+ def side(point)
46
+ px = point.x
47
+ py = point.y
51
48
  (@sx - px) * (@ey - py) - (@sy - py) * (@ex - px)
52
49
  end
53
50
 
54
- def tproj(p)
51
+ def tproj(point)
55
52
  if @lensq == 0
56
53
  nil
57
54
  else
58
- (@dx * (p.x - @sx) + @dy * (p.y - @sy)) / @lensq
55
+ (@dx * (point.x - @sx) + @dy * (point.y - @sy)) / @lensq
59
56
  end
60
57
  end
61
58
 
62
- def contains_point?(p)
63
- if side(p) == 0
64
- t = tproj(p)
59
+ def contains_point?(point)
60
+ if side(point) == 0
61
+ t = tproj(point)
65
62
  t && t >= 0.0 && t <= 1.0
66
63
  else
67
64
  false
@@ -69,41 +66,75 @@ module RGeo
69
66
  end
70
67
 
71
68
  def intersects_segment?(seg)
69
+ !segment_intersection(seg).nil?
70
+ end
71
+
72
+ # If this and the other segment intersect, this method will return the coordinate
73
+ # at which they intersect, otherwise nil.
74
+ # In the case of a partial overlap (parallel segments), this will return
75
+ # a single point on the overlapping portion.
76
+ #
77
+ # @param seg [Segment]
78
+ #
79
+ # @return [RGeo::Feature::Point, nil]
80
+ def segment_intersection(seg)
72
81
  s2 = seg.s
73
82
  # Handle degenerate cases
74
83
  if seg.degenerate?
75
- if @lensq == 0
76
- return @s == s2
77
- else
78
- return contains_point?(s2)
79
- end
84
+ return @s if @lensq == 0 && @s == s2
85
+
86
+ return contains_point?(s2) ? s2 : nil
80
87
  elsif @lensq == 0
81
- return seg.contains_point?(@s)
88
+ return seg.contains_point?(@s) ? @s : nil
82
89
  end
90
+
83
91
  # Both segments have nonzero length.
84
92
  sx2 = s2.x
85
93
  sy2 = s2.y
86
94
  dx2 = seg.dx
87
95
  dy2 = seg.dy
88
96
  denom = @dx * dy2 - @dy * dx2
97
+
89
98
  if denom == 0
90
99
  # Segments are parallel. Make sure they are collinear.
91
- return false unless side(s2) == 0
92
- # 1-D check.
93
- ts = (@dx * (sx2 - @sx) + @dy * (sy2 - @sy)) / @lensq
94
- te = (@dx * (sx2 + dx2 - @sx) + @dy * (sy2 + dy2 - @sy)) / @lensq
95
- if ts < te
96
- te >= 0.0 && ts <= 1.0
97
- else
98
- ts >= 0.0 && te <= 1.0
99
- end
100
+ return nil unless side(s2) == 0
101
+
102
+ # return the first point it finds that intersects another line.
103
+ # In many cases, the intersection is actually another line
104
+ # segment, but for now, we will just return a single point.
105
+ return s2 if contains_point?(s2)
106
+ return seg.e if contains_point?(seg.e)
107
+ return @s if seg.contains_point?(@s)
108
+ return @e if seg.contains_point?(@e)
109
+ nil
100
110
  else
101
111
  # Segments are not parallel. Check the intersection of their
102
112
  # containing lines.
103
- t = (dy2 * (sx2 - @sx) + dx2 * (@sy - sy2)) / denom
104
- return false if t < 0.0 || t > 1.0
105
- t2 = (@dy * (sx2 - @sx) + @dx * (@sy - sy2)) / denom
106
- t2 >= 0.0 && t2 <= 1.0
113
+ num1 = dx2 * (@sy - sy2) - (dy2 * (@sx - sx2))
114
+ num2 = @dx * (@sy - sy2) - (@dy * (@sx - sx2))
115
+ cross1 = num1 / denom
116
+ cross2 = num2 / denom
117
+
118
+ return nil if cross1 < 0.0 || cross1 > 1.0
119
+ if cross2 >= 0.0 && cross2 <= 1.0
120
+ x = @sx + (cross1 * @dx)
121
+ y = @sy + (cross1 * @dy)
122
+
123
+ # Check if this segment contains the point.
124
+ # Sometimes round-off errors occur and intersections
125
+ # are recorded as off the line segments.
126
+ #
127
+ # If this is the case, return the closest point from
128
+ # either segment.
129
+ int_pt = @s.factory.point(x, y)
130
+
131
+ return int_pt if contains_point?(int_pt)
132
+
133
+ # find closest of @s, @e, seg.s, seg.e
134
+ [@e, seg.s, seg.e].reduce(@s) do |closest, pt|
135
+ int_pt.distance(pt) < int_pt.distance(closest) ? pt : closest
136
+ end
137
+ end
107
138
  end
108
139
  end
109
140
 
@@ -10,11 +10,18 @@ module RGeo
10
10
  module Cartesian
11
11
  # This class implements the factory for the simple cartesian
12
12
  # implementation.
13
-
14
13
  class Factory
15
14
  include Feature::Factory::Instance
16
15
  include ImplHelper::Utils
17
16
 
17
+ attr_reader :coordinate_dimension, :spatial_dimension
18
+
19
+ # Returns the SRID.
20
+ attr_reader :srid
21
+
22
+ # See RGeo::Feature::Factory#coord_sys
23
+ attr_reader :coord_sys
24
+
18
25
  # Create a new simple cartesian factory.
19
26
  #
20
27
  # See RGeo::Cartesian.simple_factory for a list of supported options.
@@ -22,74 +29,66 @@ module RGeo
22
29
  def initialize(opts = {})
23
30
  @has_z = opts[:has_z_coordinate] ? true : false
24
31
  @has_m = opts[:has_m_coordinate] ? true : false
25
- @proj4 = opts[:proj4]
26
- if @proj4 && CoordSys.check!(:proj4)
27
- if @proj4.is_a?(String) || @proj4.is_a?(Hash)
28
- @proj4 = CoordSys::Proj4.create(@proj4)
29
- end
30
- end
31
- srid = opts[:srid]
32
- @coord_sys = opts[:coord_sys]
33
- if @coord_sys.is_a?(String)
34
- @coord_sys = CoordSys::CS.create_from_wkt(@coord_sys)
35
- end
36
- if (!@proj4 || !@coord_sys) && srid && (db = opts[:srs_database])
37
- entry = db.get(srid.to_i)
38
- if entry
39
- @proj4 ||= entry.proj4
40
- @coord_sys ||= entry.coord_sys
41
- end
42
- end
43
- srid ||= @coord_sys.authority_code if @coord_sys
44
- @srid = srid.to_i
45
- @lenient_assertions = opts[:uses_lenient_assertions] ? true : false
32
+ @coordinate_dimension = 2
33
+ @coordinate_dimension += 1 if @has_z
34
+ @coordinate_dimension += 1 if @has_m
35
+ @spatial_dimension = @has_z ? 3 : 2
36
+
37
+ coord_sys_info = ImplHelper::Utils.setup_coord_sys(opts[:srid], opts[:coord_sys], opts[:coord_sys_class])
38
+ @coord_sys = coord_sys_info[:coord_sys]
39
+ @srid = coord_sys_info[:srid]
40
+
46
41
  @buffer_resolution = opts[:buffer_resolution].to_i
47
42
  @buffer_resolution = 1 if @buffer_resolution < 1
48
43
 
49
44
  wkt_generator = opts[:wkt_generator]
50
- case wkt_generator
51
- when Hash
52
- @wkt_generator = WKRep::WKTGenerator.new(wkt_generator)
53
- else
54
- @wkt_generator = WKRep::WKTGenerator.new(convert_case: :upper)
55
- end
45
+ @wkt_generator =
46
+ case wkt_generator
47
+ when Hash
48
+ WKRep::WKTGenerator.new(wkt_generator)
49
+ else
50
+ WKRep::WKTGenerator.new(convert_case: :upper)
51
+ end
56
52
  wkb_generator = opts[:wkb_generator]
57
- case wkb_generator
58
- when Hash
59
- @wkb_generator = WKRep::WKBGenerator.new(wkb_generator)
60
- else
61
- @wkb_generator = WKRep::WKBGenerator.new
62
- end
53
+ @wkb_generator =
54
+ case wkb_generator
55
+ when Hash
56
+ WKRep::WKBGenerator.new(wkb_generator)
57
+ else
58
+ WKRep::WKBGenerator.new
59
+ end
63
60
  wkt_parser = opts[:wkt_parser]
64
- case wkt_parser
65
- when Hash
66
- @wkt_parser = WKRep::WKTParser.new(self, wkt_parser)
67
- else
68
- @wkt_parser = WKRep::WKTParser.new(self)
69
- end
61
+ @wkt_parser =
62
+ case wkt_parser
63
+ when Hash
64
+ WKRep::WKTParser.new(self, wkt_parser)
65
+ else
66
+ WKRep::WKTParser.new(self)
67
+ end
70
68
  wkb_parser = opts[:wkb_parser]
71
- case wkb_parser
72
- when Hash
73
- @wkb_parser = WKRep::WKBParser.new(self, wkb_parser)
74
- else
75
- @wkb_parser = WKRep::WKBParser.new(self)
76
- end
69
+ @wkb_parser =
70
+ case wkb_parser
71
+ when Hash
72
+ WKRep::WKBParser.new(self, wkb_parser)
73
+ else
74
+ WKRep::WKBParser.new(self)
75
+ end
77
76
  end
78
77
 
79
78
  # Equivalence test.
80
79
 
81
- def eql?(rhs)
82
- rhs.is_a?(self.class) && @srid == rhs.srid &&
83
- @has_z == rhs.property(:has_z_coordinate) &&
84
- @has_m == rhs.property(:has_m_coordinate) &&
85
- @proj4.eql?(rhs.proj4)
80
+ def eql?(other)
81
+ other.is_a?(self.class) && @srid == other.srid &&
82
+ @has_z == other.property(:has_z_coordinate) &&
83
+ @has_m == other.property(:has_m_coordinate) &&
84
+ @coord_sys == other.instance_variable_get(:@coord_sys)
86
85
  end
87
86
  alias == eql?
88
87
 
89
88
  # Standard hash code
90
89
 
91
90
  def hash
92
- @hash ||= [@srid, @has_z, @has_m, @proj4].hash
91
+ @hash ||= [@srid, @has_z, @has_m, @coord_sys].hash
93
92
  end
94
93
 
95
94
  # Marshal support
@@ -103,26 +102,16 @@ module RGeo
103
102
  "wkbg" => @wkb_generator.properties,
104
103
  "wktp" => @wkt_parser.properties,
105
104
  "wkbp" => @wkb_parser.properties,
106
- "lena" => @lenient_assertions,
107
105
  "bufr" => @buffer_resolution
108
106
  }
109
- hash_["proj4"] = @proj4.marshal_dump if @proj4
110
107
  hash_["cs"] = @coord_sys.to_wkt if @coord_sys
111
108
  hash_
112
109
  end
113
110
 
114
111
  def marshal_load(data) # :nodoc:
115
- if (proj4_data = data["proj4"]) && CoordSys.check!(:proj4)
116
- proj4 = CoordSys::Proj4.allocate
117
- proj4.marshal_load(proj4_data)
118
- else
119
- proj4 = nil
120
- end
121
- if (coord_sys_data = data["cs"])
122
- coord_sys = CoordSys::CS.create_from_wkt(coord_sys_data)
123
- else
124
- coord_sys = nil
125
- end
112
+ cs_class = CoordSys::CONFIG.default_coord_sys_class
113
+ coord_sys = data["cs"]&.then { |cs| cs_class.create_from_wkt(cs) }
114
+
126
115
  initialize(
127
116
  has_z_coordinate: data["hasz"],
128
117
  has_m_coordinate: data["hasm"],
@@ -131,9 +120,7 @@ module RGeo
131
120
  wkb_generator: symbolize_hash(data["wkbg"]),
132
121
  wkt_parser: symbolize_hash(data["wktp"]),
133
122
  wkb_parser: symbolize_hash(data["wkbp"]),
134
- uses_lenient_assertions: data["lena"],
135
123
  buffer_resolution: data["bufr"],
136
- proj4: proj4,
137
124
  coord_sys: coord_sys
138
125
  )
139
126
  end
@@ -144,34 +131,18 @@ module RGeo
144
131
  coder["has_z_coordinate"] = @has_z
145
132
  coder["has_m_coordinate"] = @has_m
146
133
  coder["srid"] = @srid
147
- coder["lenient_assertions"] = @lenient_assertions
148
134
  coder["buffer_resolution"] = @buffer_resolution
149
135
  coder["wkt_generator"] = @wkt_generator.properties
150
136
  coder["wkb_generator"] = @wkb_generator.properties
151
137
  coder["wkt_parser"] = @wkt_parser.properties
152
138
  coder["wkb_parser"] = @wkb_parser.properties
153
- if @proj4
154
- str = @proj4.original_str || @proj4.canonical_str
155
- coder["proj4"] = @proj4.radians? ? { "proj4" => str, "radians" => true } : str
156
- end
157
139
  coder["coord_sys"] = @coord_sys.to_wkt if @coord_sys
158
140
  end
159
141
 
160
142
  def init_with(coder) # :nodoc:
161
- if (proj4_data = coder["proj4"]) && CoordSys.check!(:proj4)
162
- if proj4_data.is_a?(Hash)
163
- proj4 = CoordSys::Proj4.create(proj4_data["proj4"], radians: proj4_data["radians"])
164
- else
165
- proj4 = CoordSys::Proj4.create(proj4_data.to_s)
166
- end
167
- else
168
- proj4 = nil
169
- end
170
- if (coord_sys_data = coder["cs"])
171
- coord_sys = CoordSys::CS.create_from_wkt(coord_sys_data.to_s)
172
- else
173
- coord_sys = nil
174
- end
143
+ cs_class = CoordSys::CONFIG.default_coord_sys_class
144
+ coord_sys = coder["cs"]&.then { |cs| cs_class.create_from_wkt(cs) }
145
+
175
146
  initialize(
176
147
  has_z_coordinate: coder["has_z_coordinate"],
177
148
  has_m_coordinate: coder["has_m_coordinate"],
@@ -180,17 +151,11 @@ module RGeo
180
151
  wkb_generator: symbolize_hash(coder["wkb_generator"]),
181
152
  wkt_parser: symbolize_hash(coder["wkt_parser"]),
182
153
  wkb_parser: symbolize_hash(coder["wkb_parser"]),
183
- uses_lenient_assertions: coder["lenient_assertions"],
184
154
  buffer_resolution: coder["buffer_resolution"],
185
- proj4: proj4,
186
155
  coord_sys: coord_sys
187
156
  )
188
157
  end
189
158
 
190
- # Returns the SRID.
191
-
192
- attr_reader :srid
193
-
194
159
  # See RGeo::Feature::Factory#property
195
160
 
196
161
  def property(name)
@@ -199,8 +164,6 @@ module RGeo
199
164
  @has_z
200
165
  when :has_m_coordinate
201
166
  @has_m
202
- when :uses_lenient_assertions
203
- @lenient_assertions
204
167
  when :buffer_resolution
205
168
  @buffer_resolution
206
169
  when :is_cartesian
@@ -274,14 +237,6 @@ module RGeo
274
237
  MultiPolygonImpl.new(self, elems)
275
238
  end
276
239
 
277
- # See RGeo::Feature::Factory#proj4
278
-
279
- attr_reader :proj4
280
-
281
- # See RGeo::Feature::Factory#coord_sys
282
-
283
- attr_reader :coord_sys
284
-
285
240
  def generate_wkt(obj)
286
241
  @wkt_generator.generate(obj)
287
242
  end