Class: GrassGis::Context

Inherits:
Object
  • Object
show all
Defined in:
lib/grassgis/context.rb

Constant Summary collapse

ROOT_MODULES =
%w(d g i r v s m p)
REQUIRED_CONFIG =
[:gisbase, :location]

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config) ⇒ Context

Returns a new instance of Context.



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/grassgis/context.rb', line 9

def initialize(config)
  # TODO: raise error unless required parameters are present
  # apply configuration defaults
  config[:gisdbase] ||= File.join(ENV['HOME'], 'grassdata')
  config[:mapset]  ||= ENV['USER']
  unless config[:version]
    version_file = File.join(config[:gisbase], 'etc', 'VERSIONNUMBER')
    if File.exists?(version_file)
      config[:version] = File.read(version_file).split.first
    end
  end
  config[:message_format] ||= 'plain'
  config[:true_color] = true unless config.key?(:true_color)
  config[:transparent] = true unless config.key?(:transparent)
  config[:png_auto_write] = true unless config.key?(:png_auto_write)
  config[:gnuplot] ||= 'gnuplot -persist'
  config[:gui] ||= 'wxpython'
  config[:python] ||= 'python'
  config[:pythonpath] ||= File.join(config[:gisbase], 'etc', 'python')

  config[:errors] ||= :raise
  config[:echo] = :commands unless config.key?(:echo)

  @config = config
  @tools = (config[:tools] == false) ? false : true

  locals = config[:locals] || {}
  locals.each do |var_name, value|
    define_singleton_method(var_name){ value }
  end
end

Instance Attribute Details

#historyObject (readonly)

Commands executed in the session are kept in the history array

GrassGis.session config do
   g.region res: 10
   g.region res: 20
   g.region res: 30
   puts history[-3] # => "g.region res=10"
   puts history[-2] # => "g.region res=20"
   puts history[-1] # => "g.region res=30"
   puts history[-2].output
end


53
54
55
# File 'lib/grassgis/context.rb', line 53

def history
  @history
end

Instance Method Details

#allocateObject



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/grassgis/context.rb', line 88

def allocate
  @original_env = {}

  mapset = Mapset.new(self)
  actual_mapset = mapset.exists? ? mapset.to_s : 'PERMANENT'
  set_gisrc @config.merge(mapset: actual_mapset)

  replace_var 'GISBASE', @config[:gisbase]
  replace_var 'GRASS_VERSION', @config[:version]
  replace_var 'GRASS_MESSAGE_FORMAT', @config[:message_format].to_s
  replace_var 'GRASS_TRUECOLOR', bool_var(@config[:true_color])
  replace_var 'GRASS_TRANSPARENT', bool_var(@config[:transparent])
  replace_var 'GRASS_PNG_AUTO_WRITE', bool_var(@config[:png_auto_write])
  replace_var 'GRASS_GNUPLOT', @config[:gnuplot]
  replace_var 'GRASS_PYTHON', @config[:python]
  insert_path 'PYTHONPATH', @config[:pythonpath]

  paths = ['bin', 'scripts']
  if OS.windows?
    # paths << 'lib'
    paths.unshift 'lib'
  else
    insert_path 'LD_LIBRARY_PATH', File.join(@config[:gisbase], 'lib')
    ENV['GRASS_LD_LIBRARY_PATH'] = ENV['LD_LIBRARY_PATH']
  end
  paths = paths.map { |path| File.join(@config[:gisbase], path) }
  if OS.windows?
    osgeo4w_dir = ENV['OSGEO4W_ROOT'] || "C:\\OSGeo4W"
    if File.directory?(osgeo4w_dir)
      paths << File.join(osgeo4w_dir, 'bin')
    end
  end
  insert_path 'PATH', *paths
  insert_path 'MANPATH', File.join(@config[:gisbase], 'man')
  @history = []
  extend GrassGis::Tools if @tools
end

#change_mapset(new_mapset) ⇒ Object

This should be used instead of g.mapset to avoid problems under Windows



215
216
217
218
# File 'lib/grassgis/context.rb', line 215

def change_mapset(new_mapset)
  log "Change mapset to #{new_mapset}"
  set_gisrc @config.merge(mapset: new_mapset)
end

#configurationObject



84
85
86
# File 'lib/grassgis/context.rb', line 84

def configuration
  @config
end

#disposeObject



126
127
128
129
130
131
132
133
134
135
# File 'lib/grassgis/context.rb', line 126

def dispose
  @gisrc.unlink if @gisrc
  @gisrc = nil
  if @original_env
    @original_env.each do |var, value|
      ENV[var] = value
    end
  end
  @original_env = {}
end

#dry?Boolean

Returns:

  • (Boolean)


176
177
178
# File 'lib/grassgis/context.rb', line 176

def dry?
  @config[:dry]
end

#error?Boolean

Did last command exit with error status

Returns:

  • (Boolean)


66
67
68
# File 'lib/grassgis/context.rb', line 66

def error?
  GrassGis.error? last
end

#error_infoObject



70
71
72
# File 'lib/grassgis/context.rb', line 70

def error_info
  GrassGis.error_info last
end

#error_outputObject

Standar error output of last command executed



80
81
82
# File 'lib/grassgis/context.rb', line 80

def error_output
  last.error_output
end

#errorsObject

Array of commands that resulted in error in the session



61
62
63
# File 'lib/grassgis/context.rb', line 61

def errors
  history.select { |cmd| GrassGis.error?(cmd) }
end

#execute(cmd) ⇒ Object



180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/grassgis/context.rb', line 180

def execute(cmd)
  @history << cmd
  if @config[:echo]
    puts cmd.to_s(with_input: false)
  end
  log("Execute command:") { cmd.to_s(with_input: true) }
  unless dry?
    cmd.run error_output: :separate
  end
  if cmd.output
    puts cmd.output if @config[:echo] == :output
  end
  handle_errors cmd
  cmd
end

#grass_versionObject

Version of GRASS in use in the session, as a comparable version object.

Example of use:

GrassGis.session configuration do
  if grass_version >= GrassGis.version('7.0.0')
    r.relief input: 'dem', output: 'relief'
  else
    r.shaded.relief map: 'dem', shadedmap: 'relief'
  end
end


244
245
246
# File 'lib/grassgis/context.rb', line 244

def grass_version
  GrassGis.version @config[:version]
end

#lastObject

Last command executed in the session (history)



56
57
58
# File 'lib/grassgis/context.rb', line 56

def last
  history.last
end

#log(text, options = {}) ⇒ Object



196
197
198
199
200
201
202
203
204
205
206
207
208
# File 'lib/grassgis/context.rb', line 196

def log(text, options = {})
  log_file = logging_file
  if log_file
    timestamp = Time.now.strftime("%H:%M:%S")
    msg = "#{timestamp} - #{text}"
    log_message log_file, msg
    indented_text = options[:indented]
    indented_text ||= yield if !indented_text && block_given?
    if indented_text
      log_message log_file, indented_text, indentation: '  '
    end
  end
end

#log_headerObject



220
221
222
223
224
225
226
227
228
229
# File 'lib/grassgis/context.rb', line 220

def log_header
  log_file = logging_file
  if log_file
    msg = "Start GrassGis Session [#{Time.now}]"
    log_message log_file, "# #{'='*msg.size}"
    log_message log_file, "# #{msg}"
    log_message log_file, configuration.to_yaml, indentation: '# '
    log_message log_file, "# #{'-'*msg.size}"
  end
end

#logging?Boolean

Returns:

  • (Boolean)


210
211
212
# File 'lib/grassgis/context.rb', line 210

def logging?
  !!logging_file
end

#outputObject

Output of the last command executed



75
76
77
# File 'lib/grassgis/context.rb', line 75

def output
  last.output
end

#session(&blk) ⇒ Object

Evaluate a block of code in the context of a GRASS session

Useful to pass a GRASS context around and use it to execute GRASS commands, e.g.:

def helper(grass, ...)
   # can invoke GRASS commands using grass:
   grass.g.region res: 10
   # Or use a session block to abbreviate typing:
   grass.session do
     g.region res: 10
     ...
   end
end

GrassGis.session ... do
  helper seld, ...
  ...
end


168
169
170
171
172
173
174
# File 'lib/grassgis/context.rb', line 168

def session(&blk)
  if blk.arity == 1
    blk.call self
  else
    instance_eval &blk
  end
end