Class: RGeo::WKRep::WKBGenerator
- Inherits:
-
Object
- Object
- RGeo::WKRep::WKBGenerator
- 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 }.freeze
Instance Attribute Summary collapse
-
#type_format ⇒ Object
readonly
Returns the format for type codes.
Instance Method Summary collapse
-
#_emit_byte(value_) ⇒ Object
:nodoc:.
-
#_emit_doubles(array_) ⇒ Object
:nodoc:.
-
#_emit_integer(value_) ⇒ Object
:nodoc:.
-
#_emit_line_string_coords(obj_) ⇒ Object
:nodoc:.
-
#_finish_emitter ⇒ Object
:nodoc:.
-
#_generate_feature(obj_, toplevel_ = false) ⇒ Object
:nodoc:.
-
#_point_coords(obj_, array_ = []) ⇒ Object
:nodoc:.
-
#_properties ⇒ Object
:nodoc:.
-
#_start_emitter ⇒ Object
:nodoc:.
-
#emit_ewkb_srid? ⇒ Boolean
Returns whether SRID is embedded.
-
#generate(obj_) ⇒ Object
Generate and return the WKB format for the given geometry object, according to the current settings.
-
#hex_format? ⇒ Boolean
Returns whether output is converted to hex.
-
#initialize(opts_ = {}) ⇒ WKBGenerator
constructor
Create and configure a WKB generator.
-
#little_endian? ⇒ Boolean
Returns whether output is little-endian (NDR).
Constructor Details
#initialize(opts_ = {}) ⇒ WKBGenerator
Create and configure a WKB generator. See the WKBGenerator documentation for the options that can be passed.
59 60 61 62 63 64 65 |
# File 'lib/rgeo/wkrep/wkb_generator.rb', line 59 def initialize(opts_ = {}) @type_format = opts_[:type_format] || :wkb11 @emit_ewkb_srid = @type_format == :ewkb ? (opts_[:emit_ewkb_srid] ? true : false) : nil @hex_format = opts_[:hex_format] ? true : false @little_endian = opts_[:little_endian] ? true : false end |
Instance Attribute Details
#type_format ⇒ Object (readonly)
Returns the format for type codes. See WKBGenerator for details.
68 69 70 |
# File 'lib/rgeo/wkrep/wkb_generator.rb', line 68 def type_format @type_format end |
Instance Method Details
#_emit_byte(value_) ⇒ Object
:nodoc:
182 183 184 |
# File 'lib/rgeo/wkrep/wkb_generator.rb', line 182 def _emit_byte(value_) # :nodoc: @cur_array << [value_].pack("C") end |
#_emit_doubles(array_) ⇒ Object
:nodoc:
190 191 192 |
# File 'lib/rgeo/wkrep/wkb_generator.rb', line 190 def _emit_doubles(array_) # :nodoc: @cur_array << array_.pack(@little_endian ? "E*" : "G*") end |
#_emit_integer(value_) ⇒ Object
:nodoc:
186 187 188 |
# File 'lib/rgeo/wkrep/wkb_generator.rb', line 186 def _emit_integer(value_) # :nodoc: @cur_array << [value_].pack(@little_endian ? "V" : "N") end |
#_emit_line_string_coords(obj_) ⇒ Object
:nodoc:
171 172 173 174 175 176 |
# File 'lib/rgeo/wkrep/wkb_generator.rb', line 171 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_emitter ⇒ Object
:nodoc:
194 195 196 197 198 |
# File 'lib/rgeo/wkrep/wkb_generator.rb', line 194 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:
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
# File 'lib/rgeo/wkrep/wkb_generator.rb', line 114 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:
163 164 165 166 167 168 169 |
# File 'lib/rgeo/wkrep/wkb_generator.rb', line 163 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 |
#_properties ⇒ Object
:nodoc:
87 88 89 90 91 92 93 94 |
# File 'lib/rgeo/wkrep/wkb_generator.rb', line 87 def _properties # :nodoc: { "type_format" => @type_format.to_s, "emit_ewkb_srid" => @emit_ewkb_srid, "hex_format" => @hex_format, "little_endian" => @little_endian } end |
#_start_emitter ⇒ Object
:nodoc:
178 179 180 |
# File 'lib/rgeo/wkrep/wkb_generator.rb', line 178 def _start_emitter # :nodoc: @cur_array = [] end |
#emit_ewkb_srid? ⇒ Boolean
Returns whether SRID is embedded. See WKBGenerator for details.
71 72 73 |
# File 'lib/rgeo/wkrep/wkb_generator.rb', line 71 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.
99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/rgeo/wkrep/wkb_generator.rb', line 99 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? ⇒ Boolean
Returns whether output is converted to hex. See WKBGenerator for details.
77 78 79 |
# File 'lib/rgeo/wkrep/wkb_generator.rb', line 77 def hex_format? @hex_format end |
#little_endian? ⇒ Boolean
Returns whether output is little-endian (NDR). See WKBGenerator for details.
83 84 85 |
# File 'lib/rgeo/wkrep/wkb_generator.rb', line 83 def little_endian? @little_endian end |