Skip to content

Commit

Permalink
Start with single example for table generation
Browse files Browse the repository at this point in the history
  • Loading branch information
annehaley committed Aug 30, 2024
1 parent 528834a commit 1a8f153
Show file tree
Hide file tree
Showing 6 changed files with 175 additions and 1 deletion.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ node_modules/
test/externaldata

docs/source/*
docs/format_examples
docs/format_table.rst
!docs/source/*.py
!docs/source/*.rst
docs/_build
Expand Down
29 changes: 29 additions & 0 deletions docs/format_examples_datastore.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import pooch
from pathlib import Path

EXAMPLES_FOLDER = Path('format_examples')

format_examples = [
dict(
name='TIFF (Tagged Image File Format)',
reference='https://www.itu.int/itudoc/itu-t/com16/tiff-fx/docs/tiff6.pdf',
examples=[
dict(
filename='utmsmall.tif',
url='https://github.com/OSGeo/gdal/raw/master/autotest/gcore/data/utmsmall.tif',
hash='f40dae6e8b5e18f3648e9f095e22a0d7027014bb463418d32f732c3756d8c54f',
),
],
),
]


def fetch_all():
for format_data in format_examples:
for example in format_data.get('examples', []):
pooch.retrieve(
url=example.get('url'),
known_hash=example.get('hash'),
fname=example.get('filename'),
path=EXAMPLES_FOLDER,
)
10 changes: 9 additions & 1 deletion docs/formats.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,15 @@ Preferred Extensions and Mime Types

Images can generally be read regardless of their name. By default, when opening an image with ``large_image.open()``, each tile source reader is tried in turn until one source can open the file. Each source lists preferred file extensions and mime types with a priority level. If the file ends with one of these extensions or has one of these mimetypes, the order that the source readers are tried is adjusted based on the specified priority.

The file extensions and mime types that are listed by the core sources that can affect source processing order are listed below. See ``large_image.listSources()`` for details about priority of the different source and the ``large_image.constants.SourcePriority`` for the priority meaning.
The file extensions and mime types that are listed by the core sources that can affect source processing order are listed below. See ``large_image.listSources()`` for details about priority of the different sources and the ``large_image.constants.SourcePriority`` for the priority meaning.

The following table describes the primary formats supported by ``large-image`` and the acceptable extensions for each format. This table also describes the ``large-image-source-*`` modules that can be used to read each format.

For a full list of all accepted extensions, see :ref:`extensions`.

.. include:: format_table.rst

.. _extensions:

Extensions
~~~~~~~~~~
Expand Down
131 changes: 131 additions & 0 deletions docs/generate_format_table.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import large_image
from pathlib import Path
from format_examples_datastore import EXAMPLES_FOLDER, format_examples, fetch_all


TABLE_FILE = Path('./format_table.rst')


def generate():
fetch_all()
large_image.tilesource.loadTileSources()
available_tilesources = large_image.tilesource.AvailableTileSources

results = []
for format_data in format_examples:
name = format_data.get('name')
reference = format_data.get('reference')
for example in format_data.get('examples', []):
filename = example.get('filename')
url = example.get('url')
extension = filename.split('.')[-1]
filepath = Path(EXAMPLES_FOLDER, filename)
print(f'Evaluating {filename}. ')
for tilesource_name, readable in large_image.canReadList(filepath):
tilesource = available_tilesources.get(tilesource_name)
if readable and tilesource:
try:
s = tilesource(filepath)
results.append(
dict(
name=name,
reference=reference,
extension=extension,
filename=filename,
url=url,
tilesource=tilesource_name,
# TODO: find a way to determine if multiframe is allowed
multiframe=True,
geospatial=hasattr(s, 'projection'),
write=hasattr(s, 'addTile'),
associated=(
s.getAssociatedImagesList
is not large_image.tilesource.FileTileSource.getAssociatedImagesList
),
)
)
except large_image.exceptions.TileSourceError:
pass

# combine rows that only differ on tilesource
table_rows = {}
for result in results:
row_base_key = result.get('extension')
row_key_index = 0
row_key = f'{row_base_key}_{row_key_index}'
while row_key in table_rows:
if all(
[
value == table_rows[row_key][key]
for key, value in result.items()
if key != 'tilesource'
]
):
if not isinstance(table_rows[row_key]['tilesource'], list):
table_rows[row_key]['tilesource'] = [
table_rows[row_key]['tilesource'],
]
table_rows[row_key]['tilesource'] = [
*table_rows[row_key]['tilesource'],
result['tilesource'],
]
break
else:
row_key_index += 1
row_key = f'{row_base_key}_{row_key_index}'
if row_key not in table_rows:
table_rows[row_key] = result

columns = [
dict(label='Format', key='name'),
dict(label='Extension', key='extension'),
dict(label='Tile Source', key='tilesource'),
dict(label='Multiframe Allowed', key='multiframe'),
dict(label='Geospatial Allowed', key='geospatial'),
dict(label='Write Allowed', key='write'),
dict(label='Associated Images Allowed', key='associated'),
dict(label='Example File', key='url'),
]
lines = [
'.. list-table:: Primary Formats',
' :header-rows: 1',
'',
]
for index, col in enumerate(columns):
label = col.get('label')
if index == 0:
lines.append(f' * - {label}')
else:
lines.append(f' - {label}')
for row_key, row in table_rows.items():
lines.append('') # blank line for ref separation
lines.append(f' .. _{row_key}:')
for index, col in enumerate(columns):
col_key = col.get('key')
col_value = row.get(col_key)
if col_key == 'extension':
# format extensions with monospace font
col_value = f'``{col_value}``'
elif col_key == 'name':
# include reference as link on format name
reference_link = row.get('reference')
if reference_link:
col_value = f'`{col_value} <{reference_link}>`_'
elif col_key == 'url':
# reformat example download link
col_value = (
f'`Download example {row.get("extension")} file <{col_value}>`_'
)
elif col_key == 'tilesource':
# join tilesource lists with commas
if isinstance(col_value, list):
col_value = ', '.join(col_value)

if index == 0:
lines.append(f' * - {col_value} :ref:`🔗 <{row_key}>`')
else:
lines.append(f' - {col_value}')
lines.append('')
with open(TABLE_FILE, 'w') as f:
f.write('\n'.join(lines))
print('Wrote format table at', str(TABLE_FILE))
3 changes: 3 additions & 0 deletions docs/make_docs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ set -e
cd "$(dirname $0)"
stat make_docs.sh

# generate file format table
python -c "import generate_format_table;generate_format_table.generate()"

# git clean -fxd .

mkdir -p ../build/docs-work
Expand Down
1 change: 1 addition & 0 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,7 @@ deps =
sphinx-rtd-theme
sphinxcontrib-jquery
sphinxcontrib-mermaid
pooch
changedir = {toxinidir}/docs
allowlist_externals =
make_docs.sh
Expand Down

0 comments on commit 1a8f153

Please sign in to comment.