mapdisplay.py 23 KB

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