dialogs.py 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. # -*- coding: utf-8 -*-
  2. """
  3. @package datacatalog.dialogs
  4. @brief Dialogs used in data catalog
  5. Classes:
  6. - dialogs::CatalogReprojectionDialog
  7. (C) 2017 by the GRASS Development Team
  8. This program is free software under the GNU General Public License
  9. (>=v2). Read the file COPYING that comes with GRASS for details.
  10. @author Anna Petrasova <kratochanna gmail.com>
  11. """
  12. import wx
  13. from gui_core.widgets import FloatValidator, IntegerValidator
  14. from core.giface import Notification
  15. from core.gcmd import RunCommand
  16. from gui_core.wrap import Button, StaticText, TextCtrl
  17. from grass.script import parse_key_val, region_env
  18. class CatalogReprojectionDialog(wx.Dialog):
  19. def __init__(self, parent, giface, inputGisdbase, inputLocation,
  20. inputMapset, inputLayer, inputEnv,
  21. outputGisdbase, outputLocation, outputMapset, outputLayer,
  22. etype, outputEnv, callback,
  23. id=wx.ID_ANY, title=_("Reprojection"),
  24. style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER):
  25. self.parent = parent
  26. self._giface = giface
  27. wx.Dialog.__init__(self, parent, id, title, style=style,
  28. name="ReprojectionDialog")
  29. self.panel = wx.Panel(parent=self)
  30. self.iGisdbase = inputGisdbase
  31. self.iLocation = inputLocation
  32. self.iMapset = inputMapset
  33. self.iLayer = inputLayer
  34. self.iEnv = inputEnv
  35. self.oGisdbase = outputGisdbase
  36. self.oLocation = outputLocation
  37. self.oMapset = outputMapset
  38. self.oLayer = outputLayer
  39. self.etype = etype
  40. self.oEnv = outputEnv
  41. self.callback = callback
  42. self._widgets()
  43. self._doLayout()
  44. if self.etype == 'raster':
  45. self._estimateResampling()
  46. self._estimateResolution()
  47. def _widgets(self):
  48. if self.etype == 'raster':
  49. self.resolution = TextCtrl(self.panel, validator=FloatValidator())
  50. self.resampling = wx.Choice(self.panel, size=(200, -1),
  51. choices=['nearest', 'bilinear', 'bicubic', 'lanczos',
  52. 'bilinear_f', 'bicubic_f', 'lanczos_f'])
  53. else:
  54. self.vsplit = TextCtrl(self.panel, validator=IntegerValidator())
  55. self.vsplit.SetValue('10000')
  56. #
  57. # buttons
  58. #
  59. self.btn_close = Button(parent=self.panel, id=wx.ID_CLOSE)
  60. self.SetEscapeId(self.btn_close.GetId())
  61. # run
  62. self.btn_run = Button(parent=self.panel, id=wx.ID_OK, label=_("Reproject"))
  63. if self.etype == 'raster':
  64. self.btn_run.SetToolTip(_("Reproject raster"))
  65. elif self.etype == 'vector':
  66. self.btn_run.SetToolTip(_("Reproject vector"))
  67. self.btn_run.SetDefault()
  68. self.btn_run.Bind(wx.EVT_BUTTON, self.OnReproject)
  69. def _doLayout(self):
  70. """Do layout"""
  71. dialogSizer = wx.BoxSizer(wx.VERTICAL)
  72. optionsSizer = wx.GridBagSizer(5, 5)
  73. label = _("Map layer <{ml}> needs to be reprojected.\n"
  74. "Please review and modify reprojection parameters:").format(ml=self.iLayer)
  75. dialogSizer.Add(StaticText(self.panel, label=label),
  76. flag=wx.ALL | wx.EXPAND, border=10)
  77. if self.etype == 'raster':
  78. optionsSizer.Add(StaticText(self.panel, label=_("Estimated resolution:")),
  79. pos=(0, 0), flag=wx.EXPAND | wx.ALIGN_CENTER_VERTICAL)
  80. optionsSizer.Add(self.resolution, pos=(0, 1), flag=wx.EXPAND)
  81. optionsSizer.Add(StaticText(self.panel, label=_("Resampling method:")),
  82. pos=(1, 0), flag=wx.EXPAND | wx.ALIGN_CENTER_VERTICAL)
  83. optionsSizer.Add(self.resampling, pos=(1, 1), flag=wx.EXPAND)
  84. else:
  85. optionsSizer.Add(StaticText(self.panel, label=_("Maximum segment length:")),
  86. pos=(1, 0), flag=wx.EXPAND | wx.ALIGN_CENTER_VERTICAL)
  87. optionsSizer.Add(self.vsplit, pos=(1, 1), flag=wx.EXPAND)
  88. optionsSizer.AddGrowableCol(1)
  89. dialogSizer.Add(optionsSizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=10)
  90. helptext = StaticText(self.panel,
  91. label="For more reprojection options,"
  92. " please see {module}".format(module='r.proj' if self.etype == 'raster'
  93. else 'v.proj'))
  94. dialogSizer.Add(helptext, proportion=0, flag=wx.ALL | wx.EXPAND, border=10)
  95. #
  96. # buttons
  97. #
  98. btnStdSizer = wx.StdDialogButtonSizer()
  99. btnStdSizer.AddButton(self.btn_run)
  100. btnStdSizer.AddButton(self.btn_close)
  101. btnStdSizer.Realize()
  102. dialogSizer.Add(btnStdSizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
  103. self.panel.SetSizer(dialogSizer)
  104. dialogSizer.Fit(self.panel)
  105. self.Layout()
  106. self.SetSize(self.GetBestSize())
  107. def _estimateResolution(self):
  108. output = RunCommand('r.proj', flags='g', quiet=False, read=True, input=self.iLayer,
  109. dbase=self.iGisdbase, location=self.iLocation, mapset=self.iMapset,
  110. env=self.oEnv).strip()
  111. params = parse_key_val(output, vsep=' ')
  112. output = RunCommand('g.region', flags='ug', quiet=False, read=True, env=self.oEnv,
  113. parse=lambda x: parse_key_val(x, val_type=float), **params)
  114. cell_ns = (output['n'] - output['s']) / output['rows']
  115. cell_ew = (output['e'] - output['w']) / output['cols']
  116. estimate = (cell_ew + cell_ns) / 2.
  117. self.resolution.SetValue(str(estimate))
  118. self.params = params
  119. def _estimateResampling(self):
  120. output = RunCommand('r.info', flags='g', quiet=False, read=True, map=self.iLayer,
  121. env=self.iEnv, parse=parse_key_val)
  122. if output['datatype'] == 'CELL':
  123. self.resampling.SetStringSelection('nearest')
  124. else:
  125. self.resampling.SetStringSelection('bilinear')
  126. def OnReproject(self, event):
  127. cmd = []
  128. if self.etype == 'raster':
  129. cmd.append('r.proj')
  130. cmd.append('dbase=' + self.iGisdbase)
  131. cmd.append('location=' + self.iLocation)
  132. cmd.append('mapset=' + self.iMapset)
  133. cmd.append('input=' + self.iLayer)
  134. cmd.append('output=' + self.oLayer)
  135. cmd.append('method=' + self.resampling.GetStringSelection())
  136. self.oEnv['GRASS_REGION'] = region_env(n=self.params['n'], s=self.params['s'],
  137. e=self.params['e'], w=self.params['w'],
  138. flags='a', res=float(self.resolution.GetValue()),
  139. env=self.oEnv)
  140. else:
  141. cmd.append('v.proj')
  142. cmd.append('dbase=' + self.iGisdbase)
  143. cmd.append('location=' + self.iLocation)
  144. cmd.append('mapset=' + self.iMapset)
  145. cmd.append('input=' + self.iLayer)
  146. cmd.append('output=' + self.oLayer)
  147. cmd.append('smax=' + self.vsplit.GetValue())
  148. self._giface.RunCmd(cmd, env=self.oEnv, compReg=False, addLayer=False,
  149. onDone=self._onDone, userData=None,
  150. notification=Notification.MAKE_VISIBLE)
  151. event.Skip()
  152. def _onDone(self, event):
  153. self.callback()