mapdisplay.py 23 KB

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