Class: GeoRuby::Shp4r::ShpFile

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/geo_ruby/shp4r/shp_file.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


8
9
10
11
12
13
14
15
16
17
18
19
20
# File 'lib/geo_ruby/shp4r/shp_file.rb', line 8

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 = ::GeoRuby::Shp4r::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


3
4
5
# File 'lib/geo_ruby/shp4r/shp_file.rb', line 3

def file_length
  @file_length
end

#file_rootObject (readonly)

Returns the value of attribute file_root


3
4
5
# File 'lib/geo_ruby/shp4r/shp_file.rb', line 3

def file_root
  @file_root
end

#mmaxObject (readonly)

Returns the value of attribute mmax


3
4
5
# File 'lib/geo_ruby/shp4r/shp_file.rb', line 3

def mmax
  @mmax
end

#mminObject (readonly)

Returns the value of attribute mmin


3
4
5
# File 'lib/geo_ruby/shp4r/shp_file.rb', line 3

def mmin
  @mmin
end

#record_countObject (readonly)

Returns the value of attribute record_count


3
4
5
# File 'lib/geo_ruby/shp4r/shp_file.rb', line 3

def record_count
  @record_count
end

#shp_typeObject (readonly)

Returns the value of attribute shp_type


3
4
5
# File 'lib/geo_ruby/shp4r/shp_file.rb', line 3

def shp_type
  @shp_type
end

#xmaxObject (readonly)

Returns the value of attribute xmax


3
4
5
# File 'lib/geo_ruby/shp4r/shp_file.rb', line 3

def xmax
  @xmax
end

#xminObject (readonly)

Returns the value of attribute xmin


3
4
5
# File 'lib/geo_ruby/shp4r/shp_file.rb', line 3

def xmin
  @xmin
end

#ymaxObject (readonly)

Returns the value of attribute ymax


3
4
5
# File 'lib/geo_ruby/shp4r/shp_file.rb', line 3

def ymax
  @ymax
end

#yminObject (readonly)

Returns the value of attribute ymin


3
4
5
# File 'lib/geo_ruby/shp4r/shp_file.rb', line 3

def ymin
  @ymin
end

#zmaxObject (readonly)

Returns the value of attribute zmax


3
4
5
# File 'lib/geo_ruby/shp4r/shp_file.rb', line 3

def zmax
  @zmax
end

#zminObject (readonly)

Returns the value of attribute zmin


3
4
5
# File 'lib/geo_ruby/shp4r/shp_file.rb', line 3

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.


39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/geo_ruby/shp4r/shp_file.rb', line 39

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(...).


28
29
30
31
32
33
34
35
36
# File 'lib/geo_ruby/shp4r/shp_file.rb', line 28

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


103
104
105
# File 'lib/geo_ruby/shp4r/shp_file.rb', line 103

def [](i)
  get_record(i)
end

#closeObject

Closes a shapefile


63
64
65
66
67
# File 'lib/geo_ruby/shp4r/shp_file.rb', line 63

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

#eachObject Also known as: each_record

Goes through each record


95
96
97
98
99
# File 'lib/geo_ruby/shp4r/shp_file.rb', line 95

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)

90
91
92
# File 'lib/geo_ruby/shp4r/shp_file.rb', line 90

def empty?
  record_count == 0
end

#fieldsObject

return the description of data fields


85
86
87
# File 'lib/geo_ruby/shp4r/shp_file.rb', line 85

def fields
  @dbf.fields
end

#recordsObject

Returns all the records


108
109
110
111
112
# File 'lib/geo_ruby/shp4r/shp_file.rb', line 108

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.


23
24
25
# File 'lib/geo_ruby/shp4r/shp_file.rb', line 23

def reload!
  initialize(@file_root)
end

#transactionObject

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


70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/geo_ruby/shp4r/shp_file.rb', line 70

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