Last active
December 16, 2015 02:39
-
-
Save jheidt/5364448 to your computer and use it in GitHub Desktop.
Messing around with a ruby Well-Known-Binary converter.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module WellKnownBinary | |
require 'bindata' | |
TYPE_ID = { | |
:point => 1, | |
:linestring => 2, | |
:polygon => 3, | |
:multipoint => 4, | |
:multilinestring => 5, | |
:multipolygon => 6, | |
:geometrycollection => 7, | |
:circularstring => 8, | |
:compoundcurve => 9, | |
:curvepolygon => 10, | |
:multicurve => 11, | |
:multisurface => 12, | |
:curve => 13, | |
:surface => 14, | |
:polyhedralsurface => 15, | |
:tin => 16, | |
:triangle => 17 | |
}.freeze | |
BYTE_ORDER = { | |
:big_endian => 0, | |
:xdr => 0, | |
:little_endian => 1, | |
:ndr => 1 | |
}.freeze | |
class DefineByteOrder < BinData::Record | |
uint8 :byte_order, :initial_value => BYTE_ORDER[:little_endian] | |
def big_endian? | |
byte_order == 0 | |
end | |
def little_endian? | |
byte_order != 0 | |
end | |
end | |
class PointBE < BinData::Record | |
double_be :x | |
double_be :y | |
end | |
class PointLE < BinData::Record | |
double_le :x | |
double_le :y | |
end | |
class PointArrayBE < DefineByteOrder | |
uint32be :num_points | |
array :points, :initial_length => :num_points, :type => :PointBE | |
end | |
class PointArrayLE < DefineByteOrder | |
uint32le :num_points | |
array :points, :initial_length => :num_points, :type => :PointLE | |
end | |
class WKBPoint < DefineByteOrder | |
# uint32 :wkb_type, :value => WKB_TYPE_ID[:wkb_point] | |
choice :wkb_type, :copy_on_change => true, :selection => lambda { big_endian? } do | |
uint32be true, :value => TYPE_ID[:point] | |
uint32le false, :value => TYPE_ID[:point] | |
end | |
#Point :point | |
choice :point, :copy_on_change => true, :selection => lambda { big_endian? } do | |
PointBE true | |
PointLE false | |
end | |
end | |
class WKBLineString < DefineByteOrder | |
#uint32 :wkb_type, :value => WKB_TYPE_ID[:wkb_linestring] | |
choice :wkb_type, | |
:copy_on_change => true, | |
:selection => lambda { big_endian? } do | |
uint32be true, :value => TYPE_ID[:linestring] | |
uint32le false, :value => TYPE_ID[:linestring] | |
end | |
#PointArray :points | |
choice :point, | |
:copy_on_change => true, | |
:selection => lambda { big_endian? } do | |
PointArrayBE true | |
PointArrayLE false | |
end | |
end | |
end | |
include WellKnownBinary | |
# converts a byte array to a hex string | |
def bin_to_hex(s) | |
s.unpack('H*').first | |
end | |
# | |
# converts a hex string to a byte array | |
# s = hex string | |
def hex_to_bin(s) | |
s.scan(/../).map { |x| x.hex }.pack('c*') | |
end | |
# create a WKB point | |
foo = WKBPoint.new( :point => { :x => 47.0001, :y => 89.0011 } ) | |
# inspect the point | |
# p foo | |
# get the byte array (WKB) | |
foo_bin = foo.to_binary_s | |
# get the hex string for the byte array | |
foo_hex = bin_to_hex( foo_bin ) | |
# display the hex string | |
# puts " foo hex: #{foo_hex}" | |
# convert from hex string back to a byte array | |
re_foo = WKBPoint.read( hex_to_bin('01010000008D976E1283C0F33F16FBCBEEC9C30240') ) | |
p re_foo | |
puts "created from string" | |
puts "created: #{ bin_to_hex(re_foo.to_binary_s) }" | |
puts "" | |
re_foo.byte_order = 0 | |
puts "changed byte order to big endian" | |
puts | |
puts " big-endian: #{ bin_to_hex(re_foo.to_binary_s) }" | |
puts | |
p re_foo | |
re_foo.byte_order = 1 | |
puts "changed byte order to little endian" | |
puts | |
puts " little-endian: #{ bin_to_hex(re_foo.to_binary_s) }" | |
puts | |
p re_foo | |
# Creating from WKB hex string: 01010000008D976E1283C0F33F16FBCBEEC9C30240 | |
# | |
# {"byte_order"=>1, "wkb_type"=>1, "point"=>{"x"=>1.2345, "y"=>2.3456}} | |
# created from string | |
# created: 01010000008d976e1283c0f33f16fbcbeec9c30240 | |
# | |
# changed byte order to big endian | |
# | |
# big-endian: 00000000013ff3c083126e978d4002c3c9eecbfb16 | |
# | |
# {"byte_order"=>0, "wkb_type"=>1, "point"=>{"x"=>1.2345, "y"=>2.3456}} | |
# changed byte order to little endian | |
# | |
# little-endian: 01010000008d976e1283c0f33f16fbcbeec9c30240 | |
# | |
# {"byte_order"=>1, "wkb_type"=>1, "point"=>{"x"=>1.2345, "y"=>2.3456}} | |
# | |
# > Process Exit Code: 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment