g.gui.rdigit.py 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. #!/usr/bin/env python3
  2. ############################################################################
  3. #
  4. # MODULE: g.gui.rdigit
  5. # AUTHOR(S): Anna Petrasova <kratochanna gmail.com>,
  6. # Tomas Zigo <tomas.zigo slovanet.sk> (standalone module)
  7. # PURPOSE: wxGUI Raster Digitizer
  8. # COPYRIGHT: (C) 2014-2020 by Anna Petrasova, and the GRASS Development Team
  9. #
  10. # This program is free software; you can redistribute it and/or
  11. # modify it under the terms of the GNU General Public License as
  12. # published by the Free Software Foundation; either version 2 of the
  13. # License, or (at your option) any later version.
  14. #
  15. # This program is distributed in the hope that it will be useful, but
  16. # WITHOUT ANY WARRANTY; without even the implied warranty of
  17. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  18. # General Public License for more details.
  19. #
  20. ############################################################################
  21. # %module
  22. # % description: Interactive editing and digitizing of raster maps.
  23. # % keyword: general
  24. # % keyword: GUI
  25. # % keyword: raster
  26. # % keyword: editing
  27. # % keyword: digitizer
  28. # %end
  29. # %option G_OPT_R_OUTPUT
  30. # % key: create
  31. # % label: Name of new raster map to create
  32. # % required: no
  33. # % guisection: Create
  34. # %end
  35. # %option G_OPT_R_BASE
  36. # % required: no
  37. # % guisection: Create
  38. # %end
  39. # %option G_OPT_R_TYPE
  40. # % answer: CELL
  41. # % required: no
  42. # % guisection: Create
  43. # %end
  44. # %option G_OPT_R_INPUT
  45. # % key: edit
  46. # % required: no
  47. # % label: Name of existing raster map to edit
  48. # % guisection: Edit
  49. # %end
  50. # %rules
  51. # % exclusive: create, edit
  52. # % required: create, edit
  53. # % requires: base, create
  54. # %end
  55. import os
  56. import grass.script as gs
  57. def main():
  58. gs.set_raise_on_error(False)
  59. options, flags = gs.parser()
  60. # import wx only after running parser
  61. # to avoid issues with complex imports when only interface is needed
  62. import wx
  63. from grass.script.setup import set_gui_path
  64. set_gui_path()
  65. from core.render import Map
  66. from mapdisp.frame import MapFrame
  67. from mapdisp.main import DMonGrassInterface
  68. from core.settings import UserSettings
  69. # define classes which needs imports as local
  70. # for longer definitions, a separate file would be a better option
  71. class RDigitMapFrame(MapFrame):
  72. def __init__(
  73. self,
  74. new_map=None,
  75. base_map=None,
  76. edit_map=None,
  77. map_type=None,
  78. ):
  79. MapFrame.__init__(
  80. self,
  81. parent=None,
  82. Map=Map(),
  83. giface=DMonGrassInterface(None),
  84. title=_("Raster Digitizer - GRASS GIS"),
  85. size=(850, 600),
  86. )
  87. # this giface issue not solved yet, we must set mapframe afterwards
  88. self._giface._mapframe = self
  89. self._giface.mapCreated.connect(self.OnMapCreated)
  90. self._mapObj = self.GetMap()
  91. # load raster map
  92. self._addLayer(name=new_map if new_map else edit_map)
  93. # switch toolbar
  94. self.AddToolbar("rdigit", fixed=True)
  95. rdigit = self.toolbars["rdigit"]
  96. if new_map:
  97. rdigit._mapSelectionCombo.Unbind(wx.EVT_COMBOBOX)
  98. self.rdigit.SelectNewMap(
  99. standalone=True,
  100. mapName=new_map,
  101. bgMap=base_map,
  102. mapType=map_type,
  103. )
  104. rdigit._mapSelectionCombo.Bind(
  105. wx.EVT_COMBOBOX,
  106. rdigit.OnMapSelection,
  107. )
  108. else:
  109. rdigit._mapSelectionCombo.SetSelection(n=1)
  110. rdigit.OnMapSelection()
  111. # use Close instead of QuitRDigit for standalone tool
  112. self.rdigit.quitDigitizer.disconnect(self.QuitRDigit)
  113. self.rdigit.quitDigitizer.connect(lambda: self.Close())
  114. def _addLayer(self, name, ltype="raster"):
  115. """Add layer into map
  116. :param str name: map name
  117. :param str ltype: layer type
  118. """
  119. mapLayer = self._mapObj.AddLayer(
  120. ltype=ltype,
  121. name=name,
  122. command=["d.rast", "map={}".format(name)],
  123. active=True,
  124. hidden=False,
  125. opacity=1.0,
  126. render=True,
  127. )
  128. def OnMapCreated(self, name, ltype):
  129. """Add new created raster layer into map
  130. :param str name: map name
  131. :param str ltype: layer type
  132. """
  133. self._mapObj.Clean()
  134. self._addLayer(name=name, ltype=ltype)
  135. self.GetMapWindow().UpdateMap()
  136. kwargs = {
  137. "new_map": options["create"],
  138. "base_map": options["base"],
  139. "edit_map": options["edit"],
  140. "map_type": options["type"],
  141. }
  142. mapset = gs.gisenv()["MAPSET"]
  143. if kwargs["edit_map"]:
  144. edit_map = gs.find_file(
  145. name=kwargs["edit_map"],
  146. element="raster",
  147. mapset=mapset,
  148. )["fullname"]
  149. if not edit_map:
  150. gs.fatal(
  151. _(
  152. "Raster map <{}> not found in current mapset.".format(
  153. options["edit"],
  154. ),
  155. ),
  156. )
  157. else:
  158. kwargs["edit_map"] = edit_map
  159. else:
  160. if kwargs["base_map"]:
  161. base_map = gs.find_file(
  162. name=kwargs["base_map"],
  163. element="raster",
  164. mapset=mapset,
  165. )["fullname"]
  166. if not base_map:
  167. gs.fatal(
  168. _(
  169. "Base raster map <{}> not found in "
  170. "current mapset.".format(
  171. options["base"],
  172. ),
  173. ),
  174. )
  175. kwargs["base_map"] = base_map
  176. # allow immediate rendering
  177. driver = UserSettings.Get(
  178. group="display",
  179. key="driver",
  180. subkey="type",
  181. )
  182. if driver == "png":
  183. os.environ["GRASS_RENDER_IMMEDIATE"] = "png"
  184. else:
  185. os.environ["GRASS_RENDER_IMMEDIATE"] = "cairo"
  186. app = wx.App()
  187. frame = RDigitMapFrame(**kwargs)
  188. frame.Show()
  189. app.MainLoop()
  190. if __name__ == "__main__":
  191. main()