gcpmapdisp.py 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700
  1. """!
  2. @package gcpmapdisp.py
  3. @brief display to manage ground control points with two toolbars, one for
  4. various display management functions, one for manipulating GCPs.
  5. Classes:
  6. - MapFrame
  7. (C) 2006-2010 by the GRASS Development Team
  8. This program is free software under the GNU General Public
  9. License (>=v2). Read the file COPYING that comes with GRASS
  10. for details.
  11. Derived from mapdisp.py
  12. @author Markus Metz
  13. """
  14. import os
  15. import sys
  16. import glob
  17. import math
  18. import tempfile
  19. import copy
  20. import platform
  21. import globalvar
  22. import wx
  23. import wx.aui
  24. try:
  25. import subprocess
  26. except:
  27. CompatPath = os.path.join(globalvar.ETCWXDIR)
  28. sys.path.append(CompatPath)
  29. from compat import subprocess
  30. gmpath = os.path.join(globalvar.ETCWXDIR, "icons")
  31. sys.path.append(gmpath)
  32. grassPath = os.path.join(globalvar.ETCDIR, "python")
  33. sys.path.append(grassPath)
  34. import render
  35. import toolbars
  36. import menuform
  37. import gselect
  38. import disp_print
  39. import gcmd
  40. import dbm
  41. import dbm_dialogs
  42. import globalvar
  43. import utils
  44. import gdialogs
  45. import mapdisp_statusbar as sb
  46. from mapdisp import MapFrameBase
  47. from grass.script import core as grass
  48. from debug import Debug
  49. from icon import Icons
  50. from preferences import globalSettings as UserSettings
  51. from mapdisp_window import BufferedWindow
  52. # for standalone app
  53. cmdfilename = None
  54. class MapFrame(MapFrameBase):
  55. """!Main frame for map display window. Drawing takes place in
  56. child double buffered drawing window.
  57. """
  58. def __init__(self, parent=None, title=_("GRASS GIS Manage Ground Control Points"),
  59. toolbars=["gcpdisp"], tree=None, notebook=None, lmgr=None,
  60. page=None, Map=None, auimgr=None, name = 'GCPMapWindow', **kwargs):
  61. """!Main map display window with toolbars, statusbar and
  62. DrawWindow
  63. @param toolbars array of activated toolbars, e.g. ['map', 'digit']
  64. @param tree reference to layer tree
  65. @param notebook control book ID in Layer Manager
  66. @param lmgr Layer Manager
  67. @param page notebook page with layer tree
  68. @param Map instance of render.Map
  69. @param auimgs AUI manager
  70. @param kwargs wx.Frame attribures
  71. """
  72. MapFrameBase.__init__(self, parent = parent, title = title, toolbars = toolbars,
  73. tree = tree, notebook = notebook, lmgr = lmgr, page = page,
  74. Map = Map, auimgr = auimgr, name = name, **kwargs)
  75. #
  76. # Add toolbars
  77. #
  78. self.toolbars = { 'map' : None,
  79. 'vdigit' : None,
  80. 'georect' : None,
  81. 'gcpdisp' : None,
  82. 'gcpman' : None,
  83. 'nviz' : None }
  84. for toolb in toolbars:
  85. self.AddToolbar(toolb)
  86. self.activemap = self.toolbars['gcpdisp'].togglemap
  87. self.activemap.SetSelection(0)
  88. self.SrcMap = self.grwiz.SrcMap # instance of render.Map
  89. self.TgtMap = self.grwiz.TgtMap # instance of render.Map
  90. self._mgr.SetDockSizeConstraint(0.5, 0.5)
  91. #
  92. # Add statusbar
  93. #
  94. # items for choice
  95. self.statusbarItems = [sb.SbCoordinates,
  96. sb.SbRegionExtent,
  97. sb.SbCompRegionExtent,
  98. sb.SbShowRegion,
  99. sb.SbResolution,
  100. sb.SbDisplayGeometry,
  101. sb.SbMapScale,
  102. sb.SbProjection,
  103. sb.SbGoToGCP,
  104. sb.SbRMSError]
  105. # create statusbar and its manager
  106. statusbar = self.CreateStatusBar(number = 4, style = 0)
  107. statusbar.SetStatusWidths([-5, -2, -1, -1])
  108. self.statusbarManager = sb.SbManager(mapframe = self, statusbar = statusbar)
  109. # fill statusbar manager
  110. self.statusbarManager.AddStatusbarItemsByClass(self.statusbarItems, mapframe = self, statusbar = statusbar)
  111. self.statusbarManager.AddStatusbarItem(sb.SbMask(self, statusbar = statusbar, position = 2))
  112. self.statusbarManager.AddStatusbarItem(sb.SbRender(self, statusbar = statusbar, position = 3))
  113. self.statusbarManager.SetMode(8) # goto GCP
  114. self.statusbarManager.Update()
  115. #
  116. # Init map display (buffered DC & set default cursor)
  117. #
  118. self.grwiz.SwitchEnv('source')
  119. self.SrcMapWindow = BufferedWindow(self, id=wx.ID_ANY,
  120. Map=self.SrcMap, tree=self.tree, lmgr=self._layerManager)
  121. self.grwiz.SwitchEnv('target')
  122. self.TgtMapWindow = BufferedWindow(self, id=wx.ID_ANY,
  123. Map=self.TgtMap, tree=self.tree, lmgr=self._layerManager)
  124. self.MapWindow = self.SrcMapWindow
  125. self.Map = self.SrcMap
  126. self.SrcMapWindow.SetCursor(self.cursors["cross"])
  127. self.TgtMapWindow.SetCursor(self.cursors["cross"])
  128. #
  129. # initialize region values
  130. #
  131. self.__InitDisplay()
  132. #
  133. # Bind various events
  134. #
  135. self.Bind(wx.EVT_ACTIVATE, self.OnFocus)
  136. self.Bind(render.EVT_UPDATE_PRGBAR, self.OnUpdateProgress)
  137. self.Bind(wx.EVT_SIZE, self.OnDispResize)
  138. self.activemap.Bind(wx.EVT_CHOICE, self.OnUpdateActive)
  139. #
  140. # Update fancy gui style
  141. #
  142. # AuiManager wants a CentrePane, workaround to get two equally sized windows
  143. self.list = self.CreateGCPList()
  144. #self.SrcMapWindow.SetSize((300, 300))
  145. #self.TgtMapWindow.SetSize((300, 300))
  146. self.list.SetSize((100, 150))
  147. self._mgr.AddPane(self.list, wx.aui.AuiPaneInfo().
  148. Name("gcplist").Caption(_("GCP List")).LeftDockable(False).
  149. RightDockable(False).PinButton().FloatingSize((600,200)).
  150. CloseButton(False).DestroyOnClose(True).
  151. Top().Layer(1).MinSize((200,100)))
  152. self._mgr.AddPane(self.SrcMapWindow, wx.aui.AuiPaneInfo().
  153. Name("source").Caption(_("Source Display")).Dockable(False).
  154. CloseButton(False).DestroyOnClose(True).Floatable(False).
  155. Centre())
  156. self._mgr.AddPane(self.TgtMapWindow, wx.aui.AuiPaneInfo().
  157. Name("target").Caption(_("Target Display")).Dockable(False).
  158. CloseButton(False).DestroyOnClose(True).Floatable(False).
  159. Right().Layer(0))
  160. srcwidth, srcheight = self.SrcMapWindow.GetSize()
  161. tgtwidth, tgtheight = self.TgtMapWindow.GetSize()
  162. srcwidth = (srcwidth + tgtwidth) / 2
  163. self._mgr.GetPane("target").Hide()
  164. self._mgr.Update()
  165. self._mgr.GetPane("source").BestSize((srcwidth, srcheight))
  166. self._mgr.GetPane("target").BestSize((srcwidth, srcheight))
  167. if self.show_target:
  168. self._mgr.GetPane("target").Show()
  169. else:
  170. self.activemap.Enable(False)
  171. # needed by Mac OS, does not harm on Linux, breaks display on Windows
  172. if platform.system() != 'Windows':
  173. self._mgr.Update()
  174. #
  175. # Init print module and classes
  176. #
  177. self.printopt = disp_print.PrintOptions(self, self.MapWindow)
  178. #
  179. # Initialization of digitization tool
  180. #
  181. self.digit = None
  182. # set active map
  183. self.MapWindow = self.SrcMapWindow
  184. self.Map = self.SrcMap
  185. # do not init zoom history here, that happens when zooming to map(s)
  186. #
  187. # Re-use dialogs
  188. #
  189. self.dialogs = {}
  190. self.dialogs['attributes'] = None
  191. self.dialogs['category'] = None
  192. self.dialogs['barscale'] = None
  193. self.dialogs['legend'] = None
  194. self.decorationDialog = None # decoration/overlays
  195. def AddToolbar(self, name):
  196. """!Add defined toolbar to the window
  197. Currently known toolbars are:
  198. - 'map' - basic map toolbar
  199. - 'vdigit' - vector digitizer
  200. - 'gcpdisp' - GCP Manager, Display
  201. - 'gcpman' - GCP Manager, points management
  202. - 'georect' - georectifier
  203. - 'nviz' - 3D view mode
  204. """
  205. # default toolbar
  206. if name == "map":
  207. self.toolbars['map'] = toolbars.MapToolbar(self, self.Map)
  208. self._mgr.AddPane(self.toolbars['map'],
  209. wx.aui.AuiPaneInfo().
  210. Name("maptoolbar").Caption(_("Map Toolbar")).
  211. ToolbarPane().Top().
  212. LeftDockable(False).RightDockable(False).
  213. BottomDockable(False).TopDockable(True).
  214. CloseButton(False).Layer(2).
  215. BestSize((self.toolbars['map'].GetSize())))
  216. # GCP display
  217. elif name == "gcpdisp":
  218. self.toolbars['gcpdisp'] = toolbars.GCPDisplayToolbar(self)
  219. self._mgr.AddPane(self.toolbars['gcpdisp'],
  220. wx.aui.AuiPaneInfo().
  221. Name("gcpdisplaytoolbar").Caption(_("GCP Display toolbar")).
  222. ToolbarPane().Top().
  223. LeftDockable(False).RightDockable(False).
  224. BottomDockable(False).TopDockable(True).
  225. CloseButton(False).Layer(2))
  226. if self.show_target == False:
  227. self.toolbars['gcpdisp'].Enable('zoommenu', enable = False)
  228. self.toolbars['gcpman'] = toolbars.GCPManToolbar(self)
  229. self._mgr.AddPane(self.toolbars['gcpman'],
  230. wx.aui.AuiPaneInfo().
  231. Name("gcpmanagertoolbar").Caption(_("GCP Manager toolbar")).
  232. ToolbarPane().Top().Row(1).
  233. LeftDockable(False).RightDockable(False).
  234. BottomDockable(False).TopDockable(True).
  235. CloseButton(False).Layer(2))
  236. self._mgr.Update()
  237. def __InitDisplay(self):
  238. """
  239. Initialize map display, set dimensions and map region
  240. """
  241. self.width, self.height = self.GetClientSize()
  242. Debug.msg(2, "MapFrame.__InitDisplay():")
  243. self.grwiz.SwitchEnv('source')
  244. self.SrcMap.ChangeMapSize(self.GetClientSize())
  245. self.SrcMap.region = self.SrcMap.GetRegion() # g.region -upgc
  246. self.grwiz.SwitchEnv('target')
  247. self.TgtMap.ChangeMapSize(self.GetClientSize())
  248. self.TgtMap.region = self.TgtMap.GetRegion() # g.region -upgc
  249. # self.SrcMap.SetRegion() # adjust region to match display window
  250. # self.TgtMap.SetRegion() # adjust region to match display window
  251. def OnUpdateProgress(self, event):
  252. """
  253. Update progress bar info
  254. """
  255. self.GetProgressBar().SetValue(event.value)
  256. event.Skip()
  257. def OnFocus(self, event):
  258. """
  259. Change choicebook page to match display.
  260. Or set display for georectifying
  261. """
  262. if self._layerManager and \
  263. self._layerManager.gcpmanagement:
  264. # in GCP Management, set focus to current MapWindow for mouse actions
  265. self.OnPointer(event)
  266. self.MapWindow.SetFocus()
  267. else:
  268. # change bookcontrol page to page associated with display
  269. # GCP Manager: use bookcontrol?
  270. if self.page:
  271. pgnum = self.layerbook.GetPageIndex(self.page)
  272. if pgnum > -1:
  273. self.layerbook.SetSelection(pgnum)
  274. event.Skip()
  275. def OnDraw(self, event):
  276. """!Re-display current map composition
  277. """
  278. self.MapWindow.UpdateMap(render = False)
  279. def OnRender(self, event):
  280. """!Re-render map composition (each map layer)
  281. """
  282. # delete tmp map layers (queries)
  283. qlayer = self.Map.GetListOfLayers(l_name=globalvar.QUERYLAYER)
  284. for layer in qlayer:
  285. self.Map.DeleteLayer(layer)
  286. self.SrcMapWindow.UpdateMap(render=True)
  287. if self.show_target:
  288. self.TgtMapWindow.UpdateMap(render=True)
  289. # update statusbar
  290. self.StatusbarUpdate()
  291. def OnPointer(self, event):
  292. """!Pointer button clicked
  293. """
  294. # change the cursor
  295. self.SrcMapWindow.SetCursor(self.cursors["cross"])
  296. self.SrcMapWindow.mouse['use'] = "pointer"
  297. self.SrcMapWindow.mouse['box'] = "point"
  298. self.TgtMapWindow.SetCursor(self.cursors["cross"])
  299. self.TgtMapWindow.mouse['use'] = "pointer"
  300. self.TgtMapWindow.mouse['box'] = "point"
  301. def OnZoomIn(self, event):
  302. """
  303. Zoom in the map.
  304. Set mouse cursor, zoombox attributes, and zoom direction
  305. """
  306. if self.toolbars['map']:
  307. self.toolbars['map'].OnTool(event)
  308. self.toolbars['map'].action['desc'] = ''
  309. self.MapWindow.mouse['use'] = "zoom"
  310. self.MapWindow.mouse['box'] = "box"
  311. self.MapWindow.zoomtype = 1
  312. self.MapWindow.pen = wx.Pen(colour='Red', width=2, style=wx.SHORT_DASH)
  313. # change the cursor
  314. self.MapWindow.SetCursor(self.cursors["cross"])
  315. if self.MapWindow == self.SrcMapWindow:
  316. win = self.TgtMapWindow
  317. elif self.MapWindow == self.TgtMapWindow:
  318. win = self.SrcMapWindow
  319. win.mouse['use'] = "zoom"
  320. win.mouse['box'] = "box"
  321. win.zoomtype = 1
  322. win.pen = wx.Pen(colour='Red', width=2, style=wx.SHORT_DASH)
  323. # change the cursor
  324. win.SetCursor(self.cursors["cross"])
  325. def OnZoomOut(self, event):
  326. """
  327. Zoom out the map.
  328. Set mouse cursor, zoombox attributes, and zoom direction
  329. """
  330. if self.toolbars['map']:
  331. self.toolbars['map'].OnTool(event)
  332. self.toolbars['map'].action['desc'] = ''
  333. self.MapWindow.mouse['use'] = "zoom"
  334. self.MapWindow.mouse['box'] = "box"
  335. self.MapWindow.zoomtype = -1
  336. self.MapWindow.pen = wx.Pen(colour='Red', width=2, style=wx.SHORT_DASH)
  337. # change the cursor
  338. self.MapWindow.SetCursor(self.cursors["cross"])
  339. if self.MapWindow == self.SrcMapWindow:
  340. win = self.TgtMapWindow
  341. elif self.MapWindow == self.TgtMapWindow:
  342. win = self.SrcMapWindow
  343. win.mouse['use'] = "zoom"
  344. win.mouse['box'] = "box"
  345. win.zoomtype = -1
  346. win.pen = wx.Pen(colour='Red', width=2, style=wx.SHORT_DASH)
  347. # change the cursor
  348. win.SetCursor(self.cursors["cross"])
  349. def OnZoomBack(self, event):
  350. """
  351. Zoom last (previously stored position)
  352. """
  353. self.MapWindow.ZoomBack()
  354. def OnPan(self, event):
  355. """
  356. Panning, set mouse to drag
  357. """
  358. if self.toolbars['map']:
  359. self.toolbars['map'].OnTool(event)
  360. self.toolbars['map'].action['desc'] = ''
  361. self.MapWindow.mouse['use'] = "pan"
  362. self.MapWindow.mouse['box'] = "pan"
  363. self.MapWindow.zoomtype = 0
  364. # change the cursor
  365. self.MapWindow.SetCursor(self.cursors["hand"])
  366. if self.MapWindow == self.SrcMapWindow:
  367. win = self.TgtMapWindow
  368. elif self.MapWindow == self.TgtMapWindow:
  369. win = self.SrcMapWindow
  370. win.mouse['use'] = "pan"
  371. win.mouse['box'] = "pan"
  372. win.zoomtype = 0
  373. # change the cursor
  374. win.SetCursor(self.cursors["hand"])
  375. def OnErase(self, event):
  376. """
  377. Erase the canvas
  378. """
  379. self.MapWindow.EraseMap()
  380. if self.MapWindow == self.SrcMapWindow:
  381. win = self.TgtMapWindow
  382. elif self.MapWindow == self.TgtMapWindow:
  383. win = self.SrcMapWindow
  384. win.EraseMap()
  385. def OnZoomRegion(self, event):
  386. """
  387. Zoom to region
  388. """
  389. self.Map.getRegion()
  390. self.Map.getResolution()
  391. self.UpdateMap()
  392. # event.Skip()
  393. def OnAlignRegion(self, event):
  394. """
  395. Align region
  396. """
  397. if not self.Map.alignRegion:
  398. self.Map.alignRegion = True
  399. else:
  400. self.Map.alignRegion = False
  401. # event.Skip()
  402. def SaveToFile(self, event):
  403. """!Save map to image
  404. """
  405. img = self.MapWindow.img
  406. if not img:
  407. gcmd.GMessage(parent = self,
  408. message = _("Nothing to render (empty map). Operation canceled."))
  409. return
  410. filetype, ltype = gdialogs.GetImageHandlers(img)
  411. # get size
  412. dlg = gdialogs.ImageSizeDialog(self)
  413. dlg.CentreOnParent()
  414. if dlg.ShowModal() != wx.ID_OK:
  415. dlg.Destroy()
  416. return
  417. width, height = dlg.GetValues()
  418. dlg.Destroy()
  419. # get filename
  420. dlg = wx.FileDialog(parent = self,
  421. message = _("Choose a file name to save the image "
  422. "(no need to add extension)"),
  423. wildcard = filetype,
  424. style=wx.SAVE | wx.FD_OVERWRITE_PROMPT)
  425. if dlg.ShowModal() == wx.ID_OK:
  426. path = dlg.GetPath()
  427. if not path:
  428. dlg.Destroy()
  429. return
  430. base, ext = os.path.splitext(path)
  431. fileType = ltype[dlg.GetFilterIndex()]['type']
  432. extType = ltype[dlg.GetFilterIndex()]['ext']
  433. if ext != extType:
  434. path = base + '.' + extType
  435. self.MapWindow.SaveToFile(path, fileType,
  436. width, height)
  437. dlg.Destroy()
  438. def PrintMenu(self, event):
  439. """
  440. Print options and output menu for map display
  441. """
  442. point = wx.GetMousePosition()
  443. printmenu = wx.Menu()
  444. # Add items to the menu
  445. setup = wx.MenuItem(printmenu, wx.ID_ANY, _('Page setup'))
  446. printmenu.AppendItem(setup)
  447. self.Bind(wx.EVT_MENU, self.printopt.OnPageSetup, setup)
  448. preview = wx.MenuItem(printmenu, wx.ID_ANY, _('Print preview'))
  449. printmenu.AppendItem(preview)
  450. self.Bind(wx.EVT_MENU, self.printopt.OnPrintPreview, preview)
  451. doprint = wx.MenuItem(printmenu, wx.ID_ANY, _('Print display'))
  452. printmenu.AppendItem(doprint)
  453. self.Bind(wx.EVT_MENU, self.printopt.OnDoPrint, doprint)
  454. # Popup the menu. If an item is selected then its handler
  455. # will be called before PopupMenu returns.
  456. self.PopupMenu(printmenu)
  457. printmenu.Destroy()
  458. def FormatDist(self, dist):
  459. """!Format length numbers and units in a nice way,
  460. as a function of length. From code by Hamish Bowman
  461. Grass Development Team 2006"""
  462. mapunits = self.Map.projinfo['units']
  463. if mapunits == 'metres': mapunits = 'meters'
  464. outunits = mapunits
  465. dist = float(dist)
  466. divisor = 1.0
  467. # figure out which units to use
  468. if mapunits == 'meters':
  469. if dist > 2500.0:
  470. outunits = 'km'
  471. divisor = 1000.0
  472. else: outunits = 'm'
  473. elif mapunits == 'feet':
  474. # nano-bug: we match any "feet", but US Survey feet is really
  475. # 5279.9894 per statute mile, or 10.6' per 1000 miles. As >1000
  476. # miles the tick markers are rounded to the nearest 10th of a
  477. # mile (528'), the difference in foot flavours is ignored.
  478. if dist > 5280.0:
  479. outunits = 'miles'
  480. divisor = 5280.0
  481. else:
  482. outunits = 'ft'
  483. elif 'degree' in mapunits:
  484. if dist < 1:
  485. outunits = 'min'
  486. divisor = (1/60.0)
  487. else:
  488. outunits = 'deg'
  489. # format numbers in a nice way
  490. if (dist/divisor) >= 2500.0:
  491. outdist = round(dist/divisor)
  492. elif (dist/divisor) >= 1000.0:
  493. outdist = round(dist/divisor,1)
  494. elif (dist/divisor) > 0.0:
  495. outdist = round(dist/divisor,int(math.ceil(3-math.log10(dist/divisor))))
  496. else:
  497. outdist = float(dist/divisor)
  498. return (outdist, outunits)
  499. def OnZoomToMap(self, event):
  500. """!
  501. Set display extents to match selected raster (including NULLs)
  502. or vector map.
  503. """
  504. self.MapWindow.ZoomToMap(layers = self.Map.GetListOfLayers())
  505. def OnZoomToRaster(self, event):
  506. """!
  507. Set display extents to match selected raster map (ignore NULLs)
  508. """
  509. self.MapWindow.ZoomToMap(ignoreNulls = True)
  510. def OnZoomToWind(self, event):
  511. """!Set display geometry to match computational region
  512. settings (set with g.region)
  513. """
  514. self.MapWindow.ZoomToWind()
  515. def OnZoomToDefault(self, event):
  516. """!Set display geometry to match default region settings
  517. """
  518. self.MapWindow.ZoomToDefault()
  519. def OnZoomToSaved(self, event):
  520. """!Set display geometry to match extents in
  521. saved region file
  522. """
  523. self.MapWindow.ZoomToSaved()
  524. def OnDisplayToWind(self, event):
  525. """!Set computational region (WIND file) to match display
  526. extents
  527. """
  528. self.MapWindow.DisplayToWind()
  529. def SaveDisplayRegion(self, event):
  530. """!Save display extents to named region file.
  531. """
  532. self.MapWindow.SaveDisplayRegion()
  533. def OnZoomMenu(self, event):
  534. """!Popup Zoom menu
  535. """
  536. point = wx.GetMousePosition()
  537. zoommenu = wx.Menu()
  538. # Add items to the menu
  539. zoomwind = wx.MenuItem(zoommenu, wx.ID_ANY, _('Zoom to computational region (set with g.region)'))
  540. zoommenu.AppendItem(zoomwind)
  541. self.Bind(wx.EVT_MENU, self.OnZoomToWind, zoomwind)
  542. zoomdefault = wx.MenuItem(zoommenu, wx.ID_ANY, _('Zoom to default region'))
  543. zoommenu.AppendItem(zoomdefault)
  544. self.Bind(wx.EVT_MENU, self.OnZoomToDefault, zoomdefault)
  545. zoomsaved = wx.MenuItem(zoommenu, wx.ID_ANY, _('Zoom to saved region'))
  546. zoommenu.AppendItem(zoomsaved)
  547. self.Bind(wx.EVT_MENU, self.OnZoomToSaved, zoomsaved)
  548. savewind = wx.MenuItem(zoommenu, wx.ID_ANY, _('Set computational region from display'))
  549. zoommenu.AppendItem(savewind)
  550. self.Bind(wx.EVT_MENU, self.OnDisplayToWind, savewind)
  551. savezoom = wx.MenuItem(zoommenu, wx.ID_ANY, _('Save display geometry to named region'))
  552. zoommenu.AppendItem(savezoom)
  553. self.Bind(wx.EVT_MENU, self.SaveDisplayRegion, savezoom)
  554. # Popup the menu. If an item is selected then its handler
  555. # will be called before PopupMenu returns.
  556. self.PopupMenu(zoommenu)
  557. zoommenu.Destroy()
  558. def IsStandalone(self):
  559. """!Check if Map display is standalone"""
  560. if self._layerManager:
  561. return False
  562. return True
  563. def GetLayerManager(self):
  564. """!Get reference to Layer Manager
  565. @return window reference
  566. @return None (if standalone)
  567. """
  568. return self._layerManager
  569. def GetSrcWindow(self):
  570. return self.SrcMapWindow
  571. def GetTgtWindow(self):
  572. return self.TgtMapWindow
  573. def GetShowTarget(self):
  574. return self.show_target
  575. # end of class MapFrame