rgeo 0.2.8 → 0.2.9

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.
@@ -82,7 +82,14 @@ module RGeo
82
82
 
83
83
 
84
84
  def create_from_proj4(geography_factory_, proj4_, opts_={})
85
- projection_factory_ = Cartesian.preferred_factory(:proj4 => proj4_, :coord_sys => opts_[:coord_sys], :srid => opts_[:srid], :buffer_resolution => opts_[:buffer_resolution], :lenient_multi_polygon_assertions => opts_[:lenient_multi_polygon_assertions], :has_z_coordinate => opts_[:has_z_coordinate], :has_m_coordinate => opts_[:has_m_coordinate])
85
+ projection_factory_ = Cartesian.preferred_factory(:proj4 => proj4_,
86
+ :coord_sys => opts_[:coord_sys], :srid => opts_[:srid],
87
+ :buffer_resolution => opts_[:buffer_resolution],
88
+ :lenient_multi_polygon_assertions => opts_[:lenient_multi_polygon_assertions],
89
+ :has_z_coordinate => opts_[:has_z_coordinate],
90
+ :has_m_coordinate => opts_[:has_m_coordinate],
91
+ :wkt_parser => opts_[:wkt_parser], :wkt_generator => opts_[:wkt_generator],
92
+ :wkb_parser => opts_[:wkb_parser], :wkb_generator => opts_[:wkb_generator])
86
93
  new(geography_factory_, projection_factory_)
87
94
  end
88
95
 
data/lib/rgeo/geos.rb CHANGED
@@ -51,7 +51,7 @@ module RGeo
51
51
  # therefore not documented.
52
52
  #
53
53
  # To use the Geos implementation, first obtain a factory using the
54
- # ::RGeo::Geos::factory method. You may then call any of the standard
54
+ # ::RGeo::Geos.factory method. You may then call any of the standard
55
55
  # factory methods on the resulting object.
56
56
 
57
57
  module Geos
@@ -53,10 +53,13 @@ module RGeo
53
53
  # Create a new factory. Returns nil if the GEOS implementation is
54
54
  # not supported.
55
55
  #
56
- # See ::RGeo::Geos::factory for a list of supported options.
56
+ # See ::RGeo::Geos.factory for a list of supported options.
57
57
 
58
58
  def create(opts_={})
59
+ # Make sure GEOS is available
59
60
  return nil unless respond_to?(:_create)
61
+
62
+ # Get flags to pass to the C extension
60
63
  flags_ = 0
61
64
  flags_ |= 1 if opts_[:lenient_multi_polygon_assertions]
62
65
  flags_ |= 2 if opts_[:has_z_coordinate]
@@ -64,8 +67,32 @@ module RGeo
64
67
  if flags_ & 6 == 6
65
68
  raise Error::UnsupportedOperation, "GEOS cannot support both Z and M coordinates at the same time."
66
69
  end
70
+
71
+ # Buffer resolution
67
72
  buffer_resolution_ = opts_[:buffer_resolution].to_i
68
73
  buffer_resolution_ = 1 if buffer_resolution_ < 1
74
+
75
+ # Interpret the generator options
76
+ wkt_generator_ = opts_[:wkt_generator]
77
+ case wkt_generator_
78
+ when :geos
79
+ wkt_generator_ = nil
80
+ when ::Hash
81
+ wkt_generator_ = WKRep::WKTGenerator.new(wkt_generator_)
82
+ else
83
+ wkt_generator_ = WKRep::WKTGenerator.new(:convert_case => :upper)
84
+ end
85
+ wkb_generator_ = opts_[:wkb_generator]
86
+ case wkb_generator_
87
+ when :geos
88
+ wkb_generator_ = nil
89
+ when ::Hash
90
+ wkb_generator_ = WKRep::WKBGenerator.new(wkb_generator_)
91
+ else
92
+ wkb_generator_ = WKRep::WKBGenerator.new
93
+ end
94
+
95
+ # Coordinate system (srid, proj4, and coord_sys)
69
96
  srid_ = opts_[:srid]
70
97
  proj4_ = opts_[:proj4]
71
98
  if CoordSys::Proj4.supported?
@@ -87,9 +114,39 @@ module RGeo
87
114
  end
88
115
  end
89
116
  srid_ ||= coord_sys_.authority_code if coord_sys_
90
- result_ = _create(flags_, srid_.to_i, buffer_resolution_)
117
+
118
+ # Create the factory and set instance variables
119
+ result_ = _create(flags_, srid_.to_i, buffer_resolution_, wkt_generator_, wkb_generator_)
120
+
121
+ # Interpret parser options
122
+ wkt_parser_ = opts_[:wkt_parser]
123
+ case wkt_parser_
124
+ when :geos
125
+ wkt_parser_ = nil
126
+ when ::Hash
127
+ wkt_parser_ = WKRep::WKTParser.new(result_, wkt_parser_)
128
+ else
129
+ wkt_parser_ = WKRep::WKTParser.new(result_)
130
+ end
131
+ wkb_parser_ = opts_[:wkb_parser]
132
+ case wkb_parser_
133
+ when :geos
134
+ wkb_parser_ = nil
135
+ when ::Hash
136
+ wkb_parser_ = WKRep::WKBParser.new(result_, wkb_parser_)
137
+ else
138
+ wkb_parser_ = WKRep::WKBParser.new(result_)
139
+ end
140
+
141
+ # Set instance variables
91
142
  result_.instance_variable_set(:@proj4, proj4_)
92
143
  result_.instance_variable_set(:@coord_sys, coord_sys_)
144
+ result_.instance_variable_set(:@wkt_parser, wkt_parser_)
145
+ result_.instance_variable_set(:@wkb_parser, wkb_parser_)
146
+ result_.instance_variable_set(:@wkt_generator, wkt_generator_)
147
+ result_.instance_variable_set(:@wkb_generator, wkb_generator_)
148
+
149
+ # Return the result
93
150
  result_
94
151
  end
95
152
  alias_method :new, :create
@@ -152,14 +209,22 @@ module RGeo
152
209
  # See ::RGeo::Feature::Factory#parse_wkt
153
210
 
154
211
  def parse_wkt(str_)
155
- _parse_wkt_impl(str_)
212
+ if @wkt_parser
213
+ @wkt_parser.parse(str_)
214
+ else
215
+ _parse_wkt_impl(str_)
216
+ end
156
217
  end
157
218
 
158
219
 
159
220
  # See ::RGeo::Feature::Factory#parse_wkb
160
221
 
161
222
  def parse_wkb(str_)
162
- _parse_wkb_impl(str_)
223
+ if @wkb_parser
224
+ @wkb_parser.parse(str_)
225
+ else
226
+ _parse_wkb_impl(str_)
227
+ end
163
228
  end
164
229
 
165
230
 
@@ -63,7 +63,7 @@ module RGeo
63
63
  Feature::MultiPoint => MultiPointImpl,
64
64
  Feature::MultiLineString => MultiLineStringImpl,
65
65
  Feature::MultiPolygon => MultiPolygonImpl,
66
- }
66
+ }.freeze
67
67
  end
68
68
  # :startdoc:
69
69
 
@@ -105,6 +105,37 @@ module RGeo
105
105
  # Support <tt>z_coordinate</tt>. Default is false.
106
106
  # [<tt>:has_m_coordinate</tt>]
107
107
  # Support <tt>m_coordinate</tt>. Default is false.
108
+ # [<tt>:wkt_parser</tt>]
109
+ # Configure the parser for WKT. You may either pass a hash of
110
+ # configuration parameters for WKRep::WKTParser.new, or the
111
+ # special value <tt>:geos</tt>, indicating to use the native
112
+ # GEOS parser. Default is the empty hash, indicating the default
113
+ # configuration for WKRep::WKTParser.
114
+ # Note that the special <tt>:geos</tt> value is not supported for
115
+ # ZM factories, since GEOS currently can't handle ZM natively.
116
+ # [<tt>:wkb_parser</tt>]
117
+ # Configure the parser for WKB. You may either pass a hash of
118
+ # configuration parameters for WKRep::WKBParser.new, or the
119
+ # special value <tt>:geos</tt>, indicating to use the native
120
+ # GEOS parser. Default is the empty hash, indicating the default
121
+ # configuration for WKRep::WKBParser.
122
+ # Note that the special <tt>:geos</tt> value is not supported for
123
+ # ZM factories, since GEOS currently can't handle ZM natively.
124
+ # [<tt>:wkt_generator</tt>]
125
+ # Configure the generator for WKT. You may either pass a hash of
126
+ # configuration parameters for WKRep::WKTGenerator.new, or the
127
+ # special value <tt>:geos</tt>, indicating to use the native
128
+ # GEOS generator. Default is <tt>{:convert_case => :upper}</tt>.
129
+ # Note that the special <tt>:geos</tt> value is not supported for
130
+ # ZM factories, since GEOS currently can't handle ZM natively.
131
+ # [<tt>:wkb_generator</tt>]
132
+ # Configure the generator for WKB. You may either pass a hash of
133
+ # configuration parameters for WKRep::WKBGenerator.new, or the
134
+ # special value <tt>:geos</tt>, indicating to use the native
135
+ # GEOS generator. Default is the empty hash, indicating the
136
+ # default configuration for WKRep::WKBGenerator.
137
+ # Note that the special <tt>:geos</tt> value is not supported for
138
+ # ZM factories, since GEOS currently can't handle ZM natively.
108
139
 
109
140
  def factory(opts_={})
110
141
  if supported?
@@ -76,10 +76,41 @@ module RGeo
76
76
  config_ = {
77
77
  :lenient_multi_polygon_assertions => opts_[:lenient_multi_polygon_assertions],
78
78
  :buffer_resolution => opts_[:buffer_resolution],
79
+ :wkt_generator => opts_[:wkt_generator], :wkt_parser => opts_[:wkt_parser],
80
+ :wkb_generator => opts_[:wkb_generator], :wkb_parser => opts_[:wkb_parser],
79
81
  :srid => srid_.to_i, :proj4 => proj4_, :coord_sys => coord_sys_,
80
82
  }
81
83
  @zfactory = Factory.create(config_.merge(:has_z_coordinate => true))
82
84
  @mfactory = Factory.create(config_.merge(:has_m_coordinate => true))
85
+
86
+ wkt_generator_ = opts_[:wkt_generator]
87
+ case wkt_generator_
88
+ when ::Hash
89
+ @wkt_generator = WKRep::WKTGenerator.new(wkt_generator_)
90
+ else
91
+ @wkt_generator = WKRep::WKTGenerator.new(:convert_case => :upper)
92
+ end
93
+ wkb_generator_ = opts_[:wkb_generator]
94
+ case wkb_generator_
95
+ when ::Hash
96
+ @wkb_generator = WKRep::WKBGenerator.new(wkb_generator_)
97
+ else
98
+ @wkb_generator = WKRep::WKBGenerator.new
99
+ end
100
+ wkt_parser_ = opts_[:wkt_parser]
101
+ case wkt_parser_
102
+ when ::Hash
103
+ @wkt_parser = WKRep::WKTParser.new(self, wkt_parser_)
104
+ else
105
+ @wkt_parser = WKRep::WKTParser.new(self)
106
+ end
107
+ wkb_parser_ = opts_[:wkb_parser]
108
+ case wkb_parser_
109
+ when ::Hash
110
+ @wkb_parser = WKRep::WKBParser.new(self, wkb_parser_)
111
+ else
112
+ @wkb_parser = WKRep::WKBParser.new(self)
113
+ end
83
114
  end
84
115
 
85
116
 
@@ -142,14 +173,14 @@ module RGeo
142
173
  # See ::RGeo::Feature::Factory#parse_wkt
143
174
 
144
175
  def parse_wkt(str_)
145
- WKRep::WKTParser.new(self).parse(str_)
176
+ @wkt_parser.parse(str_)
146
177
  end
147
178
 
148
179
 
149
180
  # See ::RGeo::Feature::Factory#parse_wkb
150
181
 
151
182
  def parse_wkb(str_)
152
- WKRep::WKBParser.new(self).parse(str_)
183
+ @wkb_parser.parse(str_)
153
184
  end
154
185
 
155
186
 
@@ -101,12 +101,12 @@ module RGeo
101
101
 
102
102
 
103
103
  def as_text
104
- WKRep::WKTGenerator.new.generate(self)
104
+ @factory.instance_variable_get(:@wkt_generator).generate(self)
105
105
  end
106
106
 
107
107
 
108
108
  def as_binary
109
- WKRep::WKBGenerator.new.generate(self)
109
+ @factory.instance_variable_get(:@wkb_generator).generate(self)
110
110
  end
111
111
 
112
112
 
@@ -415,7 +415,7 @@ module RGeo
415
415
  Feature::MultiPoint => ZMGeometryCollectionImpl,
416
416
  Feature::MultiLineString => ZMMultiLineStringImpl,
417
417
  Feature::MultiPolygon => ZMMultiPolygonImpl,
418
- }
418
+ }.freeze
419
419
 
420
420
 
421
421
  def self.create(factory_, zgeometry_, mgeometry_)
@@ -68,12 +68,12 @@ module RGeo
68
68
 
69
69
 
70
70
  def as_text
71
- WKRep::WKTGenerator.new.generate(self)
71
+ @factory.instance_variable_get(:@wkt_generator).generate(self)
72
72
  end
73
73
 
74
74
 
75
75
  def as_binary
76
- WKRep::WKBGenerator.new.generate(self)
76
+ @factory.instance_variable_get(:@wkb_generator).generate(self)
77
77
  end
78
78
 
79
79
 
@@ -85,7 +85,7 @@ module RGeo
85
85
  Feature::MultiLineString => 5,
86
86
  Feature::MultiPolygon => 6,
87
87
  Feature::GeometryCollection => 7,
88
- }
88
+ }.freeze
89
89
  # :startdoc:
90
90
 
91
91
 
@@ -105,46 +105,23 @@ module RGeo
105
105
  @type_format
106
106
  end
107
107
 
108
- # Sets the format for type codes. See WKBGenerator for details.
109
- def type_format=(value_)
110
- @type_format = value_
111
- end
112
-
113
108
  # Returns whether SRID is embedded. See WKBGenerator for details.
114
109
  def emit_ewkb_srid?
115
110
  @emit_ewkb_srid
116
111
  end
117
112
 
118
- # Sets whether SRID is embedded. Available only when the type_format
119
- # is <tt>:ewkb</tt>. See WKBGenerator for details.
120
- def emit_ewkb_srid=(value_)
121
- @emit_ewkb_srid = @type_format == :ewkb && value_
122
- end
123
-
124
113
  # Returns whether output is converted to hex.
125
114
  # See WKBGenerator for details.
126
115
  def hex_format?
127
116
  @hex_format
128
117
  end
129
118
 
130
- # Sets whether output is converted to hex.
131
- # See WKBGenerator for details.
132
- def hex_format=(value_)
133
- @hex_format = value_ ? true : false
134
- end
135
-
136
119
  # Returns whether output is little-endian (NDR).
137
120
  # See WKBGenerator for details.
138
121
  def little_endian?
139
122
  @little_endian
140
123
  end
141
124
 
142
- # Sets whether output is little-endian (NDR).
143
- # See WKBGenerator for details.
144
- def little_endian=(value_)
145
- @little_endian = value_ ? true : false
146
- end
147
-
148
125
 
149
126
  # Generate and return the WKB format for the given geometry object,
150
127
  # according to the current settings.
@@ -81,7 +81,16 @@ module RGeo
81
81
  # documentation for the options that can be passed.
82
82
 
83
83
  def initialize(factory_generator_=nil, opts_={})
84
- self.factory_generator = factory_generator_
84
+ if factory_generator_.kind_of?(Feature::Factory::Instance)
85
+ @factory_generator = Feature::FactoryGenerator.single(factory_generator_)
86
+ @exact_factory = factory_generator_
87
+ elsif factory_generator_.respond_to?(:call)
88
+ @factory_generator = factory_generator_
89
+ @exact_factory = nil
90
+ else
91
+ @factory_generator = Cartesian.method(:preferred_factory)
92
+ @exact_factory = nil
93
+ end
85
94
  @support_ewkb = opts_[:support_ewkb] ? true : false
86
95
  @support_wkb12 = opts_[:support_wkb12] ? true : false
87
96
  @ignore_extra_bytes = opts_[:ignore_extra_bytes] ? true : false
@@ -100,70 +109,41 @@ module RGeo
100
109
  @exact_factory
101
110
  end
102
111
 
103
- # Sets the factory_generator. See WKBParser for details.
104
- def factory_generator=(value_)
105
- if value_.kind_of?(Feature::Factory::Instance)
106
- @factory_generator = Feature::FactoryGenerator.single(value_)
107
- @exact_factory = value_
108
- elsif value_.respond_to?(:call)
109
- @factory_generator = value_
110
- @exact_factory = nil
111
- else
112
- @factory_generator = Cartesian.method(:preferred_factory)
113
- @exact_factory = nil
114
- end
115
- end
116
-
117
- # Sets the factory_generator to the given block.
118
- # See WKBParser for details.
119
- def to_generate_factory(&block_)
120
- @factory_generator = block_
121
- end
122
-
123
112
  # Returns true if this parser supports EWKB.
124
113
  # See WKBParser for details.
125
114
  def support_ewkb?
126
115
  @support_ewkb
127
116
  end
128
117
 
129
- # Sets the the support_ewkb flag. See WKBParser for details.
130
- def support_ewkb=(value_)
131
- @support_ewkb = value_ ? true : false
132
- end
133
-
134
118
  # Returns true if this parser supports SFS 1.2 extensions.
135
119
  # See WKBParser for details.
136
120
  def support_wkb12?
137
121
  @support_wkb12
138
122
  end
139
123
 
140
- # Sets the the support_wkb12 flag. See WKBParser for details.
141
- def support_wkb12=(value_)
142
- @support_wkb12 = value_ ? true : false
143
- end
144
-
145
124
  # Returns true if this parser ignores extra bytes.
146
125
  # See WKBParser for details.
147
126
  def ignore_extra_bytes?
148
127
  @ignore_extra_bytes
149
128
  end
150
129
 
151
- # Sets the the ignore_extra_bytes flag. See WKBParser for details.
152
- def ignore_extra_bytes=(value_)
153
- @ignore_extra_bytes = value_ ? true : false
154
- end
155
-
156
-
157
- # Parse the given hex string, and return a geometry object.
158
-
159
- def parse_hex(str_)
160
- parse([str_].pack('H*'))
130
+ # Returns true if this parser can auto-detect hex.
131
+ # See WKBParser for details.
132
+ def auto_detect_hex?
133
+ @auto_detect_hex
161
134
  end
162
135
 
163
136
 
164
- # Parse the given binary data, and return a geometry object.
137
+ # Parse the given binary data or hexadecimal string, and return a
138
+ # geometry object.
139
+ #
140
+ # The #parse_hex method is a synonym, present for historical
141
+ # reasons but deprecated. Use #parse instead.
165
142
 
166
143
  def parse(data_)
144
+ if data_[0,1] =~ /[0-9a-fA-F]/
145
+ data_ = [data_].pack('H*')
146
+ end
167
147
  @cur_has_z = nil
168
148
  @cur_has_m = nil
169
149
  @cur_srid = nil
@@ -183,10 +163,19 @@ module RGeo
183
163
  end
184
164
  obj_
185
165
  end
166
+ alias_method :parse_hex, :parse
186
167
 
187
168
 
188
169
  def _parse_object(contained_) # :nodoc:
189
- little_endian_ = _get_byte == 1
170
+ endian_value_ = _get_byte
171
+ case endian_value_
172
+ when 0
173
+ little_endian_ = false
174
+ when 1
175
+ little_endian_ = true
176
+ else
177
+ raise Error::ParseError, "Bad endian byte value: #{endian_value_}"
178
+ end
190
179
  type_code_ = _get_integer(little_endian_)
191
180
  has_z_ = false
192
181
  has_m_ = false