1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567 |
- """
- @package mapdisp.frame
- @brief Map display with toolbar for various display management
- functions, and additional toolbars (vector digitizer, 3d view).
- Can be used either from Layer Manager or as d.mon backend.
- Classes:
- - mapdisp::MapFrame
- (C) 2006-2016 by the GRASS Development Team
- This program is free software under the GNU General Public License
- (>=v2). Read the file COPYING that comes with GRASS for details.
- @author Michael Barton
- @author Jachym Cepicky
- @author Martin Landa <landa.martin gmail.com>
- @author Vaclav Petras <wenzeslaus gmail.com> (SingleMapFrame, handlers support)
- @author Anna Kratochvilova <kratochanna gmail.com> (SingleMapFrame)
- @author Stepan Turek <stepan.turek seznam.cz> (handlers support)
- """
- import os
- import sys
- import copy
- from core import globalvar
- import wx
- import wx.aui
- from core.render import Map
- from mapdisp.toolbars import MapToolbar, NvizIcons
- from mapdisp.gprint import PrintOptions
- from core.gcmd import GError, GMessage, RunCommand
- from dbmgr.dialogs import DisplayAttributesDialog
- from core.utils import ListOfCatsToRange, GetLayerNameFromCmd, _
- from gui_core.dialogs import GetImageHandlers, ImageSizeDialog
- from core.debug import Debug
- from core.settings import UserSettings
- from gui_core.mapdisp import SingleMapFrame
- from mapwin.base import MapWindowProperties
- from gui_core.query import QueryDialog, PrepareQueryResults
- from mapwin.buffered import BufferedMapWindow
- from mapwin.decorations import LegendController, BarscaleController, \
- ArrowController, DtextController, LegendVectController
- from modules.histogram import HistogramFrame
- from wxplot.histogram import HistogramPlotFrame
- from wxplot.profile import ProfileFrame
- from wxplot.scatter import ScatterFrame
- from mapwin.analysis import ProfileController, MeasureDistanceController, \
- MeasureAreaController
- from gui_core.forms import GUI
- from core.giface import Notification
- from gui_core.vselect import VectorSelectBase, VectorSelectHighlighter
- from mapdisp import statusbar as sb
- import grass.script as grass
- from grass.pydispatch.signal import Signal
- class MapFrame(SingleMapFrame):
- """Main frame for map display window. Drawing takes place in
- child double buffered drawing window.
- """
- def __init__(self, parent, giface, title=_("GRASS GIS - Map display"),
- toolbars=["map"], statusbar=True,
- tree=None, notebook=None, lmgr=None,
- page=None, Map=None, auimgr=None, name='MapWindow', **kwargs):
- """Main map display window with toolbars, statusbar and
- 2D map window, 3D map window and digitizer.
- :param toolbars: array of activated toolbars, e.g. ['map', 'digit']
- :param statusbar: True to add statusbar
- :param tree: reference to layer tree
- :param notebook: control book ID in Layer Manager
- :param lmgr: Layer Manager
- :param page: notebook page with layer tree
- :param map: instance of render.Map
- :param auimgr: AUI manager
- :param name: frame name
- :param kwargs: wx.Frame attributes
- """
- SingleMapFrame.__init__(self, parent=parent, title=title,
- Map=Map, auimgr=auimgr, name=name, **kwargs)
- self._giface = giface
- # Layer Manager object
- # need by GLWindow (a lot), VDigitWindow (a little bit)
- self._layerManager = lmgr
- # Layer Manager layer tree object
- # used for VDigit toolbar and window and GLWindow
- self.tree = tree
- # Notebook page holding the layer tree
- # used only in OnCloseWindow
- self.page = page
- # Layer Manager layer tree notebook
- # used only in OnCloseWindow
- self.layerbook = notebook
- # Emitted when starting (switching to) 3D mode.
- # Parameter firstTime specifies if 3D was already actived.
- self.starting3dMode = Signal("MapFrame.starting3dMode")
- # Emitted when ending (switching from) 3D mode.
- self.ending3dMode = Signal("MapFrame.ending3dMode")
- # properties are shared in other objects, so defining here
- self.mapWindowProperties = MapWindowProperties()
- self.mapWindowProperties.setValuesFromUserSettings()
- #
- # Add toolbars
- #
- for toolb in toolbars:
- self.AddToolbar(toolb)
- #
- # Add statusbar
- #
- self.statusbarManager = None
- if statusbar:
- self.CreateStatusbar()
- # init decoration objects
- self.decorations = {}
- self._decorationWindows = {}
- self.mapWindowProperties.autoRenderChanged.connect(
- lambda value:
- self.OnRender(None) if value else None)
- #
- # Init map display (buffered DC & set default cursor)
- #
- self.MapWindow2D = BufferedMapWindow(
- self, giface=self._giface, Map=self.Map,
- properties=self.mapWindowProperties, overlays=self.decorations)
- self.MapWindow2D.mapQueried.connect(self.Query)
- self.MapWindow2D.overlayActivated.connect(self._activateOverlay)
- self.MapWindow2D.overlayRemoved.connect(self._removeOverlay)
- self.MapWindow2D.overlayRemoved.connect(self._removeOverlay)
- self._setUpMapWindow(self.MapWindow2D)
- self.MapWindow2D.mouseHandlerUnregistered.connect(self.ResetPointer)
- self.MapWindow2D.InitZoomHistory()
- self.MapWindow2D.zoomChanged.connect(self.StatusbarUpdate)
- self._giface.updateMap.connect(self.MapWindow2D.UpdateMap)
- # default is 2D display mode
- self.MapWindow = self.MapWindow2D
- self.MapWindow.SetNamedCursor('default')
- # used by vector digitizer
- self.MapWindowVDigit = None
- # used by Nviz (3D display mode)
- self.MapWindow3D = None
- if 'map' in self.toolbars:
- self.toolbars['map'].SelectDefault()
- #
- # Bind various events
- #
- self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
- self.Bind(wx.EVT_SIZE, self.OnSize)
- #
- # Update fancy gui style
- #
- self._mgr.AddPane(self.MapWindow, wx.aui.AuiPaneInfo().CentrePane().
- Dockable(False).BestSize((-1, -1)).Name('2d').
- CloseButton(False).DestroyOnClose(True).
- Layer(0))
- self._mgr.Update()
- #
- # Init print module and classes
- #
- self.printopt = PrintOptions(self, self.MapWindow)
- #
- # Re-use dialogs
- #
- self.dialogs = {}
- self.dialogs['attributes'] = None
- self.dialogs['category'] = None
- self.dialogs['vnet'] = None
- self.dialogs['query'] = None
- self.dialogs['vselect'] = None
- # initialize layers to query (d.what.vect/rast)
- self._vectQueryLayers = []
- self._rastQueryLayers = []
- # initialize highlighter for vector features
- self._highlighter_layer = None
- self.measureController = None
- self._resize()
- def CreateStatusbar(self):
- if self.statusbarManager:
- return
- # items for choice
- self.statusbarItems = [sb.SbCoordinates,
- sb.SbRegionExtent,
- sb.SbCompRegionExtent,
- sb.SbShowRegion,
- sb.SbAlignExtent,
- sb.SbResolution,
- sb.SbDisplayGeometry,
- sb.SbMapScale,
- sb.SbGoTo,
- sb.SbProjection]
- self.statusbarItemsHiddenInNviz = (sb.SbAlignExtent,
- sb.SbDisplayGeometry,
- sb.SbShowRegion,
- sb.SbResolution,
- sb.SbMapScale)
- # create statusbar and its manager
- statusbar = self.CreateStatusBar(number=4, style=0)
- if globalvar.wxPython3:
- statusbar.SetMinHeight(24)
- statusbar.SetStatusWidths([-5, -2, -1, -1])
- self.statusbarManager = sb.SbManager(
- mapframe=self, statusbar=statusbar)
- # fill statusbar manager
- self.statusbarManager.AddStatusbarItemsByClass(
- self.statusbarItems, mapframe=self, statusbar=statusbar)
- self.statusbarManager.AddStatusbarItem(
- sb.SbMask(self, statusbar=statusbar, position=2))
- sbRender = sb.SbRender(self, statusbar=statusbar, position=3)
- self.statusbarManager.AddStatusbarItem(sbRender)
- self.statusbarManager.Update()
- #
- self.Map.GetRenderMgr().updateProgress.connect(self.statusbarManager.SetProgress)
- self.Map.GetRenderMgr().renderingFailed.connect(lambda cmd, error: self._giface.WriteError(
- _("Failed to run command '{command}'. Details:\n{error}").format(command=' '.join(cmd), error=error)))
- def GetMapWindow(self):
- return self.MapWindow
- def SetTitleNumber(self, displayId=1):
- """Set map display title"""
- try:
- grassVersion = grass.version()['version']
- except KeyError:
- sys.stderr.write(_("Unable to get GRASS version\n"))
- grassVersion = "?"
- gisenv = grass.gisenv()
- title = _("GRASS GIS %(version)s Map Display: %(id)s - Location: %(loc)s@%(mapset)s") % {
- 'version': grassVersion,
- 'id': str(displayId),
- 'loc': gisenv["LOCATION_NAME"],
- 'mapset': gisenv["MAPSET"]}
- self.SetTitle(title)
- def _addToolbarVDigit(self):
- """Add vector digitizer toolbar
- """
- from vdigit.main import haveVDigit, VDigit
- from vdigit.toolbars import VDigitToolbar
- if not haveVDigit:
- from vdigit import errorMsg
- self.toolbars['map'].combo.SetValue(_("2D view"))
- GError(_("Unable to start wxGUI vector digitizer.\n"
- "Details: %s") % errorMsg, parent=self)
- return
- if not self.MapWindowVDigit:
- from vdigit.mapwindow import VDigitWindow
- self.MapWindowVDigit = VDigitWindow(
- parent=self, giface=self._giface,
- properties=self.mapWindowProperties, Map=self.Map,
- tree=self.tree, lmgr=self._layerManager,
- overlays=self.decorations)
- self._setUpMapWindow(self.MapWindowVDigit)
- self.MapWindowVDigit.digitizingInfo.connect(
- lambda text:
- self.statusbarManager.statusbarItems['coordinates'].SetAdditionalInfo(text))
- self.MapWindowVDigit.digitizingInfoUnavailable.connect(
- lambda: self.statusbarManager.statusbarItems['coordinates'].SetAdditionalInfo(None))
- self.MapWindowVDigit.Show()
- self._mgr.AddPane(
- self.MapWindowVDigit, wx.aui.AuiPaneInfo().CentrePane(). Dockable(False).BestSize(
- (-1, -1)).Name('vdigit'). CloseButton(False).DestroyOnClose(True). Layer(0))
- self._switchMapWindow(self.MapWindowVDigit)
- if self._mgr.GetPane('2d').IsShown():
- self._mgr.GetPane('2d').Hide()
- elif self._mgr.GetPane('3d').IsShown():
- self._mgr.GetPane('3d').Hide()
- self._mgr.GetPane('vdigit').Show()
- if 'vdigit' not in self.toolbars:
- self.toolbars['vdigit'] = VDigitToolbar(
- parent=self, toolSwitcher=self._toolSwitcher,
- MapWindow=self.MapWindow, digitClass=VDigit,
- giface=self._giface)
- self.MapWindowVDigit.SetToolbar(self.toolbars['vdigit'])
- self._mgr.AddPane(self.toolbars['vdigit'],
- wx.aui.AuiPaneInfo().
- Name("vdigittoolbar").Caption(_("Vector Digitizer Toolbar")).
- ToolbarPane().Top().Row(1).
- LeftDockable(False).RightDockable(False).
- BottomDockable(False).TopDockable(True).
- CloseButton(False).Layer(2).
- BestSize((self.toolbars['vdigit'].GetBestSize())))
- # change mouse to draw digitized line
- self.MapWindow.mouse['box'] = "point"
- self.MapWindow.zoomtype = 0
- self.MapWindow.pen = wx.Pen(colour='red', width=2, style=wx.SOLID)
- self.MapWindow.polypen = wx.Pen(
- colour='green', width=2, style=wx.SOLID)
- def AddNviz(self):
- """Add 3D view mode window
- """
- from nviz.main import haveNviz, GLWindow, errorMsg
- # check for GLCanvas and OpenGL
- if not haveNviz:
- self.toolbars['map'].combo.SetValue(_("2D view"))
- GError(
- parent=self, message=_(
- "Unable to switch to 3D display mode.\nThe Nviz python extension "
- "was not found or loaded properly.\n"
- "Switching back to 2D display mode.\n\nDetails: %s" %
- errorMsg))
- return
- # here was disabling 3D for other displays, now done on starting3dMode
- self.toolbars['map'].Enable2D(False)
- # add rotate tool to map toolbar
- self.toolbars['map'].InsertTool(
- (('rotate',
- NvizIcons['rotate'],
- self.OnRotate,
- wx.ITEM_CHECK,
- 7),
- )) # 7 is position
- self._toolSwitcher.AddToolToGroup(
- group='mouseUse', toolbar=self.toolbars['map'],
- tool=self.toolbars['map'].rotate)
- self.toolbars['map'].InsertTool((('flyThrough', NvizIcons['flyThrough'],
- self.OnFlyThrough, wx.ITEM_CHECK, 8),))
- self._toolSwitcher.AddToolToGroup(
- group='mouseUse', toolbar=self.toolbars['map'],
- tool=self.toolbars['map'].flyThrough)
- # update status bar
- self.statusbarManager.HideStatusbarChoiceItemsByClass(
- self.statusbarItemsHiddenInNviz)
- self.statusbarManager.SetMode(0)
- # erase map window
- self.MapWindow.EraseMap()
- self._giface.WriteCmdLog(
- _("Starting 3D view mode..."),
- notification=Notification.HIGHLIGHT)
- self.SetStatusText(_("Please wait, loading data..."), 0)
- # create GL window
- if not self.MapWindow3D:
- self.MapWindow3D = GLWindow(
- self,
- giface=self._giface,
- id=wx.ID_ANY,
- frame=self,
- Map=self.Map,
- tree=self.tree,
- lmgr=self._layerManager)
- self._setUpMapWindow(self.MapWindow3D)
- self.MapWindow3D.mapQueried.connect(self.Query)
- self._switchMapWindow(self.MapWindow3D)
- self.MapWindow.SetNamedCursor('default')
- # here was AddNvizTools in lmgr
- self.starting3dMode.emit(firstTime=True)
- # switch from MapWindow to MapWindowGL
- self._mgr.GetPane('2d').Hide()
- self._mgr.AddPane(
- self.MapWindow3D, wx.aui.AuiPaneInfo().CentrePane(). Dockable(False).BestSize(
- (-1, -1)).Name('3d'). CloseButton(False).DestroyOnClose(True). Layer(0))
- self.MapWindow3D.Show()
- self.MapWindow3D.ResetViewHistory()
- self.MapWindow3D.UpdateView(None)
- self.MapWindow3D.overlayActivated.connect(self._activateOverlay)
- self.MapWindow3D.overlayRemoved.connect(self._removeOverlay)
- else:
- self._switchMapWindow(self.MapWindow3D)
- os.environ['GRASS_REGION'] = self.Map.SetRegion(
- windres=True, windres3=True)
- self.MapWindow3D.GetDisplay().Init()
- del os.environ['GRASS_REGION']
- # switch from MapWindow to MapWindowGL
- self._mgr.GetPane('2d').Hide()
- self._mgr.GetPane('3d').Show()
- # here was AddNvizTools in lmgr and updating of pages
- self.starting3dMode.emit(firstTime=False)
- self.MapWindow3D.ResetViewHistory()
- # connect signals for updating overlays
- for overlay in self.decorations.values():
- overlay.overlayChanged.connect(self.MapWindow3D.UpdateOverlays)
- self.Map.GetRenderMgr().renderDone.connect(self.MapWindow3D._onUpdateOverlays)
- self._giface.updateMap.disconnect(self.MapWindow2D.UpdateMap)
- self._giface.updateMap.connect(self.MapWindow3D.UpdateMap)
- self.MapWindow3D.overlays = self.MapWindow2D.overlays
- # update overlays needs to be called after because getClientSize
- # is called during update and it must give reasonable values
- wx.CallAfter(self.MapWindow3D.UpdateOverlays)
- self.SetStatusText("", 0)
- self._mgr.Update()
- def Disable3dMode(self):
- """Disables 3D mode (NVIZ) in user interface."""
- # TODO: this is broken since item is removed but switch is drived by
- # index
- if '3D' in self.toolbars['map'].combo.GetString(1):
- self.toolbars['map'].combo.Delete(1)
- def RemoveNviz(self):
- """Restore 2D view"""
- try:
- self.toolbars['map'].RemoveTool(self.toolbars['map'].rotate)
- self.toolbars['map'].RemoveTool(self.toolbars['map'].flyThrough)
- except AttributeError:
- pass
- # update status bar
- self.statusbarManager.ShowStatusbarChoiceItemsByClass(
- self.statusbarItemsHiddenInNviz)
- self.statusbarManager.SetMode(UserSettings.Get(group='display',
- key='statusbarMode',
- subkey='selection'))
- self.SetStatusText(_("Please wait, unloading data..."), 0)
- # unloading messages from library cause highlight anyway
- self._giface.WriteCmdLog(_("Switching back to 2D view mode..."),
- notification=Notification.NO_NOTIFICATION)
- if self.MapWindow3D:
- self.MapWindow3D.OnClose(event=None)
- # switch from MapWindowGL to MapWindow
- self._mgr.GetPane('2d').Show()
- self._mgr.GetPane('3d').Hide()
- self._switchMapWindow(self.MapWindow2D)
- # here was RemoveNvizTools form lmgr
- self.ending3dMode.emit()
- try:
- self.MapWindow2D.overlays = self.MapWindow3D.overlays
- except AttributeError:
- pass
- # TODO: here we end because self.MapWindow3D is None for a while
- self._giface.updateMap.disconnect(self.MapWindow3D.UpdateMap)
- self._giface.updateMap.connect(self.MapWindow2D.UpdateMap)
- # disconnect overlays
- for overlay in self.decorations.values():
- overlay.overlayChanged.disconnect(self.MapWindow3D.UpdateOverlays)
- self.Map.GetRenderMgr().renderDone.disconnect(self.MapWindow3D._onUpdateOverlays)
- self.MapWindow3D.ClearTextures()
- self.MapWindow.UpdateMap()
- self._mgr.Update()
- self.GetMapToolbar().SelectDefault()
- def AddToolbar(self, name, fixed=False):
- """Add defined toolbar to the window
- Currently recognized toolbars are:
- - 'map' - basic map toolbar
- - 'vdigit' - vector digitizer
- :param name: toolbar to add
- :param fixed: fixed toolbar
- """
- # default toolbar
- if name == "map":
- if 'map' not in self.toolbars:
- self.toolbars['map'] = MapToolbar(
- self, toolSwitcher=self._toolSwitcher)
- self._mgr.AddPane(self.toolbars['map'],
- wx.aui.AuiPaneInfo().
- Name("maptoolbar").Caption(_("Map Toolbar")).
- ToolbarPane().Top().Name('mapToolbar').
- LeftDockable(False).RightDockable(False).
- BottomDockable(False).TopDockable(True).
- CloseButton(False).Layer(2).
- BestSize((self.toolbars['map'].GetBestSize())))
- # vector digitizer
- elif name == "vdigit":
- self.toolbars['map'].combo.SetValue(_("Vector digitizer"))
- self._addToolbarVDigit()
- if fixed:
- self.toolbars['map'].combo.Disable()
- self._mgr.Update()
- def RemoveToolbar(self, name, destroy=False):
- """Removes defined toolbar from the window
- :param name toolbar to remove
- :param destroy True to destroy otherwise toolbar is only hidden
- """
- self._mgr.DetachPane(self.toolbars[name])
- if destroy:
- self._toolSwitcher.RemoveToolbarFromGroup(
- 'mouseUse', self.toolbars[name])
- self.toolbars[name].Destroy()
- self.toolbars.pop(name)
- else:
- self.toolbars[name].Hide()
- if name == 'vdigit':
- self._mgr.GetPane('vdigit').Hide()
- self._mgr.GetPane('2d').Show()
- self._switchMapWindow(self.MapWindow2D)
- self.toolbars['map'].Enable2D(True)
- self._mgr.Update()
- def IsPaneShown(self, name):
- """Check if pane (toolbar, mapWindow ...) of given name is currently shown"""
- if self._mgr.GetPane(name).IsOk():
- return self._mgr.GetPane(name).IsShown()
- return False
- def RemoveQueryLayer(self):
- """Removes temporary map layers (queries)"""
- qlayer = self.GetMap().GetListOfLayers(name=globalvar.QUERYLAYER)
- for layer in qlayer:
- self.GetMap().DeleteLayer(layer)
- def OnRender(self, event):
- """Re-render map composition (each map layer)
- """
- self.RemoveQueryLayer()
- # deselect features in vdigit
- if self.GetToolbar('vdigit'):
- if self.MapWindow.digit:
- self.MapWindow.digit.GetDisplay().SetSelected([])
- self.MapWindow.UpdateMap(render=True, renderVector=True)
- else:
- self.MapWindow.UpdateMap(render=True)
- # reset dialog with selected features
- if self.dialogs['vselect']:
- self.dialogs['vselect'].Reset()
- # update statusbar
- self.StatusbarUpdate()
- def OnPointer(self, event):
- """Pointer button clicked
- """
- self.MapWindow.SetModePointer()
- if self.GetToolbar('vdigit'):
- self.toolbars['vdigit'].action['id'] = -1
- self.toolbars['vdigit'].action['desc'] = ''
- def OnSelect(self, event):
- """Vector feature selection button clicked
- """
- layerList = self._giface.GetLayerList()
- layerSelected = layerList.GetSelectedLayer()
- if not self.dialogs['vselect']:
- if layerSelected is None:
- GMessage(_("No map layer selected. Operation canceled."))
- return
- self.dialogs['vselect'] = VectorSelectBase(
- self.parent, self._giface)
- self.dialogs['vselect'].CreateDialog(createButton=True)
- self.dialogs['vselect'].onCloseDialog.connect(
- self._onCloseVectorSelectDialog)
- def _onCloseVectorSelectDialog(self):
- self.dialogs['vselect'] = None
- def OnRotate(self, event):
- """Rotate 3D view
- """
- self.MapWindow.mouse['use'] = "rotate"
- # change the cursor
- self.MapWindow.SetNamedCursor('hand')
- def OnFlyThrough(self, event):
- """Fly-through mode
- """
- self.MapWindow.mouse['use'] = "fly"
- # change the cursor
- self.MapWindow.SetNamedCursor('hand')
- self.MapWindow.SetFocus()
- def SaveToFile(self, event):
- """Save map to image
- """
- filetype, ltype = self._prepareSaveToFile()
- if not ltype:
- return
- # get size
- dlg = ImageSizeDialog(self)
- dlg.CentreOnParent()
- if dlg.ShowModal() != wx.ID_OK:
- dlg.Destroy()
- return
- width, height = dlg.GetValues()
- dlg.Destroy()
- # get filename
- dlg = wx.FileDialog(parent=self,
- message=_("Choose a file name to save the image "
- "(no need to add extension)"),
- wildcard=filetype,
- style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
- if dlg.ShowModal() == wx.ID_OK:
- path = dlg.GetPath()
- if not path:
- dlg.Destroy()
- return
- base, ext = os.path.splitext(path)
- fileType = ltype[dlg.GetFilterIndex()]['type']
- extType = ltype[dlg.GetFilterIndex()]['ext']
- if ext != extType:
- path = base + '.' + extType
- self.MapWindow.SaveToFile(path, fileType,
- width, height)
- dlg.Destroy()
- def DOutFile(self, command):
- """Saves map to image by running d.out.file from gui or d.mon.
- Command is expected to be validated by parser.
- """
- filetype, ltype = self._prepareSaveToFile()
- if not ltype:
- return
- width, height = self.MapWindow.GetClientSize()
- for param in command[1:]:
- p, val = param.split('=')
- if p == 'format': # must be there
- if self.IsPaneShown('3d'):
- extType = 'ppm'
- else:
- extType = val
- if p == 'output': # must be there
- name = val
- elif p == 'size':
- width, height = val.split(',')
- base, ext = os.path.splitext(name)
- if not ext:
- name = base + '.' + extType
- elif ext[1:] != extType:
- extType = ext[1:]
- if self.IsPaneShown('3d'):
- bitmapType = 'ppm'
- else:
- bitmapType = wx.BITMAP_TYPE_PNG # default type
- for each in ltype:
- if each['ext'] == extType:
- bitmapType = each['type']
- break
- self.MapWindow.SaveToFile(name, bitmapType, int(width), int(height))
- def DOutFileOptData(self, dcmd, layer, params, propwin):
- """Dummy function which is called when d.out.file is called
- and returns parsed and validated command which is then passed
- to DOutFile method."""
- if not dcmd:
- return
- self.DOutFile(dcmd)
- def DToRast(self, command):
- """Saves currently loaded composition of layers as a raster map.
- """
- if self.IsPaneShown('3d'):
- self._giface.WriteError(
- _('d.to.rast can be used only in 2D mode.'))
- return
- outputRaster = None
- overwrite = False
- for param in command[1:]:
- try:
- p, val = param.split('=')
- if p == 'output':
- outputRaster = val
- except ValueError:
- if param.startswith('--overwrite'):
- overwrite = True
- if not outputRaster:
- return
- # output file as PNG
- tmpName = 'd_to_rast_tmp'
- pngFile = grass.tempfile(create=False) + '.png'
- dOutFileCmd = ['d.out.file', 'output=' + pngFile, 'format=png']
- self.DOutFile(dOutFileCmd)
- # import back as red, green, blue rasters
- returncode, messages = RunCommand(
- 'r.in.gdal', flags='o', input=pngFile, output=tmpName, quiet=True,
- overwrite=overwrite, getErrorMsg=True)
- if not returncode == 0:
- self._giface.WriteError(_('Failed to run d.to.rast:\n') + messages)
- return
- # set region for composite
- grass.use_temp_region()
- returncode, messages = RunCommand('g.region', raster=tmpName + '.red',
- quiet=True, getErrorMsg=True)
- if not returncode == 0:
- grass.del_temp_region()
- self._giface.WriteError(_('Failed to run d.to.rast:\n') + messages)
- return
- # composite
- returncode, messages = RunCommand(
- 'r.composite', red=tmpName + '.red', green=tmpName + '.green',
- blue=tmpName + '.blue', output=outputRaster, quiet=True,
- overwrite=overwrite, getErrorMsg=True)
- grass.del_temp_region()
- RunCommand(
- 'g.remove',
- type='raster',
- flags='f',
- quiet=True,
- name=[
- tmpName +
- '.red',
- tmpName +
- '.green',
- tmpName +
- '.blue'])
- if not returncode == 0:
- self._giface.WriteError(_('Failed to run d.to.rast:\n') + messages)
- grass.try_remove(pngFile)
- return
- # alignExtent changes only region variable
- oldRegion = self.GetMap().GetCurrentRegion().copy()
- self.GetMap().AlignExtentFromDisplay()
- region = self.GetMap().GetCurrentRegion().copy()
- self.GetMap().region.update(oldRegion)
- RunCommand('r.region', map=outputRaster, n=region['n'], s=region['s'],
- e=region['e'], w=region['w'], quiet=True)
- grass.try_remove(pngFile)
- def DToRastOptData(self, dcmd, layer, params, propwin):
- """Dummy function which is called when d.to.rast is called
- and returns parsed and validated command which is then passed
- to DToRast method."""
- if not dcmd:
- return
- self.DToRast(dcmd)
- def _prepareSaveToFile(self):
- """Get wildcards and format extensions."""
- if self.IsPaneShown('3d'):
- filetype = "TIF file (*.tif)|*.tif|PPM file (*.ppm)|*.ppm"
- ltype = [{'ext': 'tif', 'type': 'tif'},
- {'ext': 'ppm', 'type': 'ppm'}]
- else:
- img = self.MapWindow.img
- if not img:
- GMessage(
- parent=self,
- message=_(
- "Nothing to render (empty map). Operation canceled."))
- return None, None
- filetype, ltype = GetImageHandlers(img)
- return filetype, ltype
- def PrintMenu(self, event):
- """
- Print options and output menu for map display
- """
- printmenu = wx.Menu()
- # Add items to the menu
- setup = wx.MenuItem(printmenu, wx.ID_ANY, _('Page setup'))
- printmenu.AppendItem(setup)
- self.Bind(wx.EVT_MENU, self.printopt.OnPageSetup, setup)
- preview = wx.MenuItem(printmenu, wx.ID_ANY, _('Print preview'))
- printmenu.AppendItem(preview)
- self.Bind(wx.EVT_MENU, self.printopt.OnPrintPreview, preview)
- doprint = wx.MenuItem(printmenu, wx.ID_ANY, _('Print display'))
- printmenu.AppendItem(doprint)
- self.Bind(wx.EVT_MENU, self.printopt.OnDoPrint, doprint)
- # Popup the menu. If an item is selected then its handler
- # will be called before PopupMenu returns.
- self.PopupMenu(printmenu)
- printmenu.Destroy()
- def OnCloseWindow(self, event):
- """Window closed.
- Also close associated layer tree page
- """
- Debug.msg(2, "MapFrame.OnCloseWindow(): function starts")
- pgnum = None
- self.Map.Clean()
- # close edited map and 3D tools properly
- if self.GetToolbar('vdigit'):
- maplayer = self.toolbars['vdigit'].GetLayer()
- if maplayer:
- self.toolbars['vdigit'].OnExit()
- if self.IsPaneShown('3d'):
- self.RemoveNviz()
- if hasattr(self, 'rdigit') and self.rdigit:
- self.rdigit.CleanUp()
- if not self._layerManager:
- self.Destroy()
- elif self.page:
- pgnum = self.layerbook.GetPageIndex(self.page)
- if pgnum > -1:
- self.layerbook.DeletePage(pgnum)
- Debug.msg(2, "MapFrame.OnCloseWindow(): function ends")
- def Query(self, x, y):
- """Query selected layers.
- :param x,y: coordinates
- """
- if self._vectQueryLayers or self._rastQueryLayers:
- rast = self._rastQueryLayers
- vect = self._vectQueryLayers
- else:
- layers = self._giface.GetLayerList().GetSelectedLayers(checkedOnly=False)
- rast = []
- vect = []
- for layer in layers:
- if layer.type == 'command':
- continue
- name, found = GetLayerNameFromCmd(layer.cmd)
- if not found:
- continue
- ltype = layer.maplayer.GetType()
- if ltype == 'raster':
- rast.append(name)
- elif ltype in ('rgb', 'his'):
- for iname in name.split('\n'):
- rast.append(iname)
- elif ltype in ('vector', 'thememap', 'themechart'):
- vect.append(name)
- if vect:
- # check for vector maps open to be edited
- digitToolbar = self.GetToolbar('vdigit')
- if digitToolbar:
- lmap = digitToolbar.GetLayer().GetName()
- for name in vect:
- if lmap == name:
- self._giface.WriteWarning(
- _("Vector map <%s> " "opened for editing - skipped.") % lmap)
- vect.remove(name)
- if not (rast + vect):
- GMessage(
- parent=self,
- message=_(
- 'No raster or vector map layer selected for querying.'))
- return
- # set query snap distance for v.what at map unit equivalent of 10
- # pixels
- qdist = 10.0 * (
- (self.Map.region['e'] - self.Map.region['w']) / self.Map.width)
- # TODO: replace returning None by exception or so
- try:
- east, north = self.MapWindow.Pixel2Cell((x, y))
- except TypeError:
- return
- if not self.IsPaneShown('3d'):
- self.QueryMap(east, north, qdist, rast, vect)
- else:
- if rast:
- self.MapWindow.QuerySurface(x, y)
- if vect:
- self.QueryMap(east, north, qdist, rast=[], vect=vect)
- def SetQueryLayersAndActivate(self, ltype, maps):
- """Activate query mode and set layers to query.
- This method is used for querying in d.mon using d.what.rast/vect"""
- self.toolbars['map'].SelectTool(self.toolbars['map'].query)
- if ltype == 'vector':
- self._vectQueryLayers = maps
- elif ltype == 'raster':
- self._rastQueryLayers = maps
- def QueryMap(self, east, north, qdist, rast, vect):
- """Query raster or vector map layers by r/v.what
- :param east,north: coordinates
- :param qdist: query distance
- :param rast: raster map names
- :param vect: vector map names
- """
- Debug.msg(1, "QueryMap(): raster=%s vector=%s" % (','.join(rast),
- ','.join(vect)))
- if self._highlighter_layer is None:
- self._highlighter_layer = VectorSelectHighlighter(
- mapdisp=self._giface.GetMapDisplay(), giface=self._giface)
- # use display region settings instead of computation region settings
- self.tmpreg = os.getenv("GRASS_REGION")
- os.environ["GRASS_REGION"] = self.Map.SetRegion(windres=False)
- rastQuery = []
- vectQuery = []
- if rast:
- rastQuery = grass.raster_what(map=rast, coord=(east, north),
- localized=True)
- if vect:
- encoding = UserSettings.Get(
- group='atm', key='encoding', subkey='value')
- try:
- vectQuery = grass.vector_what(
- map=vect, coord=(east, north),
- distance=qdist, encoding=encoding)
- except grass.ScriptError:
- GError(
- parent=self, message=_(
- "Failed to query vector map(s) <{maps}>. "
- "Check database settings and topology.").format(
- maps=','.join(vect)))
- self._QueryMapDone()
- self._highlighter_layer.Clear()
- if vectQuery and 'Category' in vectQuery[0]:
- self._queryHighlight(vectQuery)
- result = rastQuery + vectQuery
- result = PrepareQueryResults(coordinates=(east, north), result=result)
- if self.dialogs['query']:
- self.dialogs['query'].Raise()
- self.dialogs['query'].SetData(result)
- else:
- self.dialogs['query'] = QueryDialog(parent=self, data=result)
- self.dialogs['query'].Bind(wx.EVT_CLOSE, self._oncloseQueryDialog)
- self.dialogs['query'].redirectOutput.connect(
- self._onRedirectQueryOutput)
- self.dialogs['query'].Show()
- def _oncloseQueryDialog(self, event):
- self.dialogs['query'] = None
- self._vectQueryLayers = []
- self._rastQueryLayers = []
- self._highlighter_layer.Clear()
- self._highlighter_layer = None
- event.Skip()
- def _onRedirectQueryOutput(self, output, style='log'):
- """Writes query output into console"""
- if style == 'log':
- self._giface.WriteLog(
- output, notification=Notification.MAKE_VISIBLE)
- elif style == 'cmd':
- self._giface.WriteCmdLog(output)
- def _queryHighlight(self, vectQuery):
- """Highlight category from query."""
- if len(vectQuery) > 0:
- self._highlighter_layer.SetLayer(vectQuery[0]['Layer'])
- self._highlighter_layer.SetMap(vectQuery[0]['Map'])
- tmp = list()
- for i in vectQuery:
- tmp.append(i['Category'])
- self._highlighter_layer.SetCats(tmp)
- self._highlighter_layer.DrawSelected()
- def _QueryMapDone(self):
- """Restore settings after querying (restore GRASS_REGION)
- """
- if hasattr(self, "tmpreg"):
- if self.tmpreg:
- os.environ["GRASS_REGION"] = self.tmpreg
- elif 'GRASS_REGION' in os.environ:
- del os.environ["GRASS_REGION"]
- elif 'GRASS_REGION' in os.environ:
- del os.environ["GRASS_REGION"]
- if hasattr(self, "tmpreg"):
- del self.tmpreg
- def OnQuery(self, event):
- """Query tools menu"""
- self.MapWindow.mouse['use'] = "query"
- self.MapWindow.mouse['box'] = "point"
- self.MapWindow.zoomtype = 0
- # change the cursor
- self.MapWindow.SetNamedCursor('cross')
- def AddTmpVectorMapLayer(self, name, cats, useId=False, addLayer=True):
- """Add temporal vector map layer to map composition
- :param name: name of map layer
- :param useId: use feature id instead of category
- """
- # color settings from ATM
- color = UserSettings.Get(group='atm', key='highlight', subkey='color')
- colorStr = str(color[0]) + ":" + \
- str(color[1]) + ":" + \
- str(color[2])
- # icon used in vector display and its size
- icon = ''
- size = 0
- # here we know that there is one selected layer and it is vector
- layerSelected = self._giface.GetLayerList().GetSelectedLayer()
- if not layerSelected:
- return None
- vparam = layerSelected.cmd
- for p in vparam:
- if '=' in p:
- parg, pval = p.split('=', 1)
- if parg == 'icon':
- icon = pval
- elif parg == 'size':
- size = float(pval)
- pattern = [
- "d.vect",
- "map=%s" %
- name,
- "color=%s" %
- colorStr,
- "fill_color=%s" %
- colorStr,
- "width=%d" %
- UserSettings.Get(
- group='atm',
- key='highlight',
- subkey='width')]
- if icon != '':
- pattern.append('icon=%s' % icon)
- if size > 0:
- pattern.append('size=%i' % size)
- if useId:
- cmd = pattern
- cmd.append('-i')
- cmd.append('cats=%s' % str(cats))
- else:
- cmd = []
- for layer in cats.keys():
- cmd.append(copy.copy(pattern))
- lcats = cats[layer]
- cmd[-1].append("layer=%d" % layer)
- cmd[-1].append("cats=%s" % ListOfCatsToRange(lcats))
- if addLayer:
- args = {}
- if useId:
- args['ltype'] = 'vector'
- else:
- args['ltype'] = 'command'
- return self.Map.AddLayer(name=globalvar.QUERYLAYER, command=cmd,
- active=True, hidden=True, opacity=1.0,
- render=True, **args)
- else:
- return cmd
- def OnMeasureDistance(self, event):
- self._onMeasure(MeasureDistanceController)
- def OnMeasureArea(self, event):
- self._onMeasure(MeasureAreaController)
- def _onMeasure(self, controller):
- """Starts measurement mode.
- :param controller: measurement class (MeasureDistanceController, MeasureAreaController)
- """
- self.measureController = controller(
- self._giface, mapWindow=self.GetMapWindow())
- # assure that the mode is ended and lines are cleared whenever other
- # tool is selected
- self._toolSwitcher.toggleToolChanged.connect(
- lambda: self.measureController.Stop())
- self.measureController.Start()
- def OnProfile(self, event):
- """Launch profile tool
- """
- rasters = []
- layers = self._giface.GetLayerList().GetSelectedLayers()
- for layer in layers:
- if layer.type == 'raster':
- rasters.append(layer.maplayer.name)
- self.Profile(rasters=rasters)
- def Profile(self, rasters=None):
- """Launch profile tool"""
- self.profileController = ProfileController(
- self._giface, mapWindow=self.GetMapWindow())
- win = ProfileFrame(parent=self, rasterList=rasters,
- units=self.Map.projinfo['units'],
- controller=self.profileController)
- win.Show()
- # Open raster select dialog to make sure that a raster (and
- # the desired raster) is selected to be profiled
- win.OnSelectRaster(None)
- def OnHistogramPyPlot(self, event):
- """Init PyPlot histogram display canvas and tools
- """
- raster = []
- for layer in self._giface.GetLayerList().GetSelectedLayers():
- if layer.maplayer.GetType() == 'raster':
- raster.append(layer.maplayer.GetName())
- win = HistogramPlotFrame(parent=self, rasterList=raster)
- win.CentreOnParent()
- win.Show()
- def OnScatterplot(self, event):
- """Init PyPlot scatterplot display canvas and tools
- """
- raster = []
- for layer in self._giface.GetLayerList().GetSelectedLayers():
- if layer.maplayer.GetType() == 'raster':
- raster.append(layer.maplayer.GetName())
- win = ScatterFrame(parent=self, rasterList=raster)
- win.CentreOnParent()
- win.Show()
- # Open raster select dialog to make sure that at least 2 rasters (and the desired rasters)
- # are selected to be plotted
- win.OnSelectRaster(None)
- def OnHistogram(self, event):
- """Init histogram display canvas and tools
- """
- win = HistogramFrame(self, giface=self._giface)
- win.CentreOnParent()
- win.Show()
- win.Refresh()
- win.Update()
- def _activateOverlay(self, overlayId):
- """Launch decoration dialog according to overlay id.
- :param overlayId: id of overlay
- """
- dlg = self.decorations[overlayId].dialog
- if dlg.IsShown():
- dlg.SetFocus()
- dlg.Raise()
- else:
- dlg.Show()
- def _removeOverlay(self, overlayId):
- """Hide overlay.
- :param overlayId: id of overlay
- """
- del self._decorationWindows[self.decorations[overlayId].dialog]
- self.decorations[overlayId].Remove()
- del self.decorations[overlayId]
- def AddBarscale(self, cmd=None):
- """Handler for scale bar map decoration menu selection."""
- if self.IsPaneShown('3d'):
- self.MapWindow3D.SetDrawScalebar((70, 70))
- return
- if cmd:
- show = False
- else:
- show = True
- cmd = ['d.barscale']
- # Decoration overlay control dialog
- GUI(parent=self, giface=self._giface, show=show, modal=False).ParseCommand(
- cmd, completed=(self.GetOptData, None, None))
- self.MapWindow.mouse['use'] = 'pointer'
- def AddLegend(self, cmd=None):
- """Handler for legend map decoration menu selection."""
- if cmd:
- show = False
- else:
- show = True
- cmd = ['d.legend']
- layers = self._giface.GetLayerList().GetSelectedLayers()
- for layer in layers:
- if layer.type == 'raster':
- cmd.append('raster={rast}'.format(rast=layer.maplayer.name))
- break
- GUI(parent=self, giface=self._giface, show=show, modal=False).ParseCommand(
- cmd, completed=(self.GetOptData, None, None))
- self.MapWindow.mouse['use'] = 'pointer'
- def AddLegendVect(self, cmd=None, showDialog=None):
- """Handler for legend map decoration menu selection."""
- if cmd:
- show = False
- else:
- show = True
- cmd = ['d.legend.vect']
- layers = self._giface.GetLayerList().GetSelectedLayers()
- GUI(parent=self, giface=self._giface, show=show, modal=False).ParseCommand(
- cmd, completed=(self.GetOptData, None, None))
- self.MapWindow.mouse['use'] = 'pointer'
- def AddArrow(self, cmd=None):
- """Handler for north arrow menu selection."""
- if self.IsPaneShown('3d'):
- # here was opening of appearance page of nviz notebook
- # but now moved to MapWindow3D where are other problematic nviz
- # calls
- self.MapWindow3D.SetDrawArrow((70, 70))
- return
- if cmd:
- show = False
- else:
- show = True
- cmd = ['d.northarrow']
- # Decoration overlay control dialog
- GUI(parent=self, giface=self._giface, show=show, modal=False).ParseCommand(
- cmd, completed=(self.GetOptData, None, None))
- self.MapWindow.mouse['use'] = 'pointer'
- def AddDtext(self, cmd=None):
- """Handler for d.text menu selection."""
- if cmd:
- show = False
- else:
- show = True
- cmd = ['d.text']
- # Decoration overlay control dialog
- GUI(parent=self, giface=self._giface, show=show, modal=False).ParseCommand(
- cmd, completed=(self.GetOptData, None, None))
- self.MapWindow.mouse['use'] = 'pointer'
- def GetOptData(self, dcmd, layer, params, propwin):
- """Called after options are set through module dialog.
- :param dcmd: resulting command
- :param layer: not used
- :param params: module parameters (not used)
- :param propwin: dialog window
- """
- if not dcmd:
- return
- if propwin in self._decorationWindows:
- overlay = self._decorationWindows[propwin]
- else:
- cmd = dcmd[0]
- if cmd == 'd.northarrow':
- overlay = ArrowController(self.Map, self._giface)
- elif cmd == 'd.barscale':
- overlay = BarscaleController(self.Map, self._giface)
- elif cmd == 'd.legend':
- overlay = LegendController(self.Map, self._giface)
- elif cmd == 'd.legend.vect':
- overlay = LegendVectController(self.Map, self._giface)
- elif cmd == 'd.text':
- overlay = DtextController(self.Map, self._giface)
- self.decorations[overlay.id] = overlay
- overlay.overlayChanged.connect(lambda: self.MapWindow2D.UpdateMap(
- render=False, renderVector=False))
- if self.MapWindow3D:
- overlay.overlayChanged.connect(self.MapWindow3D.UpdateOverlays)
- overlay.dialog = propwin
- self._decorationWindows[propwin] = overlay
- overlay.cmd = dcmd
- overlay.Show()
- def OnZoomToMap(self, event):
- """Set display extents to match selected raster (including
- NULLs) or vector map.
- """
- Debug.msg(3, "MapFrame.OnZoomToMap()")
- layers = None
- if self.IsStandalone():
- layers = self.MapWindow.GetMap().GetListOfLayers(active=False)
- self.MapWindow.ZoomToMap(layers=layers)
- def OnZoomToRaster(self, event):
- """Set display extents to match selected raster map (ignore NULLs)
- """
- self.MapWindow.ZoomToMap(ignoreNulls=True)
- def OnZoomToSaved(self, event):
- """Set display geometry to match extents in
- saved region file
- """
- self.MapWindow.SetRegion(zoomOnly=True)
- def OnSetDisplayToWind(self, event):
- """Set computational region (WIND file) to match display
- extents
- """
- self.MapWindow.DisplayToWind()
- def OnSetWindToRegion(self, event):
- """Set computational region (WIND file) from named region
- file
- """
- self.MapWindow.SetRegion(zoomOnly=False)
- def OnSetExtentToWind(self, event):
- """Set compulational region extent interactively"""
- self.MapWindow.SetModeDrawRegion()
- def OnSaveDisplayRegion(self, event):
- """Save display extents to named region file.
- """
- self.MapWindow.SaveRegion(display=True)
- def OnSaveWindRegion(self, event):
- """Save computational region to named region file.
- """
- self.MapWindow.SaveRegion(display=False)
- def OnZoomMenu(self, event):
- """Popup Zoom menu
- """
- zoommenu = wx.Menu()
- for label, handler in (
- (_('Zoom to default region'),
- self.OnZoomToDefault),
- (_('Zoom to saved region'),
- self.OnZoomToSaved),
- (None, None),
- (_('Set computational region extent from display'),
- self.OnSetDisplayToWind),
- (_('Set computational region extent interactively'),
- self.OnSetExtentToWind),
- (_('Set computational region from named region'),
- self.OnSetWindToRegion),
- (None, None),
- (_('Save display geometry to named region'),
- self.OnSaveDisplayRegion),
- (_('Save computational region to named region'),
- self.OnSaveWindRegion)):
- if label:
- mid = wx.MenuItem(zoommenu, wx.ID_ANY, label)
- zoommenu.AppendItem(mid)
- self.Bind(wx.EVT_MENU, handler, mid)
- else:
- zoommenu.AppendSeparator()
- # Popup the menu. If an item is selected then its handler will
- # be called before PopupMenu returns.
- self.PopupMenu(zoommenu)
- zoommenu.Destroy()
- def SetProperties(self, render=False, mode=0, showCompExtent=False,
- constrainRes=False, projection=False, alignExtent=True):
- """Set properies of map display window"""
- self.mapWindowProperties.autoRender = render
- self.statusbarManager.SetMode(mode)
- self.StatusbarUpdate()
- self.mapWindowProperties.showRegion = showCompExtent
- self.mapWindowProperties.alignExtent = alignExtent
- self.mapWindowProperties.resolution = constrainRes
- self.SetProperty('projection', projection)
- def IsStandalone(self):
- """Check if Map display is standalone
- .. deprecated:: 7.0
- """
- # TODO: once it is removed from 2 places in vdigit it can be deleted
- # here and also in base class and other classes in the tree (hopefully)
- # and one place here still uses IsStandalone
- Debug.msg(1, "MapFrame.IsStandalone(): Method IsStandalone is"
- "depreciated, use some general approach instead such as"
- " Signals or giface")
- if self._layerManager:
- return False
- return True
- def GetLayerManager(self):
- """Get reference to Layer Manager
- :return: window reference
- :return: None (if standalone)
- .. deprecated:: 7.0
- """
- Debug.msg(1, "MapFrame.GetLayerManager(): Method GetLayerManager is"
- "depreciated, use some general approach instead such as"
- " Signals or giface")
- return self._layerManager
- def GetMapToolbar(self):
- """Returns toolbar with zooming tools"""
- return self.toolbars['map'] if 'map' in self.toolbars else None
- def GetToolbarNames(self):
- """Return toolbar names"""
- return self.toolbars.keys()
- def GetDialog(self, name):
- """Get selected dialog if exist"""
- return self.dialogs.get(name, None)
- def OnVNet(self, event):
- """Dialog for v.net* modules
- """
- if self.dialogs['vnet']:
- self.dialogs['vnet'].Raise()
- return
- from vnet.dialogs import VNETDialog
- self.dialogs['vnet'] = VNETDialog(parent=self, giface=self._giface)
- self.dialogs['vnet'].CenterOnScreen()
- self.dialogs['vnet'].Show()
- def ResetPointer(self):
- """Sets pointer mode.
- Sets pointer and toggles it (e.g. after unregistration of mouse
- handler).
- """
- self.GetMapToolbar().SelectDefault()
- def _switchMapWindow(self, map_win):
- """Notifies activated and disactivated map_wins."""
- self.MapWindow.DisactivateWin()
- map_win.ActivateWin()
- self.MapWindow = map_win
- def AddRDigit(self):
- """Adds raster digitizer: creates toolbar and digitizer controller,
- binds events and signals."""
- from rdigit.controller import RDigitController, EVT_UPDATE_PROGRESS
- from rdigit.toolbars import RDigitToolbar
- self.rdigit = RDigitController(self._giface,
- mapWindow=self.GetMapWindow())
- self.toolbars['rdigit'] = RDigitToolbar(
- parent=self, controller=self.rdigit,
- toolSwitcher=self._toolSwitcher)
- # connect signals
- self.rdigit.newRasterCreated.connect(
- self.toolbars['rdigit'].NewRasterAdded)
- self.rdigit.newRasterCreated.connect(
- lambda name: self._giface.mapCreated.emit(
- name=name, ltype='raster'))
- self.rdigit.newFeatureCreated.connect(
- self.toolbars['rdigit'].UpdateCellValues)
- self.rdigit.uploadMapCategories.connect(
- self.toolbars['rdigit'].UpdateCellValues)
- self.rdigit.showNotification.connect(
- lambda text: self.SetStatusText(text, 0))
- self.rdigit.quitDigitizer.connect(self.QuitRDigit)
- self.rdigit.Bind(
- EVT_UPDATE_PROGRESS,
- lambda evt: self.statusbarManager.SetProgress(
- evt.range,
- evt.value,
- evt.text))
- rasters = self.GetMap().GetListOfLayers(
- ltype='raster', mapset=grass.gisenv()['MAPSET'])
- self.toolbars['rdigit'].UpdateRasterLayers(rasters)
- self.toolbars['rdigit'].SelectDefault()
- self.GetMap().layerAdded.connect(self._updateRDigitLayers)
- self.GetMap().layerRemoved.connect(self._updateRDigitLayers)
- self.GetMap().layerChanged.connect(self._updateRDigitLayers)
- self._mgr.AddPane(self.toolbars['rdigit'],
- wx.aui.AuiPaneInfo().
- Name("rdigit toolbar").Caption(_("Raster Digitizer Toolbar")).
- ToolbarPane().Top().Row(1).
- LeftDockable(False).RightDockable(False).
- BottomDockable(False).TopDockable(True).Floatable().
- CloseButton(False).Layer(2).DestroyOnClose().
- BestSize((self.toolbars['rdigit'].GetBestSize())))
- self._mgr.Update()
- self.rdigit.Start()
- def _updateRDigitLayers(self, layer):
- mapset = grass.gisenv()['MAPSET']
- self.toolbars['rdigit'].UpdateRasterLayers(
- rasters=self.GetMap().GetListOfLayers(
- ltype='raster', mapset=mapset))
- def QuitRDigit(self):
- """Calls digitizer cleanup, removes digitizer object and disconnects
- signals from Map."""
- self.rdigit.CleanUp()
- # disconnect updating layers
- self.GetMap().layerAdded.disconnect(self._updateRDigitLayers)
- self.GetMap().layerRemoved.disconnect(self._updateRDigitLayers)
- self.GetMap().layerChanged.disconnect(self._updateRDigitLayers)
- self.RemoveToolbar('rdigit', destroy=True)
- self.rdigit = None
|