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
# 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[:errors] ||= :raise
  config[:echo] = :commands unless config.key?(:echo)

  @config = config

  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

50
51
52
# File 'lib/grassgis/context.rb', line 50

def history
  @history
end

Instance Method Details

#allocateObject


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
111
112
113
114
115
116
117
118
# File 'lib/grassgis/context.rb', line 85

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]

  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 = []
end

#change_mapset(new_mapset) ⇒ Object

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


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

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

#configurationObject


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

def configuration
  @config
end

#disposeObject


120
121
122
123
124
125
126
127
128
129
# File 'lib/grassgis/context.rb', line 120

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)

170
171
172
# File 'lib/grassgis/context.rb', line 170

def dry?
  @config[:dry]
end

#error?Boolean

Did last command exit with error status

Returns:

  • (Boolean)

63
64
65
# File 'lib/grassgis/context.rb', line 63

def error?
  GrassGis.error? last
end

#error_infoObject


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

def error_info
  GrassGis.error_info last
end

#error_outputObject

Standar error output of last command executed


77
78
79
# File 'lib/grassgis/context.rb', line 77

def error_output
  last.error_output
end

#errorsObject

Array of commands that resulted in error in the session


58
59
60
# File 'lib/grassgis/context.rb', line 58

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

#execute(cmd) ⇒ Object


174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/grassgis/context.rb', line 174

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

238
239
240
# File 'lib/grassgis/context.rb', line 238

def grass_version
  Gem::Version.new @config[:version]
end

#lastObject

Last command executed in the session (history)


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

def last
  history.last
end

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


190
191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/grassgis/context.rb', line 190

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


214
215
216
217
218
219
220
221
222
223
# File 'lib/grassgis/context.rb', line 214

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)

204
205
206
# File 'lib/grassgis/context.rb', line 204

def logging?
  !!logging_file
end

#outputObject

Output of the last command executed


72
73
74
# File 'lib/grassgis/context.rb', line 72

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

162
163
164
165
166
167
168
# File 'lib/grassgis/context.rb', line 162

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