Class: GeoRuby::Shp4r::ShpFile

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/geo_ruby/shp4r/shp.rb

Overview

An interface to an ESRI shapefile (actually 3 files : shp, shx and dbf). Currently supports only the reading of geometries.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(file) ⇒ ShpFile

Opens a SHP file. Both “abc.shp” and “abc” are accepted. The files “abc.shp”, “abc.shx” and “abc.dbf” must be present



33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/geo_ruby/shp4r/shp.rb', line 33

def initialize(file)
  #strip the shp out of the file if present
  @file_root = file.gsub(/.shp$/i,"")
  #check existence of shp, dbf and shx files
  unless File.exists?(@file_root + ".shp") and File.exists?(@file_root + ".dbf") and File.exists?(@file_root + ".shx")
    raise MalformedShpException.new("Missing one of shp, dbf or shx for: #{@file}")
  end

  @dbf = Dbf::Reader.open(@file_root + ".dbf")
  @shx = File.open(@file_root + ".shx","rb")
  @shp = File.open(@file_root + ".shp","rb")
  read_index
end

Instance Attribute Details

#file_lengthObject (readonly)

Returns the value of attribute file_length.



28
29
30
# File 'lib/geo_ruby/shp4r/shp.rb', line 28

def file_length
  @file_length
end

#file_rootObject (readonly)

Returns the value of attribute file_root.



28
29
30
# File 'lib/geo_ruby/shp4r/shp.rb', line 28

def file_root
  @file_root
end

#mmaxObject (readonly)

Returns the value of attribute mmax.



28
29
30
# File 'lib/geo_ruby/shp4r/shp.rb', line 28

def mmax
  @mmax
end

#mminObject (readonly)

Returns the value of attribute mmin.



28
29
30
# File 'lib/geo_ruby/shp4r/shp.rb', line 28

def mmin
  @mmin
end

#record_countObject (readonly)

Returns the value of attribute record_count.



28
29
30
# File 'lib/geo_ruby/shp4r/shp.rb', line 28

def record_count
  @record_count
end

#shp_typeObject (readonly)

Returns the value of attribute shp_type.



28
29
30
# File 'lib/geo_ruby/shp4r/shp.rb', line 28

def shp_type
  @shp_type
end

#xmaxObject (readonly)

Returns the value of attribute xmax.



28
29
30
# File 'lib/geo_ruby/shp4r/shp.rb', line 28

def xmax
  @xmax
end

#xminObject (readonly)

Returns the value of attribute xmin.



28
29
30
# File 'lib/geo_ruby/shp4r/shp.rb', line 28

def xmin
  @xmin
end

#ymaxObject (readonly)

Returns the value of attribute ymax.



28
29
30
# File 'lib/geo_ruby/shp4r/shp.rb', line 28

def ymax
  @ymax
end

#yminObject (readonly)

Returns the value of attribute ymin.



28
29
30
# File 'lib/geo_ruby/shp4r/shp.rb', line 28

def ymin
  @ymin
end

#zmaxObject (readonly)

Returns the value of attribute zmax.



28
29
30
# File 'lib/geo_ruby/shp4r/shp.rb', line 28

def zmax
  @zmax
end

#zminObject (readonly)

Returns the value of attribute zmin.



28
29
30
# File 'lib/geo_ruby/shp4r/shp.rb', line 28

def zmin
  @zmin
end

Class Method Details

.create(file, shp_type, fields, &proc) ⇒ Object

create a new Shapefile of the specified shp type (see ShpType) and with the attribute specified in the fields array (see Dbf::Field). If a block is given, the ShpFile object newly created is passed to it.



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/geo_ruby/shp4r/shp.rb', line 64

def self.create(file,shp_type,fields,&proc)
  file_root = file.gsub(/.shp$/i,"")
  shx_io = File.open(file_root + ".shx","wb")
  shp_io = File.open(file_root + ".shp","wb")
  dbf_io = File.open(file_root + ".dbf","wb")
  str = [9994,0,0,0,0,0,50,1000,shp_type,0,0,0,0,0,0,0,0].pack("N7V2E8")
  shp_io << str
  shx_io << str
  rec_length = 1 + fields.inject(0) {|s,f| s + f.length} #+1 for the prefixed space (active record marker)
  dbf_io << [3,107,7,7,0,33 + 32 * fields.length,rec_length ].pack("c4Vv2x20") #32 bytes for first part of header
  fields.each do |field|
    dbf_io << [field.name,field.type,field.length,field.decimal].pack("a10xax4CCx14")
  end
  dbf_io << ['0d'].pack("H2")

  shx_io.close
  shp_io.close
  dbf_io.close

  open(file,&proc)

end

.open(file) ⇒ Object

opens a SHP “file”. If a block is given, the ShpFile object is yielded to it and is closed upon return. Else a call to open is equivalent to ShpFile.new(...).



53
54
55
56
57
58
59
60
61
# File 'lib/geo_ruby/shp4r/shp.rb', line 53

def self.open(file)
  shpfile = ShpFile.new(file)
  if block_given?
    yield shpfile
    shpfile.close
  else
    shpfile
  end
end

Instance Method Details

#[](i) ⇒ Object

Returns record i



128
129
130
# File 'lib/geo_ruby/shp4r/shp.rb', line 128

def [](i)
  get_record(i)
end

#closeObject

Closes a shapefile



88
89
90
91
92
# File 'lib/geo_ruby/shp4r/shp.rb', line 88

def close
  @dbf.close
  @shx.close
  @shp.close
end

#eachObject Also known as: each_record

Goes through each record



120
121
122
123
124
# File 'lib/geo_ruby/shp4r/shp.rb', line 120

def each
  (0...record_count).each do |i|
    yield get_record(i)
  end
end

#empty?Boolean

Tests if the file has no record

Returns:

  • (Boolean)


115
116
117
# File 'lib/geo_ruby/shp4r/shp.rb', line 115

def empty?
  record_count == 0
end

#fieldsObject

return the description of data fields



110
111
112
# File 'lib/geo_ruby/shp4r/shp.rb', line 110

def fields
  @dbf.fields
end

#recordsObject

Returns all the records



133
134
135
136
137
# File 'lib/geo_ruby/shp4r/shp.rb', line 133

def records
  Array.new(record_count) do |i|
    get_record(i)
  end
end

#reload!Object

force the reopening of the files compsing the shp. Close before calling this.



48
49
50
# File 'lib/geo_ruby/shp4r/shp.rb', line 48

def reload!
  initialize(@file_root)
end

#transactionObject

starts a transaction, to buffer physical file operations on the shapefile components.



95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/geo_ruby/shp4r/shp.rb', line 95

def transaction
  trs = ShpTransaction.new(self,@dbf)
  if block_given?
    answer = yield trs
    if answer == :rollback
      trs.rollback
    elsif !trs.rollbacked
      trs.commit
    end
  else
    trs
  end
end