Skip to content

Instantly share code, notes, and snippets.

@tohka
Created June 8, 2019 05:41
Show Gist options
  • Save tohka/4cc6dba6c287824d60cb23f429b16b9c to your computer and use it in GitHub Desktop.
Save tohka/4cc6dba6c287824d60cb23f429b16b9c to your computer and use it in GitHub Desktop.
#!/usr/bin/ruby
def read_data(io, type, bo, label = '')
data = nil
bytes = nil
value = nil
if type == :int
data = io.read(4)
if bo == :big
value = data.unpack('N')[0]
elsif bo == :little
value = data.unpack('V')[0]
else
raise ArgumentError
end
bytes = "%04x %04x" % data.unpack('n2')
elsif type == :double
data = io.read(8)
if bo == :big
value = data.unpack('G')[0]
elsif bo == :little
value = data.unpack('E')[0]
else
raise ArgumentError
end
bytes = "%04x %04x %04x %04x" % data.unpack('n4')
else
raise ArgumentError
end
str = [label, "value= #{value}", bytes, type.to_s, bo.to_s].join("\t")
[value, str]
end
Dir.glob('*.shp').sort.each do |path|
open(path, 'rb') do |io|
puts '##########################################'
puts "dump #{path}"
puts '--------------------------------'
puts 'File Header'
puts '--------------------------------'
puts read_data(io, :int, :big, 'File Code')[1]
puts read_data(io, :int, :big, 'Unused')[1]
puts read_data(io, :int, :big, 'Unused')[1]
puts read_data(io, :int, :big, 'Unused')[1]
puts read_data(io, :int, :big, 'Unused')[1]
puts read_data(io, :int, :big, 'Unused')[1]
puts read_data(io, :int, :big, 'File Length')[1]
puts read_data(io, :int, :little, 'Version')[1]
puts read_data(io, :int, :little, 'Shape Type')[1]
puts read_data(io, :double, :little, 'Xmin')[1]
puts read_data(io, :double, :little, 'Ymin')[1]
puts read_data(io, :double, :little, 'Xmax')[1]
puts read_data(io, :double, :little, 'Ymax')[1]
puts read_data(io, :double, :little, 'Zmin')[1]
puts read_data(io, :double, :little, 'Zmax')[1]
puts read_data(io, :double, :little, 'Mmin')[1]
puts read_data(io, :double, :little, 'Mmax')[1]
puts '--------------------------------'
puts 'Records'
puts '--------------------------------'
until io.eof?
puts read_data(io, :int, :big, 'Record Number')[1]
puts read_data(io, :int, :big, 'Content Length')[1]
v = read_data(io, :int, :little, 'Shape Type')
puts v[1]
if v[0] == 0 # Null Shape
nil
elsif v[0] == 1 # Point
puts read_data(io, :double, :little, 'X')[1]
puts read_data(io, :double, :little, 'Y')[1]
elsif v[0] == 3 || v[0] == 5 # PolyLine or Polygon
puts read_data(io, :double, :little, 'Xmin')[1]
puts read_data(io, :double, :little, 'Ymin')[1]
puts read_data(io, :double, :little, 'Xmax')[1]
puts read_data(io, :double, :little, 'Ymax')[1]
parts = read_data(io, :int, :little, 'NumParts')
puts parts[1]
points = read_data(io, :int, :little, 'NumPoints')
puts points[1]
parts[0].times do |i|
puts read_data(io, :int, :little, "Index of part[#{i}]")[1]
end
points[0].times do |i|
puts read_data(io, :double, :little, "X[#{i}]")[1]
puts read_data(io, :double, :little, "Y[#{i}]")[1]
end
end
puts '------------'
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment