Class: RGeo::WKRep::WKBGenerator

Inherits:
Object
  • Object
show all
Defined in:
lib/rgeo/wkrep/wkb_generator.rb

Overview

This class provides the functionality of serializing a geometry as WKB (well-known binary) format. You may also customize the serializer to generate PostGIS EWKB extensions to the output, or to follow the Simple Features Specification 1.2 extensions for Z and M coordinates.

To use this class, create an instance with the desired settings and customizations, and call the generate method.

Configuration options

The following options are recognized. These can be passed to the constructor, or set on the object afterwards.

:type_format

The format for type codes. Possible values are :wkb11, indicating SFS 1.1 WKB (i.e. no Z or M values); :ewkb, indicating the PostGIS EWKB extensions (i.e. Z and M presence flagged by the two high bits of the type code, and support for embedded SRID); or :wkb12 (indicating SFS 1.2 WKB (i.e. Z and M presence flagged by adding 1000 and/or 2000 to the type code.) Default is :wkb11.

:emit_ewkb_srid

If true, embed the SRID in the toplevel geometry. Available only if :type_format is :ewkb. Default is false.

:hex_format

If true, output a hex string instead of a byte string. Default is false.

:little_endian

If true, output little endian (NDR) byte order. If false, output big endian (XDR), or network byte order. Default is false.

Constant Summary collapse

TYPE_CODES =

:stopdoc:

{
  Feature::Point => 1,
  Feature::LineString => 2,
  Feature::LinearRing => 2,
  Feature::Line => 2,
  Feature::Polygon => 3,
  Feature::MultiPoint => 4,
  Feature::MultiLineString => 5,
  Feature::MultiPolygon => 6,
  Feature::GeometryCollection => 7,
}

Instance Method Summary collapse

Constructor Details

#initialize(opts_ = {}) ⇒ WKBGenerator

Create and configure a WKB generator. See the WKBGenerator documentation for the options that can be passed.



95
96
97
98
99
100
# File 'lib/rgeo/wkrep/wkb_generator.rb', line 95

def initialize(opts_={})
  @type_format = opts_[:type_format] || :wkb11
  @emit_ewkb_srid = opts_[:emit_ewkb_srid] ? true : false if @type_format == :ewkb
  @hex_format = opts_[:hex_format] ? true : false
  @little_endian = opts_[:little_endian] ? true : false
end

Instance Method Details

#_emit_byte(value_) ⇒ Object

:nodoc:



240
241
242
# File 'lib/rgeo/wkrep/wkb_generator.rb', line 240

def _emit_byte(value_)  # :nodoc:
  @cur_array << [value_].pack("C")
end

#_emit_doubles(array_) ⇒ Object

:nodoc:



250
251
252
# File 'lib/rgeo/wkrep/wkb_generator.rb', line 250

def _emit_doubles(array_)  # :nodoc:
  @cur_array << array_.pack(@little_endian ? 'E*' : 'G*')
end

#_emit_integer(value_) ⇒ Object

:nodoc:



245
246
247
# File 'lib/rgeo/wkrep/wkb_generator.rb', line 245

def _emit_integer(value_)  # :nodoc:
  @cur_array << [value_].pack(@little_endian ? 'V' : 'N')
end

#_emit_line_string_coords(obj_) ⇒ Object

:nodoc:



227
228
229
230
231
232
# File 'lib/rgeo/wkrep/wkb_generator.rb', line 227

def _emit_line_string_coords(obj_)  # :nodoc:
  array_ = []
  obj_.points.each{ |p_| _point_coords(p_, array_) }
  _emit_integer(obj_.num_points)
  _emit_doubles(array_)
end

#_finish_emitterObject

:nodoc:



255
256
257
258
259
# File 'lib/rgeo/wkrep/wkb_generator.rb', line 255

def _finish_emitter  # :nodoc:
  str_ = @cur_array.join
  @cur_array = nil
  @hex_format ? str_.unpack("H*")[0] : str_
end

#_generate_feature(obj_, toplevel_ = false) ⇒ Object

:nodoc:



168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
# File 'lib/rgeo/wkrep/wkb_generator.rb', line 168

def _generate_feature(obj_, toplevel_=false)  # :nodoc:
  _emit_byte(@little_endian ? 1 : 0)
  type_ = obj_.geometry_type
  type_code_ = TYPE_CODES[type_]
  unless type_code_
    raise Error::ParseError, "Unrecognized Geometry Type: #{type_}"
  end
  emit_srid_ = false
  if @type_format == :ewkb
    type_code_ |= 0x80000000 if @cur_has_z
    type_code_ |= 0x40000000 if @cur_has_m
    if @emit_ewkb_srid && toplevel_
      type_code_ |= 0x20000000
      emit_srid_ = true
    end
  elsif @type_format == :wkb12
    type_code_ += 1000 if @cur_has_z
    type_code_ += 2000 if @cur_has_m
  end
  _emit_integer(type_code_)
  _emit_integer(obj_.srid) if emit_srid_
  if type_ == Feature::Point
    _emit_doubles(_point_coords(obj_))
  elsif type_.subtype_of?(Feature::LineString)
    _emit_line_string_coords(obj_)
  elsif type_ == Feature::Polygon
    exterior_ring_ = obj_.exterior_ring
    if exterior_ring_.is_empty?
      _emit_integer(0)
    else
      _emit_integer(1 + obj_.num_interior_rings)
      _emit_line_string_coords(exterior_ring_)
      obj_.interior_rings.each{ |r_| _emit_line_string_coords(r_) }
    end
  elsif type_ == Feature::GeometryCollection
    _emit_integer(obj_.num_geometries)
    obj_.each{ |g_| _generate_feature(g_) }
  elsif type_ == Feature::MultiPoint
    _emit_integer(obj_.num_geometries)
    obj_.each{ |g_| _generate_feature(g_) }
  elsif type_ == Feature::MultiLineString
    _emit_integer(obj_.num_geometries)
    obj_.each{ |g_| _generate_feature(g_) }
  elsif type_ == Feature::MultiPolygon
    _emit_integer(obj_.num_geometries)
    obj_.each{ |g_| _generate_feature(g_) }
  end
end

#_point_coords(obj_, array_ = []) ⇒ Object

:nodoc:



218
219
220
221
222
223
224
# File 'lib/rgeo/wkrep/wkb_generator.rb', line 218

def _point_coords(obj_, array_=[])  # :nodoc:
  array_ << obj_.x
  array_ << obj_.y
  array_ << obj_.z if @cur_has_z
  array_ << obj_.m if @cur_has_m
  array_
end

#_start_emitterObject

:nodoc:



235
236
237
# File 'lib/rgeo/wkrep/wkb_generator.rb', line 235

def _start_emitter  # :nodoc:
  @cur_array = []
end

#emit_ewkb_srid=(value_) ⇒ Object

Sets whether SRID is embedded. Available only when the type_format is :ewkb. See WKBGenerator for details.



120
121
122
# File 'lib/rgeo/wkrep/wkb_generator.rb', line 120

def emit_ewkb_srid=(value_)
  @emit_ewkb_srid = @type_format == :ewkb && value_
end

#emit_ewkb_srid?Boolean

Returns whether SRID is embedded. See WKBGenerator for details.

Returns:

  • (Boolean)


114
115
116
# File 'lib/rgeo/wkrep/wkb_generator.rb', line 114

def emit_ewkb_srid?
  @emit_ewkb_srid
end

#generate(obj_) ⇒ Object

Generate and return the WKB format for the given geometry object, according to the current settings.



152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/rgeo/wkrep/wkb_generator.rb', line 152

def generate(obj_)
  factory_ = obj_.factory
  if @type_format == :ewkb || @type_format == :wkb12
    @cur_has_z = factory_.property(:has_z_coordinate)
    @cur_has_m = factory_.property(:has_m_coordinate)
  else
    @cur_has_z = nil
    @cur_has_m = nil
  end
  @cur_dims = 2 + (@cur_has_z ? 1 : 0) + (@cur_has_m ? 1 : 0)
  _start_emitter
  _generate_feature(obj_, true)
  _finish_emitter
end

#hex_format=(value_) ⇒ Object

Sets whether output is converted to hex. See WKBGenerator for details.



132
133
134
# File 'lib/rgeo/wkrep/wkb_generator.rb', line 132

def hex_format=(value_)
  @hex_format = value_ ? true : false
end

#hex_format?Boolean

Returns whether output is converted to hex. See WKBGenerator for details.

Returns:

  • (Boolean)


126
127
128
# File 'lib/rgeo/wkrep/wkb_generator.rb', line 126

def hex_format?
  @hex_format
end

#little_endian=(value_) ⇒ Object

Sets whether output is little-endian (NDR). See WKBGenerator for details.



144
145
146
# File 'lib/rgeo/wkrep/wkb_generator.rb', line 144

def little_endian=(value_)
  @little_endian = value_ ? true : false
end

#little_endian?Boolean

Returns whether output is little-endian (NDR). See WKBGenerator for details.

Returns:

  • (Boolean)


138
139
140
# File 'lib/rgeo/wkrep/wkb_generator.rb', line 138

def little_endian?
  @little_endian
end

#type_formatObject

Returns the format for type codes. See WKBGenerator for details.



104
105
106
# File 'lib/rgeo/wkrep/wkb_generator.rb', line 104

def type_format
  @type_format
end

#type_format=(value_) ⇒ Object

Sets the format for type codes. See WKBGenerator for details.



109
110
111
# File 'lib/rgeo/wkrep/wkb_generator.rb', line 109

def type_format=(value_)
  @type_format = value_
end