Class: RGeo::CoordSys::SRSDatabase::Proj4Data

Inherits:
Object
  • Object
show all
Defined in:
lib/rgeo/coord_sys/srs_database/proj4_data.rb

Overview

A spatial reference database implementation backed by coordinate system files installed as part of the proj4 library. For a given Proj4Data object, you specify a single file (e.g. the epsg data file), and you can retrieve records by ID number.

Instance Method Summary collapse

Constructor Details

#initialize(filename_, opts_ = {}) ⇒ Proj4Data

Connect to one of the proj4 data files. You should provide the file name, optionally the installation directory if it is not in a typical location, and several additional options.

These options are recognized:

:dir

The path for the share/proj directory that contains the requested data file. By default, the Proj4Data class will try a number of directories for you, including /usr/local/share/proj, /opt/local/share/proj, /usr/share/proj, and a few other variants. However, if you have proj4 installed elsewhere, you can provide an explicit directory using this option. You may also pass nil as the value, in which case all the normal lookup paths will be disabled, and you will have to provide the full path as the file name.

:cache

If set to true, this class caches previously looked up entries so subsequent lookups do not have to reread the file. If set to :read_all, then ALL values in the file are read in and cached the first time a lookup is done. If set to :preload, then ALL values in the file are read in immediately when the database is created. Default is false, indicating that the file will be reread on every lookup.

:authority

If set, its value is taken as the authority name for all entries. The authority code will be set to the identifier. If not set, then the authority fields of entries will be blank.


81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/rgeo/coord_sys/srs_database/proj4_data.rb', line 81

def initialize(filename_, opts_={})
  dir_ = nil
  if opts_.include?(:dir)
    dir_ = opts_[:dir]
  else
    ['/usr/local/share/proj', '/usr/local/proj/share/proj', '/usr/local/proj4/share/proj', '/opt/local/share/proj', '/opt/proj/share/proj', '/opt/proj4/share/proj', '/opt/share/proj', '/usr/share/proj'].each do |d_|
      if ::File.directory?(d_) && ::File.readable?(d_)
        dir_ = d_
        break
      end
    end
  end
  @path = dir_ ? "#{dir_}/#{filename_}" : filename_
  @authority = opts_[:authority]
  if opts_[:cache]
    @cache = {}
    case opts_[:cache]
    when :read_all
      @populate_state = 1
    when :preload
      _search_file(nil)
      @populate_state = 2
    else
      @populate_state = 0
    end
  else
    @cache = nil
    @populate_state = 0
  end
end

Instance Method Details

#_search_file(ident_) ⇒ Object

:nodoc:


140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/rgeo/coord_sys/srs_database/proj4_data.rb', line 140

def _search_file(ident_)  # :nodoc:
  ::File.open(@path) do |file_|
    cur_name_ = nil
    cur_ident_ = nil
    cur_text_ = nil
    file_.each do |line_|
      line_.strip!
      if (comment_delim_ = line_.index('#'))
        cur_name_ = line_[comment_delim_+1..-1].strip
        line_ = line_[0..comment_delim_-1].strip
      end
      unless cur_ident_
        if line_ =~ /^<(\w+)>(.*)/
          cur_ident_ = $1
          cur_text_ = []
          line_ = $2.strip
        end
      end
      if cur_ident_
        if line_[-2..-1] == '<>'
          cur_text_ << line_[0..-3].strip
          cur_text_ = cur_text_.join(' ')
          if ident_.nil?
            @cache[ident_] = Entry.new(ident_, :authority => @authority, :authority_code => @authority ? id_ : nil, :name => cur_name_, :proj4 => cur_text_)
          end
          if cur_ident_ == ident_
            return [ident_, cur_name_, cur_text_]
          end
          cur_ident_ = nil
          cur_name_ = nil
          cur_text_ = nil
        else
          cur_text_ << line_
        end
      end
    end
  end
  nil
end

#clear_cacheObject

Clear the cache if one exists.


134
135
136
137
# File 'lib/rgeo/coord_sys/srs_database/proj4_data.rb', line 134

def clear_cache
  @cache.clear if @cache
  @populate_state = 1 if @populate_state == 2
end

#get(ident_) ⇒ Object

Retrieve the Entry for the given ID number.


115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/rgeo/coord_sys/srs_database/proj4_data.rb', line 115

def get(ident_)
  ident_ = ident_.to_s
  return @cache[ident_] if @cache && @cache.include?(ident_)
  result_ = nil
  if @populate_state == 0
    data_ = _search_file(ident_)
    result_ = Entry.new(ident_, :authority => @authority, :authority_code => @authority ? ident_ : nil, :name => data_[1], :proj4 => data_[2]) if data_
    @cache[ident_] = result_ if @cache
  elsif @populate_state == 1
    _search_file(nil)
    result_ = @cache[ident_]
    @populate_state = 2
  end
  result_
end