Skip to content

Commit

Permalink
Merge pull request #11252 from rouault/doc_python_notebooks
Browse files Browse the repository at this point in the history
Doc: Python: move files around and add executable examples using myst-nb
  • Loading branch information
rouault authored Nov 18, 2024
2 parents c9731d1 + 92ecc59 commit 8f0abd4
Show file tree
Hide file tree
Showing 17 changed files with 218 additions and 27 deletions.
1 change: 1 addition & 0 deletions doc/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ recommonmark
sphinx-markdown-tables
sphinxcontrib-spelling
sphinxcontrib-jquery
myst_nb
13 changes: 2 additions & 11 deletions doc/source/api/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -81,18 +81,9 @@ API
----------

.. toctree::
:maxdepth: 1
:maxdepth: 2

python_bindings
python/osgeo
python/raster_api
python/vector_api
python/spatial_ref_api
python/mdim_api
python/utilities
python/general
python_gotchas
python_samples
python/index


`Java API <../java/index.html>`_
Expand Down
Binary file added doc/source/api/python/data/byte.tif
Binary file not shown.
4 changes: 2 additions & 2 deletions doc/source/api/python/general.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
.. _python_general:

Python General API
==================
General API
===========

Configuration Management
------------------------
Expand Down
22 changes: 22 additions & 0 deletions doc/source/api/python/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
.. _python_api:

================================================================================
Python API
================================================================================

.. only:: not latex

.. toctree::
:maxdepth: 2

python_bindings
python_examples
osgeo
raster_api
vector_api
spatial_ref_api
mdim_api
utilities
general
python_gotchas
python_samples
4 changes: 2 additions & 2 deletions doc/source/api/python/mdim_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
.. _python_mdim_api:

Python Multi-dimensional array API
==================================
Multi-dimensional array API
===========================

.. autoclass:: osgeo.gdal.Group
:members:
Expand Down
4 changes: 2 additions & 2 deletions doc/source/api/python/osgeo.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
.. _python_osgeo:

GDAL Python submodules
======================
Submodules
==========


Submodules
Expand Down
File renamed without changes.
121 changes: 121 additions & 0 deletions doc/source/api/python/python_examples.myst
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
---
jupytext:
formats: md:myst
text_representation:
extension: .md
format_name: myst
kernelspec:
display_name: Python 3
language: python
name: python3
---

# Examples

## Getting information on a raster dataset using dedicated methods

The following snippet uses individual API methods to retrieve characters of
a GDAL raster dataset and its bands.

```{code-cell}

from osgeo import gdal
import json

gdal.UseExceptions()

ds = gdal.Open("data/byte.tif")
print(f"Width: {ds.RasterXSize}")
print(f"Height: {ds.RasterYSize}")
print(f"Number of bands: {ds.RasterCount}")
```

```{code-cell}
srs = ds.GetSpatialRef()
srs_unit = ""
if srs:
srs_as_projjson = json.loads(srs.ExportToPROJJSON())
print("SRS:")
srs_type = srs_as_projjson["type"]
print(f" Type: {srs_type}")
name = srs_as_projjson["name"]
print(f" Name: {name}")
if "id" in srs_as_projjson:
id = srs_as_projjson["id"]
authority = id["authority"]
code = id["code"]
print(f" Id: {authority}:{code}")
srs_unit = " " + srs_as_projjson["coordinate_system"]["axis"][0]["unit"]
```

```{code-cell}
geotransform = ds.GetGeoTransform()
if geotransform[2] == 0 and geotransform[4] == 0:
print(f"Upper-left corner georeferenced position: X={geotransform[0]}{srs_unit}, Y={geotransform[3]}{srs_unit}")
print(f"Horizontal resolution: {geotransform[1]}{srs_unit}")
print(f"Vertical resolution: {geotransform[5]}{srs_unit} (negative value indicates a north-up image)")
else:
print(f"Geotransformation matrix: {geotransform}")
print(f"Metadata: {ds.GetMetadata()}")
```

```{code-cell}
for idx, band in enumerate(ds):
print(f"Band {idx+1}:")
print(f" Data type: {gdal.GetDataTypeName(band.DataType)}")
block_width, block_height = band.GetBlockSize()
print(f" Block width: {block_width}")
print(f" Block height: {block_height}")
print(f" Metadata: {band.GetMetadata()}")
```

```{code-cell}
:tags: [remove-output]

# Explicitly close the dataset. May be needed in creation/update scenarios, to
# make sure all data is properly flushed to storage, or even in read-only
# scenarios, if you want to delete the file afterwards (on Windows).
# You may also use a context manager with "with gdal.Open(...) as ds" as shown
# in later examples.
ds.Close()
```

## Getting information on a raster dataset using gdal.Info()

The following snippet uses the {py:func}`osgeo.gdal.Info()` method to retrieve characters of
a GDAL raster dataset and its bands, as a JSON document.

```{code-cell}
:tags: [hide-output]

from osgeo import gdal
import pprint

gdal.UseExceptions()

with gdal.Open("data/byte.tif") as ds:
info = gdal.Info(ds, format='json')
del info["stac"] # to avoid cluttering below output
pprint.pprint(info, indent=2, width=100)
```

## Reading a whole raster as a numpy array

The following snippet uses the {py:func}`osgeo.gdal.Dataset.ReadAsArray()`
method to retrieve the pixel values of all the bands of a dataset as a
[numpy array](https://numpy.org/doc/stable/reference/generated/numpy.array.html).

A 2D array is returned for a single band image. A 3D array, with first dimension
being the band one, is returned for images with multiple bands.

```{code-cell}
:tags: [hide-output]

from osgeo import gdal

gdal.UseExceptions()

with gdal.Open("data/byte.tif") as ds:
array = ds.ReadAsArray()
print(array)
```
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
.. _python_gotchas:

================================================================================
Python Gotchas in the GDAL and OGR Python Bindings
Gotchas in the GDAL and OGR Python Bindings
================================================================================

This page lists aspects of GDAL's and OGR's Python bindings that may catch Python programmers by surprise.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
.. _python_samples:

================================================================================
Python Sample scripts
Sample scripts
================================================================================

The following are sample scripts intended to give an idea how to use the
Expand Down
4 changes: 2 additions & 2 deletions doc/source/api/python/raster_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
.. _python_raster_api:

Python Raster API
=================
Raster API
==========

This page contains classes, methods, functions that relate to the GDAL :ref:`raster_data_model`:

Expand Down
4 changes: 2 additions & 2 deletions doc/source/api/python/spatial_ref_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
.. _python_spatial_ref_api:

Python Spatial Reference System API
===================================
Spatial Reference System API
============================

This page contains classes, methods and functions that relate to spatial reference systems:

Expand Down
4 changes: 2 additions & 2 deletions doc/source/api/python/utilities.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
.. _python_utilities:

Python Utilities
================
Utilities API
=============

Raster Utilities
----------------
Expand Down
4 changes: 2 additions & 2 deletions doc/source/api/python/vector_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
.. _python_vector_api:

Python Vector API
=================
Vector API
==========

This page contains classes, methods, functions that relate to the GDAL :ref:`vector_data_model`. The :py:class:`Driver` and :py:class:`Dataset` classes, which applies to both vector and raster data, are documented with the :ref:`python_raster_api`.

Expand Down
15 changes: 15 additions & 0 deletions doc/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
"sphinx.ext.napoleon",
"sphinxcontrib.jquery",
"sphinxcontrib.spelling",
"myst_nb",
]

# Add any paths that contain templates here, relative to this directory.
Expand All @@ -84,6 +85,7 @@
"substitutions.rst",
"programs/options/*.rst",
"api/python/modules.rst",
"gdal_rtd/README.md",
]

# Prevents double hyphen (--) to be replaced by Unicode long dash character
Expand Down Expand Up @@ -112,6 +114,12 @@
.. |offline-download| replace:: {offline_download_text}
"""

source_suffix = {
".rst": "restructuredtext",
".ipynb": "myst-nb",
".myst": "myst-nb",
}

# -- Options for HTML output -------------------------------------------------

# The theme to use for HTML and HTML Help pages. See the documentation for
Expand Down Expand Up @@ -577,3 +585,10 @@
spelling_ignore_contributor_names = False

spelling_word_list_filename = ["spelling_wordlist.txt"]

# -- myst-nb --------------------------------------------------

# Sets `text/plain` as the highest priority for `spelling` output.
nb_mime_priority_overrides = [
("spelling", "text/plain", 0),
]
41 changes: 41 additions & 0 deletions doc/source/development/dev_documentation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -407,3 +407,44 @@ Use ``describe`` to document create parameters::
.. describe:: WORLDFILE=YES

Force the generation of an associated ESRI world file (with the extension .wld).

MyST-NB - Executable notebooks
##############################

Quoting `MyST-NB documentation <https://myst-nb.readthedocs.io/en/latest/index.html>`__,
"MyST-NB is a module within the Executable Books Project, an international
collaboration to build open source tools that facilitate publishing computational
narratives using the Jupyter ecosystem. It is also a core component of Jupyter Book."

The documentation is written in a special markdown dialect, MyST Markdown,
that can include code cells:

.. code-block:: markdown
```{code-cell}
:tags: [hide-output]
from osgeo import gdal
import pprint
gdal.UseExceptions()
with gdal.Open("data/byte.tif") as ds:
info = gdal.Info(ds, format='json')
del info["stac"] # to avoid cluttering below output
pprint.pprint(info, indent=2, width=100)
```
See :file:`doc/source/api/python/python_examples.myst` for an example.

Consult how to author `text-based notebooks <https://myst-nb.readthedocs.io/en/latest/authoring/text-notebooks.html>`__
for more details.`

Building full GDAL documentation, even in incremental mode, is rather slow.
It is possible to partly render to HTML a MyST file with:

.. code-block:: shell
$ mystnb-docutils-html5 --nb-read-as-md=true source/api/python/python_examples.myst > out.html
You will get some warnings, but executable run will be executed and rendered.

0 comments on commit 8f0abd4

Please sign in to comment.