Bläddra i källkod

Add session initiations functions for Jupyter Notebooks (#1629)

* Create subpackage grass.jupyter.
* Add examples as an additional notebook.
* The API is experimental.
* The init function starts a session, but there is no way of ending it.
* The display function reflects the current practice in notebooks. It will be reworked during GSoC 2021.
Caitlin H 3 år sedan
förälder
incheckning
d1a8a690de

+ 1 - 0
.gitignore

@@ -41,3 +41,4 @@ mswindows/osgeo4w/package/
 mswindows/osgeo4w/setup*.hint
 mswindows/osgeo4w/vc/
 daag*.s
+doc/notebooks/.ipynb_checkpoints/

+ 113 - 0
doc/notebooks/jupyter_integration.ipynb

@@ -0,0 +1,113 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Improved Integration of GRASS and Jupyter\n",
+    "\n",
+    "As part of Google Summer of Code 2021, we've been working to shorten and simplify the launch of GRASS in Jupyter and imporve the map displays. You can find out more abou the project and follow the progress on the [GRASS wiki page](https://trac.osgeo.org/grass/wiki/GSoC/2021/JupyterAndGRASS).\n",
+    "\n",
+    "This notebook is designed to run in binder and demonstrate the usage of `grass.jupyter`, the new module of Jupyter-specific functions for GRASS."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "import os\n",
+    "import subprocess\n",
+    "import sys\n",
+    "from IPython.display import Image"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "gisbase = subprocess.check_output([\"grass\", \"--config\", \"path\"], text=True).strip()\n",
+    "os.environ[\"GISBASE\"] = gisbase\n",
+    "sys.path.append(os.path.join(gisbase, \"etc\", \"python\"))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import grass.script as gs\n",
+    "import grass.jupyter as gj"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Let's check our import by printing docstring for init()\n",
+    "gj.init?"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Start GRASS Session\n",
+    "gj.init(\"../../data/grassdata\", \"nc_basic_spm_grass7\", \"user1\")\n",
+    "\n",
+    "# Set default display settings\n",
+    "gj.display_settings()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Let's display the DTM of our sample area to ensure all's working\n",
+    "\n",
+    "# Set computational region to the study area.\n",
+    "gs.parse_command(\"g.region\", raster=\"elevation\", flags=\"pg\")\n",
+    "\n",
+    "# Draw elevation (DTM) to get an overview of the area.\n",
+    "gs.run_command(\"r.colors\", map=\"elevation\", color=\"elevation\")\n",
+    "gs.run_command(\"d.erase\")\n",
+    "gs.run_command(\"d.rast\", map=\"elevation\")\n",
+    "gs.run_command(\"d.legend\", raster=\"elevation\", at=(65, 90, 85, 90), fontsize=15, flags=\"b\", title=\"DTM\")\n",
+    "Image(filename=\"map.png\")"
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.8.5"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}

+ 1 - 1
python/grass/Makefile

@@ -5,7 +5,7 @@ include $(MODULE_TOPDIR)/include/Make/Python.make
 
 PYDIR = $(ETC)/python/grass
 
-SUBDIRS = app exceptions script ctypes grassdb temporal pygrass pydispatch imaging gunittest bandref
+SUBDIRS = app exceptions script ctypes grassdb temporal pygrass pydispatch imaging gunittest bandref jupyter
 
 default: $(PYDIR)/__init__.py
 	$(MAKE) subdirs

+ 19 - 0
python/grass/jupyter/Makefile

@@ -0,0 +1,19 @@
+MODULE_TOPDIR = ../../..
+
+include $(MODULE_TOPDIR)/include/Make/Other.make
+include $(MODULE_TOPDIR)/include/Make/Python.make
+
+DSTDIR = $(ETC)/python/grass/jupyter
+
+MODULES = setup
+
+PYFILES := $(patsubst %,$(DSTDIR)/%.py,$(MODULES) __init__)
+PYCFILES := $(patsubst %,$(DSTDIR)/%.pyc,$(MODULES) __init__)
+
+default: $(PYFILES) $(PYCFILES)
+
+$(DSTDIR):
+	$(MKDIR) $@
+
+$(DSTDIR)/%: % | $(DSTDIR)
+	$(INSTALL_DATA) $< $@

+ 1 - 0
python/grass/jupyter/__init__.py

@@ -0,0 +1 @@
+from .setup import *

+ 74 - 0
python/grass/jupyter/setup.py

@@ -0,0 +1,74 @@
+# MODULE:    grass.jupyter.setup
+#
+# AUTHOR(S): Caitlin Haedrich <caitlin DOT haedrich AT gmail>
+#
+# PURPOSE:   This module contains functions for launching a GRASS session
+#           in Jupyter Notebooks
+#
+# COPYRIGHT: (C) 2021 Caitlin Haedrich, and 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.
+
+import os
+
+import grass.script as gs
+import grass.script.setup as gsetup
+
+
+def _set_notebook_defaults():
+    """
+    This function sets several GRASS environment variables that are
+    important for GRASS to run smoothly in Jupyter.
+
+    It also allows GRASS to overwrite existing maps of the same name.
+    """
+    # We want functions to raise exceptions and see standard output of
+    # the modules in the notebook.
+    gs.set_raise_on_error(True)
+    gs.set_capture_stderr(True)
+
+    # Allow overwrite of existing maps
+    os.environ["GRASS_OVERWRITE"] = "1"
+
+
+def init(path, location, mapset):
+    """
+    This function initiates a GRASS session and sets GRASS
+    environment variables.
+
+    Inputs:
+        path - path to grass databases
+        location - name of GRASS location
+        mapset - name of mapset within location
+    """
+    # Create a GRASS GIS session.
+    gsetup.init(os.environ["GISBASE"], path, location, mapset)
+    # Set GRASS env. variables
+    _set_notebook_defaults()
+
+
+def display_settings(font="sans", driver="cairo"):
+    """
+    This function sets the display settings for a GRASS session
+    in Jupyter Notebooks.
+
+    Example Usage: display_settings(font="sans", driver="cairo")
+
+    Inputs:
+        font - specifies the font as either the name of a font from
+        $GISBASE/etc/fontcap (or alternative fontcap file specified by
+        GRASS_FONT_CAP), or alternatively the full path to a FreeType
+        font file.
+
+        driver - tell teh display library which driver to use
+            Possible values: "cairo", "png", "ps", "html"
+    """
+    # Set display font
+    os.environ["GRASS_FONT"] = font
+
+    # Set display modeules to render to a file (named map.png by
+    # default).
+    os.environ["GRASS_RENDER_IMMEDIATE"] = driver
+    os.environ["GRASS_RENDER_FILE_READ"] = "TRUE"