4 @brief Map display with toolbar for various display management
5 functions, and additional toolbars (vector digitizer, 3d view).
7 Can be used either from Layer Manager or as d.mon backend.
12 (C) 2006-2011 by the GRASS Development Team
14 This program is free software under the GNU General Public License
15 (>=v2). Read the file COPYING that comes with GRASS for details.
17 @author Michael Barton
18 @author Jachym Cepicky
19 @author Martin Landa <landa.martin gmail.com>
20 @author Vaclav Petras <wenzeslaus gmail.com> (MapFrameBase)
21 @author Anna Kratochvilova <kratochanna gmail.com> (MapFrameBase)
29 from core
import globalvar
33 sys.path.append(os.path.join(globalvar.ETCWXDIR,
"icons"))
34 sys.path.append(os.path.join(globalvar.ETCDIR,
"python"))
36 from core
import globalvar
41 from core.gcmd import GError, GMessage, RunCommand
43 from core.utils import ListOfCatsToRange, GetLayerNameFromCmd
44 from gui_core.dialogs import GetImageHandlers, ImageSizeDialog, DecorationDialog, TextLayerDialog
52 from mapdisp
import statusbar
as sb
59 """!Main frame for map display window. Drawing takes place in
60 child double buffered drawing window.
62 def __init__(self, parent = None, title = _(
"GRASS GIS - Map display"),
63 toolbars = [
"map"], tree =
None, notebook =
None, lmgr =
None,
64 page =
None, Map =
None, auimgr =
None, name =
'MapWindow', **kwargs):
65 """!Main map display window with toolbars, statusbar and
66 BufferedWindow (map canvas)
68 @param toolbars array of activated toolbars, e.g. ['map', 'digit']
69 @param tree reference to layer tree
70 @param notebook control book ID in Layer Manager
71 @param lmgr Layer Manager
72 @param page notebook page with layer tree
73 @param Map instance of render.Map
74 @param auimgs AUI manager
75 @param name frame name
76 @param kwargs wx.Frame attributes
78 MapFrameBase.__init__(self, parent = parent, title = title, toolbars = toolbars,
79 Map = Map, auimgr = auimgr, name = name, **kwargs)
88 for toolb
in toolbars:
98 sb.SbCompRegionExtent,
102 sb.SbDisplayGeometry,
108 sb.SbDisplayGeometry,
114 statusbar = self.CreateStatusBar(number = 4, style = 0)
115 statusbar.SetStatusWidths([-5, -2, -1, -1])
119 self.statusbarManager.AddStatusbarItemsByClass(self.
statusbarItems, mapframe = self, statusbar = statusbar)
120 self.statusbarManager.AddStatusbarItem(sb.SbMask(self, statusbar = statusbar, position = 2))
121 self.statusbarManager.AddStatusbarItem(sb.SbRender(self, statusbar = statusbar, position = 3))
123 self.statusbarManager.Update()
132 self.MapWindow.SetCursor(self.cursors[
"default"])
141 self._initMap(map = self.Map)
146 self.Bind(wx.EVT_ACTIVATE, self.
OnFocus)
153 self._mgr.AddPane(self.
MapWindow, wx.aui.AuiPaneInfo().CentrePane().
154 Dockable(
False).BestSize((-1,-1)).Name(
'2d').
155 CloseButton(
False).DestroyOnClose(
True).
167 self.MapWindow.ZoomHistory(self.Map.region[
'n'],
168 self.Map.region[
's'],
169 self.Map.region[
'e'],
170 self.Map.region[
'w'])
176 self.
dialogs[
'attributes'] =
None
177 self.
dialogs[
'category'] =
None
178 self.
dialogs[
'barscale'] =
None
186 def _addToolbarVDigit(self):
187 """!Add vector digitizer toolbar
192 from vdigit
import errorMsg
193 msg = _(
"Unable to start wxGUI vector digitizer.\nDo you want to start "
194 "TCL/TK digitizer (v.digit) instead?\n\n"
195 "Details: %s" % errorMsg)
197 self.toolbars[
'map'].combo.SetValue(_(
"2D view"))
198 dlg = wx.MessageDialog(parent = self,
200 caption=_(
"Vector digitizer failed"),
201 style = wx.YES_NO | wx.CENTRE)
202 if dlg.ShowModal() == wx.ID_YES:
203 mapName = self.tree.GetPyData(self.tree.layer_selected)[0][
'maplayer'].GetName()
204 self._layerManager.goutput.RunCmd([
'v.digit',
'map=%s' % mapName],
208 self.toolbars[
'map'].combo.SetValue(_(
"2D view"))
212 log = self._layerManager.goutput
219 Map = self.Map, tree = self.
tree,
221 self.MapWindowVDigit.Show()
222 self._mgr.AddPane(self.
MapWindowVDigit, wx.aui.AuiPaneInfo().CentrePane().
223 Dockable(
False).BestSize((-1,-1)).Name(
'vdigit').
224 CloseButton(
False).DestroyOnClose(
True).
229 if self._mgr.GetPane(
'2d').IsShown():
230 self._mgr.GetPane(
'2d').Hide()
231 elif self._mgr.GetPane(
'3d').IsShown():
232 self._mgr.GetPane(
'3d').Hide()
233 self._mgr.GetPane(
'vdigit').Show()
234 self.toolbars[
'vdigit'] = VDigitToolbar(parent = self, mapcontent = self.Map,
235 layerTree = self.
tree,
237 self.MapWindowVDigit.SetToolbar(self.toolbars[
'vdigit'])
239 self._mgr.AddPane(self.toolbars[
'vdigit'],
240 wx.aui.AuiPaneInfo().
241 Name(
"vdigittoolbar").Caption(_(
"Vector Digitizer Toolbar")).
242 ToolbarPane().Top().Row(1).
243 LeftDockable(
False).RightDockable(
False).
244 BottomDockable(
False).TopDockable(
True).
245 CloseButton(
False).Layer(2).
246 BestSize((self.toolbars[
'vdigit'].GetBestSize())))
248 self.MapWindow.mouse[
'box'] =
"point"
249 self.MapWindow.zoomtype = 0
250 self.MapWindow.pen = wx.Pen(colour =
'red', width = 2, style = wx.SOLID)
251 self.MapWindow.polypen = wx.Pen(colour =
'green', width = 2, style = wx.SOLID)
254 """!Add 3D view mode window
260 self.toolbars[
'map'].combo.SetValue(_(
"2D view"))
261 GError(parent = self,
262 message = _(
"Unable to switch to 3D display mode.\nThe Nviz python extension "
263 "was not found or loaded properly.\n"
264 "Switching back to 2D display mode.\n\nDetails: %s" % nviz.errorMsg))
268 for page
in range(0, self._layerManager.GetLayerNotebook().GetPageCount()):
269 mapdisp = self._layerManager.GetLayerNotebook().GetPage(page).maptree.GetMapDisplay()
270 if self._layerManager.GetLayerNotebook().GetPage(page) != self._layerManager.currentPage:
273 self.toolbars[
'map'].Enable2D(
False)
275 self.toolbars[
'map'].InsertTool(((
'rotate', NvizIcons[
'rotate'],
277 self.toolbars[
'map'].InsertTool(((
'flyThrough', NvizIcons[
'flyThrough'],
279 self.toolbars[
'map'].ChangeToolsDesc(mode2d =
False)
283 self.statusbarManager.SetMode(0)
286 self.MapWindow.EraseMap()
288 self._layerManager.goutput.WriteCmdLog(_(
"Starting 3D view mode..."),
290 self.SetStatusText(_(
"Please wait, loading data..."), 0)
297 self.MapWindow.SetCursor(self.cursors[
"default"])
300 self._layerManager.AddNvizTools()
303 self._mgr.GetPane(
'2d').Hide()
304 self._mgr.AddPane(self.
MapWindow3D, wx.aui.AuiPaneInfo().CentrePane().
305 Dockable(
False).BestSize((-1,-1)).Name(
'3d').
306 CloseButton(
False).DestroyOnClose(
True).
309 self.MapWindow3D.Show()
310 self.MapWindow3D.ResetViewHistory()
311 self.MapWindow3D.UpdateView(
None)
314 os.environ[
'GRASS_REGION'] = self.Map.SetRegion(windres =
True)
315 self.MapWindow3D.GetDisplay().Init()
316 del os.environ[
'GRASS_REGION']
319 self._mgr.GetPane(
'2d').Hide()
320 self._mgr.GetPane(
'3d').Show()
323 self._layerManager.AddNvizTools()
324 self.MapWindow3D.ResetViewHistory()
325 for page
in (
'view',
'light',
'fringe',
'constant',
'cplane',
'animation'):
326 self._layerManager.nviz.UpdatePage(page)
328 self.MapWindow3D.overlays = self.MapWindow2D.overlays
329 self.MapWindow3D.textdict = self.MapWindow2D.textdict
332 wx.CallAfter(self.MapWindow3D.UpdateOverlays)
334 self.SetStatusText(
"", 0)
338 """!Restore 2D view"""
340 self.toolbars[
'map'].RemoveTool(self.toolbars[
'map'].rotate)
341 self.toolbars[
'map'].RemoveTool(self.toolbars[
'map'].flyThrough)
342 except AttributeError:
347 self.statusbarManager.SetMode(UserSettings.Get(group =
'display',
348 key =
'statusbarMode',
349 subkey =
'selection'))
350 self.SetStatusText(_(
"Please wait, unloading data..."), 0)
351 self._layerManager.goutput.WriteCmdLog(_(
"Switching back to 2D view mode..."),
354 self.MapWindow3D.OnClose(event =
None)
356 self._mgr.GetPane(
'2d').Show()
357 self._mgr.GetPane(
'3d').Hide()
361 self._layerManager.RemoveNvizTools()
363 self.MapWindow2D.overlays = self.MapWindow3D.overlays
364 self.MapWindow2D.textdict = self.MapWindow3D.textdict
365 except AttributeError:
367 self.MapWindow.UpdateMap()
371 """!Add defined toolbar to the window
373 Currently known toolbars are:
374 - 'map' - basic map toolbar
375 - 'vdigit' - vector digitizer
376 - 'gcpdisp' - GCP Manager Display
380 self.toolbars[
'map'] = MapToolbar(self, self.Map)
382 self._mgr.AddPane(self.toolbars[
'map'],
383 wx.aui.AuiPaneInfo().
384 Name(
"maptoolbar").Caption(_(
"Map Toolbar")).
385 ToolbarPane().Top().Name(
'mapToolbar').
386 LeftDockable(
False).RightDockable(
False).
387 BottomDockable(
False).TopDockable(
True).
388 CloseButton(
False).Layer(2).
389 BestSize((self.toolbars[
'map'].GetBestSize())))
392 elif name ==
"vdigit":
398 """!Removes defined toolbar from the window
400 @todo Only hide, activate by calling AddToolbar()
406 self._mgr.DetachPane(self.toolbars[name])
407 self.toolbars[name].Destroy()
408 self.toolbars.pop(name)
411 self._mgr.GetPane(
'vdigit').Hide()
412 self._mgr.GetPane(
'2d').Show()
415 self.toolbars[
'map'].combo.SetValue(_(
"2D view"))
416 self.toolbars[
'map'].Enable2D(
True)
421 """!Check if pane (toolbar, mapWindow ...) of given name is currently shown"""
422 if self._mgr.GetPane(name).IsOk():
423 return self._mgr.GetPane(name).IsShown()
427 """!Update progress bar info
429 self.GetProgressBar().
SetValue(event.value)
434 """!Change choicebook page to match display.
438 pgnum = self.layerbook.GetPageIndex(self.
page)
440 self.layerbook.SetSelection(pgnum)
441 self._layerManager.currentPage = self.layerbook.GetCurrentPage()
446 """!Removes temporary map layers (queries)"""
447 qlayer = self.GetMap().GetListOfLayers(l_name = globalvar.QUERYLAYER)
449 self.GetMap().DeleteLayer(layer)
452 """!Re-render map composition (each map layer)
457 if self.MapWindow.mouse[
"use"]
in (
"measure",
459 self.MapWindow.polycoords = []
460 self.MapWindow.ClearLines()
463 if self.GetToolbar(
'vdigit'):
464 if self.MapWindow.digit:
465 self.MapWindow.digit.GetDisplay().SetSelected([])
466 self.MapWindow.UpdateMap(render =
True, renderVector =
True)
468 self.MapWindow.UpdateMap(render =
True)
471 self.StatusbarUpdate()
474 """!Pointer button clicked
478 self.toolbars[
'map'].OnTool(event)
479 self.toolbars[
'map'].action[
'desc'] =
''
481 self.MapWindow.mouse[
'use'] =
"pointer"
482 self.MapWindow.mouse[
'box'] =
"point"
485 if self.GetToolbar(
'vdigit'):
487 self.MapWindow.SetCursor(self.cursors[
"cross"])
490 if self.toolbars[
'vdigit'].GetAction()
in [
'addLine']:
491 if self.toolbars[
'vdigit'].GetAction(
'type')
in [
'point',
'centroid']:
492 self.MapWindow.mouse[
'box'] =
'point'
494 self.MapWindow.mouse[
'box'] =
'line'
495 elif self.toolbars[
'vdigit'].GetAction()
in [
'addVertex',
'removeVertex',
'splitLine',
496 'editLine',
'displayCats',
'queryMap',
498 self.MapWindow.mouse[
'box'] =
'point'
500 self.MapWindow.mouse[
'box'] =
'box'
503 self.MapWindow.SetCursor(self.cursors[
"default"])
509 self.toolbars[
'map'].OnTool(event)
510 self.toolbars[
'map'].action[
'desc'] =
''
512 self.MapWindow.mouse[
'use'] =
"rotate"
515 self.MapWindow.SetCursor(self.cursors[
"hand"])
520 if self.toolbars[
'map']:
521 self.toolbars[
'map'].OnTool(event)
522 self.toolbars[
'map'].action[
'desc'] =
''
524 self.MapWindow.mouse[
'use'] =
"fly"
527 self.MapWindow.SetCursor(self.cursors[
"hand"])
528 self.MapWindow.SetFocus()
535 self.Map.getResolution()
543 if not self.Map.alignRegion:
544 self.Map.alignRegion =
True
546 self.Map.alignRegion =
False
550 """!Save map to image
553 filetype =
"TIF file (*.tif)|*.tif|PPM file (*.ppm)|*.ppm"
554 ltype = [{
'ext' :
'tif',
'type' :
'tif' },
555 {
'ext' :
'ppm',
'type' :
'ppm' }]
557 img = self.MapWindow.img
559 GMessage(parent = self,
560 message = _(
"Nothing to render (empty map). Operation canceled."))
565 dlg = ImageSizeDialog(self)
567 if dlg.ShowModal() != wx.ID_OK:
570 width, height = dlg.GetValues()
574 dlg = wx.FileDialog(parent = self,
575 message = _(
"Choose a file name to save the image "
576 "(no need to add extension)"),
578 style = wx.SAVE | wx.FD_OVERWRITE_PROMPT)
580 if dlg.ShowModal() == wx.ID_OK:
586 base, ext = os.path.splitext(path)
587 fileType = ltype[dlg.GetFilterIndex()][
'type']
588 extType = ltype[dlg.GetFilterIndex()][
'ext']
590 path = base +
'.' + extType
592 self.MapWindow.SaveToFile(path, fileType,
599 Print options and output menu for map display
601 point = wx.GetMousePosition()
602 printmenu = wx.Menu()
604 setup = wx.MenuItem(printmenu, wx.ID_ANY, _(
'Page setup'))
605 printmenu.AppendItem(setup)
606 self.Bind(wx.EVT_MENU, self.printopt.OnPageSetup, setup)
608 preview = wx.MenuItem(printmenu, wx.ID_ANY, _(
'Print preview'))
609 printmenu.AppendItem(preview)
610 self.Bind(wx.EVT_MENU, self.printopt.OnPrintPreview, preview)
612 doprint = wx.MenuItem(printmenu, wx.ID_ANY, _(
'Print display'))
613 printmenu.AppendItem(doprint)
614 self.Bind(wx.EVT_MENU, self.printopt.OnDoPrint, doprint)
618 self.PopupMenu(printmenu)
623 Also close associated layer tree page
629 if self.GetToolbar(
'vdigit'):
630 maplayer = self.toolbars[
'vdigit'].GetLayer()
632 self.toolbars[
'vdigit'].OnExit()
639 pgnum = self.layerbook.GetPageIndex(self.
page)
641 self.layerbook.DeletePage(pgnum)
644 """!Query selected layers.
646 Calls QueryMap in case of raster or more vectors,
647 or QueryVector in case of one vector with db connection.
649 @param x,y coordinates
650 @param layers selected tree item layers
655 ltype = self.tree.GetPyData(layer)[0][
'maplayer'].GetType()
656 if ltype
in (
'raster',
'rgb',
'his',
657 'vector',
'thememap',
'themechart'):
658 filteredLayers.append(layer)
660 if not filteredLayers:
661 GMessage(parent = self,
662 message = _(
'No raster or vector map layer selected for querying.'))
665 layers = filteredLayers
667 qdist = 10.0 * ((self.Map.region[
'e'] - self.Map.region[
'w']) / self.Map.width)
668 east, north = self.MapWindow.Pixel2Cell((x, y))
670 posWindow = self.ClientToScreen((x + self.MapWindow.dialogOffset,
671 y + self.MapWindow.dialogOffset))
675 isDbConnection =
False
677 maplayer = self.tree.GetPyData(l)[0][
'maplayer']
678 if maplayer.GetType() ==
'raster':
681 if maplayer.GetType() ==
'vector':
683 isDbConnection = grass.vector_db(maplayer.GetName())
686 if isRaster
or nVectors > 1
or not isDbConnection:
687 self.
QueryMap(east, north, qdist, layers)
689 self.
QueryVector(east, north, qdist, posWindow, layers[0])
692 self.MapWindow.QuerySurface(x, y)
693 if nVectors > 1
or not isDbConnection:
694 self.
QueryMap(east, north, qdist, layers)
696 self.
QueryVector(east, north, qdist, posWindow, layers[0])
699 """!Query raster or vector map layers by r/v.what
701 @param east,north coordinates
702 @param qdist query distance
703 @param layers selected tree items
707 rcmd = [
'r.what',
'--v']
708 vcmd = [
'v.what',
'--v']
711 ltype = self.tree.GetPyData(layer)[0][
'maplayer'].GetType()
712 dcmd = self.tree.GetPyData(layer)[0][
'cmd']
717 if ltype ==
'raster':
719 elif ltype
in (
'rgb',
'his'):
720 for iname
in name.split(
'\n'):
722 elif ltype
in (
'vector',
'thememap',
'themechart'):
727 os.environ[
"GRASS_REGION"] = self.Map.SetRegion(windres =
False)
733 rcmd.append(
'input=%s' %
','.join(rast))
734 rcmd.append(
'east_north=%f,%f' % (float(east), float(north)))
738 digitToolbar = self.GetToolbar(
'vdigit')
740 lmap = digitToolbar.GetLayer().GetName()
743 self._layerManager.goutput.WriteWarning(_(
"Vector map <%s> "
744 "opened for editing - skipped.") % map)
748 self._layerManager.goutput.WriteCmdLog(_(
"Nothing to query."))
752 vcmd.append(
'map=%s' %
','.join(vect))
753 vcmd.append(
'east_north=%f,%f' % (float(east), float(north)))
754 vcmd.append(
'distance=%f' % float(qdist))
756 Debug.msg(1,
"QueryMap(): raster=%s vector=%s" % (
','.join(rast),
761 self._layerManager.goutput.RunCmd(rcmd,
765 self._layerManager.goutput.RunCmd(vcmd,
768 def _QueryMapDone(self, cmd, returncode):
769 """!Restore settings after querying (restore GRASS_REGION)
771 @param returncode command return code
773 if hasattr(self,
"tmpreg"):
775 os.environ[
"GRASS_REGION"] = self.
tmpreg
776 elif 'GRASS_REGION' in os.environ:
777 del os.environ[
"GRASS_REGION"]
778 elif 'GRASS_REGION' in os.environ:
779 del os.environ[
"GRASS_REGION"]
781 if hasattr(self,
"tmpreg"):
785 """!Query vector map layer features
787 Attribute data of selected vector object are displayed in GUI dialog.
788 Data can be modified (On Submit)
790 mapName = self.tree.GetPyData(layer)[0][
'maplayer'].name
792 if self.tree.GetPyData(layer)[0][
'maplayer'].GetMapset() != \
793 grass.gisenv()[
'MAPSET']:
798 if self.
dialogs[
'attributes']
is None:
799 dlg = DisplayAttributesDialog(parent = self.
MapWindow,
801 query = ((east, north), qdist),
804 self.
dialogs[
'attributes'] = dlg
808 if not self.
dialogs[
'attributes'].mapDBInfo
or \
809 self.
dialogs[
'attributes'].mapDBInfo.map != mapName:
815 if not self.
dialogs[
'attributes'].IsFound():
816 self._layerManager.goutput.WriteLog(_(
'Nothing found.'))
818 cats = self.
dialogs[
'attributes'].GetCats()
821 if not self.
IsPaneShown(
'3d')
and self.IsAutoRendered():
823 qlayer = self.Map.GetListOfLayers(l_name = globalvar.QUERYLAYER)[0]
827 if self.
dialogs[
'attributes'].mapDBInfo
and cats:
828 if not self.
IsPaneShown(
'3d')
and self.IsAutoRendered():
838 opacity = self.tree.GetPyData(layer)[0][
'maplayer'].GetOpacity(float =
True)
839 qlayer.SetOpacity(opacity)
841 self.MapWindow.UpdateMap(render =
False, renderVector =
False)
842 if not self.
dialogs[
'attributes'].IsShown():
843 self.
dialogs[
'attributes'].Show()
846 self.Map.DeleteLayer(qlayer)
847 self.MapWindow.UpdateMap(render =
False, renderVector =
False)
848 if self.
dialogs[
'attributes'].IsShown():
849 self.
dialogs[
'attributes'].Hide()
852 """!Query tools menu"""
854 self.toolbars[
'map'].OnTool(event)
855 action = self.toolbars[
'map'].GetAction()
857 self.toolbars[
'map'].action[
'desc'] =
'queryMap'
858 self.MapWindow.mouse[
'use'] =
"query"
862 self._layerManager.notebook.SetSelectionByName(
'output')
864 self.MapWindow.mouse[
'box'] =
"point"
865 self.MapWindow.zoomtype = 0
868 self.MapWindow.SetCursor(self.cursors[
"cross"])
871 """!Add temporal vector map layer to map composition
873 @param name name of map layer
874 @param useId use feature id instead of category
877 color = UserSettings.Get(group =
'atm', key =
'highlight', subkey =
'color')
878 colorStr = str(color[0]) +
":" + \
879 str(color[1]) +
":" + \
885 vparam = self.tree.GetPyData(self.tree.layer_selected)[0][
'cmd']
888 parg,pval = p.split(
'=', 1)
889 if parg ==
'icon': icon = pval
890 elif parg ==
'size': size = float(pval)
894 "color=%s" % colorStr,
895 "fcolor=%s" % colorStr,
896 "width=%d" % UserSettings.Get(group =
'atm', key =
'highlight', subkey =
'width')]
898 pattern.append(
'icon=%s' % icon)
900 pattern.append(
'size=%i' % size)
905 cmd.append(
'cats=%s' % str(cats))
908 for layer
in cats.keys():
909 cmd.append(copy.copy(pattern))
911 cmd[-1].append(
"layer=%d" % layer)
916 return self.Map.AddLayer(type =
'vector', name = globalvar.QUERYLAYER, command = cmd,
917 l_active =
True, l_hidden =
True, l_opacity = 1.0)
919 return self.Map.AddLayer(type =
'command', name = globalvar.QUERYLAYER, command = cmd,
920 l_active =
True, l_hidden =
True, l_opacity = 1.0)
925 """!Init measurement routine that calculates map distance
926 along transect drawn on map display
931 self._layerManager.notebook.SetSelectionByName(
'output')
934 self.MapWindow.mouse[
'use'] =
"measure"
935 self.MapWindow.mouse[
'box'] =
"line"
936 self.MapWindow.zoomtype = 0
937 self.MapWindow.pen = wx.Pen(colour =
'red', width = 2, style = wx.SHORT_DASH)
938 self.MapWindow.polypen = wx.Pen(colour =
'green', width = 2, style = wx.SHORT_DASH)
941 self.MapWindow.SetCursor(self.cursors[
"pencil"])
944 self._layerManager.goutput.WriteWarning(_(
'Click and drag with left mouse button '
946 'Double click with left button to clear.'))
948 if self.Map.projinfo[
'proj'] !=
'xy':
949 units = self.Map.projinfo[
'units']
950 self._layerManager.goutput.WriteCmdLog(_(
'Measuring distance') +
' ('
953 self._layerManager.goutput.WriteCmdLog(_(
'Measuring distance:'))
955 if self.Map.projinfo[
'proj'] ==
'll':
961 gislib.G_begin_distance_calculations()
962 except ImportError, e:
963 self._layerManager.goutput.WriteWarning(_(
'Geodesic distance is not yet '
964 'supported by this tool.\n'
968 """!Calculate map distance from screen distance
969 and print to output window
971 self._layerManager.notebook.SetSelectionByName(
'output')
973 dist, (north, east) = self.MapWindow.Distance(beginpt, endpt)
975 dist =
round(dist, 3)
984 if self.Map.projinfo[
'proj'] ==
'xy' or 'degree' not in self.Map.projinfo[
'unit']:
985 angle = int(math.degrees(math.atan2(north,east)) + 0.5)
992 mstring =
'%s = %s %s\n%s = %s %s\n%s = %d %s\n%s' \
993 % (_(
'segment'), strdist, dunits,
994 _(
'total distance'), strtotdist, tdunits,
995 _(
'bearing'), angle, _(
'degrees (clockwise from grid-north)'),
998 mstring =
'%s = %s %s\n%s = %s %s\n%s' \
999 % (_(
'segment'), strdist, dunits,
1000 _(
'total distance'), strtotdist, tdunits,
1003 self._layerManager.goutput.WriteLog(mstring)
1008 """!Launch profile tool
1011 if self.tree.layer_selected
and \
1012 self.tree.GetPyData(self.tree.layer_selected)[0][
'type'] ==
'raster':
1013 raster.append(self.tree.GetPyData(self.tree.layer_selected)[0][
'maplayer'].name)
1015 win = ProfileFrame(parent = self, rasterList = raster)
1017 win.CentreOnParent()
1021 win.OnSelectRaster(
None)
1024 """!Format length numbers and units in a nice way,
1025 as a function of length. From code by Hamish Bowman
1026 Grass Development Team 2006"""
1028 mapunits = self.Map.projinfo[
'units']
1029 if mapunits ==
'metres':
1036 if mapunits ==
'meters':
1040 else: outunits =
'm'
1041 elif mapunits ==
'feet':
1051 elif 'degree' in mapunits
and \
1062 if (dist/divisor) >= 2500.0:
1063 outdist =
round(dist/divisor)
1064 elif (dist/divisor) >= 1000.0:
1065 outdist =
round(dist/divisor,1)
1066 elif (dist/divisor) > 0.0:
1067 outdist =
round(dist/divisor,int(math.ceil(3-math.log10(dist/divisor))))
1069 outdist = float(dist/divisor)
1071 return (outdist, outunits)
1074 """!Init histogram display canvas and tools
1076 win = HistogramFrame(self)
1078 win.CentreOnParent()
1084 """!Handler for scale/arrow map decoration menu selection.
1100 DecorationDialog(parent = self, title = _(
'Scale and North arrow'),
1102 style = wx.DEFAULT_DIALOG_STYLE | wx.CENTRE,
1103 cmd = [
'd.barscale',
'at=0,5'],
1106 checktxt = _(
"Show/hide scale and North arrow"),
1107 ctrltxt = _(
"scale object"))
1109 self.
dialogs[
'barscale'].CentreOnParent()
1112 self.
dialogs[
'barscale'].Show()
1113 self.MapWindow.mouse[
'use'] =
'pointer'
1116 """!Handler for legend map decoration menu selection.
1123 cmd = [
'd.legend',
'at=5,50,2,5']
1124 if self.tree.layer_selected
and \
1125 self.tree.GetPyData(self.tree.layer_selected)[0][
'type'] ==
'raster':
1126 cmd.append(
'map=%s' % self.tree.GetPyData(self.tree.layer_selected)[0][
'maplayer'].name)
1130 DecorationDialog(parent = self, title = (
'Legend'),
1132 style = wx.DEFAULT_DIALOG_STYLE | wx.CENTRE,
1136 checktxt = _(
"Show/hide legend"),
1137 ctrltxt = _(
"legend object"))
1139 self.
dialogs[
'legend'].CentreOnParent()
1143 self.MapWindow.mouse[
'use'] =
'pointer'
1146 """!Handler for text decoration menu selection.
1148 if self.MapWindow.dragid > -1:
1149 id = self.MapWindow.dragid
1150 self.MapWindow.dragid = -1
1153 if len(self.MapWindow.textdict.keys()) > 0:
1154 id =
max(self.MapWindow.textdict.keys()) + 1
1158 self.
dialogs[
'text'] = TextLayerDialog(parent = self, ovlId = id,
1159 title = _(
'Add text layer'),
1161 self.
dialogs[
'text'].CenterOnParent()
1164 if self.
dialogs[
'text'].ShowModal() == wx.ID_OK:
1165 text = self.
dialogs[
'text'].GetValues()[
'text']
1166 active = self.
dialogs[
'text'].GetValues()[
'active']
1169 if text ==
'' or active ==
False:
1171 self.MapWindow2D.pdc.ClearId(id)
1172 self.MapWindow2D.pdc.RemoveId(id)
1173 del self.MapWindow.textdict[id]
1175 self.MapWindow3D.UpdateOverlays()
1176 self.MapWindow.UpdateMap()
1178 self.MapWindow2D.UpdateMap(render =
False, renderVector =
False)
1184 self.MapWindow.textdict[id] = self.
dialogs[
'text'].GetValues()
1187 self.MapWindow3D.UpdateOverlays()
1188 self.MapWindow3D.UpdateMap()
1190 self.MapWindow2D.pdc.ClearId(id)
1191 self.MapWindow2D.pdc.SetId(id)
1192 self.MapWindow2D.UpdateMap(render =
False, renderVector =
False)
1194 self.MapWindow.mouse[
'use'] =
'pointer'
1197 """!Handler for north arrow menu selection.
1198 Opens Appearance page of nviz notebook.
1201 self._layerManager.nviz.SetPage(
'decoration')
1202 self.MapWindow3D.SetDrawArrow((70, 70))
1205 """!Callback method for decoration overlay command generated by
1206 dialog created in menuform.py
1210 self.Map.ChangeOverlay(ovltype = type, type =
'overlay', name =
'', command = dcmd,
1211 l_active =
True, l_render =
False)
1212 self.params[type] = params
1213 self.propwin[type] = propwin
1216 """!Set display extents to match selected raster (including
1217 NULLs) or vector map.
1219 self.MapWindow.ZoomToMap()
1222 """!Set display extents to match selected raster map (ignore NULLs)
1224 self.MapWindow.ZoomToMap(ignoreNulls =
True)
1227 """!Set display geometry to match extents in
1230 self.MapWindow.ZoomToSaved()
1233 """!Set computational region (WIND file) to match display
1236 self.MapWindow.DisplayToWind()
1239 """!Save display extents to named region file.
1241 self.MapWindow.SaveRegion(display =
True)
1244 """!Save computational region to named region file.
1246 self.MapWindow.SaveRegion(display =
False)
1251 point = wx.GetMousePosition()
1252 zoommenu = wx.Menu()
1254 for label, handler
in ((_(
'Zoom to computational region'), self.OnZoomToWind),
1255 (_(
'Zoom to default region'), self.OnZoomToDefault),
1257 (_(
'Set computational region from display extent'), self.
OnDisplayToWind),
1260 mid = wx.MenuItem(zoommenu, wx.ID_ANY, label)
1261 zoommenu.AppendItem(mid)
1262 self.Bind(wx.EVT_MENU, handler, mid)
1266 self.PopupMenu(zoommenu)
1269 def SetProperties(self, render = False, mode = 0, showCompExtent = False,
1270 constrainRes =
False, projection =
False, alignExtent =
True):
1271 """!Set properies of map display window"""
1272 self.SetProperty(
'render', render)
1273 self.statusbarManager.SetMode(mode)
1274 self.StatusbarUpdate()
1275 self.SetProperty(
'region', showCompExtent)
1276 self.SetProperty(
'alignExtent', alignExtent)
1277 self.SetProperty(
'resolution', constrainRes)
1278 self.SetProperty(
'projection', projection)
1281 """!Check if Map display is standalone"""
1288 """!Get reference to Layer Manager
1290 @return window reference
1291 @return None (if standalone)
1296 """!Returns toolbar with zooming tools"""
1297 return self.toolbars[
'map']
def OnAddArrow
Handler for north arrow menu selection.
def Query
Query selected layers.
def OnAddText
Handler for text decoration menu selection.
def OnFocus
Change choicebook page to match display.
def ListOfCatsToRange
Convert list of category number to range(s)
def OnZoomMenu
Popup Zoom menu.
def OnQuery
Query tools menu.
def SaveToFile
Save map to image.
def OnZoomToSaved
Set display geometry to match extents in saved region file.
def OnRotate
Rotate 3D view.
def OnZoomToRaster
Set display extents to match selected raster map (ignore NULLs)
def SetProperties
Set properies of map display window.
def OnPointer
Pointer button clicked.
def GetOptData
Callback method for decoration overlay command generated by dialog created in menuform.py.
def _QueryMapDone
Restore settings after querying (restore GRASS_REGION)
def OnFlyThrough
Fly-through mode.
def GetLayerManager
Get reference to Layer Manager.
def OnAddBarscale
Handler for scale/arrow map decoration menu selection.
def OnSaveDisplayRegion
Save display extents to named region file.
def OnUpdateProgress
Update progress bar info.
Various dialogs used in wxGUI.
def RemoveToolbar
Removes defined toolbar from the window.
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 QueryMap
Query raster or vector map layers by r/v.what.
def QueryVector
Query vector map layer features.
def OnSaveWindRegion
Save computational region to named region file.
def IsStandalone
Check if Map display is standalone.
def AddNviz
Add 3D view mode window.
def GetLayerNameFromCmd
Get map name from GRASS command.
Plotting histogram based on d.histogram.
def AddTmpVectorMapLayer
Add temporal vector map layer to map composition.
def OnRender
Re-render map composition (each map layer)
def RemoveNviz
Restore 2D view.
def GetImageHandlers
Get list of supported image handlers.
def OnDisplayToWind
Set computational region (WIND file) to match display extents.
Main frame for map display window.
def OnHistogram
Init histogram display canvas and tools.
statusbarItemsHiddenInNviz
def FormatDist
Format length numbers and units in a nice way, as a function of length.
def OnZoomToMap
Set display extents to match selected raster (including NULLs) or vector map.
Misc utilities for wxGUI.
Map display canvas for wxGUI vector digitizer.
def AddToolbar
Add defined toolbar to the window.
def OnProfile
Launch profile tool.
Map display canvas - buffered window.
def OnAddLegend
Handler for legend map decoration menu selection.
def GetMapToolbar
Returns toolbar with zooming tools.
def MeasureDist
Calculate map distance from screen distance and print to output window.
def IsPaneShown
Check if pane (toolbar, mapWindow ...) of given name is currently shown.
def OnMeasure
Init measurement routine that calculates map distance along transect drawn on map display...
def __init__
Main map display window with toolbars, statusbar and BufferedWindow (map canvas)
def RemoveQueryLayer
Removes temporary map layers (queries)
def _addToolbarVDigit
Add vector digitizer toolbar.
def OnCloseWindow
Window closed.