rgeo 2.3.1 → 3.0.1

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