Module: GrassGis::Tools

Defined in:
lib/grassgis/tools.rb

Overview

Convenient shortcuts and tools for use in GRASS sessions Currently only implemented for GRASS 7

Instance Method Summary collapse

Instance Method Details

#accessible_mapsetsObject



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

def accessible_mapsets
  g.mapsets '-p'
  output.lines.to_a.last.split
end

#available_mapsetsObject



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

def available_mapsets
  g.mapsets '-l'
  output.lines.to_a.last.split
end

#copy_map(map, options = {}) ⇒ Object



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/grassgis/tools.rb', line 120

def copy_map(map, options = {})
  type = options[:type]
  raise "Must specify type to copy a map" unless type
  if map.include?('@')
    map, mapset = map.split('@').last
  end
  from_mapset = options[:from]
  if from_mapset && from_mapset != mapset
    raise "Inconsistent origin mapset"
  end
  from_mapset ||= mapset
  unless from_mapset
    from_mapset = map_mapset(map, type: options[:type])
  end
  to_mapset = options[:to]
  unless from_mapset && to_mapset
    raise "Must specify origin and destination mapsets"
  end
  if from_mapset != to_mapset
    original_map = "#{map}@#{from_mapset}"
    with_mapset to_mapset do
      if grass_version >= GrassGis.version('7.0.0')
        g.copy type => [original_map, map]
      else
        param = { vector: 'vect', raster: 'rast', raster_3d: 'rast3d' }[type.to_sym]
        g.copy param => [original_map, map]
      end
    end
    original_map
  end
end

#create_mapset(mapset) ⇒ Object



152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/grassgis/tools.rb', line 152

def create_mapset(mapset)
  if true
    # TODO: if mapset optional argument added to Mapset constructor:
    # ms = GrassGis::Mapset.new(self, mapset)
    keep_mapset = configuration[:mapset]
    configuration[:mapset] = mapset
    ms = GrassGis::Mapset.new(self)
    ms.create! unless ms.exists?
    configuration[:mapset] = keep_mapset
  else
    # This will fail under windows
    current = current_mapset
    g.mapset '-c',
      mapset: mapset,
      location: configuration[:location],
      dbase: configuration[:gisdbase]
    g.mapset current
  end
end

#current_mapsetObject



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

def current_mapset
  g.mapsets '-p'
  current_mapset = output.lines.to_a.last.split.first
end

#explicit_map_mapset(map) ⇒ Object



81
82
83
84
85
# File 'lib/grassgis/tools.rb', line 81

def explicit_map_mapset(map)
  if map.include?('@')
    map.split('@').last
  end
end

#map_exists?(map, options = {}) ⇒ Boolean

Returns:

  • (Boolean)


5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# File 'lib/grassgis/tools.rb', line 5

def map_exists?(map, options = {})
  types = Array(options[:type])
  types = 'all' if types.empty?
  mapsets = []
  if map.include?('@')
    map, mapset = map.split('@')
    mapsets << mapset
  end
  mapsets += Array(options[:mapset])
  if mapsets.empty?
    g.list types.join(',')
  else
    g.list types.join(','), mapset: mapsets.join(',')
  end
  maps = output.split.map { |m| m.split('@').first }
  maps.include?(map)
end

#map_mapset(map, options = {}) ⇒ Object



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/grassgis/tools.rb', line 87

def map_mapset(map, options = {})
  if map.include?('@')
    map.split('@').last
  else
    type = options[:type]
    raise "Must specify type of the map" unless type
    accessible = accessible_mapsets
    accessible.each do |mapset|
      return mapset if map_exists?(map, type: type, mapset: mapset)
    end
    available = available_mapsets - accessible
    available.each do |mapset|
      return mapset if map_exists?(map, type: type, mapset: mapset)
    end
    nil
  end
end

#move_map(map, options = {}) ⇒ Object



172
173
174
175
# File 'lib/grassgis/tools.rb', line 172

def move_map(map, options = {})
  original_map = copy_map(map, options)
  remove_map original_map, type: options[:type]
end

#raster_exists?(map, options = {}) ⇒ Boolean

Returns:

  • (Boolean)


23
24
25
# File 'lib/grassgis/tools.rb', line 23

def raster_exists?(map, options = {})
  map_exists? map, options.merge(type: 'rast')
end

#raster_info(map) ⇒ Object



35
36
37
38
# File 'lib/grassgis/tools.rb', line 35

def raster_info(map)
  r.info '-g', map
  shell_to_hash
end

#raster_res(map) ⇒ Object



45
46
47
48
# File 'lib/grassgis/tools.rb', line 45

def raster_res(map)
  info = raster_info(map)
  info.values_at('ewres', 'nsres').map(&:to_i)
end

#region_infoObject



40
41
42
43
# File 'lib/grassgis/tools.rb', line 40

def region_info
  g.region '-m'
  shell_to_hash
end

#region_resObject



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

def region_res
  info = region_info
  info.values_at('ewres', 'nsres').map(&:to_i)
end

#remove_map(map, options = {}) ⇒ Object



105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/grassgis/tools.rb', line 105

def remove_map(map, options = {})
  type = options[:type]
  raise "Must specify type to remove a map" unless type
  mapset = explicit_map_mapset(map) || options[:mapset] || map_mapset(map, type: type)
  raise "Map not found #{map} (#{type})" unless mapset
  with_mapset(mapset) do
    if grass_version >= GrassGis.version('7.0.0')
      g.remove '-f', type: type, name: map
    else
      param = { vector: 'vect', raster: 'rast', raster_3d: 'rast3d' }[type.to_sym]
      g.remove '-f', param => map
    end
  end
end

#resamp_average(options = {}) ⇒ Object



177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
# File 'lib/grassgis/tools.rb', line 177

def resamp_average(options = {})
  input_raster = options[:input]
  raise "Raster #{input_raster} not found" unless raster_exists?(input_raster)
  input_res = raster_res(input_raster)

  if options[:output_res]
    output_res = options[:output_res]
    unless output_res.is_a?(Array)
      output_res = [output_res, output_res]
    end
  else
    output_res = region_res
  end

  output_raster = options[:output]

  if options[:direction]
    unless raster_exists?("#{input_raster}_sin")
      g.region ewres: input_res[0], nsres: input_res[1]
      r.mapcalc "#{input_raster}_sin = sin(#{input_raster})"
    end
    unless raster_exists?("#{input_raster}_cos")
      g.region ewres: input_res[0], nsres: input_res[1]
      r.mapcalc "#{input_raster}_cos = cos(#{input_raster})"
    end
    g.region ewres: output_res[0], nsres: output_res[1]
    r.resamp.stats '--overwrite', input: "#{input_raster}_cos", output: "#{output_raster}_cos"
    r.resamp.stats '--overwrite', input: "#{input_raster}_sin", output: "#{output_raster}_sin"
    r.mapcalc "#{output_raster} = atan(#{output_raster}_cos,#{output_raster}_sin)"
    r.colors map: output_raster, raster: input_raster
    g.remove '-f', type: 'raster', name: ["#{output_raster}_cos", "#{output_raster}_sin"]
  else
    g.region ewres: output_res[0], nsres: output_res[1]
    r.resamp.stats input: input_raster, output: output_raster
    r.colors map: output_raster, raster: input_raster
  end
end

#shell_to_hashObject



31
32
33
# File 'lib/grassgis/tools.rb', line 31

def shell_to_hash
  Hash[output.lines.map{|l| l.strip.split('=')}]
end

#vector_exists?(map, options = {}) ⇒ Boolean

Returns:

  • (Boolean)


27
28
29
# File 'lib/grassgis/tools.rb', line 27

def vector_exists?(map, options = {})
  map_exists? map, options.merge(type: 'vect')
end

#with_mapset(mapset) {|_self| ... } ⇒ Object

Yields:

  • (_self)

Yield Parameters:



60
61
62
63
64
65
66
67
68
69
# File 'lib/grassgis/tools.rb', line 60

def with_mapset(mapset)
  current = current_mapset
  if mapset != current
    change_mapset mapset
  end
  yield self
  if mapset != current
    change_mapset current
  end
end