grid.py 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675
  1. # -*- coding: utf-8 -*-
  2. """
  3. Created on Thu Mar 28 11:06:00 2013
  4. @author: pietro
  5. """
  6. import os
  7. import multiprocessing as mltp
  8. import subprocess as sub
  9. import shutil as sht
  10. from grass.script.setup import write_gisrc
  11. from grass.pygrass.gis import Mapset, Location
  12. from grass.pygrass.gis.region import Region
  13. from grass.pygrass.modules import Module
  14. from grass.pygrass.functions import get_mapset_raster, findmaps
  15. from grass.pygrass.modules.grid.split import split_region_tiles
  16. from grass.pygrass.modules.grid.patch import rpatch_map
  17. def select(parms, ptype):
  18. """Select only a certain type of parameters.
  19. Parameters
  20. ----------
  21. params : DictType parameters
  22. A DictType parameter with inputs or outputs of a Module class.
  23. ptype : string
  24. String define the type of parameter that we want to select,
  25. valid ptype are: 'raster', 'vector', 'group'
  26. Returns
  27. -------
  28. An iterator with the value of the parameter.
  29. Examples
  30. --------
  31. ::
  32. >>> slp = Module('r.slope.aspect',
  33. ... elevation='ele', slope='slp', aspect='asp',
  34. ... run_=False)
  35. >>> for rast in select(slp.outputs, 'raster'):
  36. ... print rast
  37. ...
  38. slp
  39. asp
  40. """
  41. for k in parms:
  42. par = parms[k]
  43. if par.type == ptype or par.typedesc == ptype and par.value:
  44. if par.multiple:
  45. for val in par.value:
  46. yield val
  47. else:
  48. yield par.value
  49. def copy_special_mapset_files(path_src, path_dst):
  50. """Copy all the special GRASS files that are contained in
  51. a mapset to another mapset."""
  52. for fil in (fi for fi in os.listdir(path_src) if fi.isupper()):
  53. sht.copy(os.path.join(path_src, fil), path_dst)
  54. def copy_mapset(mapset, path):
  55. """Copy mapset to another place without copying raster and vector data.
  56. Parameters
  57. ----------
  58. mapset : mapset_like
  59. A Mapset instance.
  60. path : string
  61. Path where the new mapset must be copied.
  62. Returns
  63. -------
  64. The instance of the new Mapset.
  65. Examples
  66. --------
  67. ::
  68. >>> mset = Mapset()
  69. >>> mset.name
  70. 'user1'
  71. >>> import tempfile as tmp
  72. >>> import os
  73. >>> path = os.path.join(tmp.gettempdir(), 'my_loc', 'my_mset')
  74. >>> copy_mapset(mset, path)
  75. Mapset('user1')
  76. >>> sorted(os.listdir(path))
  77. ['PERMANENT', 'user1']
  78. >>> sorted(os.listdir(os.path.join(path, 'PERMANENT')))
  79. ['DEFAULT_WIND', 'PROJ_INFO', 'PROJ_UNITS', 'VAR', 'WIND']
  80. >>> sorted(os.listdir(os.path.join(path, 'user1')))
  81. ['CURGROUP', 'SEARCH_PATH', 'VAR', 'WIND']
  82. >>> import shutil
  83. >>> shutil.rmtree(path)
  84. """
  85. per_old = os.path.join(mapset.gisdbase, mapset.location, 'PERMANENT')
  86. per_new = os.path.join(path, 'PERMANENT')
  87. map_old = mapset.path()
  88. map_new = os.path.join(path, mapset.name)
  89. if not os.path.isdir(per_new):
  90. os.makedirs(per_new)
  91. if not os.path.isdir(map_new):
  92. os.mkdir(map_new)
  93. copy_special_mapset_files(per_old, per_new)
  94. copy_special_mapset_files(map_old, map_new)
  95. gisdbase, location = os.path.split(path)
  96. return Mapset(mapset.name, location, gisdbase)
  97. def read_gisrc(gisrc):
  98. """Read a GISRC file and return a tuple with the mapset, location
  99. and gisdbase.
  100. Examples
  101. --------
  102. ::
  103. >>> import os
  104. >>> read_gisrc(os.environ['GISRC']) # doctest: +ELLIPSIS
  105. ('user1', ...)
  106. """
  107. with open(gisrc, 'r') as gfile:
  108. gis = dict([(k.strip(), v.strip())
  109. for k, v in [row.split(':') for row in gfile]])
  110. return gis['MAPSET'], gis['LOCATION_NAME'], gis['GISDBASE']
  111. def get_mapset(gisrc_src, gisrc_dst):
  112. """Get mapset from a GISRC source to a GISRC destination.
  113. Parameters
  114. ----------
  115. gisrc_src : path to the GISRC source
  116. gisrc_dst : path to the GISRC destination
  117. Returns
  118. -------
  119. A tuple with Mapset(src), Mapset(dst)
  120. """
  121. msrc, lsrc, gsrc = read_gisrc(gisrc_src)
  122. mdst, ldst, gdst = read_gisrc(gisrc_dst)
  123. path_src = os.path.join(gsrc, lsrc, msrc)
  124. path_dst = os.path.join(gdst, ldst, mdst)
  125. if not os.path.isdir(path_dst):
  126. os.makedirs(path_dst)
  127. copy_special_mapset_files(path_src, path_dst)
  128. src = Mapset(msrc, lsrc, gsrc)
  129. dst = Mapset(mdst, ldst, gdst)
  130. visible = [m for m in src.visible]
  131. visible.append(src.name)
  132. dst.visible.extend(visible)
  133. return src, dst
  134. def copy_groups(groups, gisrc_src, gisrc_dst, region=None):
  135. """Copy group from one mapset to another, crop the raster to the region.
  136. Parameters
  137. ----------
  138. groups : list of strings
  139. A list of strings with the group that must be copied
  140. from a master to another.
  141. gisrc_src : path to the GISRC source
  142. Path of the GISRC file from where we want to copy the groups.
  143. gisrc_dst : path to the GISRC destination
  144. Path of the GISRC file where the groups will be created.
  145. region : region_like or dictionary
  146. A region like object or a dictionary with the region parameters that
  147. will be used to crop the rasters of the groups.
  148. Returns
  149. -------
  150. None.
  151. """
  152. env = os.environ.copy()
  153. # instantiate modules
  154. get_grp = Module('i.group', flags='lg', stdout_=sub.PIPE, run_=False)
  155. set_grp = Module('i.group')
  156. get_grp.run_ = True
  157. rmloc = lambda r: r.split('@')[0] if '@' in r else r
  158. src = read_gisrc(gisrc_src)
  159. dst = read_gisrc(gisrc_dst)
  160. rm = True if src[2] != dst[2] else False
  161. all_rasts = [r[0]
  162. for r in findmaps('rast', location=dst[1], gisdbase=dst[2])]
  163. for grp in groups:
  164. # change gisdbase to src
  165. env['GISRC'] = gisrc_src
  166. get_grp(group=grp, env_=env)
  167. rasts = [r for r in get_grp.outputs.stdout.split()]
  168. # change gisdbase to dst
  169. env['GISRC'] = gisrc_dst
  170. rast2cp = [r for r in rasts if rmloc(r) not in all_rasts]
  171. if rast2cp:
  172. copy_rasters(rast2cp, gisrc_src, gisrc_dst, region=region)
  173. set_grp(group=grp,
  174. input=[rmloc(r) for r in rasts] if rast2cp or rm else rasts,
  175. env_=env)
  176. def set_region(region, gisrc_src, gisrc_dst, env):
  177. """Set a region into two different mapsets.
  178. Parameters
  179. ----------
  180. region : region_like or dictionary
  181. A region like object or a dictionary with the region parameters that
  182. will be used to crop the rasters.
  183. gisrc_src : path to the GISRC source
  184. Path of the GISRC file from where we want to copy the rasters.
  185. gisrc_dst : path to the GISRC destination
  186. Path of the GISRC file where the rasters will be created.
  187. region : dictionary
  188. A dictionary with the variable environment to use.
  189. Returns
  190. -------
  191. None.
  192. """
  193. reg_str = "g.region n=%(north)r s=%(south)r " \
  194. "e=%(east)r w=%(west)r " \
  195. "nsres=%(nsres)r ewres=%(ewres)r"
  196. reg_cmd = reg_str % dict(region.items())
  197. env['GISRC'] = gisrc_src
  198. sub.Popen(reg_cmd, shell=True, env=env)
  199. env['GISRC'] = gisrc_dst
  200. sub.Popen(reg_cmd, shell=True, env=env)
  201. def copy_rasters(rasters, gisrc_src, gisrc_dst, region=None):
  202. """Copy rasters from one mapset to another, crop the raster to the region.
  203. Parameters
  204. ----------
  205. rasters : list of strings
  206. A list of strings with the raster map that must be copied
  207. from a master to another.
  208. gisrc_src : path to the GISRC source
  209. Path of the GISRC file from where we want to copy the rasters.
  210. gisrc_dst : path to the GISRC destination
  211. Path of the GISRC file where the rasters will be created.
  212. region : region_like or dictionary
  213. A region like object or a dictionary with the region parameters that
  214. will be used to crop the rasters.
  215. Returns
  216. -------
  217. None.
  218. """
  219. env = os.environ.copy()
  220. if region:
  221. set_region(region, gisrc_src, gisrc_dst, env)
  222. path_dst = os.path.join(*read_gisrc(gisrc_dst)[::-1])
  223. nam = "copy%d__%s" % (id(gisrc_dst), '%s')
  224. # instantiate modules
  225. mpclc = Module('r.mapcalc')
  226. rpck = Module('r.pack')
  227. rupck = Module('r.unpack')
  228. remove = Module('g.remove')
  229. for rast in rasters:
  230. rast_clean = rast.split('@')[0] if '@' in rast else rast
  231. # change gisdbase to src
  232. env['GISRC'] = gisrc_src
  233. name = nam % rast_clean
  234. mpclc(expression="%s=%s" % (name, rast), overwrite=True, env_=env)
  235. file_dst = "%s.pack" % os.path.join(path_dst, name)
  236. rpck(input=name, output=file_dst, overwrite=True, env_=env)
  237. remove(rast=name, env_=env)
  238. # change gisdbase to dst
  239. env['GISRC'] = gisrc_dst
  240. rupck(input=file_dst, output=rast_clean, overwrite=True, env_=env)
  241. os.remove(file_dst)
  242. def copy_vectors(vectors, gisrc_src, gisrc_dst):
  243. """Copy vectors from one mapset to another, crop the raster to the region.
  244. Parameters
  245. ----------
  246. vectors : list of strings
  247. A list of strings with the raster map that must be copied
  248. from a master to another.
  249. gisrc_src : path to the GISRC source
  250. Path of the GISRC file from where we want to copy the vectors.
  251. gisrc_dst : path to the GISRC destination
  252. Path of the GISRC file where the vectors will be created.
  253. Returns
  254. -------
  255. None.
  256. """
  257. env = os.environ.copy()
  258. path_dst = os.path.join(*read_gisrc(gisrc_dst))
  259. nam = "copy%d__%s" % (id(gisrc_dst), '%s')
  260. # instantiate modules
  261. vpck = Module('v.pack')
  262. vupck = Module('v.unpack')
  263. remove = Module('g.remove')
  264. for vect in vectors:
  265. # change gisdbase to src
  266. env['GISRC'] = gisrc_src
  267. name = nam % vect
  268. file_dst = "%s.pack" % os.path.join(path_dst, name)
  269. vpck(input=name, output=file_dst, overwrite=True, env_=env)
  270. remove(vect=name, env_=env)
  271. # change gisdbase to dst
  272. env['GISRC'] = gisrc_dst
  273. vupck(input=file_dst, output=vect, overwrite=True, env_=env)
  274. os.remove(file_dst)
  275. def get_cmd(cmdd):
  276. """Transform a cmd dictionary to a list of parameters. It is useful to
  277. pickle a Module class and cnvert into a string that can be used with
  278. `Popen(get_cmd(cmdd), shell=True)`.
  279. Parameters
  280. ----------
  281. cmdd : dict
  282. A module dictionary with all the parameters.
  283. Examples
  284. --------
  285. ::
  286. >>> slp = Module('r.slope.aspect',
  287. ... elevation='ele', slope='slp', aspect='asp',
  288. ... overwrite=True, run_=False)
  289. >>> get_cmd(slp.get_dict()) # doctest: +ELLIPSIS
  290. ['r.slope.aspect', 'elevation=ele', 'format=degrees', ..., '--o']
  291. """
  292. cmd = [cmdd['name'], ]
  293. cmd.extend(("%s=%s" % (k, v) for k, v in cmdd['inputs']
  294. if not isinstance(v, list)))
  295. cmd.extend(("%s=%s" % (k, ','.join(vals if isinstance(vals[0], str)
  296. else [repr(v) for v in vals]))
  297. for k, vals in cmdd['inputs']
  298. if isinstance(vals, list)))
  299. cmd.extend(("%s=%s" % (k, v) for k, v in cmdd['outputs']
  300. if not isinstance(v, list)))
  301. cmd.extend(("%s=%s" % (k, ','.join([repr(v) for v in vals]))
  302. for k, vals in cmdd['outputs'] if isinstance(vals, list)))
  303. cmd.extend(("%s" % (flg) for flg in cmdd['flags'] if len(flg) == 1))
  304. cmd.extend(("--%s" % (flg[0]) for flg in cmdd['flags'] if len(flg) > 1))
  305. return cmd
  306. def cmd_exe(args):
  307. """Create a mapset, and execute a cmd inside.
  308. Parameters
  309. ----------
  310. `args` is a tuple that contains:
  311. bbox : dict
  312. A dict with the region parameters (n, s, e, w, etc.)
  313. that we want to set before to apply the command.
  314. mapnames : dict
  315. A dictionary to substitute the input if the domain has
  316. been splitted in several tiles.
  317. gisrc_src : path to the GISRC source
  318. Path of the GISRC file from where we want to copy the groups.
  319. gisrc_dst : path to the GISRC destination
  320. Path of the GISRC file where the groups will be created.
  321. cmd : dictionary
  322. A dictionary with all the parameter of a GRASS module.
  323. groups: list
  324. A list of strings with the groups that we want to copy in the mapset.
  325. Returns
  326. -------
  327. None.
  328. """
  329. bbox, mapnames, gisrc_src, gisrc_dst, cmd, groups = args
  330. src, dst = get_mapset(gisrc_src, gisrc_dst)
  331. env = os.environ.copy()
  332. env['GISRC'] = gisrc_dst
  333. if mapnames:
  334. inputs = dict(cmd['inputs'])
  335. # reset the inputs to
  336. for key in mapnames:
  337. inputs[key] = mapnames[key]
  338. cmd['inputs'] = inputs.items()
  339. # set the region to the tile
  340. sub.Popen(['g,region', 'rast=%s' % key], env=env).wait()
  341. else:
  342. # set the computational region
  343. lcmd = ['g.region', ]
  344. lcmd.extend(["%s=%s" % (k, v) for k, v in bbox.iteritems()])
  345. sub.Popen(lcmd, env=env).wait()
  346. if groups:
  347. copy_groups(groups, gisrc_src, gisrc_dst)
  348. # run the grass command
  349. sub.Popen(get_cmd(cmd), env=env).wait()
  350. # remove temp GISRC
  351. os.remove(gisrc_dst)
  352. class GridModule(object):
  353. """Run GRASS raster commands in a multiproccessing mode.
  354. Parameters
  355. -----------
  356. cmd: raster GRASS command
  357. Only command staring with r.* are valid.
  358. width: integer
  359. Width of the tile, in pixel.
  360. height: integer
  361. Height of the tile, in pixel.
  362. overlap: integer
  363. Overlap between tiles, in pixel.
  364. processes: number of threads
  365. Default value is equal to the number of processor available.
  366. split: boolean
  367. If True use r.tile to split all the inputs.
  368. run_: boolean
  369. If False only instantiate the object.
  370. args and kargs: cmd parameters
  371. Give all the parameters to the command.
  372. Examples
  373. --------
  374. ::
  375. >>> grd = GridModule('r.slope.aspect',
  376. ... width=500, height=500, overlap=2,
  377. ... processes=None, split=False,
  378. ... elevation='elevation',
  379. ... slope='slope', aspect='aspect', overwrite=True)
  380. >>> grd.run()
  381. """
  382. def __init__(self, cmd, width=None, height=None, overlap=0, processes=None,
  383. split=False, debug=False, region=None, move=None, log=False,
  384. start_row=0, start_col=0, out_prefix='',
  385. *args, **kargs):
  386. kargs['run_'] = False
  387. self.mset = Mapset()
  388. self.module = Module(cmd, *args, **kargs)
  389. self.width = width
  390. self.height = height
  391. self.overlap = overlap
  392. self.processes = processes
  393. self.region = region if region else Region()
  394. self.start_row = start_row
  395. self.start_col = start_col
  396. self.out_prefix = out_prefix
  397. self.log = log
  398. self.move = move
  399. self.gisrc_src = os.environ['GISRC']
  400. self.n_mset, self.gisrc_dst = None, None
  401. if self.move:
  402. self.n_mset = copy_mapset(self.mset, self.move)
  403. self.gisrc_dst = write_gisrc(self.n_mset.gisdbase,
  404. self.n_mset.location,
  405. self.n_mset.name)
  406. rasters = [r for r in select(self.module.inputs, 'raster')]
  407. if rasters:
  408. copy_rasters(rasters, self.gisrc_src, self.gisrc_dst,
  409. region=self.region)
  410. vectors = [v for v in select(self.module.inputs, 'vector')]
  411. if vectors:
  412. copy_vectors(vectors, self.gisrc_src, self.gisrc_dst)
  413. groups = [g for g in select(self.module.inputs, 'group')]
  414. if groups:
  415. copy_groups(groups, self.gisrc_src, self.gisrc_dst,
  416. region=self.region)
  417. self.bboxes = split_region_tiles(region=region,
  418. width=width, height=height,
  419. overlap=overlap)
  420. self.msetstr = cmd.replace('.', '') + "_%03d_%03d"
  421. self.inlist = None
  422. if split:
  423. self.split()
  424. self.debug = debug
  425. def __del__(self):
  426. if self.gisrc_dst:
  427. # remove GISRC file
  428. os.remove(self.gisrc_dst)
  429. def clean_location(self, location=None):
  430. """Remove all created mapsets."""
  431. if location is None:
  432. if self.n_mset:
  433. self.n_mset.current()
  434. location = Location()
  435. mapsets = location.mapsets(self.msetstr.split('_')[0] + '_*')
  436. for mset in mapsets:
  437. Mapset(mset).delete()
  438. if self.n_mset and self.n_mset.is_current():
  439. self.mset.current()
  440. def split(self):
  441. """Split all the raster inputs using r.tile"""
  442. rtile = Module('r.tile')
  443. inlist = {}
  444. for inm in select(self.module.inputs, 'raster'):
  445. rtile(input=inm.value, output=inm.value,
  446. width=self.width, height=self.height,
  447. overlap=self.overlap)
  448. patt = '%s-*' % inm.value
  449. inlist[inm.value] = sorted(self.mset.glist(type='rast',
  450. pattern=patt))
  451. self.inlist = inlist
  452. def get_works(self):
  453. """Return a list of tuble with the parameters for cmd_exe function"""
  454. works = []
  455. reg = Region()
  456. if self.move:
  457. mdst, ldst, gdst = read_gisrc(self.gisrc_dst)
  458. else:
  459. ldst, gdst = self.mset.location, self.mset.gisdbase
  460. cmd = self.module.get_dict()
  461. groups = [g for g in select(self.module.inputs, 'group')]
  462. for row, box_row in enumerate(self.bboxes):
  463. for col, box in enumerate(box_row):
  464. inms = None
  465. if self.inlist:
  466. inms = {}
  467. cols = len(box_row)
  468. for key in self.inlist:
  469. indx = row * cols + col
  470. inms[key] = "%s@%s" % (self.inlist[key][indx],
  471. self.mset.name)
  472. # set the computational region, prepare the region parameters
  473. bbox = dict([(k[0], str(v)) for k, v in box.items()[:-2]])
  474. bbox['nsres'] = '%f' % reg.nsres
  475. bbox['ewres'] = '%f' % reg.ewres
  476. new_mset = self.msetstr % (self.start_row + row,
  477. self.start_col + col),
  478. works.append((bbox, inms,
  479. self.gisrc_src,
  480. write_gisrc(gdst, ldst, new_mset),
  481. cmd, groups))
  482. return works
  483. def define_mapset_inputs(self):
  484. """Add the mapset information to the input maps
  485. """
  486. for inmap in self.module.inputs:
  487. inm = self.module.inputs[inmap]
  488. if inm.type in ('raster', 'vector') and inm.value:
  489. if '@' not in inm.value:
  490. mset = get_mapset_raster(inm.value)
  491. inm.value = inm.value + '@%s' % mset
  492. def run(self, patch=True, clean=True):
  493. """Run the GRASS command."""
  494. self.module.flags.overwrite = True
  495. self.define_mapset_inputs()
  496. if self.debug:
  497. for wrk in self.get_works():
  498. cmd_exe(wrk)
  499. else:
  500. pool = mltp.Pool(processes=self.processes)
  501. result = pool.map_async(cmd_exe, self.get_works())
  502. result.wait()
  503. if not result.successful():
  504. raise RuntimeError
  505. if patch:
  506. if self.move:
  507. os.environ['GISRC'] = self.gisrc_dst
  508. self.n_mset.current()
  509. self.patch()
  510. os.environ['GISRC'] = self.gisrc_src
  511. self.mset.current()
  512. # copy the outputs from dst => src
  513. routputs = [self.out_prefix + o
  514. for o in select(self.module.outputs, 'raster')]
  515. copy_rasters(routputs, self.gisrc_dst, self.gisrc_src)
  516. else:
  517. self.patch()
  518. if self.log:
  519. # record in the temp directory
  520. from grass.lib.gis import G_tempfile
  521. tmp, dummy = os.path.split(G_tempfile())
  522. tmpdir = os.path.join(tmp, self.module.name)
  523. for k in self.module.outputs:
  524. par = self.module.outputs[k]
  525. if par.typedesc == 'raster' and par.value:
  526. dirpath = os.path.join(tmpdir, par.name)
  527. if not os.path.isdir(dirpath):
  528. os.makedirs(dirpath)
  529. fil = open(os.path.join(dirpath,
  530. self.out_prefix + par.value), 'w+')
  531. fil.close()
  532. if clean:
  533. self.clean_location()
  534. self.rm_tiles()
  535. if self.n_mset:
  536. gisdbase, location = os.path.split(self.move)
  537. self.clean_location(Location(location, gisdbase))
  538. # rm temporary gis_rc
  539. os.remove(self.gisrc_dst)
  540. self.gisrc_dst = None
  541. sht.rmtree(os.path.join(self.move, 'PERMANENT'))
  542. sht.rmtree(os.path.join(self.move, self.mset.name))
  543. def patch(self):
  544. """Patch the final results."""
  545. bboxes = split_region_tiles(width=self.width, height=self.height)
  546. loc = Location()
  547. mset = loc[self.mset.name]
  548. mset.visible.extend(loc.mapsets())
  549. for otmap in self.module.outputs:
  550. otm = self.module.outputs[otmap]
  551. if otm.typedesc == 'raster' and otm.value:
  552. rpatch_map(otm.value,
  553. self.mset.name, self.msetstr, bboxes,
  554. self.module.flags.overwrite,
  555. self.start_row, self.start_col, self.out_prefix)
  556. def rm_tiles(self):
  557. """Remove all the tiles."""
  558. # if split, remove tiles
  559. if self.inlist:
  560. grm = Module('g.remove')
  561. for key in self.inlist:
  562. grm(rast=self.inlist[key])