rgeo 3.0.0.pre.rc.1 → 3.0.0.pre.rc.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +12 -12
  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 +391 -410
  11. data/ext/geos_c_impl/factory.h +66 -48
  12. data/ext/geos_c_impl/geometry.c +417 -299
  13. data/ext/geos_c_impl/geometry.h +5 -5
  14. data/ext/geos_c_impl/geometry_collection.c +289 -213
  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 +231 -200
  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 -63
  22. data/ext/geos_c_impl/point.h +4 -5
  23. data/ext/geos_c_impl/polygon.c +133 -94
  24. data/ext/geos_c_impl/polygon.h +10 -8
  25. data/ext/geos_c_impl/preface.h +8 -13
  26. data/ext/geos_c_impl/ruby_more.c +60 -0
  27. data/ext/geos_c_impl/ruby_more.h +17 -0
  28. data/lib/rgeo/cartesian/bounding_box.rb +1 -1
  29. data/lib/rgeo/cartesian/factory.rb +14 -50
  30. data/lib/rgeo/cartesian/feature_classes.rb +2 -0
  31. data/lib/rgeo/cartesian/feature_methods.rb +16 -5
  32. data/lib/rgeo/cartesian/interface.rb +6 -35
  33. data/lib/rgeo/coord_sys/cs/entities.rb +214 -0
  34. data/lib/rgeo/coord_sys/cs/wkt_parser.rb +15 -8
  35. data/lib/rgeo/coord_sys.rb +1 -20
  36. data/lib/rgeo/feature/curve.rb +0 -10
  37. data/lib/rgeo/feature/factory.rb +1 -9
  38. data/lib/rgeo/feature/factory_generator.rb +3 -10
  39. data/lib/rgeo/feature/geometry.rb +77 -8
  40. data/lib/rgeo/feature/multi_curve.rb +0 -5
  41. data/lib/rgeo/feature/types.rb +5 -5
  42. data/lib/rgeo/geographic/factory.rb +15 -42
  43. data/lib/rgeo/geographic/interface.rb +28 -127
  44. data/lib/rgeo/geographic/projected_feature_methods.rb +16 -10
  45. data/lib/rgeo/geographic/projected_window.rb +1 -1
  46. data/lib/rgeo/geographic/{proj4_projector.rb → projector.rb} +3 -3
  47. data/lib/rgeo/geographic/simple_mercator_projector.rb +1 -10
  48. data/lib/rgeo/geographic/spherical_feature_methods.rb +17 -6
  49. data/lib/rgeo/geographic.rb +1 -1
  50. data/lib/rgeo/geos/capi_factory.rb +37 -98
  51. data/lib/rgeo/geos/capi_feature_classes.rb +15 -25
  52. data/lib/rgeo/geos/ffi_factory.rb +58 -99
  53. data/lib/rgeo/geos/ffi_feature_methods.rb +15 -29
  54. data/lib/rgeo/geos/interface.rb +5 -37
  55. data/lib/rgeo/geos/zm_factory.rb +5 -43
  56. data/lib/rgeo/geos/zm_feature_methods.rb +15 -24
  57. data/lib/rgeo/geos.rb +8 -8
  58. data/lib/rgeo/impl_helper/basic_geometry_collection_methods.rb +1 -14
  59. data/lib/rgeo/impl_helper/basic_line_string_methods.rb +1 -19
  60. data/lib/rgeo/impl_helper/basic_point_methods.rb +0 -10
  61. data/lib/rgeo/impl_helper/basic_polygon_methods.rb +1 -9
  62. data/lib/rgeo/impl_helper/utils.rb +27 -0
  63. data/lib/rgeo/impl_helper/validity_check.rb +6 -5
  64. data/lib/rgeo/version.rb +1 -1
  65. data/lib/rgeo/wkrep/wkb_generator.rb +68 -53
  66. data/lib/rgeo/wkrep/wkb_parser.rb +19 -16
  67. data/lib/rgeo/wkrep/wkt_generator.rb +34 -34
  68. data/lib/rgeo/wkrep/wkt_parser.rb +26 -23
  69. data/lib/rgeo.rb +1 -3
  70. metadata +23 -9
  71. data/lib/rgeo/coord_sys/srs_database/entry.rb +0 -107
  72. data/lib/rgeo/coord_sys/srs_database/sr_org.rb +0 -64
  73. data/lib/rgeo/coord_sys/srs_database/url_reader.rb +0 -65
@@ -12,6 +12,22 @@ module RGeo
12
12
  def srid
13
13
  factory.srid
14
14
  end
15
+
16
+ def coordinate_dimension
17
+ factory.coordinate_dimension
18
+ end
19
+
20
+ def spatial_dimension
21
+ factory.spatial_dimension
22
+ end
23
+
24
+ def is_3d?
25
+ factory.property(:has_z_coordinate)
26
+ end
27
+
28
+ def measured?
29
+ factory.property(:has_m_coordinate)
30
+ end
15
31
  end
16
32
 
17
33
  module SphericalPointMethods # :nodoc:
@@ -121,11 +137,6 @@ module RGeo
121
137
  true
122
138
  end
123
139
 
124
- def is_simple?
125
- warn "The is_simple? method is deprecated, please use the simple? counterpart, will be removed in v3" unless ENV["RGEO_SILENCE_DEPRECATION"]
126
- simple?
127
- end
128
-
129
140
  def length
130
141
  arcs.inject(0.0) { |sum, arc| sum + arc.length } * SphericalMath::RADIUS
131
142
  end
@@ -216,7 +227,7 @@ module RGeo
216
227
  centroid_lat /= (6.0 * signed_area)
217
228
  centroid_lng /= (6.0 * signed_area)
218
229
 
219
- RGeo::Geographic.spherical_factory.point(centroid_lat, centroid_lng)
230
+ factory.point(centroid_lat, centroid_lng)
220
231
  end
221
232
  end
222
233
  end
@@ -24,7 +24,7 @@ require_relative "geographic/interface"
24
24
  require_relative "geographic/spherical_math"
25
25
  require_relative "geographic/spherical_feature_methods"
26
26
  require_relative "geographic/spherical_feature_classes"
27
- require_relative "geographic/proj4_projector"
27
+ require_relative "geographic/projector"
28
28
  require_relative "geographic/simple_mercator_projector"
29
29
  require_relative "geographic/projected_feature_methods"
30
30
  require_relative "geographic/projected_feature_classes"
@@ -20,90 +20,64 @@ module RGeo
20
20
  #
21
21
  # See RGeo::Geos.factory for a list of supported options.
22
22
 
23
- def create(opts_ = {})
23
+ def create(opts = {})
24
24
  # Make sure GEOS is available
25
25
  return unless respond_to?(:_create)
26
26
 
27
27
  # Get flags to pass to the C extension
28
28
  flags = 0
29
- flags |= 2 if opts_[:has_z_coordinate]
30
- flags |= 4 if opts_[:has_m_coordinate]
29
+ flags |= 2 if opts[:has_z_coordinate]
30
+ flags |= 4 if opts[:has_m_coordinate]
31
31
  if flags & 6 == 6
32
32
  raise Error::UnsupportedOperation, "GEOS cannot support both Z and M coordinates at the same time."
33
33
  end
34
- flags |= 8 unless opts_[:auto_prepare] == :disabled
34
+ flags |= 8 unless opts[:auto_prepare] == :disabled
35
35
 
36
36
  # Buffer resolution
37
- buffer_resolution_ = opts_[:buffer_resolution].to_i
38
- buffer_resolution_ = 1 if buffer_resolution_ < 1
37
+ buffer_resolution = opts[:buffer_resolution].to_i
38
+ buffer_resolution = 1 if buffer_resolution < 1
39
39
 
40
40
  # Interpret the generator options
41
- wkt_generator_ = opts_[:wkt_generator]
42
- case wkt_generator_
43
- when :geos
44
- wkt_generator_ = nil
41
+ wkt_generator = opts[:wkt_generator]
42
+ case wkt_generator
45
43
  when Hash
46
- wkt_generator_ = WKRep::WKTGenerator.new(wkt_generator_)
44
+ wkt_generator = WKRep::WKTGenerator.new(wkt_generator)
47
45
  else
48
- wkt_generator_ = WKRep::WKTGenerator.new(convert_case: :upper)
46
+ wkt_generator = nil
49
47
  end
50
- wkb_generator_ = opts_[:wkb_generator]
51
- case wkb_generator_
52
- when :geos
53
- wkb_generator_ = nil
48
+ wkb_generator = opts[:wkb_generator]
49
+ case wkb_generator
54
50
  when Hash
55
- wkb_generator_ = WKRep::WKBGenerator.new(wkb_generator_)
51
+ wkb_generator = WKRep::WKBGenerator.new(wkb_generator)
56
52
  else
57
- wkb_generator_ = WKRep::WKBGenerator.new
53
+ wkb_generator = nil
58
54
  end
59
55
 
60
- # Coordinate system (srid, proj4, and coord_sys)
61
- srid_ = opts_[:srid]
62
- proj4_ = opts_[:proj4]
63
- if proj4_ && CoordSys.check!(:proj4)
64
- if proj4_.is_a?(String) || proj4_.is_a?(Hash)
65
- proj4_ = CoordSys::Proj4.create(proj4_)
66
- end
67
- else
68
- proj4_ = nil
69
- end
70
- coord_sys_ = opts_[:coord_sys]
71
- if coord_sys_.is_a?(String)
72
- coord_sys_ = CoordSys::CS.create_from_wkt(coord_sys_)
73
- end
74
- if (!proj4_ || !coord_sys_) && srid_ && (db_ = opts_[:srs_database])
75
- entry_ = db_.get(srid_.to_i)
76
- if entry_
77
- proj4_ ||= entry_.proj4
78
- coord_sys_ ||= entry_.coord_sys
79
- end
80
- end
81
- srid_ ||= coord_sys_.authority_code if coord_sys_
56
+ # Coordinate system (srid and coord_sys)
57
+ coord_sys_info = ImplHelper::Utils.setup_coord_sys(opts[:srid], opts[:coord_sys], opts[:coord_sys_class])
58
+ srid = coord_sys_info[:srid]
59
+ coord_sys = coord_sys_info[:coord_sys]
82
60
 
83
61
  # Create the factory and set instance variables
84
- result = _create(flags, srid_.to_i, buffer_resolution_,
85
- wkt_generator_, wkb_generator_, proj4_, coord_sys_)
62
+ result = _create(flags, srid.to_i, buffer_resolution,
63
+ wkt_generator, wkb_generator, coord_sys)
86
64
 
87
65
  # Interpret parser options
88
- wkt_parser_ = opts_[:wkt_parser]
89
- case wkt_parser_
90
- when :geos
91
- wkt_parser_ = nil
66
+ wkt_parser = opts[:wkt_parser]
67
+ case wkt_parser
92
68
  when Hash
93
- wkt_parser_ = WKRep::WKTParser.new(result, wkt_parser_)
69
+ wkt_parser = WKRep::WKTParser.new(result, wkt_parser)
94
70
  else
95
- wkt_parser_ = WKRep::WKTParser.new(result)
71
+ wkt_parser = nil
96
72
  end
97
- wkb_parser_ = opts_[:wkb_parser]
98
- case wkb_parser_
99
- when :geos
100
- wkb_parser_ = nil
73
+ wkb_parser = opts[:wkb_parser]
74
+ case wkb_parser
101
75
  when Hash
102
- wkb_parser_ = WKRep::WKBParser.new(result, wkb_parser_)
76
+ wkb_parser = WKRep::WKBParser.new(result, wkb_parser)
103
77
  else
104
- wkb_parser_ = WKRep::WKBParser.new(result)
78
+ wkb_parser = nil
105
79
  end
106
- result._set_wkrep_parsers(wkt_parser_, wkb_parser_)
80
+ result._set_wkrep_parsers(wkt_parser, wkb_parser)
107
81
 
108
82
  # Return the result
109
83
  result
@@ -122,14 +96,14 @@ module RGeo
122
96
  def eql?(rhs_)
123
97
  rhs_.is_a?(CAPIFactory) && rhs_.srid == _srid &&
124
98
  rhs_._buffer_resolution == _buffer_resolution && rhs_._flags == _flags &&
125
- rhs_.proj4 == _proj4
99
+ rhs_.coord_sys == coord_sys
126
100
  end
127
101
  alias == eql?
128
102
 
129
103
  # Standard hash code
130
104
 
131
105
  def hash
132
- @hash ||= [_srid, _buffer_resolution, _flags, _proj4].hash
106
+ @hash ||= [_srid, _buffer_resolution, _flags].hash
133
107
  end
134
108
 
135
109
  # Marshal support
@@ -146,9 +120,6 @@ module RGeo
146
120
  "wkbp" => _wkb_parser ? _wkb_parser.properties : {},
147
121
  "apre" => auto_prepare
148
122
  }
149
- if (proj4_ = _proj4)
150
- hash_["proj4"] = proj4_.marshal_dump
151
- end
152
123
  if (coord_sys_ = _coord_sys)
153
124
  hash_["cs"] = coord_sys_.to_wkt
154
125
  end
@@ -156,14 +127,8 @@ module RGeo
156
127
  end
157
128
 
158
129
  def marshal_load(data_) # :nodoc:
159
- if (proj4_data_ = data_["proj4"]) && CoordSys.check!(:proj4)
160
- proj4_ = CoordSys::Proj4.allocate
161
- proj4_.marshal_load(proj4_data_)
162
- else
163
- proj4_ = nil
164
- end
165
130
  if (coord_sys_data_ = data_["cs"])
166
- coord_sys_ = CoordSys::CS.create_from_wkt(coord_sys_data_)
131
+ coord_sys_ = CoordSys::CONFIG.default_coord_sys_class.create_from_wkt(coord_sys_data_)
167
132
  else
168
133
  coord_sys_ = nil
169
134
  end
@@ -178,7 +143,6 @@ module RGeo
178
143
  wkt_parser: symbolize_hash(data_["wktp"]),
179
144
  wkb_parser: symbolize_hash(data_["wkbp"]),
180
145
  auto_prepare: data_["apre"],
181
- proj4: proj4_,
182
146
  coord_sys: coord_sys_
183
147
  )
184
148
  )
@@ -196,28 +160,14 @@ module RGeo
196
160
  coder_["wkt_parser"] = _wkt_parser ? _wkt_parser.properties : {}
197
161
  coder_["wkb_parser"] = _wkb_parser ? _wkb_parser.properties : {}
198
162
  coder_["auto_prepare"] = auto_prepare
199
- if (proj4_ = _proj4)
200
- str_ = proj4_.original_str || proj4_.canonical_str
201
- coder_["proj4"] = proj4_.radians? ? { "proj4" => str_, "radians" => true } : str_
202
- end
203
163
  if (coord_sys_ = _coord_sys)
204
164
  coder_["coord_sys"] = coord_sys_.to_wkt
205
165
  end
206
166
  end
207
167
 
208
168
  def init_with(coder_) # :nodoc:
209
- if (proj4_data_ = coder_["proj4"])
210
- CoordSys.check!(:proj4)
211
- if proj4_data_.is_a?(Hash)
212
- proj4_ = CoordSys::Proj4.create(proj4_data_["proj4"], radians: proj4_data_["radians"])
213
- else
214
- proj4_ = CoordSys::Proj4.create(proj4_data_.to_s)
215
- end
216
- else
217
- proj4_ = nil
218
- end
219
169
  if (coord_sys_data_ = coder_["cs"])
220
- coord_sys_ = CoordSys::CS.create_from_wkt(coord_sys_data_.to_s)
170
+ coord_sys_ = CoordSys::CONFIG.default_coord_sys_class.create_from_wkt(coord_sys_data_.to_s)
221
171
  else
222
172
  coord_sys_ = nil
223
173
  end
@@ -232,7 +182,6 @@ module RGeo
232
182
  wkt_parser: symbolize_hash(coder_["wkt_parser"]),
233
183
  wkb_parser: symbolize_hash(coder_["wkb_parser"]),
234
184
  auto_prepare: coder_["auto_prepare"] == "disabled" ? :disabled : :simple,
235
- proj4: proj4_,
236
185
  coord_sys: coord_sys_
237
186
  )
238
187
  )
@@ -283,11 +232,7 @@ module RGeo
283
232
  if (wkb_parser_ = _wkb_parser)
284
233
  wkb_parser_.parse(str_)
285
234
  else
286
- if str_[0] == "\x00" || str_[0] == "\x01"
287
- _parse_wkb_impl(str_)
288
- else
289
- _parse_wkb_impl([str_].pack('H*'))
290
- end
235
+ _parse_wkb_impl(str_)
291
236
  end
292
237
  end
293
238
 
@@ -358,12 +303,6 @@ module RGeo
358
303
  raise(RGeo::Error::InvalidGeometry, "Parse error")
359
304
  end
360
305
 
361
- # See RGeo::Feature::Factory#proj4
362
-
363
- def proj4
364
- _proj4
365
- end
366
-
367
306
  # See RGeo::Feature::Factory#coord_sys
368
307
 
369
308
  def coord_sys
@@ -382,10 +321,10 @@ module RGeo
382
321
  case original
383
322
  when CAPIGeometryMethods
384
323
  # Optimization if we're just changing factories, but the
385
- # factories are zm-compatible and proj4-compatible.
324
+ # factories are zm-compatible and coord_sys-compatible.
386
325
  if original.factory != self && ntype == type &&
387
326
  original.factory._flags & FLAG_SUPPORTS_Z_OR_M == _flags & FLAG_SUPPORTS_Z_OR_M &&
388
- (!project || original.factory.proj4 == _proj4)
327
+ (!project || original.factory.coord_sys == coord_sys)
389
328
  result = original.dup
390
329
  result.factory = self
391
330
  return result
@@ -393,7 +332,7 @@ module RGeo
393
332
  # LineString conversion optimization.
394
333
  if (original.factory != self || ntype != type) &&
395
334
  original.factory._flags & FLAG_SUPPORTS_Z_OR_M == _flags & FLAG_SUPPORTS_Z_OR_M &&
396
- (!project || original.factory.proj4 == _proj4) &&
335
+ (!project || original.factory.coord_sys == coord_sys) &&
397
336
  type.subtype_of?(Feature::LineString) && ntype.subtype_of?(Feature::LineString)
398
337
  return IMPL_CLASSES[ntype]._copy_from(self, original)
399
338
  end
@@ -13,14 +13,23 @@ module RGeo
13
13
  module CAPIGeometryMethods
14
14
  include Feature::Instance
15
15
 
16
- def is_empty? # rubocop:disable Naming/PredicateName
17
- warn "The is_empty? method is deprecated, please use the empty? counterpart, will be removed in v3" unless ENV["RGEO_SILENCE_DEPRECATION"]
18
- empty?
16
+ def coordinate_dimension
17
+ dim = 2
18
+ dim += 1 if factory.supports_z?
19
+ dim += 1 if factory.supports_m?
20
+ dim
19
21
  end
20
22
 
21
- def is_simple? # rubocop:disable Naming/PredicateName
22
- warn "The is_simple? method is deprecated, please use the simple? counterpart, will be removed in v3" unless ENV["RGEO_SILENCE_DEPRECATION"]
23
- simple?
23
+ def spatial_dimension
24
+ factory.supports_z? ? 3 : 2
25
+ end
26
+
27
+ def is_3d?
28
+ factory.supports_z?
29
+ end
30
+
31
+ def measured?
32
+ factory.supports_m?
24
33
  end
25
34
 
26
35
  def inspect
@@ -62,25 +71,6 @@ module RGeo
62
71
  alias to_s as_text
63
72
  end
64
73
 
65
- module CAPIMultiLineStringMethods # :nodoc:
66
- def is_closed? # rubocop:disable Naming/PredicateName
67
- warn "The is_closed? method is deprecated, please use the closed? counterpart, will be removed in v3" unless ENV["RGEO_SILENCE_DEPRECATION"]
68
- closed?
69
- end
70
- end
71
-
72
- module CAPILineStringMethods # :nodoc:
73
- def is_closed? # rubocop:disable Naming/PredicateName
74
- warn "The is_closed? method is deprecated, please use the closed? counterpart, will be removed in v3" unless ENV["RGEO_SILENCE_DEPRECATION"]
75
- closed?
76
- end
77
-
78
- def is_ring? # rubocop:disable Naming/PredicateName
79
- warn "The is_ring? method is deprecated, please use the ring? counterpart, will be removed in v3" unless ENV["RGEO_SILENCE_DEPRECATION"]
80
- ring?
81
- end
82
- end
83
-
84
74
  module CAPIGeometryCollectionMethods # :nodoc:
85
75
  include Enumerable
86
76
  end
@@ -25,87 +25,63 @@ module RGeo
25
25
  if @has_z && @has_m
26
26
  raise Error::UnsupportedOperation, "GEOS cannot support both Z and M coordinates at the same time."
27
27
  end
28
+ @coordinate_dimension = 2
29
+ @coordinate_dimension += 1 if @has_z
30
+ @coordinate_dimension += 1 if @has_m
31
+ @spatial_dimension = @has_z ? 3 : 2
32
+
28
33
  @_has_3d = @has_z || @has_m
29
34
  @buffer_resolution = opts[:buffer_resolution].to_i
30
35
  @buffer_resolution = 1 if @buffer_resolution < 1
31
- @_auto_prepare = opts[:auto_prepare] == :disabled ? false : true
36
+ @_auto_prepare = opts[:auto_prepare] != :disabled
32
37
 
33
38
  # Interpret the generator options
34
- wkt_generator_ = opts[:wkt_generator]
35
- case wkt_generator_
36
- when :geos
37
- @wkt_writer = ::Geos::WktWriter.new
38
- @wkt_generator = nil
39
+ wkt_generator = opts[:wkt_generator]
40
+ case wkt_generator
39
41
  when Hash
40
- @wkt_generator = WKRep::WKTGenerator.new(wkt_generator_)
42
+ @wkt_generator = WKRep::WKTGenerator.new(wkt_generator)
41
43
  @wkt_writer = nil
42
44
  else
43
- @wkt_generator = WKRep::WKTGenerator.new(convert_case: :upper)
44
- @wkt_writer = nil
45
+ @wkt_writer = ::Geos::WktWriter.new
46
+ @wkt_writer.trim = true
47
+ @wkt_generator = nil
45
48
  end
46
- wkb_generator_ = opts[:wkb_generator]
47
- case wkb_generator_
48
- when :geos
49
- @wkb_writer = ::Geos::WkbWriter.new
50
- @wkb_generator = nil
49
+ wkb_generator = opts[:wkb_generator]
50
+ case wkb_generator
51
51
  when Hash
52
- @wkb_generator = WKRep::WKBGenerator.new(wkb_generator_)
52
+ @wkb_generator = WKRep::WKBGenerator.new(wkb_generator)
53
53
  @wkb_writer = nil
54
54
  else
55
- @wkb_generator = WKRep::WKBGenerator.new
56
- @wkb_writer = nil
55
+ @wkb_writer = ::Geos::WkbWriter.new
56
+ @wkb_generator = nil
57
57
  end
58
58
 
59
- # Coordinate system (srid, proj4, and coord_sys)
60
- @srid = opts[:srid]
61
- @proj4 = opts[:proj4]
62
- if @proj4 && CoordSys.check!(:proj4)
63
- if @proj4.is_a?(String) || @proj4.is_a?(Hash)
64
- @proj4 = CoordSys::Proj4.create(@proj4)
65
- end
66
- else
67
- @proj4 = nil
68
- end
69
- @coord_sys = opts[:coord_sys]
70
- if @coord_sys.is_a?(String)
71
- @coord_sys = CoordSys::CS.create_from_wkt(@coord_sys)
72
- end
73
- if (!@proj4 || !@coord_sys) && @srid && (db = opts[:srs_database])
74
- entry = db.get(@srid.to_i)
75
- if entry
76
- @proj4 ||= entry.proj4
77
- @coord_sys ||= entry.coord_sys
78
- end
79
- end
80
- @srid ||= @coord_sys.authority_code if @coord_sys
81
- @srid = @srid.to_i
59
+ # Coordinate system (srid and coord_sys)
60
+ coord_sys_info = ImplHelper::Utils.setup_coord_sys(opts[:srid], opts[:coord_sys], opts[:coord_sys_class])
61
+ @srid = coord_sys_info[:srid]
62
+ @coord_sys = coord_sys_info[:coord_sys]
82
63
 
83
64
  # Interpret parser options
84
65
  wkt_parser = opts[:wkt_parser]
85
66
  case wkt_parser
86
- when :geos
87
- @wkt_reader = ::Geos::WktReader.new
88
- @wkt_parser = nil
89
67
  when Hash
90
68
  @wkt_parser = WKRep::WKTParser.new(self, wkt_parser)
91
69
  @wkt_reader = nil
92
70
  else
93
- @wkt_parser = WKRep::WKTParser.new(self)
94
- @wkt_reader = nil
71
+ @wkt_reader = ::Geos::WktReader.new
72
+ @wkt_parser = nil
95
73
  end
96
74
  wkb_parser = opts[:wkb_parser]
97
75
  case wkb_parser
98
- when :geos
99
- @wkb_reader = ::Geos::WkbReader.new
100
- @wkb_parser = nil
101
76
  when Hash
102
77
  @wkb_parser = WKRep::WKBParser.new(self, wkb_parser)
103
78
  @wkb_reader = nil
104
79
  else
105
- @wkb_parser = WKRep::WKBParser.new(self)
106
- @wkb_reader = nil
80
+ @wkb_reader = ::Geos::WkbReader.new
81
+ @wkb_parser = nil
107
82
  end
108
83
  end
84
+ attr_reader :coordinate_dimension, :spatial_dimension
109
85
 
110
86
  # Standard object inspection output
111
87
 
@@ -120,14 +96,14 @@ module RGeo
120
96
  @has_z == rhs.property(:has_z_coordinate) &&
121
97
  @has_m == rhs.property(:has_m_coordinate) &&
122
98
  @buffer_resolution == rhs.property(:buffer_resolution) &&
123
- @proj4.eql?(rhs.proj4)
99
+ @coord_sys.eql?(rhs.coord_sys)
124
100
  end
125
101
  alias == eql?
126
102
 
127
103
  # Standard hash code
128
104
 
129
105
  def hash
130
- @hash ||= [@srid, @has_z, @has_m, @buffer_resolution, @proj4].hash
106
+ @hash ||= [@srid, @has_z, @has_m, @buffer_resolution, @coord_sys].hash
131
107
  end
132
108
 
133
109
  # Marshal support
@@ -138,26 +114,19 @@ module RGeo
138
114
  "hasm" => @has_m,
139
115
  "srid" => @srid,
140
116
  "bufr" => @buffer_resolution,
141
- "wktg" => @wkt_generator.properties,
142
- "wkbg" => @wkb_generator.properties,
143
- "wktp" => @wkt_parser.properties,
144
- "wkbp" => @wkb_parser.properties,
117
+ "wktg" => @wkt_generator&.properties,
118
+ "wkbg" => @wkb_generator&.properties,
119
+ "wktp" => @wkt_parser&.properties,
120
+ "wkbp" => @wkb_parser&.properties,
145
121
  "apre" => @_auto_prepare
146
122
  }
147
- hash["proj4"] = @proj4.marshal_dump if @proj4
148
123
  hash["cs"] = @coord_sys.to_wkt if @coord_sys
149
124
  hash
150
125
  end
151
126
 
152
127
  def marshal_load(data) # :nodoc:
153
- if (proj4_data = data["proj4"]) && CoordSys.check!(:proj4)
154
- proj4 = CoordSys::Proj4.allocate
155
- proj4.marshal_load(proj4_data)
156
- else
157
- proj4 = nil
158
- end
159
128
  if (coord_sys_data = data["cs"])
160
- coord_sys = CoordSys::CS.create_from_wkt(coord_sys_data)
129
+ coord_sys = CoordSys::CONFIG.default_coord_sys_class.create_from_wkt(coord_sys_data)
161
130
  else
162
131
  coord_sys = nil
163
132
  end
@@ -166,12 +135,11 @@ module RGeo
166
135
  has_m_coordinate: data["hasm"],
167
136
  srid: data["srid"],
168
137
  buffer_resolution: data["bufr"],
169
- wkt_generator: symbolize_hash(data["wktg"]),
170
- wkb_generator: symbolize_hash(data["wkbg"]),
171
- wkt_parser: symbolize_hash(data["wktp"]),
172
- wkb_parser: symbolize_hash(data["wkbp"]),
138
+ wkt_generator: data["wktg"] && symbolize_hash(data["wktg"]),
139
+ wkb_generator: data["wkbg"] && symbolize_hash(data["wkbg"]),
140
+ wkt_parser: data["wktp"] && symbolize_hash(data["wktp"]),
141
+ wkb_parser: data["wkbp"] && symbolize_hash(data["wkbp"]),
173
142
  auto_prepare: (data["apre"] ? :simple : :disabled),
174
- proj4: proj4,
175
143
  coord_sys: coord_sys
176
144
  )
177
145
  end
@@ -183,31 +151,17 @@ module RGeo
183
151
  coder["has_m_coordinate"] = @has_m
184
152
  coder["srid"] = @srid
185
153
  coder["buffer_resolution"] = @buffer_resolution
186
- coder["wkt_generator"] = @wkt_generator.properties
187
- coder["wkb_generator"] = @wkb_generator.properties
188
- coder["wkt_parser"] = @wkt_parser.properties
189
- coder["wkb_parser"] = @wkb_parser.properties
154
+ coder["wkt_generator"] = @wkt_generator&.properties
155
+ coder["wkb_generator"] = @wkb_generator&.properties
156
+ coder["wkt_parser"] = @wkt_parser&.properties
157
+ coder["wkb_parser"] = @wkb_parser&.properties
190
158
  coder["auto_prepare"] = @_auto_prepare ? "simple" : "disabled"
191
- if @proj4
192
- str = @proj4.original_str || @proj4.canonical_str
193
- coder["proj4"] = @proj4.radians? ? { "proj4" => str, "radians" => true } : str
194
- end
195
159
  coder["coord_sys"] = @coord_sys.to_wkt if @coord_sys
196
160
  end
197
161
 
198
162
  def init_with(coder) # :nodoc:
199
- if (proj4_data = coder["proj4"])
200
- CoordSys.check!(:proj4)
201
- if proj4_data.is_a?(Hash)
202
- proj4 = CoordSys::Proj4.create(proj4_data["proj4"], radians: proj4_data["radians"])
203
- else
204
- proj4 = CoordSys::Proj4.create(proj4_data.to_s)
205
- end
206
- else
207
- proj4 = nil
208
- end
209
163
  if (coord_sys_data = coder["cs"])
210
- coord_sys = CoordSys::CS.create_from_wkt(coord_sys_data.to_s)
164
+ coord_sys = CoordSys::CONFIG.default_coord_sys_class.create_from_wkt(coord_sys_data.to_s)
211
165
  else
212
166
  coord_sys = nil
213
167
  end
@@ -216,12 +170,11 @@ module RGeo
216
170
  has_m_coordinate: coder["has_m_coordinate"],
217
171
  srid: coder["srid"],
218
172
  buffer_resolution: coder["buffer_resolution"],
219
- wkt_generator: symbolize_hash(coder["wkt_generator"]),
220
- wkb_generator: symbolize_hash(coder["wkb_generator"]),
221
- wkt_parser: symbolize_hash(coder["wkt_parser"]),
222
- wkb_parser: symbolize_hash(coder["wkb_parser"]),
173
+ wkt_generator: coder["wkt_generator"] && symbolize_hash(coder["wkt_generator"]),
174
+ wkb_generator: coder["wkb_generator"] && symbolize_hash(coder["wkb_generator"]),
175
+ wkt_parser: coder["wkt_parser"] && symbolize_hash(coder["wkt_parser"]),
176
+ wkb_parser: coder["wkb_parser"] && symbolize_hash(coder["wkb_parser"]),
223
177
  auto_prepare: coder["auto_prepare"] == "disabled" ? :disabled : :simple,
224
- proj4: proj4,
225
178
  coord_sys: coord_sys
226
179
  )
227
180
  end
@@ -254,7 +207,11 @@ module RGeo
254
207
  # See RGeo::Feature::Factory#parse_wkt
255
208
  def parse_wkt(str)
256
209
  if @wkt_reader
257
- wrap_fg_geom(@wkt_reader.read(str), nil)
210
+ begin
211
+ wrap_fg_geom(@wkt_reader.read(str), nil)
212
+ rescue ::Geos::WktReader::ParseError => e
213
+ raise RGeo::Error::ParseError, e.message.partition(":").last
214
+ end
258
215
  else
259
216
  @wkt_parser.parse(str)
260
217
  end
@@ -264,7 +221,12 @@ module RGeo
264
221
 
265
222
  def parse_wkb(str)
266
223
  if @wkb_reader
267
- wrap_fg_geom(@wkb_reader.read(str), nil)
224
+ begin
225
+ meth = str[0].match?(/[0-9a-fA-F]/) ? :read_hex : :read
226
+ wrap_fg_geom(@wkb_reader.public_send(meth, str), nil)
227
+ rescue ::Geos::WkbReader::ParseError => e
228
+ raise RGeo::Error::ParseError, e.message.partition(":").last
229
+ end
268
230
  else
269
231
  @wkb_parser.parse(str)
270
232
  end
@@ -405,10 +367,6 @@ module RGeo
405
367
  FFIMultiPolygonImpl.new(self, fg_geom, klasses)
406
368
  end
407
369
 
408
- # See RGeo::Feature::Factory#proj4
409
-
410
- attr_reader :proj4
411
-
412
370
  # See RGeo::Feature::Factory#coord_sys
413
371
 
414
372
  attr_reader :coord_sys
@@ -506,6 +464,7 @@ module RGeo
506
464
  def write_for_psych(geom)
507
465
  if Utils.ffi_supports_set_output_dimension || !@_has_3d
508
466
  wkt_writer = ::Geos::WktWriter.new
467
+ wkt_writer.trim = true
509
468
  wkt_writer.output_dimensions = 3 if @_has_3d
510
469
  wkt_writer.write(geom.fg_geom)
511
470
  else