2 @package gcp.mapdisplay
4 @brief Display to manage ground control points with two toolbars, one
5 for various display management functions, one for manipulating GCPs.
10 (C) 2006-2011 by the GRASS Development Team
12 This program is free software under the GNU General Public License
13 (>=v2). Read the file COPYING that comes with GRASS for details.
22 from core
import globalvar
28 from gcp.toolbars import GCPDisplayToolbar, GCPManToolbar
42 """!Main frame for map display window. Drawing takes place in
43 child double buffered drawing window.
45 def __init__(self, parent=None, title=_(
"GRASS GIS Manage Ground Control Points"),
46 toolbars=[
"gcpdisp"], tree=
None, notebook=
None, lmgr=
None,
47 page=
None, Map=
None, auimgr=
None, name =
'GCPMapWindow', **kwargs):
48 """!Main map display window with toolbars, statusbar and
51 @param toolbars array of activated toolbars, e.g. ['map', 'digit']
52 @param tree reference to layer tree
53 @param notebook control book ID in Layer Manager
54 @param lmgr Layer Manager
55 @param page notebook page with layer tree
56 @param Map instance of render.Map
57 @param auimgs AUI manager
58 @param kwargs wx.Frame attribures
61 MapFrameBase.__init__(self, parent = parent, title = title, toolbars = toolbars,
62 Map = Map, auimgr = auimgr, name = name, **kwargs)
71 for toolb
in toolbars:
75 self.activemap.SetSelection(0)
79 self._mgr.SetDockSizeConstraint(0.5, 0.5)
88 sb.SbCompRegionExtent,
99 statusbar = self.CreateStatusBar(number = 4, style = 0)
100 statusbar.SetStatusWidths([-5, -2, -1, -1])
104 self.statusbarManager.AddStatusbarItemsByClass(self.
statusbarItems, mapframe = self, statusbar = statusbar)
105 self.statusbarManager.AddStatusbarItem(sb.SbMask(self, statusbar = statusbar, position = 2))
106 self.statusbarManager.AddStatusbarItem(sb.SbRender(self, statusbar = statusbar, position = 3))
108 self.statusbarManager.SetMode(8)
109 self.statusbarManager.Update()
115 self.grwiz.SwitchEnv(
'source')
119 self.grwiz.SwitchEnv(
'target')
124 self.SrcMapWindow.SetCursor(self.cursors[
"cross"])
125 self.TgtMapWindow.SetCursor(self.cursors[
"cross"])
130 self._initMap(map = self.
SrcMap)
131 self._initMap(map = self.
TgtMap)
136 self.Bind(wx.EVT_ACTIVATE, self.
OnFocus)
138 self.Bind(wx.EVT_SIZE, self.OnDispResize)
139 self.activemap.Bind(wx.EVT_CHOICE, self.OnUpdateActive)
145 self.
list = self.CreateGCPList()
149 self.list.SetSize((100, 150))
150 self._mgr.AddPane(self.
list, wx.aui.AuiPaneInfo().
151 Name(
"gcplist").Caption(_(
"GCP List")).LeftDockable(
False).
152 RightDockable(
False).PinButton().FloatingSize((600,200)).
153 CloseButton(
False).DestroyOnClose(
True).
154 Top().Layer(1).MinSize((200,100)))
155 self._mgr.AddPane(self.
SrcMapWindow, wx.aui.AuiPaneInfo().
156 Name(
"source").Caption(_(
"Source Display")).Dockable(
False).
157 CloseButton(
False).DestroyOnClose(
True).Floatable(
False).
159 self._mgr.AddPane(self.
TgtMapWindow, wx.aui.AuiPaneInfo().
160 Name(
"target").Caption(_(
"Target Display")).Dockable(
False).
161 CloseButton(
False).DestroyOnClose(
True).Floatable(
False).
164 srcwidth, srcheight = self.SrcMapWindow.GetSize()
165 tgtwidth, tgtheight = self.TgtMapWindow.GetSize()
166 srcwidth = (srcwidth + tgtwidth) / 2
167 self._mgr.GetPane(
"target").Hide()
169 self._mgr.GetPane(
"source").BestSize((srcwidth, srcheight))
170 self._mgr.GetPane(
"target").BestSize((srcwidth, srcheight))
172 self._mgr.GetPane(
"target").Show()
174 self.activemap.Enable(
False)
176 if platform.system() !=
'Windows':
199 self.
dialogs[
'attributes'] =
None
200 self.
dialogs[
'category'] =
None
201 self.
dialogs[
'barscale'] =
None
207 """!Add defined toolbar to the window
209 Currently known toolbars are:
210 - 'map' - basic map toolbar
211 - 'vdigit' - vector digitizer
212 - 'gcpdisp' - GCP Manager, Display
213 - 'gcpman' - GCP Manager, points management
214 - 'nviz' - 3D view mode
218 self.toolbars[
'map'] = MapToolbar(self, self.
Map)
220 self._mgr.AddPane(self.toolbars[
'map'],
221 wx.aui.AuiPaneInfo().
222 Name(
"maptoolbar").Caption(_(
"Map Toolbar")).
224 LeftDockable(
False).RightDockable(
False).
225 BottomDockable(
False).TopDockable(
True).
226 CloseButton(
False).Layer(2).
227 BestSize((self.toolbars[
'map'].GetSize())))
230 elif name ==
"gcpdisp":
231 self.toolbars[
'gcpdisp'] = GCPDisplayToolbar(self)
233 self._mgr.AddPane(self.toolbars[
'gcpdisp'],
234 wx.aui.AuiPaneInfo().
235 Name(
"gcpdisplaytoolbar").Caption(_(
"GCP Display toolbar")).
237 LeftDockable(
False).RightDockable(
False).
238 BottomDockable(
False).TopDockable(
True).
239 CloseButton(
False).Layer(2))
242 self.toolbars[
'gcpdisp'].Enable(
'zoommenu', enable =
False)
244 self.toolbars[
'gcpman'] = GCPManToolbar(self)
246 self._mgr.AddPane(self.toolbars[
'gcpman'],
247 wx.aui.AuiPaneInfo().
248 Name(
"gcpmanagertoolbar").Caption(_(
"GCP Manager toolbar")).
249 ToolbarPane().Top().Row(1).
250 LeftDockable(
False).RightDockable(
False).
251 BottomDockable(
False).TopDockable(
True).
252 CloseButton(
False).Layer(2))
258 Update progress bar info
260 self.GetProgressBar().
SetValue(event.value)
266 Change choicebook page to match display.
267 Or set display for georectifying
270 self._layerManager.gcpmanagement:
273 self.MapWindow.SetFocus()
278 pgnum = self.layerbook.GetPageIndex(self.
page)
280 self.layerbook.SetSelection(pgnum)
285 """!Re-display current map composition
287 self.MapWindow.UpdateMap(render =
False)
290 """!Re-render map composition (each map layer)
294 qlayer = self.Map.GetListOfLayers(l_name=globalvar.QUERYLAYER)
296 self.Map.DeleteLayer(layer)
298 self.SrcMapWindow.UpdateMap(render=
True)
300 self.TgtMapWindow.UpdateMap(render=
True)
303 self.StatusbarUpdate()
306 """!Pointer button clicked
308 self.toolbars[
'gcpdisp'].OnTool(event)
309 self.toolbars[
'gcpdisp'].action[
'desc'] =
''
312 self.SrcMapWindow.SetCursor(self.cursors[
"cross"])
313 self.SrcMapWindow.mouse[
'use'] =
"pointer"
314 self.SrcMapWindow.mouse[
'box'] =
"point"
315 self.TgtMapWindow.SetCursor(self.cursors[
"cross"])
316 self.TgtMapWindow.mouse[
'use'] =
"pointer"
317 self.TgtMapWindow.mouse[
'box'] =
"point"
322 Set mouse cursor, zoombox attributes, and zoom direction
324 self.toolbars[
'gcpdisp'].OnTool(event)
325 self.toolbars[
'gcpdisp'].action[
'desc'] =
''
327 self.MapWindow.mouse[
'use'] =
"zoom"
328 self.MapWindow.mouse[
'box'] =
"box"
329 self.MapWindow.zoomtype = 1
330 self.MapWindow.pen = wx.Pen(colour=
'Red', width=2, style=wx.SHORT_DASH)
333 self.MapWindow.SetCursor(self.cursors[
"cross"])
340 win.mouse[
'use'] =
"zoom"
341 win.mouse[
'box'] =
"box"
343 win.pen = wx.Pen(colour=
'Red', width=2, style=wx.SHORT_DASH)
346 win.SetCursor(self.cursors[
"cross"])
351 Set mouse cursor, zoombox attributes, and zoom direction
353 self.toolbars[
'gcpdisp'].OnTool(event)
354 self.toolbars[
'gcpdisp'].action[
'desc'] =
''
356 self.MapWindow.mouse[
'use'] =
"zoom"
357 self.MapWindow.mouse[
'box'] =
"box"
358 self.MapWindow.zoomtype = -1
359 self.MapWindow.pen = wx.Pen(colour=
'Red', width=2, style=wx.SHORT_DASH)
362 self.MapWindow.SetCursor(self.cursors[
"cross"])
369 win.mouse[
'use'] =
"zoom"
370 win.mouse[
'box'] =
"box"
372 win.pen = wx.Pen(colour=
'Red', width=2, style=wx.SHORT_DASH)
375 win.SetCursor(self.cursors[
"cross"])
379 Panning, set mouse to drag
381 self.toolbars[
'gcpdisp'].OnTool(event)
382 self.toolbars[
'gcpdisp'].action[
'desc'] =
''
384 self.MapWindow.mouse[
'use'] =
"pan"
385 self.MapWindow.mouse[
'box'] =
"pan"
386 self.MapWindow.zoomtype = 0
389 self.MapWindow.SetCursor(self.cursors[
"hand"])
396 win.mouse[
'use'] =
"pan"
397 win.mouse[
'box'] =
"pan"
401 win.SetCursor(self.cursors[
"hand"])
407 self.MapWindow.EraseMap()
421 self.Map.getResolution()
429 if not self.Map.alignRegion:
430 self.Map.alignRegion =
True
432 self.Map.alignRegion =
False
436 """!Save map to image
438 img = self.MapWindow.img
440 GMessage(parent = self,
441 message = _(
"Nothing to render (empty map). Operation canceled."))
446 dlg = ImageSizeDialog(self)
448 if dlg.ShowModal() != wx.ID_OK:
451 width, height = dlg.GetValues()
455 dlg = wx.FileDialog(parent = self,
456 message = _(
"Choose a file name to save the image "
457 "(no need to add extension)"),
459 style=wx.SAVE | wx.FD_OVERWRITE_PROMPT)
461 if dlg.ShowModal() == wx.ID_OK:
467 base, ext = os.path.splitext(path)
468 fileType = ltype[dlg.GetFilterIndex()][
'type']
469 extType = ltype[dlg.GetFilterIndex()][
'ext']
471 path = base +
'.' + extType
473 self.MapWindow.SaveToFile(path, fileType,
480 Print options and output menu for map display
482 point = wx.GetMousePosition()
483 printmenu = wx.Menu()
485 setup = wx.MenuItem(printmenu, wx.ID_ANY, _(
'Page setup'))
486 printmenu.AppendItem(setup)
487 self.Bind(wx.EVT_MENU, self.printopt.OnPageSetup, setup)
489 preview = wx.MenuItem(printmenu, wx.ID_ANY, _(
'Print preview'))
490 printmenu.AppendItem(preview)
491 self.Bind(wx.EVT_MENU, self.printopt.OnPrintPreview, preview)
493 doprint = wx.MenuItem(printmenu, wx.ID_ANY, _(
'Print display'))
494 printmenu.AppendItem(doprint)
495 self.Bind(wx.EVT_MENU, self.printopt.OnDoPrint, doprint)
499 self.PopupMenu(printmenu)
503 """!Format length numbers and units in a nice way,
504 as a function of length. From code by Hamish Bowman
505 Grass Development Team 2006"""
507 mapunits = self.Map.projinfo[
'units']
508 if mapunits ==
'metres': mapunits =
'meters'
514 if mapunits ==
'meters':
519 elif mapunits ==
'feet':
529 elif 'degree' in mapunits:
537 if (dist/divisor) >= 2500.0:
538 outdist =
round(dist/divisor)
539 elif (dist/divisor) >= 1000.0:
540 outdist =
round(dist/divisor,1)
541 elif (dist/divisor) > 0.0:
542 outdist =
round(dist/divisor,int(math.ceil(3-math.log10(dist/divisor))))
544 outdist = float(dist/divisor)
546 return (outdist, outunits)
550 Set display extents to match selected raster map (ignore NULLs)
552 self.MapWindow.ZoomToMap(ignoreNulls =
True)
555 """!Set display geometry to match extents in
558 self.MapWindow.ZoomToSaved()
561 """!Set computational region (WIND file) to match display
564 self.MapWindow.DisplayToWind()
567 """!Save display extents to named region file.
569 self.MapWindow.SaveDisplayRegion()
574 point = wx.GetMousePosition()
578 zoomwind = wx.MenuItem(zoommenu, wx.ID_ANY, _(
'Zoom to computational region (set with g.region)'))
579 zoommenu.AppendItem(zoomwind)
580 self.Bind(wx.EVT_MENU, self.OnZoomToWind, zoomwind)
582 zoomdefault = wx.MenuItem(zoommenu, wx.ID_ANY, _(
'Zoom to default region'))
583 zoommenu.AppendItem(zoomdefault)
584 self.Bind(wx.EVT_MENU, self.OnZoomToDefault, zoomdefault)
586 zoomsaved = wx.MenuItem(zoommenu, wx.ID_ANY, _(
'Zoom to saved region'))
587 zoommenu.AppendItem(zoomsaved)
590 savewind = wx.MenuItem(zoommenu, wx.ID_ANY, _(
'Set computational region from display'))
591 zoommenu.AppendItem(savewind)
594 savezoom = wx.MenuItem(zoommenu, wx.ID_ANY, _(
'Save display geometry to named region'))
595 zoommenu.AppendItem(savezoom)
600 self.PopupMenu(zoommenu)
605 """!Check if Map display is standalone"""
612 """!Get reference to Layer Manager
614 @return window reference
615 @return None (if standalone)
629 """!Returns toolbar with zooming tools"""
630 return self.toolbars[
'gcpdisp']
def IsStandalone
Check if Map display is standalone.
def OnPointer
Pointer button clicked.
def OnZoomToRaster
Set display extents to match selected raster map (ignore NULLs)
def OnZoomMenu
Popup Zoom menu.
def AddToolbar
Add defined toolbar to the window.
def GetLayerManager
Get reference to Layer Manager.
def GetMapToolbar
Returns toolbar with zooming tools.
def SaveDisplayRegion
Save display extents to named region file.
def OnRender
Re-render map composition (each map layer)
Various dialogs used in wxGUI.
Print context and utility functions for printing contents of map display window.
Rendering map layers and overlays into map composition image.
Base classes for Map display window.
def OnZoomToSaved
Set display geometry to match extents in saved region file.
def GetImageHandlers
Get list of supported image handlers.
def OnDraw
Re-display current map composition.
def SaveToFile
Save map to image.
def FormatDist
Format length numbers and units in a nice way, as a function of length.
Map display canvas - buffered window.
Classes for statusbar management.
Main frame for map display window.
def OnDisplayToWind
Set computational region (WIND file) to match display extents.
def __init__
Main map display window with toolbars, statusbar and DrawWindow.