From be3c74c20a8439c5dfa0184a2446889a54af314c Mon Sep 17 00:00:00 2001 From: Alex Barreto Date: Mon, 2 Aug 2021 09:25:17 -0400 Subject: [PATCH] r.in.pdal: info.cpp also needs PDALCPPFLAGS (#1768) --- doc/notebooks/jupyter_integration.ipynb | 4 + gui/wxpython/main_window/frame.py | 135 +++++++++++++++++++++++- python/grass/jupyter/display.py | 53 ++++++++-- raster/r.in.pdal/Makefile | 2 + 4 files changed, 183 insertions(+), 11 deletions(-) diff --git a/doc/notebooks/jupyter_integration.ipynb b/doc/notebooks/jupyter_integration.ipynb index 6b159e33246..bc8cf254128 100644 --- a/doc/notebooks/jupyter_integration.ipynb +++ b/doc/notebooks/jupyter_integration.ipynb @@ -89,8 +89,12 @@ "outputs": [], "source": [ "# Demonstration of GrassRenderer for non-interactive map display\n", +<<<<<<< HEAD "\n", "r = gj.GrassRenderer(height=540, filename = \"streams_maps.png\")\n", +======= + "r = gj.GrassRenderer(height=540)\n", +>>>>>>> 523219d6d4 (r.in.pdal: info.cpp also needs PDALCPPFLAGS (#1768)) "\n", "r.run(\"d.rast\", map=\"elevation\")\n", "r.run(\"d.vect\", map=\"streams\")\n", diff --git a/gui/wxpython/main_window/frame.py b/gui/wxpython/main_window/frame.py index 05b34c6ad5a..9d4dfd1f553 100644 --- a/gui/wxpython/main_window/frame.py +++ b/gui/wxpython/main_window/frame.py @@ -82,7 +82,14 @@ from lmgr.statusbar import SbMain from lmgr.workspace import WorkspaceManager from lmgr.pyshell import PyShellWindow +<<<<<<< HEAD from lmgr.giface import LayerManagerGrassInterface +======= +from lmgr.giface import ( + LayerManagerGrassInterface, + LayerManagerGrassInterfaceForMapDisplay, +) +>>>>>>> 523219d6d4 (r.in.pdal: info.cpp also needs PDALCPPFLAGS (#1768)) from mapdisp.frame import MapPanel from datacatalog.catalog import DataCatalog from history.browser import HistoryBrowser @@ -199,8 +206,8 @@ def show_menu_errors(messages): ) ======= size = wx.Display().GetGeometry().GetSize() - self.PANE_BEST_SIZE = tuple(t / 5 for t in size) - self.PANE_MIN_SIZE = tuple(t / 10 for t in size) + self.PANE_BEST_SIZE = tuple(t / 3 for t in size) + self.PANE_MIN_SIZE = tuple(t / 7 for t in size) # create widgets and build panes self.CreateMenuBar() @@ -354,6 +361,7 @@ def IsPaneShown(self, name): return self._auimgr.GetPane(name).IsShown() return False +<<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD def SetStatusText(self, *args): @@ -369,6 +377,24 @@ def _createMainNotebook(self): >>>>>>> 4fcbd3f967 (Add Binder badge/button to readme (#1628)) ======= >>>>>>> 5871ca876b (wxGUI/Single-Window GUI: arrangement of basic widgets (#1621)) +======= + def _createMapNotebook(self): + """Create Map Display notebook""" + # create the notebook off-window to avoid flicker + client_size = self.GetClientSize() + notebook_style = ( + aui.AUI_NB_DEFAULT_STYLE | aui.AUI_NB_TAB_EXTERNAL_MOVE | wx.NO_BORDER + ) + self.mapnotebook = aui.AuiNotebook( + self, + -1, + wx.Point(client_size.x, client_size.y), + wx.Size(430, 200), + agwStyle=notebook_style, + ) + self.mapnotebook.SetArtProvider(aui.AuiDefaultTabArt()) + +>>>>>>> 523219d6d4 (r.in.pdal: info.cpp also needs PDALCPPFLAGS (#1768)) def _createDataCatalog(self, parent): """Initialize Data Catalog widget""" self.datacatalog = DataCatalog(parent=parent, giface=self._giface) @@ -448,6 +474,9 @@ def _createPythonShell(self, parent): <<<<<<< HEAD <<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 523219d6d4 (r.in.pdal: info.cpp also needs PDALCPPFLAGS (#1768)) def OnNewDisplay(self, event=None): """Create new layer tree and map display window instance""" self.NewDisplay() @@ -467,6 +496,7 @@ def NewDisplay(self, name=None, show=True): self.pg_panel = wx.Panel( self.notebookLayers, id=wx.ID_ANY, style=wx.BORDER_NONE ) +<<<<<<< HEAD # create display toolbar dmgrToolbar = DisplayPanelToolbar(guiparent=self.pg_panel, parent=self) @@ -486,16 +516,44 @@ def CreateNewMapDisplay(giface, layertree): mapdisplay = MapPanel( parent=self.mainnotebook, giface=giface, +======= + self.notebookLayers.AddPage(page=self.pg_panel, text=name, select=True) + self.currentPage = self.notebookLayers.GetCurrentPage() + self.currentPageNum = self.notebookLayers.GetSelection() + + def CreateNewMapDisplay(layertree): + """Callback function which creates a new Map Display window + :param layertree: layer tree object + :return: reference to mapdisplay instance + """ + # create instance of Map Display interface + self._gifaceForDisplay = LayerManagerGrassInterfaceForMapDisplay( + self._giface, layertree + ) + + # create Map Display + mapdisplay = MapPanel( + parent=self.mapnotebook, + giface=self._gifaceForDisplay, +>>>>>>> 523219d6d4 (r.in.pdal: info.cpp also needs PDALCPPFLAGS (#1768)) id=wx.ID_ANY, tree=layertree, lmgr=self, Map=layertree.Map, +<<<<<<< HEAD dockable=True, +======= +>>>>>>> 523219d6d4 (r.in.pdal: info.cpp also needs PDALCPPFLAGS (#1768)) title=name, size=globalvar.MAP_WINDOW_SIZE, ) # add map display panel to notebook and make it current +<<<<<<< HEAD self.mainnotebook.AddPage(mapdisplay, name) +======= + self.mapnotebook.AddPage(mapdisplay, name) + self.mapnotebook.SetSelection(self.currentPageNum) +>>>>>>> 523219d6d4 (r.in.pdal: info.cpp also needs PDALCPPFLAGS (#1768)) # set map display properties self._setUpMapDisplay(mapdisplay) @@ -524,14 +582,20 @@ def CreateNewMapDisplay(giface, layertree): # layout for controls cb_boxsizer = wx.BoxSizer(wx.VERTICAL) +<<<<<<< HEAD cb_boxsizer.Add(dmgrToolbar, proportion=0, flag=wx.EXPAND) +======= +>>>>>>> 523219d6d4 (r.in.pdal: info.cpp also needs PDALCPPFLAGS (#1768)) cb_boxsizer.Add(self.GetLayerTree(), proportion=1, flag=wx.EXPAND, border=1) self.currentPage.SetSizer(cb_boxsizer) cb_boxsizer.Fit(self.GetLayerTree()) self.currentPage.Layout() self.GetLayerTree().Layout() +<<<<<<< HEAD # Repaint Layers pane map display toolbar widget on the wxMac self._repaintLayersPaneMapDisplayToolbar() +======= +>>>>>>> 523219d6d4 (r.in.pdal: info.cpp also needs PDALCPPFLAGS (#1768)) self.displayIndex += 1 @@ -542,6 +606,7 @@ def _setUpMapDisplay(self, mapdisplay): page = self.currentPage def CanCloseDisplay(askIfSaveWorkspace): +<<<<<<< HEAD """Callback to check if user wants to close display. Map Display index can be different from index in Display tab. @@ -556,10 +621,16 @@ def CanCloseDisplay(askIfSaveWorkspace): pgnum_dict["layers"] = self.notebookLayers.GetPageIndex(page) pgnum_dict["mainnotebook"] = self.mainnotebook.GetPageIndex(mapdisplay) name = self.notebookLayers.GetPageText(pgnum_dict["layers"]) +======= + """Callback to check if user wants to close display""" + pgnum = self.notebookLayers.GetPageIndex(page) + name = self.notebookLayers.GetPageText(pgnum) +>>>>>>> 523219d6d4 (r.in.pdal: info.cpp also needs PDALCPPFLAGS (#1768)) caption = _("Close Map Display {}").format(name) if not askIfSaveWorkspace or ( askIfSaveWorkspace and self.workspace_manager.CanClosePage(caption) ): +<<<<<<< HEAD return pgnum_dict return None @@ -568,6 +639,17 @@ def CanCloseDisplay(askIfSaveWorkspace): # bind various events mapdisplay.onFocus.connect( lambda page=self.currentPage: self._onMapDisplayFocus(page), +======= + return pgnum + return None + + mapdisplay.canCloseDisplayCallback = CanCloseDisplay + + # bind various events + mapdisplay.Bind( + wx.EVT_ACTIVATE, + lambda event, page=self.currentPage: self._onMapDisplayFocus(page), +>>>>>>> 523219d6d4 (r.in.pdal: info.cpp also needs PDALCPPFLAGS (#1768)) ) mapdisplay.starting3dMode.connect( @@ -577,6 +659,10 @@ def CanCloseDisplay(askIfSaveWorkspace): ) mapdisplay.starting3dMode.connect(self.AddNvizTools) mapdisplay.ending3dMode.connect(self.RemoveNvizTools) +<<<<<<< HEAD +======= + mapdisplay.closingDisplay.connect(self._closePageNoEvent) +>>>>>>> 523219d6d4 (r.in.pdal: info.cpp also needs PDALCPPFLAGS (#1768)) # set default properties mapdisplay.SetProperties( @@ -596,6 +682,7 @@ def CanCloseDisplay(askIfSaveWorkspace): group="display", key="showCompExtent", subkey="enabled" ), ) +<<<<<<< HEAD def BuildPanes(self): """Build panes - toolbars as well as panels""" @@ -860,17 +947,19 @@ def _createMapDisplay(self, parent): """Set up Map Display""" # blank panel for testing self.mapdisplay = wx.Panel(parent=parent) +======= +>>>>>>> 523219d6d4 (r.in.pdal: info.cpp also needs PDALCPPFLAGS (#1768)) def BuildPanes(self): """Build panes - toolbars as well as panels""" # initialize all main widgets + self._createMapNotebook() self._createDataCatalog(parent=self) self._createDisplay(parent=self) self._createSearchModule(parent=self) self._createConsole(parent=self) self._createPythonShell(parent=self) - self._createMapDisplay(parent=self) self.toolbars = { "workspace": LMWorkspaceToolbar(parent=self), "tools": LMToolsToolbar(parent=self), @@ -912,8 +1001,8 @@ def BuildPanes(self): ) self._auimgr.AddPane( - self.mapdisplay, - aui.AuiPaneInfo().Name("map display").CenterPane().PaneBorder(True), + self.mapnotebook, + aui.AuiPaneInfo().Name("map display content").CenterPane().PaneBorder(True), ) self._auimgr.AddPane( @@ -1095,6 +1184,12 @@ def AddNvizTools(self, firstTime): .MinimizeButton(True) .MaximizeButton(True), ) +<<<<<<< HEAD +======= + + self._auimgr.GetPane("nviz").Show() + self._auimgr.Update() +>>>>>>> 523219d6d4 (r.in.pdal: info.cpp also needs PDALCPPFLAGS (#1768)) self._auimgr.GetPane("nviz").Show() self._auimgr.Update() @@ -1274,9 +1369,16 @@ def OnCBPageChanged(self, event): Also change active map notebook tab.""" self.currentPage = self.notebookLayers.GetCurrentPage() self.currentPageNum = self.notebookLayers.GetSelection() +<<<<<<< HEAD if hasattr(self.currentPage, "maptree") and self.mainnotebook.GetCurrentPage(): self.mainnotebook.SetSelectionToMainPage(self.GetMapDisplay()) +======= + try: + self.mapnotebook.SetSelection(self.GetMapDisplayIndex()) + except Exception: + pass +>>>>>>> 523219d6d4 (r.in.pdal: info.cpp also needs PDALCPPFLAGS (#1768)) event.Skip() @@ -1306,18 +1408,32 @@ def OnCBPageClosing(self, event): maptree = self.notebookLayers.GetPage(event.GetSelection()).maptree maptree.GetMapDisplay().CleanUp() +<<<<<<< HEAD self.mainnotebook.DeleteMainPage(self.GetMapDisplay()) +======= + self.mapnotebook.DeletePage(self.GetMapDisplayIndex()) +>>>>>>> 523219d6d4 (r.in.pdal: info.cpp also needs PDALCPPFLAGS (#1768)) maptree.Close(True) self.currentPage = None event.Skip() +<<<<<<< HEAD def _renamePageNoEvent(self, pgnum_dict, is_docked, text): if is_docked: self.mainnotebook.SetMainPageText( self.mainnotebook.GetPage(pgnum_dict["mainnotebook"]), text ) +======= + def _closePageNoEvent(self, page_index): + """Close page and destroy map display without + generating notebook page closing event""" + self.notebookLayers.Unbind(FN.EVT_FLATNOTEBOOK_PAGE_CLOSING) + self.notebookLayers.DeletePage(page_index) + self.notebookLayers.Bind(FN.EVT_FLATNOTEBOOK_PAGE_CLOSING, self.OnCBPageClosing) + self.mapnotebook.DeletePage(page_index) +>>>>>>> 523219d6d4 (r.in.pdal: info.cpp also needs PDALCPPFLAGS (#1768)) def _closePageNoEvent(self, pgnum_dict, is_docked): """If map display is docked, close page and destroy map display without @@ -1533,6 +1649,11 @@ def GetAllMapDisplays(self): """Get all (open) map displays""" return self.GetMapDisplay(onlyCurrent=False) + def GetMapDisplayIndex(self): + """Get the index of the currently active map display tab. + Can be different than index of related layertree.""" + return self.mapnotebook.GetPageIndex(self.GetMapDisplay()) + def GetLogWindow(self): """Gets console for command output and messages""" return self._gconsole @@ -2033,7 +2154,11 @@ def OnRenameDisplay(self, event): if dlg.ShowModal() == wx.ID_OK: name = dlg.GetValue() self.notebookLayers.SetPageText(page=self.currentPageNum, text=name) +<<<<<<< HEAD self.mainnotebook.SetMainPageText(page=self.GetMapDisplay(), text=name) +======= + self.mapnotebook.SetPageText(page_idx=self.GetMapDisplayIndex(), text=name) +>>>>>>> 523219d6d4 (r.in.pdal: info.cpp also needs PDALCPPFLAGS (#1768)) dlg.Destroy() def OnRasterRules(self, event): diff --git a/python/grass/jupyter/display.py b/python/grass/jupyter/display.py index 9725de55fff..d9891e9401a 100644 --- a/python/grass/jupyter/display.py +++ b/python/grass/jupyter/display.py @@ -12,8 +12,13 @@ # for details. import os +<<<<<<< HEAD from pathlib import Path +======= +import shutil +>>>>>>> 523219d6d4 (r.in.pdal: info.cpp also needs PDALCPPFLAGS (#1768)) from IPython.display import Image +import tempfile import grass.script as gs @@ -22,28 +27,64 @@ class GrassRenderer: Jupyter Notebooks.""" def __init__( - self, env=None, width=600, height=400, filename="map.png", text_size=12 + self, + height=400, + width=600, + filename=None, + env=None, + text_size=12, + renderer="cairo", ): +<<<<<<< HEAD """Initiates an instance of the GrassRenderer class.""" +======= + """Creates an instance of the GrassRenderer class. + + :param int height: height of map in pixels + :param int width: width of map in pixels + :param str filename: filename or path to save a PNG of map + :param str env: environment + :param int text_size: default text size, overwritten by most display modules + :param renderer: GRASS renderer driver (options: cairo, png, ps, html) + """ +>>>>>>> 523219d6d4 (r.in.pdal: info.cpp also needs PDALCPPFLAGS (#1768)) + + # Copy Environment if env: self._env = env.copy() else: self._env = os.environ.copy() - + # Environment Settings self._env["GRASS_RENDER_WIDTH"] = str(width) self._env["GRASS_RENDER_HEIGHT"] = str(height) +<<<<<<< HEAD self._env["GRASS_TEXT_SIZE"] = str(text_size) self._env["GRASS_RENDER_IMMEDIATE"] = "cairo" self._env["GRASS_RENDER_FILE"] = str(filename) +======= + self._env["GRASS_RENDER_TEXT_SIZE"] = str(text_size) + self._env["GRASS_RENDER_IMMEDIATE"] = renderer +>>>>>>> 523219d6d4 (r.in.pdal: info.cpp also needs PDALCPPFLAGS (#1768)) self._env["GRASS_RENDER_FILE_READ"] = "TRUE" - self._legend_file = Path(filename).with_suffix(".grass_vector_legend") - self._env["GRASS_LEGEND_FILE"] = str(self._legend_file) + # Create PNG file for map + # If not user-supplied, we will write it to a map.png in a + # temporary directory that we can delete later. We need + # this temporary directory for the legend anyways so we'll + # make it now + self._tmpdir = tempfile.TemporaryDirectory() - self._filename = filename + if filename: + self._filename = filename + else: + self._filename = os.path.join(self._tmpdir.name, "map.png") + # Set environment var for file + self._env["GRASS_RENDER_FILE"] = self._filename - self.run("d.erase") + # Create Temporary Legend File + self._legend_file = os.path.join(self._tmpdir.name, "legend.txt") + self._env["GRASS_LEGEND_FILE"] = str(self._legend_file) def run(self, module, **kwargs): """Run modules from "d." GRASS library""" diff --git a/raster/r.in.pdal/Makefile b/raster/r.in.pdal/Makefile index 05f021fae4c..59b72a52d74 100644 --- a/raster/r.in.pdal/Makefile +++ b/raster/r.in.pdal/Makefile @@ -14,6 +14,8 @@ include $(MODULE_TOPDIR)/include/Make/Module.make ======= $(OBJDIR)/main.o : EXTRA_CFLAGS += $(PDALCPPFLAGS) +$(OBJDIR)/info.o : EXTRA_CFLAGS += $(PDALCPPFLAGS) + $(OBJDIR)/grasslidarfilter.o : EXTRA_CFLAGS += $(PDALCPPFLAGS) >>>>>>> 9d4a079d2e (libcairodriver: enable Cairo with and without Fontconfig (#1697))