rgeo 0.2.8 → 0.2.9

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