controller.py 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669
  1. """
  2. @package rdigit.controller
  3. @brief rdigit controller for drawing and rasterizing
  4. Classes:
  5. - controller::RDigitController
  6. (C) 2014 by the GRASS Development Team
  7. This program is free software under the GNU General Public
  8. License (>=v2). Read the file COPYING that comes with GRASS
  9. for details.
  10. @author Anna Petrasova <kratochanna gmail.com>
  11. """
  12. import os
  13. import tempfile
  14. import wx
  15. import uuid
  16. from wx.lib.newevent import NewEvent
  17. from grass.script import core as gcore
  18. from grass.script import raster as grast
  19. from grass.exceptions import CalledModuleError, ScriptError
  20. from grass.pydispatch.signal import Signal
  21. from core.gcmd import GError, GMessage
  22. from core.settings import UserSettings
  23. from core.gthread import gThread
  24. from rdigit.dialogs import NewRasterDialog
  25. updateProgress, EVT_UPDATE_PROGRESS = NewEvent()
  26. class RDigitController(wx.EvtHandler):
  27. """Controller object for raster digitizer.
  28. Inherits from EvtHandler to be able to send wx events from thraed.
  29. """
  30. def __init__(self, giface, mapWindow):
  31. """Constructs controller
  32. :param giface: grass interface object
  33. :param mapWindow: instance of BufferedMapWindow
  34. """
  35. wx.EvtHandler.__init__(self)
  36. self._giface = giface
  37. self._mapWindow = mapWindow
  38. # thread for running rasterization process
  39. self._thread = gThread()
  40. # name of raster map which is edited (also new one)
  41. self._editedRaster = None
  42. # name of optional background raster
  43. self._backgroundRaster = None
  44. # name of temporary raster used to backup original state
  45. self._backupRasterName = None
  46. # if we edit an old raster or a new one (important for setting color
  47. # table)
  48. self._editOldRaster = False
  49. # type of output raster map (CELL, FCELL, DCELL)
  50. self._mapType = None
  51. # GraphicsSet for drawing areas, lines, points
  52. self._areas = None
  53. self._lines = None
  54. self._points = None
  55. # list of all GraphicsItems in the order of drawing
  56. self._all = []
  57. # if in state of drawing lin or area
  58. self._drawing = False
  59. # if running digitizing process in thread (to block drawing)
  60. self._running = False
  61. # color used to draw (should be moved to settings)
  62. self._drawColor = wx.GREEN
  63. # transparency used to draw (should be moved to settings)
  64. self._drawTransparency = 100
  65. # current selected drawing method
  66. self._graphicsType = 'area'
  67. # last edited cell value
  68. self._currentCellValue = None
  69. # last edited buffer value
  70. self._currentWidthValue = None
  71. # digit env
  72. self._env = os.environ.copy()
  73. self._oldMouseUse = None
  74. self._oldCursor = None
  75. # signal to add new raster to toolbar items
  76. self.newRasterCreated = Signal('RDigitController:newRasterCreated')
  77. # signal to add just used cell value in toolbar combo
  78. self.newFeatureCreated = Signal('RDigitController:newFeatureCreated')
  79. # signal to upload unique categories of background map into toolbar
  80. # combo
  81. self.uploadMapCategories = Signal(
  82. 'RDigitController:uploadMapCategories')
  83. self.quitDigitizer = Signal('RDigitController:quitDigitizer')
  84. self.showNotification = Signal('RDigitController:showNotification')
  85. def _connectAll(self):
  86. self._mapWindow.mouseLeftDown.connect(self._start)
  87. self._mapWindow.mouseLeftUp.connect(self._addPoint)
  88. self._mapWindow.mouseRightUp.connect(self._finish)
  89. self._mapWindow.Unbind(wx.EVT_CONTEXT_MENU)
  90. def _disconnectAll(self):
  91. self._mapWindow.mouseLeftDown.disconnect(self._start)
  92. self._mapWindow.mouseLeftUp.disconnect(self._addPoint)
  93. self._mapWindow.mouseRightUp.disconnect(self._finish)
  94. self._mapWindow.Bind(
  95. wx.EVT_CONTEXT_MENU,
  96. self._mapWindow.OnContextMenu)
  97. def _start(self, x, y):
  98. """Start digitizing a new object.
  99. :param x: x coordinate in map units
  100. :param y: y coordinate in map units
  101. """
  102. if self._running:
  103. return
  104. if not self._editedRaster:
  105. GMessage(parent=self._mapWindow, message=_(
  106. "Please select first the raster map"))
  107. return
  108. if not self._drawing:
  109. if self._graphicsType == 'area':
  110. item = self._areas.AddItem(coords=[])
  111. item.SetPropertyVal('penName', 'pen1')
  112. self._all.append(item)
  113. elif self._graphicsType == 'line':
  114. item = self._lines.AddItem(coords=[])
  115. item.SetPropertyVal('penName', 'pen1')
  116. self._all.append(item)
  117. elif self._graphicsType == 'point':
  118. item = self._points.AddItem(coords=[])
  119. item.SetPropertyVal('penName', 'pen1')
  120. self._all.append(item)
  121. self._drawing = True
  122. def _addPoint(self, x, y):
  123. """Add point to an object.
  124. :param x: x coordinate in map units
  125. :param y: y coordinate in map units
  126. """
  127. if self._running:
  128. return
  129. if not self._drawing:
  130. return
  131. if self._graphicsType == 'area':
  132. area = self._areas.GetItem(-1)
  133. coords = area.GetCoords() + [[x, y]]
  134. area.SetCoords(coords)
  135. self.showNotification.emit(text=_("Right click to finish area"))
  136. elif self._graphicsType == 'line':
  137. line = self._lines.GetItem(-1)
  138. coords = line.GetCoords() + [[x, y]]
  139. line.SetCoords(coords)
  140. self.showNotification.emit(text=_("Right click to finish line"))
  141. elif self._graphicsType == 'point':
  142. point = self._points.GetItem(-1)
  143. point.SetCoords([x, y])
  144. self._finish()
  145. # draw
  146. self._mapWindow.ClearLines()
  147. self._lines.Draw()
  148. self._areas.Draw()
  149. self._points.Draw()
  150. self._mapWindow.Refresh()
  151. def _finish(self):
  152. """Finish digitizing a new object and redraws.
  153. Saves current cell value and buffer width for that object.
  154. :param x: x coordinate in map units
  155. :param y: y coordinate in map units
  156. """
  157. if self._running:
  158. return
  159. if self._graphicsType == 'point':
  160. item = self._points.GetItem(-1)
  161. elif self._graphicsType == 'area':
  162. item = self._areas.GetItem(-1)
  163. elif self._graphicsType == 'line':
  164. item = self._lines.GetItem(-1)
  165. else:
  166. return
  167. self._drawing = False
  168. item.SetPropertyVal('brushName', 'done')
  169. item.AddProperty('cellValue')
  170. item.AddProperty('widthValue')
  171. item.SetPropertyVal('cellValue', self._currentCellValue)
  172. item.SetPropertyVal('widthValue', self._currentWidthValue)
  173. self.newFeatureCreated.emit()
  174. self._mapWindow.ClearLines()
  175. self._points.Draw()
  176. self._areas.Draw()
  177. self._lines.Draw()
  178. self._mapWindow.Refresh()
  179. def SelectType(self, drawingType):
  180. """Selects method (area/line/point) for drawing.
  181. Connects and disconnects signal to allow other tools
  182. in map toolbar to work.
  183. """
  184. if self._graphicsType and drawingType and self._graphicsType != drawingType \
  185. and self._drawing:
  186. # if we select different drawing tool, finish the feature
  187. self._finish()
  188. if self._graphicsType and not drawingType:
  189. self._mapWindow.ClearLines(pdc=self._mapWindow.pdcTmp)
  190. self._mapWindow.mouse['end'] = self._mapWindow.mouse['begin']
  191. # disconnect mouse events
  192. self._disconnectAll()
  193. self._mapWindow.SetNamedCursor(self._oldCursor)
  194. self._mapWindow.mouse['use'] = self._oldMouseUse
  195. elif self._graphicsType is None and drawingType:
  196. self._connectAll()
  197. # change mouse['box'] and pen to draw line during dragging
  198. # TODO: better solution for drawing this line
  199. self._mapWindow.mouse['use'] = None
  200. self._mapWindow.mouse['box'] = "line"
  201. self._mapWindow.pen = wx.Pen(
  202. colour='red', width=2, style=wx.SHORT_DASH)
  203. # change the cursor
  204. self._mapWindow.SetNamedCursor('pencil')
  205. self._graphicsType = drawingType
  206. def SetCellValue(self, value):
  207. self._currentCellValue = value
  208. def SetWidthValue(self, value):
  209. self._currentWidthValue = value
  210. def ChangeDrawColor(self, color):
  211. self._drawColor = color[:3] + (self._drawTransparency,)
  212. for each in (self._areas, self._lines, self._points):
  213. each.GetPen('pen1').SetColour(self._drawColor)
  214. each.GetBrush('done').SetColour(self._drawColor)
  215. self._mapWindow.UpdateMap(render=False)
  216. def Start(self):
  217. """Registers graphics to map window,
  218. connect required mouse signals.
  219. """
  220. self._oldMouseUse = self._mapWindow.mouse['use']
  221. self._oldCursor = self._mapWindow.GetNamedCursor()
  222. self._connectAll()
  223. # change mouse['box'] and pen to draw line during dragging
  224. # TODO: better solution for drawing this line
  225. self._mapWindow.mouse['use'] = None
  226. self._mapWindow.mouse['box'] = "line"
  227. self._mapWindow.pen = wx.Pen(
  228. colour='red', width=2, style=wx.SHORT_DASH)
  229. color = self._drawColor[:3] + (self._drawTransparency,)
  230. self._areas = self._mapWindow.RegisterGraphicsToDraw(
  231. graphicsType='polygon', pdc=self._mapWindow.pdcTransparent, mapCoords=True)
  232. self._areas.AddPen(
  233. 'pen1',
  234. wx.Pen(
  235. colour=color,
  236. width=2,
  237. style=wx.SOLID))
  238. self._areas.AddBrush('done', wx.Brush(colour=color, style=wx.SOLID))
  239. self._lines = self._mapWindow.RegisterGraphicsToDraw(
  240. graphicsType='line', pdc=self._mapWindow.pdcTransparent, mapCoords=True)
  241. self._lines.AddPen(
  242. 'pen1',
  243. wx.Pen(
  244. colour=color,
  245. width=2,
  246. style=wx.SOLID))
  247. self._lines.AddBrush('done', wx.Brush(colour=color, style=wx.SOLID))
  248. self._points = self._mapWindow.RegisterGraphicsToDraw(
  249. graphicsType='point', pdc=self._mapWindow.pdcTransparent, mapCoords=True)
  250. self._points.AddPen(
  251. 'pen1',
  252. wx.Pen(
  253. colour=color,
  254. width=2,
  255. style=wx.SOLID))
  256. self._points.AddBrush('done', wx.Brush(colour=color, style=wx.SOLID))
  257. # change the cursor
  258. self._mapWindow.SetNamedCursor('pencil')
  259. def Stop(self):
  260. """Before stopping digitizer, asks to save edits"""
  261. if self._editedRaster:
  262. dlg = wx.MessageDialog(
  263. self._mapWindow,
  264. _("Do you want to save changes?"),
  265. _("Save raster map changes"),
  266. wx.YES_NO)
  267. if dlg.ShowModal() == wx.ID_YES:
  268. if self._drawing:
  269. self._finish()
  270. self._thread.Run(callable=self._exportRaster,
  271. ondone=lambda event: self._updateAndQuit())
  272. else:
  273. self.quitDigitizer.emit()
  274. else:
  275. self.quitDigitizer.emit()
  276. def Save(self):
  277. """Saves current edits to a raster map"""
  278. if self._drawing:
  279. self._finish()
  280. self._thread.Run(callable=self._exportRaster,
  281. ondone=lambda event: self._update())
  282. def Undo(self):
  283. """Undo a change, goes object back (finished or not finished)"""
  284. if len(self._all):
  285. removed = self._all.pop(-1)
  286. # try to remove from each, it fails quietly when theitem is not
  287. # there
  288. self._areas.DeleteItem(removed)
  289. self._lines.DeleteItem(removed)
  290. self._points.DeleteItem(removed)
  291. self._drawing = False
  292. self._mapWindow.UpdateMap(render=False)
  293. def CleanUp(self, restore=True):
  294. """Cleans up drawing, temporary maps.
  295. :param restore: if restore previous cursor, mouse['use']
  296. """
  297. try:
  298. if self._backupRasterName:
  299. gcore.run_command(
  300. 'g.remove',
  301. type='raster',
  302. flags='f',
  303. name=self._backupRasterName,
  304. quiet=True)
  305. except CalledModuleError:
  306. pass
  307. self._mapWindow.ClearLines(pdc=self._mapWindow.pdcTmp)
  308. self._mapWindow.mouse['end'] = self._mapWindow.mouse['begin']
  309. # disconnect mouse events
  310. if self._graphicsType:
  311. self._disconnectAll()
  312. # unregister
  313. self._mapWindow.UnregisterGraphicsToDraw(self._areas)
  314. self._mapWindow.UnregisterGraphicsToDraw(self._lines)
  315. self._mapWindow.UnregisterGraphicsToDraw(self._points)
  316. #self._registeredGraphics = None
  317. self._mapWindow.UpdateMap(render=False)
  318. if restore:
  319. # restore mouse['use'] and cursor to the state before measuring
  320. # starts
  321. self._mapWindow.SetNamedCursor(self._oldCursor)
  322. self._mapWindow.mouse['use'] = self._oldMouseUse
  323. def _updateAndQuit(self):
  324. """Called when thread is done. Updates map and calls to quits digitizer."""
  325. self._running = False
  326. self._mapWindow.UpdateMap(render=True)
  327. self.quitDigitizer.emit()
  328. def _update(self):
  329. """Called when thread is done. Updates map."""
  330. self._running = False
  331. self._mapWindow.UpdateMap(render=True)
  332. def SelectOldMap(self, name):
  333. """After selecting old raster, creates a backup copy for editing."""
  334. try:
  335. self._backupRaster(name)
  336. except ScriptError:
  337. GError(parent=self._mapWindow, message=_(
  338. "Failed to create backup copy of edited raster map."))
  339. return False
  340. self._editedRaster = name
  341. self._mapType = grast.raster_info(map=name)['datatype']
  342. self._editOldRaster = True
  343. return True
  344. def SelectNewMap(
  345. self, standalone=False, mapName=None, bgMap=None,
  346. mapType=None,
  347. ):
  348. """After selecting new raster, shows dialog to choose name,
  349. background map and type of the new map.
  350. :params standalone, mapName, bgMap, mapType: if digitizer is
  351. launched as standalone module
  352. :param bool standalone: if digitizer is launched as standalone
  353. module
  354. :param str mapName: edited raster map name
  355. :param str bgMap: background raster map name
  356. :param str mapType: raster map type CELL, FCELL, DCELL
  357. """
  358. if standalone:
  359. try:
  360. self._createNewMap(
  361. mapName=mapName, backgroundMap=bgMap,
  362. mapType=mapType,
  363. )
  364. except ScriptError:
  365. GError(
  366. parent=self._mapWindow, message=_(
  367. "Failed to create new raster map."
  368. ),
  369. )
  370. return False
  371. return True
  372. else:
  373. dlg = NewRasterDialog(parent=self._mapWindow)
  374. dlg.CenterOnParent()
  375. if dlg.ShowModal() == wx.ID_OK:
  376. try:
  377. self._createNewMap(
  378. mapName=dlg.GetMapName(),
  379. backgroundMap=dlg.GetBackgroundMapName(),
  380. mapType=dlg.GetMapType(),
  381. )
  382. except ScriptError:
  383. GError(
  384. parent=self._mapWindow, message=_(
  385. "Failed to create new raster map."
  386. ),
  387. )
  388. return False
  389. finally:
  390. dlg.Destroy()
  391. return True
  392. else:
  393. dlg.Destroy()
  394. return False
  395. def _createNewMap(self, mapName, backgroundMap, mapType):
  396. """Creates a new raster map based on specified background and type."""
  397. name = mapName.split('@')[0]
  398. background = backgroundMap.split('@')[0]
  399. types = {'CELL': 'int', 'FCELL': 'float', 'DCELL': 'double'}
  400. if background:
  401. back = background
  402. else:
  403. back = 'null()'
  404. try:
  405. grast.mapcalc(
  406. exp="{name} = {mtype}({back})".format(
  407. name=name,
  408. mtype=types[mapType],
  409. back=back),
  410. overwrite=True,
  411. quiet=True)
  412. if background:
  413. self._backgroundRaster = backgroundMap
  414. gcore.run_command(
  415. 'r.colors',
  416. map=name,
  417. raster=self._backgroundRaster,
  418. quiet=True)
  419. if mapType == 'CELL':
  420. values = gcore.read_command('r.describe', flags='1n',
  421. map=name, quiet=True).strip()
  422. if values:
  423. self.uploadMapCategories.emit(
  424. values=values.split('\n'))
  425. except CalledModuleError:
  426. raise ScriptError
  427. self._backupRaster(name)
  428. name = name + '@' + gcore.gisenv()['MAPSET']
  429. self._editedRaster = name
  430. self._mapType = mapType
  431. self.newRasterCreated.emit(name=name)
  432. gisenv = gcore.gisenv()
  433. self._giface.grassdbChanged.emit(grassdb=gisenv['GISDBASE'],
  434. location=gisenv['LOCATION_NAME'],
  435. mapset=gisenv['MAPSET'],
  436. action='new',
  437. map=name.split('@')[0],
  438. element='raster')
  439. def _backupRaster(self, name):
  440. """Creates a temporary backup raster necessary for undo behavior.
  441. :param str name: name of raster map for which we create backup
  442. """
  443. name = name.split('@')[0]
  444. backup = name + '_backupcopy_' + str(os.getpid())
  445. try:
  446. gcore.run_command('g.copy', raster=[name, backup], quiet=True)
  447. except CalledModuleError:
  448. raise ScriptError
  449. self._backupRasterName = backup
  450. def _exportRaster(self):
  451. """Rasterizes digitized features.
  452. Uses r.in.poly and r.grow for buffering features. Creates separate raster
  453. maps depending on common cell values and buffering width necessary to
  454. keep the order of editing. These rasters are then patched together.
  455. Sets default color table for the newly digitized raster.
  456. """
  457. self._setRegion()
  458. if not self._editedRaster or self._running:
  459. return
  460. self._running = True
  461. if len(self._all) < 1:
  462. new = self._editedRaster
  463. if '@' in self._editedRaster:
  464. new = self._editedRaster.split('@')[0]
  465. gcore.run_command('g.copy', raster=[self._backupRasterName, new],
  466. overwrite=True, quiet=True)
  467. else:
  468. tempRaster = 'tmp_rdigit_rast_' + str(os.getpid())
  469. text = []
  470. rastersToPatch = []
  471. i = 0
  472. lastCellValue = lastWidthValue = None
  473. evt = updateProgress(
  474. range=len(self._all),
  475. value=0, text=_("Rasterizing..."))
  476. wx.PostEvent(self, evt)
  477. lastCellValue = self._all[0].GetPropertyVal('cellValue')
  478. lastWidthValue = self._all[0].GetPropertyVal('widthValue')
  479. for item in self._all:
  480. if item.GetPropertyVal('widthValue') and \
  481. (lastCellValue != item.GetPropertyVal('cellValue') or
  482. lastWidthValue != item.GetPropertyVal('widthValue')):
  483. if text:
  484. out = self._rasterize(
  485. text, lastWidthValue, self._mapType, tempRaster)
  486. rastersToPatch.append(out)
  487. text = []
  488. self._writeItem(item, text)
  489. out = self._rasterize(
  490. text, item.GetPropertyVal('widthValue'),
  491. self._mapType, tempRaster)
  492. rastersToPatch.append(out)
  493. text = []
  494. else:
  495. self._writeItem(item, text)
  496. lastCellValue = item.GetPropertyVal('cellValue')
  497. lastWidthValue = item.GetPropertyVal('widthValue')
  498. i += 1
  499. evt = updateProgress(
  500. range=len(self._all),
  501. value=i, text=_("Rasterizing..."))
  502. wx.PostEvent(self, evt)
  503. if text:
  504. out = self._rasterize(text, item.GetPropertyVal('widthValue'),
  505. self._mapType, tempRaster)
  506. rastersToPatch.append(out)
  507. gcore.run_command(
  508. 'r.patch', input=rastersToPatch[:: -1] +
  509. [self._backupRasterName],
  510. output=self._editedRaster, overwrite=True, quiet=True,
  511. env=self._env)
  512. gcore.run_command(
  513. 'g.remove',
  514. type='raster',
  515. flags='f',
  516. name=rastersToPatch +
  517. [tempRaster],
  518. quiet=True)
  519. try:
  520. # setting the right color table
  521. if self._editOldRaster:
  522. return
  523. if not self._backgroundRaster:
  524. table = UserSettings.Get(
  525. group='rasterLayer',
  526. key='colorTable',
  527. subkey='selection')
  528. if not table:
  529. table = 'rainbow'
  530. gcore.run_command(
  531. 'r.colors',
  532. color=table,
  533. map=self._editedRaster,
  534. quiet=True)
  535. else:
  536. gcore.run_command('r.colors', map=self._editedRaster,
  537. raster=self._backgroundRaster, quiet=True)
  538. except CalledModuleError:
  539. self._running = False
  540. GError(parent=self._mapWindow, message=_(
  541. "Failed to set default color table for edited raster map"))
  542. def _writeFeature(self, item, vtype, text):
  543. """Writes digitized features in r.in.poly format."""
  544. coords = item.GetCoords()
  545. if vtype == 'P':
  546. coords = [coords]
  547. cellValue = item.GetPropertyVal('cellValue')
  548. record = '{vtype}\n'.format(vtype=vtype)
  549. for coord in coords:
  550. record += ' '.join([str(c) for c in coord])
  551. record += '\n'
  552. record += '= {cellValue}\n'.format(cellValue=cellValue)
  553. text.append(record)
  554. def _writeItem(self, item, text):
  555. if item in self._areas.GetAllItems():
  556. self._writeFeature(item, vtype='A', text=text)
  557. elif item in self._lines.GetAllItems():
  558. self._writeFeature(item, vtype='L', text=text)
  559. elif item in self._points.GetAllItems():
  560. self._writeFeature(item, vtype='P', text=text)
  561. def _rasterize(self, text, bufferDist, mapType, tempRaster):
  562. """Performs the actual rasterization using r.in.poly
  563. and buffering with r.grow if required.
  564. :param str text: string in r.in.poly format
  565. :param float bufferDist: buffer distance in map units
  566. :param str mapType: CELL, FCELL, DCELL
  567. :param str tempRaster: name of temporary raster used in computation
  568. :return: output raster map name as a result of digitization
  569. """
  570. output = 'x' + str(uuid.uuid4())[:8]
  571. asciiFile = tempfile.NamedTemporaryFile(mode='w', delete=False)
  572. asciiFile.write('\n'.join(text))
  573. asciiFile.close()
  574. if bufferDist:
  575. bufferDist /= 2.
  576. gcore.run_command(
  577. 'r.in.poly',
  578. input=asciiFile.name,
  579. output=tempRaster,
  580. type_=mapType,
  581. overwrite=True,
  582. quiet=True)
  583. gcore.run_command('r.grow', input=tempRaster, output=output,
  584. flags='m', radius=bufferDist, quiet=True,
  585. env=self._env)
  586. else:
  587. gcore.run_command('r.in.poly', input=asciiFile.name, output=output,
  588. type_=mapType, quiet=True, env=self._env)
  589. os.unlink(asciiFile.name)
  590. return output
  591. def _setRegion(self):
  592. """Set region according input raster map"""
  593. self._env['GRASS_REGION'] = gcore.region_env(
  594. raster=self._backupRasterName)