dialogs.py 7.4 KB

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