Пример #1
0
class ExampleMapFrame(SingleMapFrame):
    """! Main frame of example tool.

    Inherits from SingleMapFrame, so map is displayed in one map widow.
    In case two map windows are needed, use DoubleMapFrame from (gui_core.mapdisp).

    @see IClassMapFrame in iclass.frame
    """

    def __init__(
        self,
        parent,
        giface,
        title=_("Example Tool"),
        toolbars=["MiscToolbar", "MapToolbar", "MainToolbar"],
        size=(800, 600),
        name="exampleWindow",
        **kwargs,
    ):
        """!Map Frame constructor

        @param parent (no parent is expected)
        @param title window title
        @param toolbars list of active toolbars (default value represents all toolbars)
        @param size default size
        """
        SingleMapFrame.__init__(
            self, parent=parent, title=title, name=name, Map=Map(), **kwargs
        )

        # Place debug message where appropriate
        # and set debug level from 1 to 5 (higher to lower level functions).
        # To enable debug mode write:
        # > g.gisenv set=WX_DEBUG=5
        Debug.msg(1, "ExampleMapFrame.__init__()")

        #
        # Add toolbars to aui manager
        #
        toolbarsCopy = toolbars[:]
        # workaround to have the same toolbar order on all platforms
        if sys.platform == "win32":
            toolbarsCopy.reverse()

        for toolbar in toolbarsCopy:
            self.AddToolbar(toolbar)

        self.mapWindowProperties = MapWindowProperties()
        self.mapWindowProperties.setValuesFromUserSettings()
        self.mapWindowProperties.autoRenderChanged.connect(
            lambda value: self.OnRender(None) if value else None
        )
        #
        # Add statusbar
        #

        # choose items in statusbar choice, which makes sense for your application
        self.statusbarItems = [
            sb.SbCoordinates,
            sb.SbRegionExtent,
            sb.SbCompRegionExtent,
            sb.SbShowRegion,
            sb.SbAlignExtent,
            sb.SbResolution,
            sb.SbDisplayGeometry,
            sb.SbMapScale,
            sb.SbGoTo,
            sb.SbProjection,
        ]

        # create statusbar and its manager
        statusbar = self.CreateStatusBar(number=4, style=0)
        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)
        )
        self.statusbarManager.AddStatusbarItem(
            sb.SbRender(self, statusbar=statusbar, position=3)
        )

        self.statusbarManager.Update()

        # create map window
        self.MapWindow = BufferedMapWindow(
            parent=self,
            Map=self.GetMap(),
            properties=self.mapWindowProperties,
            giface=self,
        )
        self._setUpMapWindow(self.MapWindow)
        self.MapWindow.InitZoomHistory()

        # create whatever you want, here it is a widget for displaying raster info
        self.info = ExampleInfoTextManager(self)

        # add map window (and other widgets) to aui manager
        self._addPanes()
        self._mgr.Update()

        # initialize variables related to your application functionality
        self.InitVariables()

        # default action
        self.GetMapToolbar().SelectDefault()

        self.Bind(wx.EVT_SIZE, self.OnSize)
        self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)

        self.SetSize(size)

    def __del__(self):
        """!Destructor deletes temporary region"""
        gcore.del_temp_region()

    def OnCloseWindow(self, event):
        """!Destroy frame"""
        self.Destroy()

    def IsStandalone(self):
        """!Check if application is standalone.

        Standalone application can work without parent.
        Parent can be e.g. Layer Manager.
        """
        if self.parent:
            return False

        return True

    def InitVariables(self):
        """!Initialize any variables nneded by application"""
        self.currentRaster = None
        self.statitistics = dict()

        # use WIND_OVERRIDE region not to affect current region
        gcore.use_temp_region()

    def _addPanes(self):
        """!Add mapwindow (and other widgets) to aui manager"""
        window = self.GetWindow()
        name = "mainWindow"
        self._mgr.AddPane(
            window,
            wx.aui.AuiPaneInfo()
            .Name(name)
            .CentrePane()
            .Dockable(False)
            .CloseButton(False)
            .DestroyOnClose(True)
            .Layer(0),
        )

        window = self.info.GetControl()
        name = "infoText"
        self._mgr.AddPane(
            window,
            wx.aui.AuiPaneInfo()
            .Name(name)
            .Caption(_("Raster Info"))
            .MinSize((250, -1))
            .Dockable(True)
            .CloseButton(False)
            .Layer(0)
            .Left(),
        )

    def AddToolbar(self, name):
        """!Add defined toolbar to the window

        Currently known toolbars are:
         - 'ExampleMapToolbar'        - basic map toolbar
         - 'ExampleMainToolbar'       - toolbar with application specific tools
         - 'ExampleMiscToolbar'       - toolbar with common tools (help, quit, ...)
        """
        # see wx.aui.AuiPaneInfo documentation for understanding all options
        if name == "MapToolbar":
            self.toolbars[name] = ExampleMapToolbar(self, self._toolSwitcher)

            self._mgr.AddPane(
                self.toolbars[name],
                wx.aui.AuiPaneInfo()
                .Name(name)
                .Caption(_("Map Toolbar"))
                .ToolbarPane()
                .Top()
                .LeftDockable(False)
                .RightDockable(False)
                .BottomDockable(False)
                .TopDockable(True)
                .CloseButton(False)
                .Layer(1)
                .Row(1)
                .BestSize((self.toolbars[name].GetBestSize())),
            )

        if name == "MiscToolbar":
            self.toolbars[name] = ExampleMiscToolbar(self)

            self._mgr.AddPane(
                self.toolbars[name],
                wx.aui.AuiPaneInfo()
                .Name(name)
                .Caption(_("Misc Toolbar"))
                .ToolbarPane()
                .Top()
                .LeftDockable(False)
                .RightDockable(False)
                .BottomDockable(False)
                .TopDockable(True)
                .CloseButton(False)
                .Layer(1)
                .Row(1)
                .BestSize((self.toolbars[name].GetBestSize())),
            )

        if name == "MainToolbar":
            self.toolbars[name] = ExampleMainToolbar(self)

            self._mgr.AddPane(
                self.toolbars[name],
                wx.aui.AuiPaneInfo()
                .Name(name)
                .Caption(_("Main Toolbar"))
                .ToolbarPane()
                .Top()
                .LeftDockable(False)
                .RightDockable(False)
                .BottomDockable(False)
                .TopDockable(True)
                .CloseButton(False)
                .Layer(1)
                .Row(1)
                .BestSize((self.toolbars[name].GetBestSize())),
            )

    def GetMapToolbar(self):
        """!Returns toolbar with zooming tools"""
        return self.toolbars["MapToolbar"]

    def OnHelp(self, event):
        """!Show help page"""
        RunCommand("g.manual", entry="wxGUI.Example")

    def OnSelectRaster(self, event):
        """!Opens dialog to select raster map"""
        dlg = ExampleMapDialog(self)

        if dlg.ShowModal() == wx.ID_OK:
            raster = gcore.find_file(name=dlg.GetRasterMap(), element="cell")
            if raster["fullname"]:
                self.SetLayer(name=raster["fullname"])
            else:
                # show user that the map name is incorrect
                GError(
                    parent=self,
                    message=_("Raster map <{raster}> not found").format(
                        raster=dlg.GetRasterMap()
                    ),
                )

        dlg.Destroy()

    def SetLayer(self, name):
        """!Sets layer in Map and updates statistics.

        @param name layer (raster) name
        """
        Debug.msg(3, "ExampleMapFrame.SetLayer(): name=%s" % name)

        # this simple application enables to keep only one raster
        self.GetMap().DeleteAllLayers()
        cmdlist = ["d.rast", "map=%s" % name]
        # add layer to Map instance (core.render)
        newLayer = self.GetMap().AddLayer(
            ltype="raster",
            command=cmdlist,
            active=True,
            name=name,
            hidden=False,
            opacity=1.0,
            render=True,
        )
        self.GetWindow().ZoomToMap(
            layers=[
                newLayer,
            ],
            render=True,
        )
        self.currentRaster = name

        # change comp. region to match new raster, so that the statistics
        # are computed for the entire raster
        RunCommand("g.region", rast=self.currentRaster, parent=self)

        self.UpdateStatistics()

    def ComputeStatitistics(self):
        """!Computes statistics for raster map using 'r.univar' module.

        @return statistic in form of dictionary
        """
        # RunCommand enables to run GRASS module
        res = RunCommand(
            "r.univar",  # module name
            flags="g",  # command flags
            map=self.currentRaster,  # module parameters
            read=True,
        )  # get command output

        return gcore.parse_key_val(res, val_type=float)

    def UpdateStatistics(self):
        """!Upadate statistic information.

        Called after changing raster map.
        """
        stats = self.ComputeStatitistics()
        self.info.WriteStatistics(name=self.currentRaster, statDict=stats)