From 4612324390bc50165e5735c61b16fee850ebbb2d Mon Sep 17 00:00:00 2001 From: <> Date: Tue, 25 Jul 2023 15:30:17 +0000 Subject: [PATCH] Deployed f9ea9b9 with MkDocs version: 1.4.3 --- .nojekyll | 0 404.html | 429 ++ API/index.html | 604 ++ Advanced/index.html | 639 ++ CLI/index.html | 667 ++ Is_it_a_COG/index.html | 720 ++ assets/images/favicon.png | Bin 0 -> 1870 bytes assets/javascripts/bundle.220ee61c.min.js | 29 + assets/javascripts/bundle.220ee61c.min.js.map | 8 + assets/javascripts/lunr/min/lunr.ar.min.js | 1 + assets/javascripts/lunr/min/lunr.da.min.js | 18 + assets/javascripts/lunr/min/lunr.de.min.js | 18 + assets/javascripts/lunr/min/lunr.du.min.js | 18 + assets/javascripts/lunr/min/lunr.es.min.js | 18 + assets/javascripts/lunr/min/lunr.fi.min.js | 18 + assets/javascripts/lunr/min/lunr.fr.min.js | 18 + assets/javascripts/lunr/min/lunr.hi.min.js | 1 + assets/javascripts/lunr/min/lunr.hu.min.js | 18 + assets/javascripts/lunr/min/lunr.hy.min.js | 1 + assets/javascripts/lunr/min/lunr.it.min.js | 18 + assets/javascripts/lunr/min/lunr.ja.min.js | 1 + assets/javascripts/lunr/min/lunr.jp.min.js | 1 + assets/javascripts/lunr/min/lunr.kn.min.js | 1 + assets/javascripts/lunr/min/lunr.ko.min.js | 1 + assets/javascripts/lunr/min/lunr.multi.min.js | 1 + assets/javascripts/lunr/min/lunr.nl.min.js | 18 + assets/javascripts/lunr/min/lunr.no.min.js | 18 + assets/javascripts/lunr/min/lunr.pt.min.js | 18 + assets/javascripts/lunr/min/lunr.ro.min.js | 18 + assets/javascripts/lunr/min/lunr.ru.min.js | 18 + assets/javascripts/lunr/min/lunr.sa.min.js | 1 + .../lunr/min/lunr.stemmer.support.min.js | 1 + assets/javascripts/lunr/min/lunr.sv.min.js | 18 + assets/javascripts/lunr/min/lunr.ta.min.js | 1 + assets/javascripts/lunr/min/lunr.te.min.js | 1 + assets/javascripts/lunr/min/lunr.th.min.js | 1 + assets/javascripts/lunr/min/lunr.tr.min.js | 18 + assets/javascripts/lunr/min/lunr.vi.min.js | 1 + assets/javascripts/lunr/min/lunr.zh.min.js | 1 + assets/javascripts/lunr/tinyseg.js | 206 + assets/javascripts/lunr/wordcut.js | 6708 +++++++++++++++++ .../workers/search.74e28a9f.min.js | 42 + .../workers/search.74e28a9f.min.js.map | 8 + assets/stylesheets/main.eebd395e.min.css | 1 + assets/stylesheets/main.eebd395e.min.css.map | 1 + assets/stylesheets/palette.ecc896b0.min.css | 1 + .../stylesheets/palette.ecc896b0.min.css.map | 1 + contributing/index.html | 548 ++ css/extra.css | 5 + index.html | 653 ++ profile/index.html | 601 ++ release-notes/index.html | 1903 +++++ search/search_index.json | 1 + sitemap.xml | 43 + sitemap.xml.gz | Bin 0 -> 283 bytes 55 files changed, 14103 insertions(+) create mode 100644 .nojekyll create mode 100644 404.html create mode 100644 API/index.html create mode 100644 Advanced/index.html create mode 100644 CLI/index.html create mode 100644 Is_it_a_COG/index.html create mode 100644 assets/images/favicon.png create mode 100644 assets/javascripts/bundle.220ee61c.min.js create mode 100644 assets/javascripts/bundle.220ee61c.min.js.map create mode 100644 assets/javascripts/lunr/min/lunr.ar.min.js create mode 100644 assets/javascripts/lunr/min/lunr.da.min.js create mode 100644 assets/javascripts/lunr/min/lunr.de.min.js create mode 100644 assets/javascripts/lunr/min/lunr.du.min.js create mode 100644 assets/javascripts/lunr/min/lunr.es.min.js create mode 100644 assets/javascripts/lunr/min/lunr.fi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.fr.min.js create mode 100644 assets/javascripts/lunr/min/lunr.hi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.hu.min.js create mode 100644 assets/javascripts/lunr/min/lunr.hy.min.js create mode 100644 assets/javascripts/lunr/min/lunr.it.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ja.min.js create mode 100644 assets/javascripts/lunr/min/lunr.jp.min.js create mode 100644 assets/javascripts/lunr/min/lunr.kn.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ko.min.js create mode 100644 assets/javascripts/lunr/min/lunr.multi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.nl.min.js create mode 100644 assets/javascripts/lunr/min/lunr.no.min.js create mode 100644 assets/javascripts/lunr/min/lunr.pt.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ro.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ru.min.js create mode 100644 assets/javascripts/lunr/min/lunr.sa.min.js create mode 100644 assets/javascripts/lunr/min/lunr.stemmer.support.min.js create mode 100644 assets/javascripts/lunr/min/lunr.sv.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ta.min.js create mode 100644 assets/javascripts/lunr/min/lunr.te.min.js create mode 100644 assets/javascripts/lunr/min/lunr.th.min.js create mode 100644 assets/javascripts/lunr/min/lunr.tr.min.js create mode 100644 assets/javascripts/lunr/min/lunr.vi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.zh.min.js create mode 100644 assets/javascripts/lunr/tinyseg.js create mode 100644 assets/javascripts/lunr/wordcut.js create mode 100644 assets/javascripts/workers/search.74e28a9f.min.js create mode 100644 assets/javascripts/workers/search.74e28a9f.min.js.map create mode 100644 assets/stylesheets/main.eebd395e.min.css create mode 100644 assets/stylesheets/main.eebd395e.min.css.map create mode 100644 assets/stylesheets/palette.ecc896b0.min.css create mode 100644 assets/stylesheets/palette.ecc896b0.min.css.map create mode 100644 contributing/index.html create mode 100644 css/extra.css create mode 100644 index.html create mode 100644 profile/index.html create mode 100644 release-notes/index.html create mode 100644 search/search_index.json create mode 100644 sitemap.xml create mode 100644 sitemap.xml.gz diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/404.html b/404.html new file mode 100644 index 00000000..5e792e70 --- /dev/null +++ b/404.html @@ -0,0 +1,429 @@ + + + + + + + + + + + + + + + + + + + + rio-cogeo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ +

404 - Not found

+ +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/API/index.html b/API/index.html new file mode 100644 index 00000000..0a9845c6 --- /dev/null +++ b/API/index.html @@ -0,0 +1,604 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Application programming interface (API) - rio-cogeo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

Application programming interface (API)

+ +

rio-cogeo can also be integrated directly in your custom script. See rio_cogeo.cogeo.cog_translate function.

+

e.g:

+

from rio_cogeo.cogeo import cog_translate
+
+def _translate(src_path, dst_path, profile="webp", profile_options={}, **options):
+    """Convert image to COG."""
+    # Format creation option (see gdalwarp `-co` option)
+    output_profile = cog_profiles.get(profile)
+    output_profile.update(dict(BIGTIFF="IF_SAFER"))
+    output_profile.update(profile_options)
+
+    # Dataset Open option (see gdalwarp `-oo` option)
+    config = dict(
+        GDAL_NUM_THREADS="ALL_CPUS",
+        GDAL_TIFF_INTERNAL_MASK=True,
+        GDAL_TIFF_OVR_BLOCKSIZE="128",
+    )
+
+    cog_translate(
+        src_path,
+        dst_path,
+        output_profile,
+        config=config,
+        in_memory=False,
+        quiet=True,
+        **options,
+    )
+    return True
+
+ref: github.com/developmentseed/cogeo-watchbot/blob/81df27470dd2eb7032d512c35af853b006d1c035/app/translator.py#L34-L56

+

Using the API with in MemoryFile

+
    +
  1. Create COG from numpy array +
    import numpy
    +
    +import mercantile
    +
    +from rasterio.io import MemoryFile
    +from rasterio.transform import from_bounds
    +
    +from rio_cogeo.cogeo import cog_translate
    +from rio_cogeo.profiles import cog_profiles
    +
    +# Create GeoTIFF profile
    +bounds = mercantile.bounds(mercantile.Tile(0,0,0))
    +
    +# Rasterio uses numpy array of shape of `(bands, height, width)`
    +width = 1024
    +height = 1024
    +nbands = 3
    +
    +img_array = tile = numpy.random.rand(nbands, height, width).astype(numpy.float32)
    +
    +src_transform = from_bounds(*bounds, width=width, height=height)
    +
    +src_profile = dict(
    +    driver="GTiff",
    +    dtype="float32",
    +    count=nbands,
    +    height=height,
    +    width=width,
    +    crs="epsg:4326",
    +    transform=src_transform,
    +)
    +
    +
    +with MemoryFile() as memfile:
    +    with memfile.open(**src_profile) as mem:
    +        # Populate the input file with numpy array
    +        mem.write(img_array)
    +
    +        dst_profile = cog_profiles.get("deflate")
    +        cog_translate(
    +            mem,
    +            "my-output-cog.tif",
    +            dst_profile,
    +            in_memory=True,
    +            quiet=True,
    +        )
    +
  2. +
  3. Create output COG in Memory
  4. +
+
from rasterio.io import MemoryFile
+
+from rio_cogeo.cogeo import cog_translate
+from rio_cogeo.profiles import cog_profiles
+
+from boto3.session import Session as boto3_session
+
+dst_profile = cog_profiles.get("deflate")
+
+with MemoryFile() as mem_dst:
+    # Important, we pass `mem_dst.name` as output dataset path
+    cog_translate("my-input-file.tif", mem_dst.name, dst_profile, in_memory=True)
+
+    # You can then use the memoryfile to do something else like
+    # upload to AWS S3
+    client = boto3_session.client("s3")
+    client.upload_fileobj(mem_dst, "my-bucket", "my-key")
+
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/Advanced/index.html b/Advanced/index.html new file mode 100644 index 00000000..26c030f4 --- /dev/null +++ b/Advanced/index.html @@ -0,0 +1,639 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Advanced Topics - rio-cogeo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

Advanced Topics

+ +

Web-Optimized COG

+

rio-cogeo provide a --web-optimized option which aims to create a web-tiling friendly COG.

+

Output dataset features:

+
    +
  • bounds and internal tiles aligned with web-mercator grid.
  • +
  • raw data and overviews resolution match mercator zoom level resolution.
  • +
+

Important

+

Because it will certainly create a larger file (with padding tiles on the side of the file), a nodata value, an alpha band or an internal mask should +be present in the input dataset. If not the original data will be surrounded by black (0) data.

+

Internal tile size

+

By default rio cogeo will create a dataset with 512x512 internal tile size. +This can be updated by passing --co BLOCKXSIZE=64 --co BLOCKYSIZE=64 options.

+

Web tiling optimization

+

Creating a Web-Optimized COG, means you'll get a file which is perfectly aligned (bounds and internal tiles) with the mercator grid and with resolution (for the raw data and overview) which map the mercator zoom level resolution. This enable to reduce the number of GET request a dynamic tiling service needs to do to create a map tile from your COG.

+

if the input dataset is not aligned to web mercator grid, the tiler will need +to fetch multiple internal tiles.

+

Overview levels

+

By default rio cogeo will calculate the optimal overview level based on dataset +size and internal tile size (overview should not be smaller than internal tile +size (e.g 512px). Overview level will be translated to decimation level of +power of two:

+
overview_level = 3
+overviews = [2 ** j for j in range(1, overview_level + 1)]
+print(overviews)
+[2, 4, 8]
+
+

Band metadata

+

By default rio cogeo DO NOT forward band metadata (e.g statistics) to the output dataset.

+
$ gdalinfo my_file.tif
+...
+Band 1 Block=576x1 Type=Float64, ColorInterp=Gray
+  NoData Value=999999986991104
+  Unit Type: mol mol-1
+  Metadata:
+    long_name=CO2 Dry-Air Column Average
+    missing_value=9.9999999e+14
+    NETCDF_DIM_time=0
+    NETCDF_VARNAME=XCO2MEAN
+    units=mol mol-1
+    _FillValue=9.9999999e+14
+
+$ rio cogeo my_file.tif my_cog.tif --blocksize 256
+
+$ gdalinfo my_cog.tif
+...
+Band 1 Block=256x256 Type=Float64, ColorInterp=Gray
+  NoData Value=999999986991104
+  Overviews: 288x181
+
+

You can use --forward-band-tags to forwards the band metadata to output dataset.

+
$ rio cogeo create my_file.tif my_cog.tif --blocksize 256 --forward-band-tags
+$ gdalinfo my_cog.tif
+...
+Band 1 Block=256x256 Type=Float64, ColorInterp=Gray
+  NoData Value=999999986991104
+  Overviews: 288x181
+  Metadata:
+    long_name=CO2 Dry-Air Column Average
+    missing_value=9.9999999e+14
+    NETCDF_DIM_time=0
+    NETCDF_VARNAME=XCO2MEAN
+    units=mol mol-1
+    _FillValue=9.9999999e+14
+
+

Nodata, Alpha and Mask

+

By default rio-cogeo will forward any nodata value or alpha channel to the +output COG.

+

If your dataset type is Byte or Unit16, you could use internal bit mask +(with the --add-mask option) to replace the Nodata value or Alpha band in +output dataset (supported by most GDAL based backends).

+

Note: when adding a mask with an input dataset having an alpha band you'll +need to use the bidx options to remove it from the output dataset.

+
# Replace the alpha band by an internal mask
+$ rio cogeo mydataset_withalpha.tif mydataset_withmask.tif --cog-profile raw --add-mask --bidx 1,2,3
+
+

Important

+

Using internal nodata value with lossy compression (webp, jpeg) is not +recommended. Please use internal masking (or alpha band if using webp).

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/CLI/index.html b/CLI/index.html new file mode 100644 index 00000000..1237eebf --- /dev/null +++ b/CLI/index.html @@ -0,0 +1,667 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Command-line interface (CLI) - rio-cogeo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

Command-line interface (CLI)

+ +

rio-cogeo modules adds a cogeo sub-command to your rasterio (rio) CLI. Three (3) commands are then available: create, info and validate.

+
$ rio cogeo --help
+  Usage: rio cogeo [OPTIONS] COMMAND [ARGS]...
+
+  Rasterio cogeo subcommands.
+
+  Options:
+    --version  Show the version and exit.
+    --help     Show this message and exit.
+
+  Commands:
+    create    Create COGEO
+    info      Lists information about a raster dataset.
+    validate  Validate COGEO
+
+

Create

+
$ rio cogeo create --help
+  Usage: rio cogeo create [OPTIONS] INPUT OUTPUT
+
+    Create Cloud Optimized Geotiff.
+
+  Options:
+    --bidx, -b                        Band indexes to copy.
+    --cog-profile, -p                 CloudOptimized GeoTIFF profile (default: deflate). [jpeg|webp|zstd|lzw|deflate|packbits|lzma|lerc|lerc_deflate|lerc_zstd|raw]
+    --nodata                          Set nodata masking values for input dataset.
+    --add-mask                        Force output dataset creation with an internal mask (convert alpha band or nodata to mask).
+    --blocksize                       Overwrite profile's tile size.
+    --dtype, -t                       Output data type. [ubyte|uint8|uint16|int16|uint32|int32|float32|float64]
+    --overview-level                  Overview level (if not provided, appropriate overview level will be selected until the smallest overview is smaller than the value of the internal blocksize)
+    --overview-resampling             Overview creation resampling algorithm (default: nearest).  [nearest|bilinear|cubic|cubic_spline|lanczos|average|mode|gauss]
+    --overview-blocksize              Overview's internal tile size (default defined by GDAL_TIFF_OVR_BLOCKSIZE env or 128)
+    --web-optimized, -w               Create COGEO optimized for Web.
+    --zoom-level-strategy             Strategy to determine zoom level (default: auto).  [lower|upper|auto]
+    --zoom-level                      Zoom level number for the highest resolution. If this option is specified, `--zoom-level-strategy` is ignored.
+    --aligned-levels                  Number of overview levels for which GeoTIFF tile and tiles defined in the tiling scheme match.
+    --resampling, -r                  Resampling algorithm (default: nearest). Will only be applied with the `--web-optimized` option.  [nearest|bilinear|cubic|cubic_spline|lanczos|average|mode|max|min|med|q1|q3|sum]
+    --in-memory / --no-in-memory      Force processing raster in memory / not in memory (default: process in memory if smaller than 120 million pixels)
+    --allow-intermediate-compression  Allow intermediate file compression to reduce memory/disk footprint.
+    --forward-band-tags               Forward band tags to output bands.
+    --forward-ns-tags                 Forward namespaced tags to output dataset.
+    --threads                         Number of worker threads for multi-threaded compression (default: ALL_CPUS)
+    --use-cog-driver                  Use GDAL COG Driver (require GDAL>=3.1).
+    --tms PATH                        Path to TileMatrixSet JSON file.
+    --co, --profile                   Driver specific creation options. See the documentation for the selected output driver for more information.
+    --config                          GDAL configuration options.
+    --quiet, -q                       Remove progressbar and other non-error output.
+    --help                            Show this message and exit.
+
+

Validate

+
$ rio cogeo validate --help
+Usage: rio cogeo validate [OPTIONS] INPUT
+
+  Validate Cloud Optimized Geotiff.
+
+Options:
+  --strict             Treat warnings as errors.
+  --config NAME=VALUE  GDAL configuration options.
+  --help               Show this message and exit.
+
+

The strict options will treat warnings (e.g missing overviews) as errors.

+

Using the --config option can be useful to restrict GDAL environment. By default GDAL will check for external files (such as overviews), which could make a COG invalid. To force GDAL to only consider the input file you can use --config GDAL_DISABLE_READDIR_ON_OPEN=EMPTY_DIR.

+

e.g: +

$ rio cogeo validate s3://bucket/geo.tif --config GDAL_DISABLE_READDIR_ON_OPEN=EMPTY_DIR --config AWS_NO_SIGN_REQUEST=YES
+

+

Info

+

(extended version or rio info).

+
$ rio cogeo info --help
+Usage: rio cogeo info [OPTIONS] INPUT
+
+  Dataset info.
+
+Options:
+  --json  Print as JSON.
+  --help  Show this message and exit.
+
+

Examples

+
# Create a COGEO with DEFLATE compression (Using default `Deflate` profile)
+$ rio cogeo create mydataset.tif mydataset_jpeg.tif
+
+# Validate COGEO
+$ rio cogeo validate mydataset_jpeg.tif
+
+# Create a COGEO with JPEG profile and the first 3 bands of the data and add internal mask
+$ rio cogeo create mydataset.tif mydataset_jpeg.tif -b 1,2,3 --add-mask --cog-profile jpeg
+
+# List Raster info
+$ rio cogeo info mydataset_jpeg.tif
+Driver: GTiff
+File: mydataset_jpeg.tif
+COG: True
+Compression: DEFLATE
+ColorSpace: None
+
+Profile
+    Width:            10980
+    Height:           10980
+    Bands:            1
+    Tiled:            True
+    Dtype:            uint16
+    NoData:           0.0
+    Alpha Band:       False
+    Internal Mask:    False
+    Interleave:       BAND
+    Colormap:         False
+
+Geo
+    Crs:              EPSG:32634
+    Origin:           (699960.0, 3600000.0)
+    Resolution:       (10.0, -10.0)
+    BoundingBox:      (699960.0, 3490200.0, 809760.0, 3600000.0)
+    MinZoom:          10
+    MaxZoom:          19
+
+IFD
+    Id      Size           BlockSize     Decimation
+    0       10980x10980    1024x1024     0
+    1       5490x5490      128x128       2
+    2       2745x2745      128x128       4
+    3       1373x1373      128x128       8
+    4       687x687        128x128       16
+
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/Is_it_a_COG/index.html b/Is_it_a_COG/index.html new file mode 100644 index 00000000..3e0a910c --- /dev/null +++ b/Is_it_a_COG/index.html @@ -0,0 +1,720 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + How To - rio-cogeo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

How to recognize a COG and how to create a proper one!

+

Requirements

+
    +
  • python 3.7
  • +
  • rio-cogeo
  • +
+

$ pip install rio-cogeo

+

The COG Specification is pretty basic

+
+

A cloud optimized GeoTIFF is a regular GeoTIFF file, aimed at being hosted on a HTTP file server, whose internal organization is friendly for consumption by clients issuing HTTP GET range request ("bytes: start_offset-end_offset" HTTP header). +It contains at its beginning the metadata of the full resolution imagery, followed by the optional presence of overview metadata, and finally the imagery itself. To make it friendly with streaming and progressive rendering, we recommend starting with the imagery of the smallest overview and finishing with the imagery of the full resolution level.

+
+

Ref: github.com/cogeotiff/cog-spec/blob/master/spec.md

+

In Short, the specification just means you MUST create a GeoTIFF with internal block (tile) and the header must be ordered.

+

From a command line point of view, it just means you need to add --co TILED=TRUE in a gdal_translate command.

+

1. Get some data

+

Natural Earth web site host really neat raster and vector datasets. Let's download a large scale raster image: www.naturalearthdata.com/downloads/50m-raster-data/50m-cross-blend-hypso/

+
$ wget https://naciscdn.org/naturalearth/50m/raster/HYP_50M_SR.zip
+
+ +

2. Inspect the data

+

Here is what we want to look at:

+
    +
  • the size in row x lines
  • +
  • the data type (byte, float, complex …)
  • +
  • the internal block size
  • +
  • the presence of overview or not
  • +
+
$ rio cogeo info HYP_50M_SR.tif
+Driver: GTiff
+File: /Users/vincentsarago/Downloads/HYP_50M_SR/HYP_50M_SR.tif
+Compression: None
+ColorSpace: None
+
+Profile
+    Width:            10800
+    Height:           5400
+    Bands:            3
+    Tiled:            False
+    Dtype:            uint8
+    NoData:           None
+    Alpha Band:       False
+    Internal Mask:    False
+    Interleave:       PIXEL
+    ColorMap:         False
+
+Geo
+    Crs:              EPSG:4326
+    Origin:           (-179.99999999999997, 90.0)
+    Resolution:       (0.03333333333333, -0.03333333333333)
+    BoundingBox:      (-179.99999999999997, -89.99999999998201, 179.99999999996405, 90.0)
+
+IFD
+    Id      Size           BlockSize     Decimation
+    0       10800x5400     10800x1       0
+
+

What we can see from the rio cogeo info output:

+
    +
  • The raster has 3 bands
  • +
  • The data type is Byte (0 → 255)
  • +
  • It's not internally tiled (Tiled: false and BlockSize=10800x1)
  • +
  • There is no overview (Only one IFD)
  • +
+

With those informations we already know the GeoTIFF is not a COG (no internal blocks), but let's confirm with the validation script.

+

3. COG validation

+
$ rio cogeo validate HYP_50M_SR.tif
+The following warnings were found:
+- The file is greater than 512xH or 512xW, it is recommended to include internal overviews
+
+The following errors were found:
+- The file is greater than 512xH or 512xW, but is not tiled
+- The offset of the main IFD should be 8 for ClassicTIFF or 16 for BigTIFF. It is 174982088 instead
+- The offset of the first block of the image should be after its IFD
+/Users/vincentsarago/Downloads/HYP_50M_SR/HYP_50M_SR.tif is NOT a valid cloud optimized GeoTIFF
+
+

As mentioned earlier, the validation script confirms the GeoTIFF is not internally tiled and doesn't have overviews.

+

4. COG creation

+

Creating a valid Cloud Optimized GeoTIFF, is not just about creating internal tiles and/or internal overviews. The file internal structure has to be specific and require a complete copy of a file, which is what rio-cogeo does internally.

+
$ rio cogeo create HYP_50M_SR.tif HYP_50M_SR_COG.tif
+Reading input: /Users/vincentsarago/Downloads/HYP_50M_SR/HYP_50M_SR.tif
+    [####################################]  100%
+Adding overviews...
+Updating dataset tags...
+Writing output to: /Users/vincentsarago/Downloads/HYP_50M_SR/HYP_50M_SR_COG.tif
+
+

You could get the same COG with GDAL commands

+
$ gdal_translate HYP_50M_SR.tif tmp.tif -co TILED=YES -co COMPRESS=DEFLATE
+$ gdaladdo -r nearest tmp.tif 2 4 8 16 32
+$ gdal_translate tmp.tif HYP_50M_SR_COG.tif -co TILED=YES -co COMPRESS=DEFLATE -co COPY_SRC_OVERVIEWS=YES
+
+

By default rio-cogeo will create a COG with 512x512 blocksize (for the raw resolution) and use DEFLATE compression to reduce file size.

+
$ rio cogeo info HYP_50M_SR_COG.tif
+Driver: GTiff
+File: /Users/vincentsarago/Downloads/HYP_50M_SR/HYP_50M_SR_COG.tif
+Compression: DEFLATE
+ColorSpace: None
+
+Profile
+    Width:            10800
+    Height:           5400
+    Bands:            3
+    Tiled:            True
+    Dtype:            uint8
+    NoData:           None
+    Alpha Band:       False
+    Internal Mask:    False
+    Interleave:       PIXEL
+    ColorMap:         False
+
+Geo
+    Crs:              EPSG:4326
+    Origin:           (-179.99999999999997, 90.0)
+    Resolution:       (0.03333333333333001, -0.03333333333333001)
+    BoundingBox:      (-179.99999999999997, -89.99999999998204, 179.9999999999641, 90.0)
+
+IFD
+    Id      Size           BlockSize     Decimation
+    0       10800x5400     512x512       0
+    1       5400x2700      128x128       2
+    2       2700x1350      128x128       4
+    3       1350x675       128x128       8
+    4       675x338        128x128       16
+
+

The importance of the compression

+
$ ls -lah
+-rw-r--r--@  1 youpi  staff   167M Oct 18  2014 HYP_50M_SR.tif
+-rw-r--r--   1 youpi  staff    58M Jun 12 14:56 HYP_50M_SR_COG.tif
+
+

By using rio-cogeo, we are not only creating a valid COG with internal tiling but we are also adding internal overviews (which let us get previews of the raw resolution with few GET requests).

+

Even with the addition of 4 levels of overviews (see IFD section in previous rio cogeo info output), we managed to reduce the file size by 3 (167Mb → 58Mb), and this is because rio cogeo applies Deflate compression by default to the COG.

+

More Magic ?

+

As seen in the first rio cogeo info output, the data has 3 bands (RGB) and is of Uint8 data type. Because of this configuration, we can use even more efficient compression like JPEG or WEBP.

+
$ rio cogeo create HYP_50M_SR.tif HYP_50M_SR_COG_jpeg.tif -p jpeg
+Reading input: /Users/vincentsarago/Downloads/HYP_50M_SR/HYP_50M_SR.tif
+    [####################################]  100%
+Adding overviews...
+Updating dataset tags...
+Writing output to: /Users/vincentsarago/Downloads/HYP_50M_SR/HYP_50M_SR_COG_jpeg.tif
+
+$ ls -lah
+-rw-r--r--@  1 vincentsarago  staff   167M Oct 18  2014 HYP_50M_SR.tif
+-rw-r--r--   1 vincentsarago  staff    58M Jun 12 14:56 HYP_50M_SR_COG.tif
+-rw-r--r--   1 vincentsarago  staff   4.8M Jun 15 11:08 HYP_50M_SR_COG_jpeg.tif
+
+

Now, our output file is only 4.8Mb, which is only ~3% of the original size 😱.

+

Note:

+
    +
  • JPEG compression is not lossless but lossy, meaning we will loose some information (change in pixel values) but if you need a COG for visual purposes the gain in size might be worth it.
  • +
  • WEBP compression has a configuration option to be lossless and will result is a file which will be ~50% smaller than the deflate version. Sadly WEBP is not provided by default in geospatial software.
  • +
+

5. Visualize

+

You can either load the COG in QGIS or use our plugin (rio-viz) to load it in a web browser.

+
$ pip install rio-viz
+$ rio viz HYP_50M_SR_COG.tif
+
+

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/assets/images/favicon.png b/assets/images/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..1cf13b9f9d978896599290a74f77d5dbe7d1655c GIT binary patch literal 1870 zcmV-U2eJ5xP)Gc)JR9QMau)O=X#!i9;T z37kk-upj^(fsR36MHs_+1RCI)NNu9}lD0S{B^g8PN?Ww(5|~L#Ng*g{WsqleV}|#l zz8@ri&cTzw_h33bHI+12+kK6WN$h#n5cD8OQt`5kw6p~9H3()bUQ8OS4Q4HTQ=1Ol z_JAocz`fLbT2^{`8n~UAo=#AUOf=SOq4pYkt;XbC&f#7lb$*7=$na!mWCQ`dBQsO0 zLFBSPj*N?#u5&pf2t4XjEGH|=pPQ8xh7tpx;US5Cx_Ju;!O`ya-yF`)b%TEt5>eP1ZX~}sjjA%FJF?h7cX8=b!DZl<6%Cv z*G0uvvU+vmnpLZ2paivG-(cd*y3$hCIcsZcYOGh{$&)A6*XX&kXZd3G8m)G$Zz-LV z^GF3VAW^Mdv!)4OM8EgqRiz~*Cji;uzl2uC9^=8I84vNp;ltJ|q-*uQwGp2ma6cY7 z;`%`!9UXO@fr&Ebapfs34OmS9^u6$)bJxrucutf>`dKPKT%%*d3XlFVKunp9 zasduxjrjs>f8V=D|J=XNZp;_Zy^WgQ$9WDjgY=z@stwiEBm9u5*|34&1Na8BMjjgf3+SHcr`5~>oz1Y?SW^=K z^bTyO6>Gar#P_W2gEMwq)ot3; zREHn~U&Dp0l6YT0&k-wLwYjb?5zGK`W6S2v+K>AM(95m2C20L|3m~rN8dprPr@t)5lsk9Hu*W z?pS990s;Ez=+Rj{x7p``4>+c0G5^pYnB1^!TL=(?HLHZ+HicG{~4F1d^5Awl_2!1jICM-!9eoLhbbT^;yHcefyTAaqRcY zmuctDopPT!%k+}x%lZRKnzykr2}}XfG_ne?nRQO~?%hkzo;@RN{P6o`&mMUWBYMTe z6i8ChtjX&gXl`nvrU>jah)2iNM%JdjqoaeaU%yVn!^70x-flljp6Q5tK}5}&X8&&G zX3fpb3E(!rH=zVI_9Gjl45w@{(ITqngWFe7@9{mX;tO25Z_8 zQHEpI+FkTU#4xu>RkN>b3Tnc3UpWzPXWm#o55GKF09j^Mh~)K7{QqbO_~(@CVq! zS<8954|P8mXN2MRs86xZ&Q4EfM@JB94b=(YGuk)s&^jiSF=t3*oNK3`rD{H`yQ?d; ztE=laAUoZx5?RC8*WKOj`%LXEkgDd>&^Q4M^z`%u0rg-It=hLCVsq!Z%^6eB-OvOT zFZ28TN&cRmgU}Elrnk43)!>Z1FCPL2K$7}gwzIc48NX}#!A1BpJP?#v5wkNprhV** z?Cpalt1oH&{r!o3eSKc&ap)iz2BTn_VV`4>9M^b3;(YY}4>#ML6{~(4mH+?%07*qo IM6N<$f(jP3KmY&$ literal 0 HcmV?d00001 diff --git a/assets/javascripts/bundle.220ee61c.min.js b/assets/javascripts/bundle.220ee61c.min.js new file mode 100644 index 00000000..116072a1 --- /dev/null +++ b/assets/javascripts/bundle.220ee61c.min.js @@ -0,0 +1,29 @@ +"use strict";(()=>{var Ci=Object.create;var gr=Object.defineProperty;var Ri=Object.getOwnPropertyDescriptor;var ki=Object.getOwnPropertyNames,Ht=Object.getOwnPropertySymbols,Hi=Object.getPrototypeOf,yr=Object.prototype.hasOwnProperty,nn=Object.prototype.propertyIsEnumerable;var rn=(e,t,r)=>t in e?gr(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,P=(e,t)=>{for(var r in t||(t={}))yr.call(t,r)&&rn(e,r,t[r]);if(Ht)for(var r of Ht(t))nn.call(t,r)&&rn(e,r,t[r]);return e};var on=(e,t)=>{var r={};for(var n in e)yr.call(e,n)&&t.indexOf(n)<0&&(r[n]=e[n]);if(e!=null&&Ht)for(var n of Ht(e))t.indexOf(n)<0&&nn.call(e,n)&&(r[n]=e[n]);return r};var Pt=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var Pi=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of ki(t))!yr.call(e,o)&&o!==r&&gr(e,o,{get:()=>t[o],enumerable:!(n=Ri(t,o))||n.enumerable});return e};var yt=(e,t,r)=>(r=e!=null?Ci(Hi(e)):{},Pi(t||!e||!e.__esModule?gr(r,"default",{value:e,enumerable:!0}):r,e));var sn=Pt((xr,an)=>{(function(e,t){typeof xr=="object"&&typeof an!="undefined"?t():typeof define=="function"&&define.amd?define(t):t()})(xr,function(){"use strict";function e(r){var n=!0,o=!1,i=null,s={text:!0,search:!0,url:!0,tel:!0,email:!0,password:!0,number:!0,date:!0,month:!0,week:!0,time:!0,datetime:!0,"datetime-local":!0};function a(O){return!!(O&&O!==document&&O.nodeName!=="HTML"&&O.nodeName!=="BODY"&&"classList"in O&&"contains"in O.classList)}function f(O){var Qe=O.type,De=O.tagName;return!!(De==="INPUT"&&s[Qe]&&!O.readOnly||De==="TEXTAREA"&&!O.readOnly||O.isContentEditable)}function c(O){O.classList.contains("focus-visible")||(O.classList.add("focus-visible"),O.setAttribute("data-focus-visible-added",""))}function u(O){O.hasAttribute("data-focus-visible-added")&&(O.classList.remove("focus-visible"),O.removeAttribute("data-focus-visible-added"))}function p(O){O.metaKey||O.altKey||O.ctrlKey||(a(r.activeElement)&&c(r.activeElement),n=!0)}function m(O){n=!1}function d(O){a(O.target)&&(n||f(O.target))&&c(O.target)}function h(O){a(O.target)&&(O.target.classList.contains("focus-visible")||O.target.hasAttribute("data-focus-visible-added"))&&(o=!0,window.clearTimeout(i),i=window.setTimeout(function(){o=!1},100),u(O.target))}function v(O){document.visibilityState==="hidden"&&(o&&(n=!0),Y())}function Y(){document.addEventListener("mousemove",N),document.addEventListener("mousedown",N),document.addEventListener("mouseup",N),document.addEventListener("pointermove",N),document.addEventListener("pointerdown",N),document.addEventListener("pointerup",N),document.addEventListener("touchmove",N),document.addEventListener("touchstart",N),document.addEventListener("touchend",N)}function B(){document.removeEventListener("mousemove",N),document.removeEventListener("mousedown",N),document.removeEventListener("mouseup",N),document.removeEventListener("pointermove",N),document.removeEventListener("pointerdown",N),document.removeEventListener("pointerup",N),document.removeEventListener("touchmove",N),document.removeEventListener("touchstart",N),document.removeEventListener("touchend",N)}function N(O){O.target.nodeName&&O.target.nodeName.toLowerCase()==="html"||(n=!1,B())}document.addEventListener("keydown",p,!0),document.addEventListener("mousedown",m,!0),document.addEventListener("pointerdown",m,!0),document.addEventListener("touchstart",m,!0),document.addEventListener("visibilitychange",v,!0),Y(),r.addEventListener("focus",d,!0),r.addEventListener("blur",h,!0),r.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&r.host?r.host.setAttribute("data-js-focus-visible",""):r.nodeType===Node.DOCUMENT_NODE&&(document.documentElement.classList.add("js-focus-visible"),document.documentElement.setAttribute("data-js-focus-visible",""))}if(typeof window!="undefined"&&typeof document!="undefined"){window.applyFocusVisiblePolyfill=e;var t;try{t=new CustomEvent("focus-visible-polyfill-ready")}catch(r){t=document.createEvent("CustomEvent"),t.initCustomEvent("focus-visible-polyfill-ready",!1,!1,{})}window.dispatchEvent(t)}typeof document!="undefined"&&e(document)})});var cn=Pt(Er=>{(function(e){var t=function(){try{return!!Symbol.iterator}catch(c){return!1}},r=t(),n=function(c){var u={next:function(){var p=c.shift();return{done:p===void 0,value:p}}};return r&&(u[Symbol.iterator]=function(){return u}),u},o=function(c){return encodeURIComponent(c).replace(/%20/g,"+")},i=function(c){return decodeURIComponent(String(c).replace(/\+/g," "))},s=function(){var c=function(p){Object.defineProperty(this,"_entries",{writable:!0,value:{}});var m=typeof p;if(m!=="undefined")if(m==="string")p!==""&&this._fromString(p);else if(p instanceof c){var d=this;p.forEach(function(B,N){d.append(N,B)})}else if(p!==null&&m==="object")if(Object.prototype.toString.call(p)==="[object Array]")for(var h=0;hd[0]?1:0}),c._entries&&(c._entries={});for(var p=0;p1?i(d[1]):"")}})})(typeof global!="undefined"?global:typeof window!="undefined"?window:typeof self!="undefined"?self:Er);(function(e){var t=function(){try{var o=new e.URL("b","http://a");return o.pathname="c d",o.href==="http://a/c%20d"&&o.searchParams}catch(i){return!1}},r=function(){var o=e.URL,i=function(f,c){typeof f!="string"&&(f=String(f)),c&&typeof c!="string"&&(c=String(c));var u=document,p;if(c&&(e.location===void 0||c!==e.location.href)){c=c.toLowerCase(),u=document.implementation.createHTMLDocument(""),p=u.createElement("base"),p.href=c,u.head.appendChild(p);try{if(p.href.indexOf(c)!==0)throw new Error(p.href)}catch(O){throw new Error("URL unable to set base "+c+" due to "+O)}}var m=u.createElement("a");m.href=f,p&&(u.body.appendChild(m),m.href=m.href);var d=u.createElement("input");if(d.type="url",d.value=f,m.protocol===":"||!/:/.test(m.href)||!d.checkValidity()&&!c)throw new TypeError("Invalid URL");Object.defineProperty(this,"_anchorElement",{value:m});var h=new e.URLSearchParams(this.search),v=!0,Y=!0,B=this;["append","delete","set"].forEach(function(O){var Qe=h[O];h[O]=function(){Qe.apply(h,arguments),v&&(Y=!1,B.search=h.toString(),Y=!0)}}),Object.defineProperty(this,"searchParams",{value:h,enumerable:!0});var N=void 0;Object.defineProperty(this,"_updateSearchParams",{enumerable:!1,configurable:!1,writable:!1,value:function(){this.search!==N&&(N=this.search,Y&&(v=!1,this.searchParams._fromString(this.search),v=!0))}})},s=i.prototype,a=function(f){Object.defineProperty(s,f,{get:function(){return this._anchorElement[f]},set:function(c){this._anchorElement[f]=c},enumerable:!0})};["hash","host","hostname","port","protocol"].forEach(function(f){a(f)}),Object.defineProperty(s,"search",{get:function(){return this._anchorElement.search},set:function(f){this._anchorElement.search=f,this._updateSearchParams()},enumerable:!0}),Object.defineProperties(s,{toString:{get:function(){var f=this;return function(){return f.href}}},href:{get:function(){return this._anchorElement.href.replace(/\?$/,"")},set:function(f){this._anchorElement.href=f,this._updateSearchParams()},enumerable:!0},pathname:{get:function(){return this._anchorElement.pathname.replace(/(^\/?)/,"/")},set:function(f){this._anchorElement.pathname=f},enumerable:!0},origin:{get:function(){var f={"http:":80,"https:":443,"ftp:":21}[this._anchorElement.protocol],c=this._anchorElement.port!=f&&this._anchorElement.port!=="";return this._anchorElement.protocol+"//"+this._anchorElement.hostname+(c?":"+this._anchorElement.port:"")},enumerable:!0},password:{get:function(){return""},set:function(f){},enumerable:!0},username:{get:function(){return""},set:function(f){},enumerable:!0}}),i.createObjectURL=function(f){return o.createObjectURL.apply(o,arguments)},i.revokeObjectURL=function(f){return o.revokeObjectURL.apply(o,arguments)},e.URL=i};if(t()||r(),e.location!==void 0&&!("origin"in e.location)){var n=function(){return e.location.protocol+"//"+e.location.hostname+(e.location.port?":"+e.location.port:"")};try{Object.defineProperty(e.location,"origin",{get:n,enumerable:!0})}catch(o){setInterval(function(){e.location.origin=n()},100)}}})(typeof global!="undefined"?global:typeof window!="undefined"?window:typeof self!="undefined"?self:Er)});var qr=Pt((Mt,Nr)=>{/*! + * clipboard.js v2.0.11 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */(function(t,r){typeof Mt=="object"&&typeof Nr=="object"?Nr.exports=r():typeof define=="function"&&define.amd?define([],r):typeof Mt=="object"?Mt.ClipboardJS=r():t.ClipboardJS=r()})(Mt,function(){return function(){var e={686:function(n,o,i){"use strict";i.d(o,{default:function(){return Ai}});var s=i(279),a=i.n(s),f=i(370),c=i.n(f),u=i(817),p=i.n(u);function m(j){try{return document.execCommand(j)}catch(T){return!1}}var d=function(T){var E=p()(T);return m("cut"),E},h=d;function v(j){var T=document.documentElement.getAttribute("dir")==="rtl",E=document.createElement("textarea");E.style.fontSize="12pt",E.style.border="0",E.style.padding="0",E.style.margin="0",E.style.position="absolute",E.style[T?"right":"left"]="-9999px";var H=window.pageYOffset||document.documentElement.scrollTop;return E.style.top="".concat(H,"px"),E.setAttribute("readonly",""),E.value=j,E}var Y=function(T,E){var H=v(T);E.container.appendChild(H);var I=p()(H);return m("copy"),H.remove(),I},B=function(T){var E=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body},H="";return typeof T=="string"?H=Y(T,E):T instanceof HTMLInputElement&&!["text","search","url","tel","password"].includes(T==null?void 0:T.type)?H=Y(T.value,E):(H=p()(T),m("copy")),H},N=B;function O(j){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?O=function(E){return typeof E}:O=function(E){return E&&typeof Symbol=="function"&&E.constructor===Symbol&&E!==Symbol.prototype?"symbol":typeof E},O(j)}var Qe=function(){var T=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},E=T.action,H=E===void 0?"copy":E,I=T.container,q=T.target,Me=T.text;if(H!=="copy"&&H!=="cut")throw new Error('Invalid "action" value, use either "copy" or "cut"');if(q!==void 0)if(q&&O(q)==="object"&&q.nodeType===1){if(H==="copy"&&q.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if(H==="cut"&&(q.hasAttribute("readonly")||q.hasAttribute("disabled")))throw new Error(`Invalid "target" attribute. You can't cut text from elements with "readonly" or "disabled" attributes`)}else throw new Error('Invalid "target" value, use a valid Element');if(Me)return N(Me,{container:I});if(q)return H==="cut"?h(q):N(q,{container:I})},De=Qe;function $e(j){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?$e=function(E){return typeof E}:$e=function(E){return E&&typeof Symbol=="function"&&E.constructor===Symbol&&E!==Symbol.prototype?"symbol":typeof E},$e(j)}function Ei(j,T){if(!(j instanceof T))throw new TypeError("Cannot call a class as a function")}function tn(j,T){for(var E=0;E0&&arguments[0]!==void 0?arguments[0]:{};this.action=typeof I.action=="function"?I.action:this.defaultAction,this.target=typeof I.target=="function"?I.target:this.defaultTarget,this.text=typeof I.text=="function"?I.text:this.defaultText,this.container=$e(I.container)==="object"?I.container:document.body}},{key:"listenClick",value:function(I){var q=this;this.listener=c()(I,"click",function(Me){return q.onClick(Me)})}},{key:"onClick",value:function(I){var q=I.delegateTarget||I.currentTarget,Me=this.action(q)||"copy",kt=De({action:Me,container:this.container,target:this.target(q),text:this.text(q)});this.emit(kt?"success":"error",{action:Me,text:kt,trigger:q,clearSelection:function(){q&&q.focus(),window.getSelection().removeAllRanges()}})}},{key:"defaultAction",value:function(I){return vr("action",I)}},{key:"defaultTarget",value:function(I){var q=vr("target",I);if(q)return document.querySelector(q)}},{key:"defaultText",value:function(I){return vr("text",I)}},{key:"destroy",value:function(){this.listener.destroy()}}],[{key:"copy",value:function(I){var q=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body};return N(I,q)}},{key:"cut",value:function(I){return h(I)}},{key:"isSupported",value:function(){var I=arguments.length>0&&arguments[0]!==void 0?arguments[0]:["copy","cut"],q=typeof I=="string"?[I]:I,Me=!!document.queryCommandSupported;return q.forEach(function(kt){Me=Me&&!!document.queryCommandSupported(kt)}),Me}}]),E}(a()),Ai=Li},828:function(n){var o=9;if(typeof Element!="undefined"&&!Element.prototype.matches){var i=Element.prototype;i.matches=i.matchesSelector||i.mozMatchesSelector||i.msMatchesSelector||i.oMatchesSelector||i.webkitMatchesSelector}function s(a,f){for(;a&&a.nodeType!==o;){if(typeof a.matches=="function"&&a.matches(f))return a;a=a.parentNode}}n.exports=s},438:function(n,o,i){var s=i(828);function a(u,p,m,d,h){var v=c.apply(this,arguments);return u.addEventListener(m,v,h),{destroy:function(){u.removeEventListener(m,v,h)}}}function f(u,p,m,d,h){return typeof u.addEventListener=="function"?a.apply(null,arguments):typeof m=="function"?a.bind(null,document).apply(null,arguments):(typeof u=="string"&&(u=document.querySelectorAll(u)),Array.prototype.map.call(u,function(v){return a(v,p,m,d,h)}))}function c(u,p,m,d){return function(h){h.delegateTarget=s(h.target,p),h.delegateTarget&&d.call(u,h)}}n.exports=f},879:function(n,o){o.node=function(i){return i!==void 0&&i instanceof HTMLElement&&i.nodeType===1},o.nodeList=function(i){var s=Object.prototype.toString.call(i);return i!==void 0&&(s==="[object NodeList]"||s==="[object HTMLCollection]")&&"length"in i&&(i.length===0||o.node(i[0]))},o.string=function(i){return typeof i=="string"||i instanceof String},o.fn=function(i){var s=Object.prototype.toString.call(i);return s==="[object Function]"}},370:function(n,o,i){var s=i(879),a=i(438);function f(m,d,h){if(!m&&!d&&!h)throw new Error("Missing required arguments");if(!s.string(d))throw new TypeError("Second argument must be a String");if(!s.fn(h))throw new TypeError("Third argument must be a Function");if(s.node(m))return c(m,d,h);if(s.nodeList(m))return u(m,d,h);if(s.string(m))return p(m,d,h);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}function c(m,d,h){return m.addEventListener(d,h),{destroy:function(){m.removeEventListener(d,h)}}}function u(m,d,h){return Array.prototype.forEach.call(m,function(v){v.addEventListener(d,h)}),{destroy:function(){Array.prototype.forEach.call(m,function(v){v.removeEventListener(d,h)})}}}function p(m,d,h){return a(document.body,m,d,h)}n.exports=f},817:function(n){function o(i){var s;if(i.nodeName==="SELECT")i.focus(),s=i.value;else if(i.nodeName==="INPUT"||i.nodeName==="TEXTAREA"){var a=i.hasAttribute("readonly");a||i.setAttribute("readonly",""),i.select(),i.setSelectionRange(0,i.value.length),a||i.removeAttribute("readonly"),s=i.value}else{i.hasAttribute("contenteditable")&&i.focus();var f=window.getSelection(),c=document.createRange();c.selectNodeContents(i),f.removeAllRanges(),f.addRange(c),s=f.toString()}return s}n.exports=o},279:function(n){function o(){}o.prototype={on:function(i,s,a){var f=this.e||(this.e={});return(f[i]||(f[i]=[])).push({fn:s,ctx:a}),this},once:function(i,s,a){var f=this;function c(){f.off(i,c),s.apply(a,arguments)}return c._=s,this.on(i,c,a)},emit:function(i){var s=[].slice.call(arguments,1),a=((this.e||(this.e={}))[i]||[]).slice(),f=0,c=a.length;for(f;f{"use strict";/*! + * escape-html + * Copyright(c) 2012-2013 TJ Holowaychuk + * Copyright(c) 2015 Andreas Lubbe + * Copyright(c) 2015 Tiancheng "Timothy" Gu + * MIT Licensed + */var rs=/["'&<>]/;Yo.exports=ns;function ns(e){var t=""+e,r=rs.exec(t);if(!r)return t;var n,o="",i=0,s=0;for(i=r.index;i0&&i[i.length-1])&&(c[0]===6||c[0]===2)){r=0;continue}if(c[0]===3&&(!i||c[1]>i[0]&&c[1]=e.length&&(e=void 0),{value:e&&e[n++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")}function W(e,t){var r=typeof Symbol=="function"&&e[Symbol.iterator];if(!r)return e;var n=r.call(e),o,i=[],s;try{for(;(t===void 0||t-- >0)&&!(o=n.next()).done;)i.push(o.value)}catch(a){s={error:a}}finally{try{o&&!o.done&&(r=n.return)&&r.call(n)}finally{if(s)throw s.error}}return i}function D(e,t,r){if(r||arguments.length===2)for(var n=0,o=t.length,i;n1||a(m,d)})})}function a(m,d){try{f(n[m](d))}catch(h){p(i[0][3],h)}}function f(m){m.value instanceof et?Promise.resolve(m.value.v).then(c,u):p(i[0][2],m)}function c(m){a("next",m)}function u(m){a("throw",m)}function p(m,d){m(d),i.shift(),i.length&&a(i[0][0],i[0][1])}}function pn(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var t=e[Symbol.asyncIterator],r;return t?t.call(e):(e=typeof Ee=="function"?Ee(e):e[Symbol.iterator](),r={},n("next"),n("throw"),n("return"),r[Symbol.asyncIterator]=function(){return this},r);function n(i){r[i]=e[i]&&function(s){return new Promise(function(a,f){s=e[i](s),o(a,f,s.done,s.value)})}}function o(i,s,a,f){Promise.resolve(f).then(function(c){i({value:c,done:a})},s)}}function C(e){return typeof e=="function"}function at(e){var t=function(n){Error.call(n),n.stack=new Error().stack},r=e(t);return r.prototype=Object.create(Error.prototype),r.prototype.constructor=r,r}var It=at(function(e){return function(r){e(this),this.message=r?r.length+` errors occurred during unsubscription: +`+r.map(function(n,o){return o+1+") "+n.toString()}).join(` + `):"",this.name="UnsubscriptionError",this.errors=r}});function Ve(e,t){if(e){var r=e.indexOf(t);0<=r&&e.splice(r,1)}}var Ie=function(){function e(t){this.initialTeardown=t,this.closed=!1,this._parentage=null,this._finalizers=null}return e.prototype.unsubscribe=function(){var t,r,n,o,i;if(!this.closed){this.closed=!0;var s=this._parentage;if(s)if(this._parentage=null,Array.isArray(s))try{for(var a=Ee(s),f=a.next();!f.done;f=a.next()){var c=f.value;c.remove(this)}}catch(v){t={error:v}}finally{try{f&&!f.done&&(r=a.return)&&r.call(a)}finally{if(t)throw t.error}}else s.remove(this);var u=this.initialTeardown;if(C(u))try{u()}catch(v){i=v instanceof It?v.errors:[v]}var p=this._finalizers;if(p){this._finalizers=null;try{for(var m=Ee(p),d=m.next();!d.done;d=m.next()){var h=d.value;try{ln(h)}catch(v){i=i!=null?i:[],v instanceof It?i=D(D([],W(i)),W(v.errors)):i.push(v)}}}catch(v){n={error:v}}finally{try{d&&!d.done&&(o=m.return)&&o.call(m)}finally{if(n)throw n.error}}}if(i)throw new It(i)}},e.prototype.add=function(t){var r;if(t&&t!==this)if(this.closed)ln(t);else{if(t instanceof e){if(t.closed||t._hasParent(this))return;t._addParent(this)}(this._finalizers=(r=this._finalizers)!==null&&r!==void 0?r:[]).push(t)}},e.prototype._hasParent=function(t){var r=this._parentage;return r===t||Array.isArray(r)&&r.includes(t)},e.prototype._addParent=function(t){var r=this._parentage;this._parentage=Array.isArray(r)?(r.push(t),r):r?[r,t]:t},e.prototype._removeParent=function(t){var r=this._parentage;r===t?this._parentage=null:Array.isArray(r)&&Ve(r,t)},e.prototype.remove=function(t){var r=this._finalizers;r&&Ve(r,t),t instanceof e&&t._removeParent(this)},e.EMPTY=function(){var t=new e;return t.closed=!0,t}(),e}();var Sr=Ie.EMPTY;function jt(e){return e instanceof Ie||e&&"closed"in e&&C(e.remove)&&C(e.add)&&C(e.unsubscribe)}function ln(e){C(e)?e():e.unsubscribe()}var Le={onUnhandledError:null,onStoppedNotification:null,Promise:void 0,useDeprecatedSynchronousErrorHandling:!1,useDeprecatedNextContext:!1};var st={setTimeout:function(e,t){for(var r=[],n=2;n0},enumerable:!1,configurable:!0}),t.prototype._trySubscribe=function(r){return this._throwIfClosed(),e.prototype._trySubscribe.call(this,r)},t.prototype._subscribe=function(r){return this._throwIfClosed(),this._checkFinalizedStatuses(r),this._innerSubscribe(r)},t.prototype._innerSubscribe=function(r){var n=this,o=this,i=o.hasError,s=o.isStopped,a=o.observers;return i||s?Sr:(this.currentObservers=null,a.push(r),new Ie(function(){n.currentObservers=null,Ve(a,r)}))},t.prototype._checkFinalizedStatuses=function(r){var n=this,o=n.hasError,i=n.thrownError,s=n.isStopped;o?r.error(i):s&&r.complete()},t.prototype.asObservable=function(){var r=new F;return r.source=this,r},t.create=function(r,n){return new xn(r,n)},t}(F);var xn=function(e){ie(t,e);function t(r,n){var o=e.call(this)||this;return o.destination=r,o.source=n,o}return t.prototype.next=function(r){var n,o;(o=(n=this.destination)===null||n===void 0?void 0:n.next)===null||o===void 0||o.call(n,r)},t.prototype.error=function(r){var n,o;(o=(n=this.destination)===null||n===void 0?void 0:n.error)===null||o===void 0||o.call(n,r)},t.prototype.complete=function(){var r,n;(n=(r=this.destination)===null||r===void 0?void 0:r.complete)===null||n===void 0||n.call(r)},t.prototype._subscribe=function(r){var n,o;return(o=(n=this.source)===null||n===void 0?void 0:n.subscribe(r))!==null&&o!==void 0?o:Sr},t}(x);var Et={now:function(){return(Et.delegate||Date).now()},delegate:void 0};var wt=function(e){ie(t,e);function t(r,n,o){r===void 0&&(r=1/0),n===void 0&&(n=1/0),o===void 0&&(o=Et);var i=e.call(this)||this;return i._bufferSize=r,i._windowTime=n,i._timestampProvider=o,i._buffer=[],i._infiniteTimeWindow=!0,i._infiniteTimeWindow=n===1/0,i._bufferSize=Math.max(1,r),i._windowTime=Math.max(1,n),i}return t.prototype.next=function(r){var n=this,o=n.isStopped,i=n._buffer,s=n._infiniteTimeWindow,a=n._timestampProvider,f=n._windowTime;o||(i.push(r),!s&&i.push(a.now()+f)),this._trimBuffer(),e.prototype.next.call(this,r)},t.prototype._subscribe=function(r){this._throwIfClosed(),this._trimBuffer();for(var n=this._innerSubscribe(r),o=this,i=o._infiniteTimeWindow,s=o._buffer,a=s.slice(),f=0;f0?e.prototype.requestAsyncId.call(this,r,n,o):(r.actions.push(this),r._scheduled||(r._scheduled=ut.requestAnimationFrame(function(){return r.flush(void 0)})))},t.prototype.recycleAsyncId=function(r,n,o){var i;if(o===void 0&&(o=0),o!=null?o>0:this.delay>0)return e.prototype.recycleAsyncId.call(this,r,n,o);var s=r.actions;n!=null&&((i=s[s.length-1])===null||i===void 0?void 0:i.id)!==n&&(ut.cancelAnimationFrame(n),r._scheduled=void 0)},t}(Wt);var Sn=function(e){ie(t,e);function t(){return e!==null&&e.apply(this,arguments)||this}return t.prototype.flush=function(r){this._active=!0;var n=this._scheduled;this._scheduled=void 0;var o=this.actions,i;r=r||o.shift();do if(i=r.execute(r.state,r.delay))break;while((r=o[0])&&r.id===n&&o.shift());if(this._active=!1,i){for(;(r=o[0])&&r.id===n&&o.shift();)r.unsubscribe();throw i}},t}(Dt);var Oe=new Sn(wn);var M=new F(function(e){return e.complete()});function Vt(e){return e&&C(e.schedule)}function Cr(e){return e[e.length-1]}function Ye(e){return C(Cr(e))?e.pop():void 0}function Te(e){return Vt(Cr(e))?e.pop():void 0}function zt(e,t){return typeof Cr(e)=="number"?e.pop():t}var pt=function(e){return e&&typeof e.length=="number"&&typeof e!="function"};function Nt(e){return C(e==null?void 0:e.then)}function qt(e){return C(e[ft])}function Kt(e){return Symbol.asyncIterator&&C(e==null?void 0:e[Symbol.asyncIterator])}function Qt(e){return new TypeError("You provided "+(e!==null&&typeof e=="object"?"an invalid object":"'"+e+"'")+" where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.")}function zi(){return typeof Symbol!="function"||!Symbol.iterator?"@@iterator":Symbol.iterator}var Yt=zi();function Gt(e){return C(e==null?void 0:e[Yt])}function Bt(e){return un(this,arguments,function(){var r,n,o,i;return $t(this,function(s){switch(s.label){case 0:r=e.getReader(),s.label=1;case 1:s.trys.push([1,,9,10]),s.label=2;case 2:return[4,et(r.read())];case 3:return n=s.sent(),o=n.value,i=n.done,i?[4,et(void 0)]:[3,5];case 4:return[2,s.sent()];case 5:return[4,et(o)];case 6:return[4,s.sent()];case 7:return s.sent(),[3,2];case 8:return[3,10];case 9:return r.releaseLock(),[7];case 10:return[2]}})})}function Jt(e){return C(e==null?void 0:e.getReader)}function U(e){if(e instanceof F)return e;if(e!=null){if(qt(e))return Ni(e);if(pt(e))return qi(e);if(Nt(e))return Ki(e);if(Kt(e))return On(e);if(Gt(e))return Qi(e);if(Jt(e))return Yi(e)}throw Qt(e)}function Ni(e){return new F(function(t){var r=e[ft]();if(C(r.subscribe))return r.subscribe(t);throw new TypeError("Provided object does not correctly implement Symbol.observable")})}function qi(e){return new F(function(t){for(var r=0;r=2;return function(n){return n.pipe(e?A(function(o,i){return e(o,i,n)}):de,ge(1),r?He(t):Dn(function(){return new Zt}))}}function Vn(){for(var e=[],t=0;t=2,!0))}function pe(e){e===void 0&&(e={});var t=e.connector,r=t===void 0?function(){return new x}:t,n=e.resetOnError,o=n===void 0?!0:n,i=e.resetOnComplete,s=i===void 0?!0:i,a=e.resetOnRefCountZero,f=a===void 0?!0:a;return function(c){var u,p,m,d=0,h=!1,v=!1,Y=function(){p==null||p.unsubscribe(),p=void 0},B=function(){Y(),u=m=void 0,h=v=!1},N=function(){var O=u;B(),O==null||O.unsubscribe()};return y(function(O,Qe){d++,!v&&!h&&Y();var De=m=m!=null?m:r();Qe.add(function(){d--,d===0&&!v&&!h&&(p=$r(N,f))}),De.subscribe(Qe),!u&&d>0&&(u=new rt({next:function($e){return De.next($e)},error:function($e){v=!0,Y(),p=$r(B,o,$e),De.error($e)},complete:function(){h=!0,Y(),p=$r(B,s),De.complete()}}),U(O).subscribe(u))})(c)}}function $r(e,t){for(var r=[],n=2;ne.next(document)),e}function K(e,t=document){return Array.from(t.querySelectorAll(e))}function z(e,t=document){let r=ce(e,t);if(typeof r=="undefined")throw new ReferenceError(`Missing element: expected "${e}" to be present`);return r}function ce(e,t=document){return t.querySelector(e)||void 0}function _e(){return document.activeElement instanceof HTMLElement&&document.activeElement||void 0}function tr(e){return L(b(document.body,"focusin"),b(document.body,"focusout")).pipe(ke(1),l(()=>{let t=_e();return typeof t!="undefined"?e.contains(t):!1}),V(e===_e()),J())}function Xe(e){return{x:e.offsetLeft,y:e.offsetTop}}function Kn(e){return L(b(window,"load"),b(window,"resize")).pipe(Ce(0,Oe),l(()=>Xe(e)),V(Xe(e)))}function rr(e){return{x:e.scrollLeft,y:e.scrollTop}}function dt(e){return L(b(e,"scroll"),b(window,"resize")).pipe(Ce(0,Oe),l(()=>rr(e)),V(rr(e)))}var Yn=function(){if(typeof Map!="undefined")return Map;function e(t,r){var n=-1;return t.some(function(o,i){return o[0]===r?(n=i,!0):!1}),n}return function(){function t(){this.__entries__=[]}return Object.defineProperty(t.prototype,"size",{get:function(){return this.__entries__.length},enumerable:!0,configurable:!0}),t.prototype.get=function(r){var n=e(this.__entries__,r),o=this.__entries__[n];return o&&o[1]},t.prototype.set=function(r,n){var o=e(this.__entries__,r);~o?this.__entries__[o][1]=n:this.__entries__.push([r,n])},t.prototype.delete=function(r){var n=this.__entries__,o=e(n,r);~o&&n.splice(o,1)},t.prototype.has=function(r){return!!~e(this.__entries__,r)},t.prototype.clear=function(){this.__entries__.splice(0)},t.prototype.forEach=function(r,n){n===void 0&&(n=null);for(var o=0,i=this.__entries__;o0},e.prototype.connect_=function(){!Wr||this.connected_||(document.addEventListener("transitionend",this.onTransitionEnd_),window.addEventListener("resize",this.refresh),va?(this.mutationsObserver_=new MutationObserver(this.refresh),this.mutationsObserver_.observe(document,{attributes:!0,childList:!0,characterData:!0,subtree:!0})):(document.addEventListener("DOMSubtreeModified",this.refresh),this.mutationEventsAdded_=!0),this.connected_=!0)},e.prototype.disconnect_=function(){!Wr||!this.connected_||(document.removeEventListener("transitionend",this.onTransitionEnd_),window.removeEventListener("resize",this.refresh),this.mutationsObserver_&&this.mutationsObserver_.disconnect(),this.mutationEventsAdded_&&document.removeEventListener("DOMSubtreeModified",this.refresh),this.mutationsObserver_=null,this.mutationEventsAdded_=!1,this.connected_=!1)},e.prototype.onTransitionEnd_=function(t){var r=t.propertyName,n=r===void 0?"":r,o=ba.some(function(i){return!!~n.indexOf(i)});o&&this.refresh()},e.getInstance=function(){return this.instance_||(this.instance_=new e),this.instance_},e.instance_=null,e}(),Gn=function(e,t){for(var r=0,n=Object.keys(t);r0},e}(),Jn=typeof WeakMap!="undefined"?new WeakMap:new Yn,Xn=function(){function e(t){if(!(this instanceof e))throw new TypeError("Cannot call a class as a function.");if(!arguments.length)throw new TypeError("1 argument required, but only 0 present.");var r=ga.getInstance(),n=new La(t,r,this);Jn.set(this,n)}return e}();["observe","unobserve","disconnect"].forEach(function(e){Xn.prototype[e]=function(){var t;return(t=Jn.get(this))[e].apply(t,arguments)}});var Aa=function(){return typeof nr.ResizeObserver!="undefined"?nr.ResizeObserver:Xn}(),Zn=Aa;var eo=new x,Ca=$(()=>k(new Zn(e=>{for(let t of e)eo.next(t)}))).pipe(g(e=>L(ze,k(e)).pipe(R(()=>e.disconnect()))),X(1));function he(e){return{width:e.offsetWidth,height:e.offsetHeight}}function ye(e){return Ca.pipe(S(t=>t.observe(e)),g(t=>eo.pipe(A(({target:r})=>r===e),R(()=>t.unobserve(e)),l(()=>he(e)))),V(he(e)))}function bt(e){return{width:e.scrollWidth,height:e.scrollHeight}}function ar(e){let t=e.parentElement;for(;t&&(e.scrollWidth<=t.scrollWidth&&e.scrollHeight<=t.scrollHeight);)t=(e=t).parentElement;return t?e:void 0}var to=new x,Ra=$(()=>k(new IntersectionObserver(e=>{for(let t of e)to.next(t)},{threshold:0}))).pipe(g(e=>L(ze,k(e)).pipe(R(()=>e.disconnect()))),X(1));function sr(e){return Ra.pipe(S(t=>t.observe(e)),g(t=>to.pipe(A(({target:r})=>r===e),R(()=>t.unobserve(e)),l(({isIntersecting:r})=>r))))}function ro(e,t=16){return dt(e).pipe(l(({y:r})=>{let n=he(e),o=bt(e);return r>=o.height-n.height-t}),J())}var cr={drawer:z("[data-md-toggle=drawer]"),search:z("[data-md-toggle=search]")};function no(e){return cr[e].checked}function Ke(e,t){cr[e].checked!==t&&cr[e].click()}function Ue(e){let t=cr[e];return b(t,"change").pipe(l(()=>t.checked),V(t.checked))}function ka(e,t){switch(e.constructor){case HTMLInputElement:return e.type==="radio"?/^Arrow/.test(t):!0;case HTMLSelectElement:case HTMLTextAreaElement:return!0;default:return e.isContentEditable}}function Ha(){return L(b(window,"compositionstart").pipe(l(()=>!0)),b(window,"compositionend").pipe(l(()=>!1))).pipe(V(!1))}function oo(){let e=b(window,"keydown").pipe(A(t=>!(t.metaKey||t.ctrlKey)),l(t=>({mode:no("search")?"search":"global",type:t.key,claim(){t.preventDefault(),t.stopPropagation()}})),A(({mode:t,type:r})=>{if(t==="global"){let n=_e();if(typeof n!="undefined")return!ka(n,r)}return!0}),pe());return Ha().pipe(g(t=>t?M:e))}function le(){return new URL(location.href)}function ot(e){location.href=e.href}function io(){return new x}function ao(e,t){if(typeof t=="string"||typeof t=="number")e.innerHTML+=t.toString();else if(t instanceof Node)e.appendChild(t);else if(Array.isArray(t))for(let r of t)ao(e,r)}function _(e,t,...r){let n=document.createElement(e);if(t)for(let o of Object.keys(t))typeof t[o]!="undefined"&&(typeof t[o]!="boolean"?n.setAttribute(o,t[o]):n.setAttribute(o,""));for(let o of r)ao(n,o);return n}function fr(e){if(e>999){let t=+((e-950)%1e3>99);return`${((e+1e-6)/1e3).toFixed(t)}k`}else return e.toString()}function so(){return location.hash.substring(1)}function Dr(e){let t=_("a",{href:e});t.addEventListener("click",r=>r.stopPropagation()),t.click()}function Pa(e){return L(b(window,"hashchange"),e).pipe(l(so),V(so()),A(t=>t.length>0),X(1))}function co(e){return Pa(e).pipe(l(t=>ce(`[id="${t}"]`)),A(t=>typeof t!="undefined"))}function Vr(e){let t=matchMedia(e);return er(r=>t.addListener(()=>r(t.matches))).pipe(V(t.matches))}function fo(){let e=matchMedia("print");return L(b(window,"beforeprint").pipe(l(()=>!0)),b(window,"afterprint").pipe(l(()=>!1))).pipe(V(e.matches))}function zr(e,t){return e.pipe(g(r=>r?t():M))}function ur(e,t={credentials:"same-origin"}){return ue(fetch(`${e}`,t)).pipe(fe(()=>M),g(r=>r.status!==200?Ot(()=>new Error(r.statusText)):k(r)))}function We(e,t){return ur(e,t).pipe(g(r=>r.json()),X(1))}function uo(e,t){let r=new DOMParser;return ur(e,t).pipe(g(n=>n.text()),l(n=>r.parseFromString(n,"text/xml")),X(1))}function pr(e){let t=_("script",{src:e});return $(()=>(document.head.appendChild(t),L(b(t,"load"),b(t,"error").pipe(g(()=>Ot(()=>new ReferenceError(`Invalid script: ${e}`))))).pipe(l(()=>{}),R(()=>document.head.removeChild(t)),ge(1))))}function po(){return{x:Math.max(0,scrollX),y:Math.max(0,scrollY)}}function lo(){return L(b(window,"scroll",{passive:!0}),b(window,"resize",{passive:!0})).pipe(l(po),V(po()))}function mo(){return{width:innerWidth,height:innerHeight}}function ho(){return b(window,"resize",{passive:!0}).pipe(l(mo),V(mo()))}function bo(){return G([lo(),ho()]).pipe(l(([e,t])=>({offset:e,size:t})),X(1))}function lr(e,{viewport$:t,header$:r}){let n=t.pipe(ee("size")),o=G([n,r]).pipe(l(()=>Xe(e)));return G([r,t,o]).pipe(l(([{height:i},{offset:s,size:a},{x:f,y:c}])=>({offset:{x:s.x-f,y:s.y-c+i},size:a})))}(()=>{function e(n,o){parent.postMessage(n,o||"*")}function t(...n){return n.reduce((o,i)=>o.then(()=>new Promise(s=>{let a=document.createElement("script");a.src=i,a.onload=s,document.body.appendChild(a)})),Promise.resolve())}var r=class extends EventTarget{constructor(n){super(),this.url=n,this.m=i=>{i.source===this.w&&(this.dispatchEvent(new MessageEvent("message",{data:i.data})),this.onmessage&&this.onmessage(i))},this.e=(i,s,a,f,c)=>{if(s===`${this.url}`){let u=new ErrorEvent("error",{message:i,filename:s,lineno:a,colno:f,error:c});this.dispatchEvent(u),this.onerror&&this.onerror(u)}};let o=document.createElement("iframe");o.hidden=!0,document.body.appendChild(this.iframe=o),this.w.document.open(),this.w.document.write(` + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

Contributing

+

Issues and pull requests are more than welcome.

+

dev install

+

$ git clone https://github.com/cogeotiff/rio-cogeo.git
+$ cd rio-cogeo
+$ pip install -e .["test","dev"]
+
+You can then run the tests with the following command:

+
python -m pytest --cov rio_cogeo --cov-report term-missing
+
+

pre-commit

+

This repo is set to use pre-commit to run isort, flake8, pydocstring, black ("uncompromising Python code formatter") and mypy when committing new code.

+
$ pre-commit install
+
+

Docs

+
$ git clone https://github.com/cogeotiff/rio-cogeo.git
+$ cd rio-cogeo
+$ pip install -e .["docs"]
+
+

Hot-reloading docs:

+
$ mkdocs serve
+
+

To manually deploy docs (note you should never need to do this because Github +Actions deploys automatically for new commits.):

+
$ mkdocs gh-deploy
+
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/css/extra.css b/css/extra.css new file mode 100644 index 00000000..81e26eea --- /dev/null +++ b/css/extra.css @@ -0,0 +1,5 @@ +:root { + --md-primary-fg-color: #231b4e;; + --md-primary-fg-color--light: #8782a3; + --md-primary-fg-color--dark: #3b3750; +} diff --git a/index.html b/index.html new file mode 100644 index 00000000..cf7a0d27 --- /dev/null +++ b/index.html @@ -0,0 +1,653 @@ + + + + + + + + + + + + + + + + + + + + + + + + rio-cogeo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

rio-cogeo

+

+ COG +

+

+ Cloud Optimized GeoTIFF (COG) creation and validation plugin for Rasterio. +

+

+ + Test + + + Coverage + + + Package version + + + Conda Forge + + + Downloads + + + Downloads + +

+ +
+

Documentation: cogeotiff.github.io/rio-cogeo/

+

Source Code: cogeotiff/rio-cogeo

+
+

Cloud Optimized GeoTIFF

+

This plugin aims to facilitate the creation and validation of Cloud Optimized +GeoTIFF (COG or COGEO). While it respects the +COG specifications, this plugin also +enforces several features:

+
    +
  • Internal overviews (User can remove overview with option --overview-level 0)
  • +
  • Internal tiles (default profiles have 512x512 internal tiles)
  • +
+

Important: in GDAL 3.1 a new COG driver has been added (doc, discussion), starting with rio-cogeo version 2.2, --use-cog-driver option was added to create COG using the COG driver.

+

Install

+
$ pip install -U pip
+$ pip install rio-cogeo
+
+

Or install from source:

+
$ pip install -U pip
+$ pip install git+https://github.com/cogeotiff/rio-cogeo.git
+
+

GDAL Version

+

It is recommended to use GDAL > 2.3.2. Previous versions might not be able to +create proper COGs (ref: OSGeo/gdal#754).

+

More info in cogeotiff/rio-cogeo#55

+

More

+

Blog post on good and bad COG formats: medium.com/@_VincentS_/do-you-really-want-people-using-your-data-ec94cd94dc3f

+

Checkout rio-glui or rio-viz rasterio plugins to explore COG locally in your web browser.

+

Contribution & Development

+

See CONTRIBUTING.md

+

Changes

+

See CHANGES.md.

+

License

+

See LICENSE

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/profile/index.html b/profile/index.html new file mode 100644 index 00000000..e0e46f1e --- /dev/null +++ b/profile/index.html @@ -0,0 +1,601 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + COG Profiles - rio-cogeo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

COG Profiles

+ +

rio-cogeo defines default Cloud Optimized GeoTIFF profiles which user can use with the CLI or directly with the API.

+

Default profiles are tiled (tiled=True) with 512x512 blocksizes.

+
from rio_cogeo.profiles import cog_profiles
+
+cog_profiles
+> {
+    'jpeg': {'driver': 'GTiff', 'interleave': 'pixel', 'tiled': True, 'blockxsize': 512, 'blockysize': 512, 'compress': 'JPEG', 'photometric': 'YCbCr'},
+    'webp': {'driver': 'GTiff', 'interleave': 'pixel', 'tiled': True, 'blockxsize': 512, 'blockysize': 512, 'compress': 'WEBP'},
+    'zstd': {'driver': 'GTiff', 'interleave': 'pixel', 'tiled': True, 'blockxsize': 512, 'blockysize': 512, 'compress': 'ZSTD'},
+    'lzw': {'driver': 'GTiff', 'interleave': 'pixel', 'tiled': True, 'blockxsize': 512, 'blockysize': 512, 'compress': 'LZW'},
+    'deflate': {'driver': 'GTiff', 'interleave': 'pixel', 'tiled': True, 'blockxsize': 512, 'blockysize': 512, 'compress': 'DEFLATE'}
+    'packbits': {'driver': 'GTiff', 'interleave': 'pixel', 'tiled': True, 'blockxsize': 512, 'blockysize': 512, 'compress': 'PACKBITS'},
+    'lzma': {'driver': 'GTiff', 'interleave': 'pixel', 'tiled': True, 'blockxsize': 512, 'blockysize': 512, 'compress': 'LZMA'},
+    'lerc': {'driver': 'GTiff', 'interleave': 'pixel', 'tiled': True, 'blockxsize': 512, 'blockysize': 512, 'compress': 'LERC'},
+    'lerc_deflate': {'driver': 'GTiff', 'interleave': 'pixel', 'tiled': True, 'blockxsize': 512, 'blockysize': 512, 'compress': 'LERC_DEFLATE'},
+    'lerc_zstd': {'driver': 'GTiff', 'interleave': 'pixel', 'tiled': True, 'blockxsize': 512, 'blockysize': 512, 'compress': 'LERC_ZSTD'},
+    'raw': {'driver': 'GTiff', 'interleave': 'pixel', 'tiled': True, 'blockxsize': 512, 'blockysize': 512}
+}
+
+

JPEG

+
    +
  • JPEG compression
  • +
  • PIXEL interleave
  • +
  • YCbCr (3 bands) colorspace or MINISBLACK (1 band)
  • +
  • limited to uint8 datatype and 3 bands data
  • +
+

WEBP

+
    +
  • WEBP compression
  • +
  • PIXEL interleave
  • +
  • limited to uint8 datatype and 3 or 4 bands data
  • +
  • Non-Standard, might not be supported by software not build against GDAL+internal libtiff + libwebp
  • +
  • Available for GDAL>=2.4.0
  • +
+

ZSTD

+
    +
  • ZSTD compression
  • +
  • PIXEL interleave
  • +
  • Non-Standard, might not be supported by software not build against GDAL + internal libtiff + libzstd
  • +
  • Available for GDAL>=2.3.0
  • +
+

Note in Nov 2018, there was a change in libtiff's ZSTD tags which create incompatibility for old ZSTD compressed GeoTIFF (link)

+

LZW

+
    +
  • LZW compression
  • +
  • PIXEL interleave
  • +
+

DEFLATE

+
    +
  • DEFLATE compression
  • +
  • PIXEL interleave
  • +
+

PACKBITS

+
    +
  • PACKBITS compression
  • +
  • PIXEL interleave
  • +
+

LZMA

+
    +
  • LZMA compression
  • +
  • PIXEL interleave
  • +
+

LERC

+
    +
  • LERC compression
  • +
  • PIXEL interleave
  • +
  • Default MAX_Z_ERROR=0 (lossless)
  • +
  • Non-Standard, might not be supported by software not build against GDAL + internal libtiff
  • +
  • Available for GDAL>=2.4.0
  • +
+

LERC_DEFLATE

+
    +
  • LERC_DEFLATE compression
  • +
  • PIXEL interleave
  • +
  • Default MAX_Z_ERROR=0 (lossless)
  • +
  • Non-Standard, might not be supported by software not build against GDAL + internal libtiff + libzstd
  • +
  • Available for GDAL>=2.4.0
  • +
+

LERC_ZSTD

+
    +
  • LERC_ZSTD compression
  • +
  • PIXEL interleave
  • +
  • Default MAX_Z_ERROR=0 (lossless)
  • +
  • Non-Standard, might not be supported by software not build against GDAL + internal libtiff + libzstd
  • +
  • Available for GDAL>=2.4.0
  • +
+

RAW

+
    +
  • NO compression
  • +
  • PIXEL interleave
  • +
+

Custom

+

Profiles can be extended by providing '--co' option in command line

+
# Create a COGEO without compression and with 1024x1024 block size and 256 overview blocksize
+$ rio cogeo create mydataset.tif mydataset_raw.tif --co BLOCKXSIZE=1024 --co BLOCKYSIZE=1024 --cog-profile raw --overview-blocksize 256
+
+

See gdal.org/drivers/raster/gtiff.html#creation-options for full details of creation options.

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/release-notes/index.html b/release-notes/index.html new file mode 100644 index 00000000..66fad73a --- /dev/null +++ b/release-notes/index.html @@ -0,0 +1,1903 @@ + + + + + + + + + + + + + + + + + + + + + + + + Release Notes - rio-cogeo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

Release Notes

+

5.0.0 (2023-07-25)

+
    +
  • update morecantile requirement to >=5.0,<6.0 (author @mentaljam, cogeotiff/rio-cogeo!267)
  • +
  • update pydantic requirement to ~=2.0 (author @mentaljam, cogeotiff/rio-cogeo!267)
  • +
  • fix pydantic deprecation warnings (author @mentaljam, cogeotiff/rio-cogeo!267)
  • +
  • replace BaseModel.json with BaseModel.model_dump_json
  • +
  • replace BaseModel.dict with BaseModel.model_dump
  • +
  • replace class Config with model_config class variables
  • +
+

4.0.1 (2023-07-11)

+
    +
  • limit pydantic requirement to `~=1.0``
  • +
+

4.0.0 (2023-05-31)

+
    +
  • update morecantile requirement to >=4.0.0
  • +
  • native support for all TileMatrixSet (with respect of the TMS spec 2.0)
  • +
  • add --tms option to specify a path to a TileMatrixSet JSON file
  • +
  • switch resampling enums to python Literal
  • +
+

breaking change

+
    +
  • +

    Web optimization is now done in rio-cogeo instead of GDAL, when using --web-optimized and --use-cog-driver options

    +
  • +
  • +

    switch from using TILING_SCHEME namespaced tags to simple TILING_SCHEME_ prefixed metadata

    +
  • +
+
# before
+with rasterio.open("cog_web.tif") as src:
+    print(src.tags(ns="TILING_SCHEME"))
+>>> {
+    "NAME": "WebMercatorQuad",
+    "ZOOM_LEVEL": "18",
+}
+
+# now
+with rasterio.open("cog_web.tif") as src:
+    print(src.tags())
+>>> {
+    "TILING_SCHEME_NAME": "WebMercatorQuad",
+    "TILING_SCHEME_ZOOM_LEVEL": "18",
+}
+
+

3.5.2 (2023-05-22)

+ +

3.5.1 (2023-04-06)

+
    +
  • Use Case-insensitive check for external overviews (author @mplough-kobold, cogeotiff/rio-cogeo!252)
  • +
  • Use destination directory for the temporary file
  • +
+

3.5.0 (2022-10-26)

+
    +
  • add python 3.11 support
  • +
+

Breaking Changes

+
    +
  • remove python 3.7 support
  • +
  • require rasterio >= 1.3.3 (ref: cogeotiff/rio-cogeo?248)
  • +
  • COG can be have blocksize (bigger than their height or width) and be tiled even if they are smaller than 512x512
  • +
+
# before
+rio cogeo create image_51x51.tif cog.tif
+rio cogeo info cog.tif --json | jq '.IFD'
+>>> [
+  {
+    "Level": 0,
+    "Width": 51,
+    "Height": 51,
+    "Blocksize": [
+      51,
+      51
+    ],
+    "Decimation": 0
+  }
+]
+rio cogeo info cog.tif --json | jq '.Profile.Tiled'
+>>> false
+
+# now
+rio cogeo create image_51x51.tif cog.tif
+rio cogeo info cog.tif --json | jq '.IFD'
+>>> [
+  {
+    "Level": 0,
+    "Width": 51,
+    "Height": 51,
+    "Blocksize": [
+      512,
+      512
+    ],
+    "Decimation": 0
+  }
+]
+rio cogeo info cog.tif --json | jq '.Profile.Tiled'
+>>> true
+
+

3.4.1 (2022-09-14)

+
    +
  • avoid breaking change for cog_info() when previously passing *kwargs to cog_validate
  • +
+

3.4.0 (2022-09-05)

+
    +
  • add python 3.10 support
  • +
  • allow forwarding namespaced metadata to output dataset
  • +
  • set GDAL config for all info methods (previously GDAL's configs were only use in the COG validation step)
  • +
+

3.3.0 (2022-06-24)

+
    +
  • allow non-GeoTIFF in cog_validate
  • +
  • allow config option in rio cogeo info CLI
  • +
+

3.2.0 (2022-04-05)

+
    +
  • Switch to pyproject.toml (cogeotiff/rio-cogeo!232)
  • +
  • add --zoom-level option to define dataset coarsest zoom level, when creating web optimized COG.
  • +
+

3.1.0 (2022-02-18)

+
    +
  • Fix equivalence for rio-cogeo and GDAL definition of aligned_levels
  • +
+

Breaking Changes:

+
    +
  • update morecantile requirement to >=3.1,<4.0. WebOptimized COGs will is now aligned with GDAL and Mercantile TMS definition.
  • +
+

3.0.3 (2021-02-14)

+
    +
  • use rasterio.vrt.WarpedVRT in utils.get_web_optimized_params to better handle dataset with GEOS projection (crossing dateline).
  • +
+

3.0.2 (2021-12-16)

+ +

3.0.1 (2021-10-27)

+
    +
  • update test and dev dependencies to rio-tiler>=3.0.0a0
  • +
+

3.0.0 (2021-09-30)

+
    +
  • no changes since 3.0.0a0
  • +
+

3.0.0a0 (2021-09-23)

+
    +
  • update to morecantile>=3.0
  • +
  • raise warning when using incompatible options for GDAL COG driver (cogeotiff/rio-cogeo!212)
  • +
+

2.3.1 (2021-07-06)

+
    +
  • update click version requirement to >=7.0 to make sure click.Choice supports the case_sensitive option.
  • +
+

2.3.0 (2021-06-25)

+ +
from rio_cogeo import cog_validate
+
+assert cog_validate("cog.tif", congig={"GDAL_DISABLE_READDIR_ON_OPEN": "EMPTY_DIR"})[0]
+
+

In previous version we were forcing GDAL_DISABLE_READDIR_ON_OPEN=FALSE in cog_validate function to check for external overviews.

+

Starting with version 2.3, it's up to the user to set the wanted GDAL configuration (e.g EMPTY_DIR: no external file check, FALSE: check for external files)

+

2.2.3 (2021-06-18)

+ +

2.2.2 (2021-06-01)

+ +

2.2.1 (2021-05-19)

+ +

2.2.0 (2021-05-18)

+ +

Breaking Changes:

+
    +
  • rio_cogeo.cogeo.cog_info now returns a pydantic model
  • +
+
from rio_cogeo.cogeo import cog_info
+
+# before
+info = cog_info("my.tif")
+assert isinstance(info, dict)
+assert info["GEO"]["CRS"]
+
+# now
+assert isinstance(info, rio_cogeo.models.Info)
+assert info.GEO.CRS
+
+ +
# before
+$ rio cogeo create in.tif out.tif -w
+$ rio cogeo info out.tif | jq .Tags
+
+>>> {
+  "AREA_OR_POINT": "Area",
+  "OVR_RESAMPLING_ALG": "NEAREST"
+}
+
+# now
+$ rio cogeo create in.tif out.tif -w
+$ rio cogeo info out.tif | jq .Tags
+>> {
+  "Image Metadata": {
+    "AREA_OR_POINT": "Area",
+    "DataType": "Generic",
+    "OVR_RESAMPLING_ALG": "NEAREST"
+  },
+  "Image Structure": {
+    "COMPRESSION": "DEFLATE",
+    "INTERLEAVE": "BAND",
+    "LAYOUT": "COG"
+  },
+  "Tiling Scheme": {
+    "NAME": "WEBMERCATORQUAD",
+    "ZOOM_LEVEL": "17"
+  }
+}
+
+ +

By default only the raw data will be aligned to the grid. To align overviews, the aligned_levels option can be used (wasn't really working in previous version).

+
    +
  • +

    rio_cogeo.utils.get_web_optimized_params has been refactored (cogeotiff/rio-cogeo!193)

    +
  • +
  • +

    cog_translate will now materialize Nodata or Alpha band to an internal mask automatically for JPEG compresssed output (cogeotiff/rio-cogeo!196)

    +
  • +
+
# before
+cog_translate(raster_path_rgba, "cogeo.tif", jpeg_profile)
+with rasterio.open("cogeo.tif") as src:
+    assert src.count == 4
+    assert src.compression.value == "JPEG"
+    assert has_alpha_band(src)
+    assert not has_mask_band(src)
+
+# now
+cog_translate(raster_path_rgba, "cogeo.tif", jpeg_profile)
+with rasterio.open("cogeo.tif") as src:
+    assert src.count == 3
+    assert src.compression.value == "JPEG"
+    assert has_mask_band(src)
+
+

2.1.4 (2021-03-31)

+ +

2.1.3 (2021-03-03)

+
    +
  • add colormap options in cog_translate to allow a user to set or update a colormap
  • +
+
cmap = {0: (0, 0, 0, 0), 1: (1, 2, 3, 255)}
+cog_translate("boring.tif", "cogeo.tif", deflate_profile, colormap=cmap)
+with rasterio.open("cogeo.tif") as cog:
+    print(cog.colormap(1)[1])
+
+>>> (1, 2, 3, 255)
+
+
    +
  • add additional_cog_metadata options in cog_translate to allow the user to add more dataset metadatas
  • +
+
cog_translate("boring.tif", "cogeo.tif", deflate_profile, additional_cog_metadata={"comments": "I made this tiff with rio-cogeo"})
+
+with rasterio.open("cogeo.tif") as cog:
+    print(cog.tags()["comment"])
+
+>>> "I made this tiff with rio-cogeo"
+
+

2.1.2 (2021-02-10)

+ +

2.1.1 (2021-01-27)

+ +
# before
+from rio_cogeo.cogeo import cog_translate, cog_validate, cog_info
+from rio_cogeo.profiles import cog_profiles
+
+# now
+from rio_cogeo import cog_translate, cog_validate, cog_info, cog_profiles
+
+

2.1.0 (2020-12-18)

+
    +
  • switch to morecantile and update the web-optimized creation method to better match GDAL 3.2.
  • +
  • add zoom_level_strategy options to match GDAL 3.2 COG driver.
  • +
  • add aligned_levels (cli and api) to select the level of overview to align with the TMS grid.
  • +
+

Breaking Changes: +* removed --latitude-adjustment/--global-maxzoom option in the CLI +* removed latitude_adjustment option in rio_cogeo.cogeo.cog_translate +* updated overview blocksize to match the blocksize of the high resolution data (instead of default to 128) +* for web-optimized COG, the highest overview level will be aligned with the TMS grid.

+

2.0.1 (2020-10-07)

+ +

2.0.0 (2020-10-05)

+

There have been no changes since 2.0a9

+

2.0a9 (2020-10-03)

+ +

2.0a8 (2020-09-28)

+
    +
  • Make sure Alpha band isn't considered as an internal mask by utils.has_mask_band (#156)
  • +
+

2.0a7.post1 (2020-09-23)

+
    +
  • Fix wrong min-zoom calculation in rio_cogeo.cogeo.cog_info
  • +
+

2.0a7 (2020-09-23)

+
    +
  • remove duplicate count information in rio_cogeo.cogeo.cog_info output (#150)
  • +
  • allow COG with IFD offset up to 200 bytes to accomodate with GDAL 3.1 changes (#151)
  • +
  • fix zoom level calculation in rio_cogeo.cogeo.cog_info
  • +
+

2.0a6 (2020-08-18)

+
    +
  • fix bug in cogeo.info when CRS in not set.
  • +
  • add minzoom/maxzoom in cogeo.info output.
  • +
+

Breaking Changes: +* rio_cogeo.utils.get_max_zoom renamed rio_cogeo.utils.get_zooms and now return min/max zoom.

+

2.0a5 (2020-07-31)

+
    +
  • move most of the cogeo info code in rio_cogeo.cogeo.cog_info api
  • +
  • add cog_validation info in cogeo info result
  • +
  • cog_validate returns a tuple (is_valid, errors, warnings) (#142, co-author with @geospatial-jeff)
  • +
  • add scale, offset, image tags and band color interpretation in cog_info (#145, #146 and #147)
  • +
+

2.0a4 (2020-06-15)

+
    +
  • Force output width and height (#140)
  • +
+

2.0a3 (2020-06-15)

+
    +
  • add info CLI (#134)
  • +
  • use Deflate as default temporary compression (#137)
  • +
+

2.0a2 (2020-05-20)

+
    +
  • add --config CLI option to pass additional GDAL Configuration options (#135)
  • +
+

2.0a1 (2020-05-07)

+
    +
  • Dropping python 2 (#128)
  • +
  • use new mercantile xy_bounds for better web-optimized file (#126)
  • +
  • Allow temporary file on disk when using MemoryFile output
  • +
  • add --blocksize option in CLI (#131)
  • +
  • depreciate rio_cogeo.utils.get_maximum_overview_level and use rasterio.rio.overview.get_maximum_overview_level (#132)
  • +
+

1.1.10 (2020-02-21)

+
    +
  • Transfer colormap (#121)
  • +
+

1.1.9 (2020-02-06)

+
    +
  • Transfer scale and offset values to output COG (#118)
  • +
+

1.1.8 (2020-01-08)

+
    +
  • Transfer color interpretation value to output COG (#113) * Thanks @pierotofy
  • +
  • Cast dataset_mask returned by rasterio to uint8 to overcome a bug in rasterio 1.1.2 (#115)
  • +
+

1.1.7 (2019-12-02)

+
    +
  • add strict option to cog_validate to treat warnings as error (#109) * Thanks @pierotofy
  • +
  • add documentation examples using MemoryFiles (#108 #107)
  • +
  • Switch to PHOTOMETRIC=MINISBLACK when PHOTOMETRIC is set to YCBCR for 1 band dataset (#41)
  • +
+

1.1.6 (2019-11-13)

+
    +
  • add -forward-band-tags options (#115)
  • +
+

1.1.5 (2019-10-04)

+
    +
  • add --allow-intermediate-compression option to reduce the memory/disk footprint (#103)
  • +
+

1.1.4 (2019-10-03)

+
    +
  • Fix support for optimizing open datasets, memfiles, and VRTs (#100 from j08lue)
  • +
+

1.1.3 (2019-09-16)

+
    +
  • Add lzma/lerc/lerc_deflate/lerc_zstd profiles (#97)
  • +
  • Add warnings and notes for non-standard compression (#97)
  • +
  • fix THREADS definition for GDAL config
  • +
+

1.1.2 (2019-09-12)

+
    +
  • Fix incorrect context behavior closing input Dataset (#94)
  • +
+

1.1.1 (2019-09-10)

+
    +
  • add safeguard to keep datatype from input to output files (#85)
  • +
+

CLI Changes: +* add -t, --dtype datatype option.

+

API Changes: +* add datatype option +* update for rasterio>=1.0.28 +* allow rasterio.io.DatasetReader input (#89)

+

Note: This release was deleted in PyPi.

+

1.1.0 (2019-07-16)

+
    +
  • check internal blocksize and adapt if raster is too small (#80)
  • +
+

1.0.0 (2019-04-19)

+
    +
  • add --web-optimized option to create a web optimized COG (#10)
  • +
  • add --latitude-adjustment/--global-maxzoom option to adjust MAX_ZOOM for global datasets
  • +
  • Web-optimized tests needs python3.6 (cogdumper)
  • +
  • add --resampling option to select the resampling algorithm when using --web-optimized
  • +
  • add --in-memory/--no-in-memory options to use temporyNamedd file instead of in-memory temp file.
  • +
+

1.0b3 (2019-03-30)

+

Breaking Changes:

+
    +
  • remove deprecated YCBCR profile
  • +
  • 512x512 dataset without internal tiling are valid
  • +
+

1.0b2 (2019-03-27)

+

Breaking Changes:

+
    +
  • Switch from JPEG to DEFLATE as default profile in CLI (#66)
  • +
+

1.0b1 (2019-03-25)

+

Breaking Changes:

+
    +
  • refactor utils.get_maximum_overview_level to get rasterio dataset +as input and reduce the number of dataset opennings (#61)
  • +
+

1.0b0 (2019-03-15)

+
    +
  • add more logging and --quiet option (#46)
  • +
  • add --overview-blocksize to set overview's internal tile size (#60)
  • +
+

Bug fixes:

+
    +
  • copy tags and description from input to output (#19)
  • +
  • copy input mask band to output mask
  • +
+

Breaking Changes:

+
    +
  • rio cogeo now has subcommands: 'create' and 'validate' (#6).
  • +
  • internal mask creation is now optional (--add-mask).
  • +
  • internal nodata or alpha channel can be forwarded to the output dataset.
  • +
  • removed default overview blocksize to be equal to the raw data blocksize (#60)
  • +
+

1.0dev10 (2019-02-12)

+
    +
  • allow non integer nodata value (#51)
  • +
  • fix GDAL blocksize options casting for overview calculation (#50)
  • +
+

1.0dev9 (2019-02-11)

+
    +
  • Renamed "ycbcr" profile's name to "jpeg" to reflect the compression name. + "ycbcr" profile will raise a "DeprecationWarning" (#44)
  • +
  • "webp" profile has been added to COG profiles. Exploitation of this new + compression mode will require GDAL 2.4 (#27)
  • +
  • Rio-cogeo can calculate the overview level based on the internal tile size + and the dataset width/height (#37)
  • +
+

1.0dev8 (2018-10-02)

+
    +
  • write tags in output file (#31)
  • +
  • add bilinear, cubic spline, lanczos resampling modes for overviews
  • +
+

1.0dev7 (2018-09-12)

+
    +
  • add resampling option for overviews (#28)
  • +
+

1.0dev6 (2018-08-23)

+
    +
  • Remove unnecessary compression for in-memory step (reduce runtime and memory usage) (#25)
  • +
+

1.0dev4 (2018-07-16)

+
    +
  • rasterio 1.0
  • +
+

1.0dev3 (2018-07-05)

+
    +
  • remove default bidx in cli (#17)
  • +
+

1.0dev2 (2018-06-28)

+
    +
  • Add ZSTD compressed COG profile (#14)
  • +
  • Fix warnings for useless boundless=True option (#13)
  • +
  • add BIGTIFF=IF_SAFER to COG profile (if BIGTIFF not set otherwise in the env)
  • +
+

Breaking Changes: +* replace "BAND" by "PIXEL" interleave in PACKBITS profile (#16)

+

1.0dev1(2018-16-13)

+
    +
  • Initial release. Requires Rasterio >= 1.0b1.
  • +
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/search/search_index.json b/search/search_index.json new file mode 100644 index 00000000..3a10f6b5 --- /dev/null +++ b/search/search_index.json @@ -0,0 +1 @@ +{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"rio-cogeo","text":"

Cloud Optimized GeoTIFF (COG) creation and validation plugin for Rasterio.

Documentation: cogeotiff.github.io/rio-cogeo/

Source Code: cogeotiff/rio-cogeo

"},{"location":"#cloud-optimized-geotiff","title":"Cloud Optimized GeoTIFF","text":"

This plugin aims to facilitate the creation and validation of Cloud Optimized GeoTIFF (COG or COGEO). While it respects the COG specifications, this plugin also enforces several features:

  • Internal overviews (User can remove overview with option --overview-level 0)
  • Internal tiles (default profiles have 512x512 internal tiles)

Important: in GDAL 3.1 a new COG driver has been added (doc, discussion), starting with rio-cogeo version 2.2, --use-cog-driver option was added to create COG using the COG driver.

"},{"location":"#install","title":"Install","text":"
$ pip install -U pip\n$ pip install rio-cogeo\n

Or install from source:

$ pip install -U pip\n$ pip install git+https://github.com/cogeotiff/rio-cogeo.git\n
"},{"location":"#gdal-version","title":"GDAL Version","text":"

It is recommended to use GDAL > 2.3.2. Previous versions might not be able to create proper COGs (ref: OSGeo/gdal#754).

More info in cogeotiff/rio-cogeo#55

"},{"location":"#more","title":"More","text":"

Blog post on good and bad COG formats: medium.com/@_VincentS_/do-you-really-want-people-using-your-data-ec94cd94dc3f

Checkout rio-glui or rio-viz rasterio plugins to explore COG locally in your web browser.

"},{"location":"#contribution-development","title":"Contribution & Development","text":"

See CONTRIBUTING.md

"},{"location":"#changes","title":"Changes","text":"

See CHANGES.md.

"},{"location":"#license","title":"License","text":"

See LICENSE

"},{"location":"API/","title":"Application programming interface (API)","text":"

rio-cogeo can also be integrated directly in your custom script. See rio_cogeo.cogeo.cog_translate function.

e.g:

from rio_cogeo.cogeo import cog_translate\n\ndef _translate(src_path, dst_path, profile=\"webp\", profile_options={}, **options):\n\"\"\"Convert image to COG.\"\"\"\n    # Format creation option (see gdalwarp `-co` option)\n    output_profile = cog_profiles.get(profile)\n    output_profile.update(dict(BIGTIFF=\"IF_SAFER\"))\n    output_profile.update(profile_options)\n\n    # Dataset Open option (see gdalwarp `-oo` option)\n    config = dict(\n        GDAL_NUM_THREADS=\"ALL_CPUS\",\n        GDAL_TIFF_INTERNAL_MASK=True,\n        GDAL_TIFF_OVR_BLOCKSIZE=\"128\",\n    )\n\n    cog_translate(\n        src_path,\n        dst_path,\n        output_profile,\n        config=config,\n        in_memory=False,\n        quiet=True,\n        **options,\n    )\n    return True\n
ref: github.com/developmentseed/cogeo-watchbot/blob/81df27470dd2eb7032d512c35af853b006d1c035/app/translator.py#L34-L56

"},{"location":"API/#using-the-api-with-in-memoryfile","title":"Using the API with in MemoryFile","text":"
  1. Create COG from numpy array
    import numpy\n\nimport mercantile\n\nfrom rasterio.io import MemoryFile\nfrom rasterio.transform import from_bounds\n\nfrom rio_cogeo.cogeo import cog_translate\nfrom rio_cogeo.profiles import cog_profiles\n\n# Create GeoTIFF profile\nbounds = mercantile.bounds(mercantile.Tile(0,0,0))\n\n# Rasterio uses numpy array of shape of `(bands, height, width)`\nwidth = 1024\nheight = 1024\nnbands = 3\n\nimg_array = tile = numpy.random.rand(nbands, height, width).astype(numpy.float32)\n\nsrc_transform = from_bounds(*bounds, width=width, height=height)\n\nsrc_profile = dict(\n    driver=\"GTiff\",\n    dtype=\"float32\",\n    count=nbands,\n    height=height,\n    width=width,\n    crs=\"epsg:4326\",\n    transform=src_transform,\n)\n\n\nwith MemoryFile() as memfile:\n    with memfile.open(**src_profile) as mem:\n        # Populate the input file with numpy array\n        mem.write(img_array)\n\n        dst_profile = cog_profiles.get(\"deflate\")\n        cog_translate(\n            mem,\n            \"my-output-cog.tif\",\n            dst_profile,\n            in_memory=True,\n            quiet=True,\n        )\n
  2. Create output COG in Memory
from rasterio.io import MemoryFile\n\nfrom rio_cogeo.cogeo import cog_translate\nfrom rio_cogeo.profiles import cog_profiles\n\nfrom boto3.session import Session as boto3_session\n\ndst_profile = cog_profiles.get(\"deflate\")\n\nwith MemoryFile() as mem_dst:\n    # Important, we pass `mem_dst.name` as output dataset path\n    cog_translate(\"my-input-file.tif\", mem_dst.name, dst_profile, in_memory=True)\n\n    # You can then use the memoryfile to do something else like\n    # upload to AWS S3\n    client = boto3_session.client(\"s3\")\n    client.upload_fileobj(mem_dst, \"my-bucket\", \"my-key\")\n
"},{"location":"Advanced/","title":"Advanced Topics","text":""},{"location":"Advanced/#web-optimized-cog","title":"Web-Optimized COG","text":"

rio-cogeo provide a --web-optimized option which aims to create a web-tiling friendly COG.

Output dataset features:

  • bounds and internal tiles aligned with web-mercator grid.
  • raw data and overviews resolution match mercator zoom level resolution.

Important

Because it will certainly create a larger file (with padding tiles on the side of the file), a nodata value, an alpha band or an internal mask should be present in the input dataset. If not the original data will be surrounded by black (0) data.

"},{"location":"Advanced/#internal-tile-size","title":"Internal tile size","text":"

By default rio cogeo will create a dataset with 512x512 internal tile size. This can be updated by passing --co BLOCKXSIZE=64 --co BLOCKYSIZE=64 options.

Web tiling optimization

Creating a Web-Optimized COG, means you'll get a file which is perfectly aligned (bounds and internal tiles) with the mercator grid and with resolution (for the raw data and overview) which map the mercator zoom level resolution. This enable to reduce the number of GET request a dynamic tiling service needs to do to create a map tile from your COG.

if the input dataset is not aligned to web mercator grid, the tiler will need to fetch multiple internal tiles.

"},{"location":"Advanced/#overview-levels","title":"Overview levels","text":"

By default rio cogeo will calculate the optimal overview level based on dataset size and internal tile size (overview should not be smaller than internal tile size (e.g 512px). Overview level will be translated to decimation level of power of two:

overview_level = 3\noverviews = [2 ** j for j in range(1, overview_level + 1)]\nprint(overviews)\n[2, 4, 8]\n
"},{"location":"Advanced/#band-metadata","title":"Band metadata","text":"

By default rio cogeo DO NOT forward band metadata (e.g statistics) to the output dataset.

$ gdalinfo my_file.tif\n...\nBand 1 Block=576x1 Type=Float64, ColorInterp=Gray\n  NoData Value=999999986991104\n  Unit Type: mol mol-1\n  Metadata:\n    long_name=CO2 Dry-Air Column Average\n    missing_value=9.9999999e+14\n    NETCDF_DIM_time=0\n    NETCDF_VARNAME=XCO2MEAN\n    units=mol mol-1\n    _FillValue=9.9999999e+14\n\n$ rio cogeo my_file.tif my_cog.tif --blocksize 256\n\n$ gdalinfo my_cog.tif\n...\nBand 1 Block=256x256 Type=Float64, ColorInterp=Gray\n  NoData Value=999999986991104\n  Overviews: 288x181\n

You can use --forward-band-tags to forwards the band metadata to output dataset.

$ rio cogeo create my_file.tif my_cog.tif --blocksize 256 --forward-band-tags\n$ gdalinfo my_cog.tif\n...\nBand 1 Block=256x256 Type=Float64, ColorInterp=Gray\n  NoData Value=999999986991104\n  Overviews: 288x181\n  Metadata:\n    long_name=CO2 Dry-Air Column Average\n    missing_value=9.9999999e+14\n    NETCDF_DIM_time=0\n    NETCDF_VARNAME=XCO2MEAN\n    units=mol mol-1\n    _FillValue=9.9999999e+14\n
"},{"location":"Advanced/#nodata-alpha-and-mask","title":"Nodata, Alpha and Mask","text":"

By default rio-cogeo will forward any nodata value or alpha channel to the output COG.

If your dataset type is Byte or Unit16, you could use internal bit mask (with the --add-mask option) to replace the Nodata value or Alpha band in output dataset (supported by most GDAL based backends).

Note: when adding a mask with an input dataset having an alpha band you'll need to use the bidx options to remove it from the output dataset.

# Replace the alpha band by an internal mask\n$ rio cogeo mydataset_withalpha.tif mydataset_withmask.tif --cog-profile raw --add-mask --bidx 1,2,3\n

Important

Using internal nodata value with lossy compression (webp, jpeg) is not recommended. Please use internal masking (or alpha band if using webp).

"},{"location":"CLI/","title":"Command-line interface (CLI)","text":"

rio-cogeo modules adds a cogeo sub-command to your rasterio (rio) CLI. Three (3) commands are then available: create, info and validate.

$ rio cogeo --help\n  Usage: rio cogeo [OPTIONS] COMMAND [ARGS]...\n\n  Rasterio cogeo subcommands.\n\n  Options:\n    --version  Show the version and exit.\n    --help     Show this message and exit.\n\n  Commands:\n    create    Create COGEO\n    info      Lists information about a raster dataset.\n    validate  Validate COGEO\n
"},{"location":"CLI/#create","title":"Create","text":"
$ rio cogeo create --help\n  Usage: rio cogeo create [OPTIONS] INPUT OUTPUT\n\n    Create Cloud Optimized Geotiff.\n\n  Options:\n    --bidx, -b                        Band indexes to copy.\n    --cog-profile, -p                 CloudOptimized GeoTIFF profile (default: deflate). [jpeg|webp|zstd|lzw|deflate|packbits|lzma|lerc|lerc_deflate|lerc_zstd|raw]\n    --nodata                          Set nodata masking values for input dataset.\n    --add-mask                        Force output dataset creation with an internal mask (convert alpha band or nodata to mask).\n    --blocksize                       Overwrite profile's tile size.\n    --dtype, -t                       Output data type. [ubyte|uint8|uint16|int16|uint32|int32|float32|float64]\n    --overview-level                  Overview level (if not provided, appropriate overview level will be selected until the smallest overview is smaller than the value of the internal blocksize)\n    --overview-resampling             Overview creation resampling algorithm (default: nearest).  [nearest|bilinear|cubic|cubic_spline|lanczos|average|mode|gauss]\n    --overview-blocksize              Overview's internal tile size (default defined by GDAL_TIFF_OVR_BLOCKSIZE env or 128)\n    --web-optimized, -w               Create COGEO optimized for Web.\n    --zoom-level-strategy             Strategy to determine zoom level (default: auto).  [lower|upper|auto]\n    --zoom-level                      Zoom level number for the highest resolution. If this option is specified, `--zoom-level-strategy` is ignored.\n    --aligned-levels                  Number of overview levels for which GeoTIFF tile and tiles defined in the tiling scheme match.\n    --resampling, -r                  Resampling algorithm (default: nearest). Will only be applied with the `--web-optimized` option.  [nearest|bilinear|cubic|cubic_spline|lanczos|average|mode|max|min|med|q1|q3|sum]\n    --in-memory / --no-in-memory      Force processing raster in memory / not in memory (default: process in memory if smaller than 120 million pixels)\n    --allow-intermediate-compression  Allow intermediate file compression to reduce memory/disk footprint.\n    --forward-band-tags               Forward band tags to output bands.\n    --forward-ns-tags                 Forward namespaced tags to output dataset.\n    --threads                         Number of worker threads for multi-threaded compression (default: ALL_CPUS)\n    --use-cog-driver                  Use GDAL COG Driver (require GDAL>=3.1).\n    --tms PATH                        Path to TileMatrixSet JSON file.\n    --co, --profile                   Driver specific creation options. See the documentation for the selected output driver for more information.\n    --config                          GDAL configuration options.\n    --quiet, -q                       Remove progressbar and other non-error output.\n    --help                            Show this message and exit.\n
"},{"location":"CLI/#validate","title":"Validate","text":"
$ rio cogeo validate --help\nUsage: rio cogeo validate [OPTIONS] INPUT\n\n  Validate Cloud Optimized Geotiff.\n\nOptions:\n  --strict             Treat warnings as errors.\n  --config NAME=VALUE  GDAL configuration options.\n  --help               Show this message and exit.\n

The strict options will treat warnings (e.g missing overviews) as errors.

Using the --config option can be useful to restrict GDAL environment. By default GDAL will check for external files (such as overviews), which could make a COG invalid. To force GDAL to only consider the input file you can use --config GDAL_DISABLE_READDIR_ON_OPEN=EMPTY_DIR.

e.g:

$ rio cogeo validate s3://bucket/geo.tif --config GDAL_DISABLE_READDIR_ON_OPEN=EMPTY_DIR --config AWS_NO_SIGN_REQUEST=YES\n

"},{"location":"CLI/#info","title":"Info","text":"

(extended version or rio info).

$ rio cogeo info --help\nUsage: rio cogeo info [OPTIONS] INPUT\n\n  Dataset info.\n\nOptions:\n  --json  Print as JSON.\n  --help  Show this message and exit.\n
"},{"location":"CLI/#examples","title":"Examples","text":"
# Create a COGEO with DEFLATE compression (Using default `Deflate` profile)\n$ rio cogeo create mydataset.tif mydataset_jpeg.tif\n\n# Validate COGEO\n$ rio cogeo validate mydataset_jpeg.tif\n\n# Create a COGEO with JPEG profile and the first 3 bands of the data and add internal mask\n$ rio cogeo create mydataset.tif mydataset_jpeg.tif -b 1,2,3 --add-mask --cog-profile jpeg\n\n# List Raster info\n$ rio cogeo info mydataset_jpeg.tif\nDriver: GTiff\nFile: mydataset_jpeg.tif\nCOG: True\nCompression: DEFLATE\nColorSpace: None\n\nProfile\n    Width:            10980\nHeight:           10980\nBands:            1\nTiled:            True\n    Dtype:            uint16\n    NoData:           0.0\n    Alpha Band:       False\n    Internal Mask:    False\n    Interleave:       BAND\n    Colormap:         False\n\nGeo\n    Crs:              EPSG:32634\n    Origin:           (699960.0, 3600000.0)\nResolution:       (10.0, -10.0)\nBoundingBox:      (699960.0, 3490200.0, 809760.0, 3600000.0)\nMinZoom:          10\nMaxZoom:          19\n\nIFD\n    Id      Size           BlockSize     Decimation\n    0       10980x10980    1024x1024     0\n1       5490x5490      128x128       2\n2       2745x2745      128x128       4\n3       1373x1373      128x128       8\n4       687x687        128x128       16\n
"},{"location":"Is_it_a_COG/","title":"How to recognize a COG and how to create a proper one!","text":"

Requirements

  • python 3.7
  • rio-cogeo

$ pip install rio-cogeo

The COG Specification is pretty basic

A cloud optimized GeoTIFF is a regular GeoTIFF file, aimed at being hosted on a HTTP file server, whose internal organization is friendly for consumption by clients issuing HTTP GET range request (\"bytes: start_offset-end_offset\" HTTP header). It contains at its beginning the metadata of the full resolution imagery, followed by the optional presence of overview metadata, and finally the imagery itself. To make it friendly with streaming and progressive rendering, we recommend starting with the imagery of the smallest overview and finishing with the imagery of the full resolution level.

Ref: github.com/cogeotiff/cog-spec/blob/master/spec.md

In Short, the specification just means you MUST create a GeoTIFF with internal block (tile) and the header must be ordered.

From a command line point of view, it just means you need to add --co TILED=TRUE in a gdal_translate command.

"},{"location":"Is_it_a_COG/#1-get-some-data","title":"1. Get some data","text":"

Natural Earth web site host really neat raster and vector datasets. Let's download a large scale raster image: www.naturalearthdata.com/downloads/50m-raster-data/50m-cross-blend-hypso/

$ wget https://naciscdn.org/naturalearth/50m/raster/HYP_50M_SR.zip\n
"},{"location":"Is_it_a_COG/#2-inspect-the-data","title":"2. Inspect the data","text":"

Here is what we want to look at:

  • the size in row x lines
  • the data type (byte, float, complex \u2026)
  • the internal block size
  • the presence of overview or not
$ rio cogeo info HYP_50M_SR.tif\nDriver: GTiff\nFile: /Users/vincentsarago/Downloads/HYP_50M_SR/HYP_50M_SR.tif\nCompression: None\nColorSpace: None\n\nProfile\n    Width:            10800\n    Height:           5400\n    Bands:            3\n    Tiled:            False\n    Dtype:            uint8\n    NoData:           None\n    Alpha Band:       False\n    Internal Mask:    False\n    Interleave:       PIXEL\n    ColorMap:         False\n\nGeo\n    Crs:              EPSG:4326\n    Origin:           (-179.99999999999997, 90.0)\n    Resolution:       (0.03333333333333, -0.03333333333333)\n    BoundingBox:      (-179.99999999999997, -89.99999999998201, 179.99999999996405, 90.0)\n\nIFD\n    Id      Size           BlockSize     Decimation\n    0       10800x5400     10800x1       0\n

What we can see from the rio cogeo info output:

  • The raster has 3 bands
  • The data type is Byte (0 \u2192 255)
  • It's not internally tiled (Tiled: false and BlockSize=10800x1)
  • There is no overview (Only one IFD)

With those informations we already know the GeoTIFF is not a COG (no internal blocks), but let's confirm with the validation script.

"},{"location":"Is_it_a_COG/#3-cog-validation","title":"3. COG validation","text":"
$ rio cogeo validate HYP_50M_SR.tif\nThe following warnings were found:\n- The file is greater than 512xH or 512xW, it is recommended to include internal overviews\n\nThe following errors were found:\n- The file is greater than 512xH or 512xW, but is not tiled\n- The offset of the main IFD should be 8 for ClassicTIFF or 16 for BigTIFF. It is 174982088 instead\n- The offset of the first block of the image should be after its IFD\n/Users/vincentsarago/Downloads/HYP_50M_SR/HYP_50M_SR.tif is NOT a valid cloud optimized GeoTIFF\n

As mentioned earlier, the validation script confirms the GeoTIFF is not internally tiled and doesn't have overviews.

"},{"location":"Is_it_a_COG/#4-cog-creation","title":"4. COG creation","text":"

Creating a valid Cloud Optimized GeoTIFF, is not just about creating internal tiles and/or internal overviews. The file internal structure has to be specific and require a complete copy of a file, which is what rio-cogeo does internally.

$ rio cogeo create HYP_50M_SR.tif HYP_50M_SR_COG.tif\nReading input: /Users/vincentsarago/Downloads/HYP_50M_SR/HYP_50M_SR.tif\n    [####################################]  100%\nAdding overviews...\nUpdating dataset tags...\nWriting output to: /Users/vincentsarago/Downloads/HYP_50M_SR/HYP_50M_SR_COG.tif\n

You could get the same COG with GDAL commands

$ gdal_translate HYP_50M_SR.tif tmp.tif -co TILED=YES -co COMPRESS=DEFLATE\n$ gdaladdo -r nearest tmp.tif 2 4 8 16 32\n$ gdal_translate tmp.tif HYP_50M_SR_COG.tif -co TILED=YES -co COMPRESS=DEFLATE -co COPY_SRC_OVERVIEWS=YES\n

By default rio-cogeo will create a COG with 512x512 blocksize (for the raw resolution) and use DEFLATE compression to reduce file size.

$ rio cogeo info HYP_50M_SR_COG.tif\nDriver: GTiff\nFile: /Users/vincentsarago/Downloads/HYP_50M_SR/HYP_50M_SR_COG.tif\nCompression: DEFLATE\nColorSpace: None\n\nProfile\n    Width:            10800\n    Height:           5400\n    Bands:            3\n    Tiled:            True\n    Dtype:            uint8\n    NoData:           None\n    Alpha Band:       False\n    Internal Mask:    False\n    Interleave:       PIXEL\n    ColorMap:         False\n\nGeo\n    Crs:              EPSG:4326\n    Origin:           (-179.99999999999997, 90.0)\n    Resolution:       (0.03333333333333001, -0.03333333333333001)\n    BoundingBox:      (-179.99999999999997, -89.99999999998204, 179.9999999999641, 90.0)\n\nIFD\n    Id      Size           BlockSize     Decimation\n    0       10800x5400     512x512       0\n    1       5400x2700      128x128       2\n    2       2700x1350      128x128       4\n    3       1350x675       128x128       8\n    4       675x338        128x128       16\n

The importance of the compression

$ ls -lah\n-rw-r--r--@  1 youpi  staff   167M Oct 18  2014 HYP_50M_SR.tif\n-rw-r--r--   1 youpi  staff    58M Jun 12 14:56 HYP_50M_SR_COG.tif\n

By using rio-cogeo, we are not only creating a valid COG with internal tiling but we are also adding internal overviews (which let us get previews of the raw resolution with few GET requests).

Even with the addition of 4 levels of overviews (see IFD section in previous rio cogeo info output), we managed to reduce the file size by 3 (167Mb \u2192 58Mb), and this is because rio cogeo applies Deflate compression by default to the COG.

More Magic ?

As seen in the first rio cogeo info output, the data has 3 bands (RGB) and is of Uint8 data type. Because of this configuration, we can use even more efficient compression like JPEG or WEBP.

$ rio cogeo create HYP_50M_SR.tif HYP_50M_SR_COG_jpeg.tif -p jpeg\nReading input: /Users/vincentsarago/Downloads/HYP_50M_SR/HYP_50M_SR.tif\n    [####################################]  100%\nAdding overviews...\nUpdating dataset tags...\nWriting output to: /Users/vincentsarago/Downloads/HYP_50M_SR/HYP_50M_SR_COG_jpeg.tif\n\n$ ls -lah\n-rw-r--r--@  1 vincentsarago  staff   167M Oct 18  2014 HYP_50M_SR.tif\n-rw-r--r--   1 vincentsarago  staff    58M Jun 12 14:56 HYP_50M_SR_COG.tif\n-rw-r--r--   1 vincentsarago  staff   4.8M Jun 15 11:08 HYP_50M_SR_COG_jpeg.tif\n

Now, our output file is only 4.8Mb, which is only ~3% of the original size \ud83d\ude31.

Note:

  • JPEG compression is not lossless but lossy, meaning we will loose some information (change in pixel values) but if you need a COG for visual purposes the gain in size might be worth it.
  • WEBP compression has a configuration option to be lossless and will result is a file which will be ~50% smaller than the deflate version. Sadly WEBP is not provided by default in geospatial software.
"},{"location":"Is_it_a_COG/#5-visualize","title":"5. Visualize","text":"

You can either load the COG in QGIS or use our plugin (rio-viz) to load it in a web browser.

$ pip install rio-viz\n$ rio viz HYP_50M_SR_COG.tif\n

"},{"location":"contributing/","title":"Contributing","text":"

Issues and pull requests are more than welcome.

dev install

$ git clone https://github.com/cogeotiff/rio-cogeo.git\n$ cd rio-cogeo\n$ pip install -e .[\"test\",\"dev\"]\n
You can then run the tests with the following command:

python -m pytest --cov rio_cogeo --cov-report term-missing\n
"},{"location":"contributing/#pre-commit","title":"pre-commit","text":"

This repo is set to use pre-commit to run isort, flake8, pydocstring, black (\"uncompromising Python code formatter\") and mypy when committing new code.

$ pre-commit install\n
"},{"location":"contributing/#docs","title":"Docs","text":"
$ git clone https://github.com/cogeotiff/rio-cogeo.git\n$ cd rio-cogeo\n$ pip install -e .[\"docs\"]\n

Hot-reloading docs:

$ mkdocs serve\n

To manually deploy docs (note you should never need to do this because Github Actions deploys automatically for new commits.):

$ mkdocs gh-deploy\n
"},{"location":"profile/","title":"COG Profiles","text":"

rio-cogeo defines default Cloud Optimized GeoTIFF profiles which user can use with the CLI or directly with the API.

Default profiles are tiled (tiled=True) with 512x512 blocksizes.

from rio_cogeo.profiles import cog_profiles\n\ncog_profiles\n> {\n    'jpeg': {'driver': 'GTiff', 'interleave': 'pixel', 'tiled': True, 'blockxsize': 512, 'blockysize': 512, 'compress': 'JPEG', 'photometric': 'YCbCr'},\n    'webp': {'driver': 'GTiff', 'interleave': 'pixel', 'tiled': True, 'blockxsize': 512, 'blockysize': 512, 'compress': 'WEBP'},\n    'zstd': {'driver': 'GTiff', 'interleave': 'pixel', 'tiled': True, 'blockxsize': 512, 'blockysize': 512, 'compress': 'ZSTD'},\n    'lzw': {'driver': 'GTiff', 'interleave': 'pixel', 'tiled': True, 'blockxsize': 512, 'blockysize': 512, 'compress': 'LZW'},\n    'deflate': {'driver': 'GTiff', 'interleave': 'pixel', 'tiled': True, 'blockxsize': 512, 'blockysize': 512, 'compress': 'DEFLATE'}\n    'packbits': {'driver': 'GTiff', 'interleave': 'pixel', 'tiled': True, 'blockxsize': 512, 'blockysize': 512, 'compress': 'PACKBITS'},\n    'lzma': {'driver': 'GTiff', 'interleave': 'pixel', 'tiled': True, 'blockxsize': 512, 'blockysize': 512, 'compress': 'LZMA'},\n    'lerc': {'driver': 'GTiff', 'interleave': 'pixel', 'tiled': True, 'blockxsize': 512, 'blockysize': 512, 'compress': 'LERC'},\n    'lerc_deflate': {'driver': 'GTiff', 'interleave': 'pixel', 'tiled': True, 'blockxsize': 512, 'blockysize': 512, 'compress': 'LERC_DEFLATE'},\n    'lerc_zstd': {'driver': 'GTiff', 'interleave': 'pixel', 'tiled': True, 'blockxsize': 512, 'blockysize': 512, 'compress': 'LERC_ZSTD'},\n    'raw': {'driver': 'GTiff', 'interleave': 'pixel', 'tiled': True, 'blockxsize': 512, 'blockysize': 512}\n}\n

JPEG

  • JPEG compression
  • PIXEL interleave
  • YCbCr (3 bands) colorspace or MINISBLACK (1 band)
  • limited to uint8 datatype and 3 bands data

WEBP

  • WEBP compression
  • PIXEL interleave
  • limited to uint8 datatype and 3 or 4 bands data
  • Non-Standard, might not be supported by software not build against GDAL+internal libtiff + libwebp
  • Available for GDAL>=2.4.0

ZSTD

  • ZSTD compression
  • PIXEL interleave
  • Non-Standard, might not be supported by software not build against GDAL + internal libtiff + libzstd
  • Available for GDAL>=2.3.0

Note in Nov 2018, there was a change in libtiff's ZSTD tags which create incompatibility for old ZSTD compressed GeoTIFF (link)

LZW

  • LZW compression
  • PIXEL interleave

DEFLATE

  • DEFLATE compression
  • PIXEL interleave

PACKBITS

  • PACKBITS compression
  • PIXEL interleave

LZMA

  • LZMA compression
  • PIXEL interleave

LERC

  • LERC compression
  • PIXEL interleave
  • Default MAX_Z_ERROR=0 (lossless)
  • Non-Standard, might not be supported by software not build against GDAL + internal libtiff
  • Available for GDAL>=2.4.0

LERC_DEFLATE

  • LERC_DEFLATE compression
  • PIXEL interleave
  • Default MAX_Z_ERROR=0 (lossless)
  • Non-Standard, might not be supported by software not build against GDAL + internal libtiff + libzstd
  • Available for GDAL>=2.4.0

LERC_ZSTD

  • LERC_ZSTD compression
  • PIXEL interleave
  • Default MAX_Z_ERROR=0 (lossless)
  • Non-Standard, might not be supported by software not build against GDAL + internal libtiff + libzstd
  • Available for GDAL>=2.4.0

RAW

  • NO compression
  • PIXEL interleave
"},{"location":"profile/#custom","title":"Custom","text":"

Profiles can be extended by providing '--co' option in command line

# Create a COGEO without compression and with 1024x1024 block size and 256 overview blocksize\n$ rio cogeo create mydataset.tif mydataset_raw.tif --co BLOCKXSIZE=1024 --co BLOCKYSIZE=1024 --cog-profile raw --overview-blocksize 256\n

See gdal.org/drivers/raster/gtiff.html#creation-options for full details of creation options.

"},{"location":"release-notes/","title":"Release Notes","text":""},{"location":"release-notes/#500-2023-07-25","title":"5.0.0 (2023-07-25)","text":"
  • update morecantile requirement to >=5.0,<6.0 (author @mentaljam, cogeotiff/rio-cogeo!267)
  • update pydantic requirement to ~=2.0 (author @mentaljam, cogeotiff/rio-cogeo!267)
  • fix pydantic deprecation warnings (author @mentaljam, cogeotiff/rio-cogeo!267)
  • replace BaseModel.json with BaseModel.model_dump_json
  • replace BaseModel.dict with BaseModel.model_dump
  • replace class Config with model_config class variables
"},{"location":"release-notes/#401-2023-07-11","title":"4.0.1 (2023-07-11)","text":"
  • limit pydantic requirement to `~=1.0``
"},{"location":"release-notes/#400-2023-05-31","title":"4.0.0 (2023-05-31)","text":"
  • update morecantile requirement to >=4.0.0
  • native support for all TileMatrixSet (with respect of the TMS spec 2.0)
  • add --tms option to specify a path to a TileMatrixSet JSON file
  • switch resampling enums to python Literal

breaking change

  • Web optimization is now done in rio-cogeo instead of GDAL, when using --web-optimized and --use-cog-driver options

  • switch from using TILING_SCHEME namespaced tags to simple TILING_SCHEME_ prefixed metadata

# before\nwith rasterio.open(\"cog_web.tif\") as src:\n    print(src.tags(ns=\"TILING_SCHEME\"))\n>>> {\n    \"NAME\": \"WebMercatorQuad\",\n    \"ZOOM_LEVEL\": \"18\",\n}\n\n# now\nwith rasterio.open(\"cog_web.tif\") as src:\n    print(src.tags())\n>>> {\n    \"TILING_SCHEME_NAME\": \"WebMercatorQuad\",\n    \"TILING_SCHEME_ZOOM_LEVEL\": \"18\",\n}\n
"},{"location":"release-notes/#352-2023-05-22","title":"3.5.2 (2023-05-22)","text":"
  • Flag GeoTIFFs with invalidated optimizations as invalid COGs (author @mplough-kobold, cogeotiff/rio-cogeo!260)
"},{"location":"release-notes/#351-2023-04-06","title":"3.5.1 (2023-04-06)","text":"
  • Use Case-insensitive check for external overviews (author @mplough-kobold, cogeotiff/rio-cogeo!252)
  • Use destination directory for the temporary file
"},{"location":"release-notes/#350-2022-10-26","title":"3.5.0 (2022-10-26)","text":"
  • add python 3.11 support

Breaking Changes

  • remove python 3.7 support
  • require rasterio >= 1.3.3 (ref: cogeotiff/rio-cogeo?248)
  • COG can be have blocksize (bigger than their height or width) and be tiled even if they are smaller than 512x512
# before\nrio cogeo create image_51x51.tif cog.tif\nrio cogeo info cog.tif --json | jq '.IFD'\n>>> [\n{\n\"Level\": 0,\n    \"Width\": 51,\n    \"Height\": 51,\n    \"Blocksize\": [\n51,\n      51\n],\n    \"Decimation\": 0\n}\n]\nrio cogeo info cog.tif --json | jq '.Profile.Tiled'\n>>> false\n\n# now\nrio cogeo create image_51x51.tif cog.tif\nrio cogeo info cog.tif --json | jq '.IFD'\n>>> [\n{\n\"Level\": 0,\n    \"Width\": 51,\n    \"Height\": 51,\n    \"Blocksize\": [\n512,\n      512\n],\n    \"Decimation\": 0\n}\n]\nrio cogeo info cog.tif --json | jq '.Profile.Tiled'\n>>> true\n
"},{"location":"release-notes/#341-2022-09-14","title":"3.4.1 (2022-09-14)","text":"
  • avoid breaking change for cog_info() when previously passing *kwargs to cog_validate
"},{"location":"release-notes/#340-2022-09-05","title":"3.4.0 (2022-09-05)","text":"
  • add python 3.10 support
  • allow forwarding namespaced metadata to output dataset
  • set GDAL config for all info methods (previously GDAL's configs were only use in the COG validation step)
"},{"location":"release-notes/#330-2022-06-24","title":"3.3.0 (2022-06-24)","text":"
  • allow non-GeoTIFF in cog_validate
  • allow config option in rio cogeo info CLI
"},{"location":"release-notes/#320-2022-04-05","title":"3.2.0 (2022-04-05)","text":"
  • Switch to pyproject.toml (cogeotiff/rio-cogeo!232)
  • add --zoom-level option to define dataset coarsest zoom level, when creating web optimized COG.
"},{"location":"release-notes/#310-2022-02-18","title":"3.1.0 (2022-02-18)","text":"
  • Fix equivalence for rio-cogeo and GDAL definition of aligned_levels

Breaking Changes:

  • update morecantile requirement to >=3.1,<4.0. WebOptimized COGs will is now aligned with GDAL and Mercantile TMS definition.
"},{"location":"release-notes/#303-2021-02-14","title":"3.0.3 (2021-02-14)","text":"
  • use rasterio.vrt.WarpedVRT in utils.get_web_optimized_params to better handle dataset with GEOS projection (crossing dateline).
"},{"location":"release-notes/#302-2021-12-16","title":"3.0.2 (2021-12-16)","text":"
  • remove usage of (soon to be deprecated) rasterio.path (cogeotiff/rio-cogeo!222)
  • add band metadata in cog_info output and update rio_cogeo.models.Info (cogeotiff/rio-cogeo!223)
"},{"location":"release-notes/#301-2021-10-27","title":"3.0.1 (2021-10-27)","text":"
  • update test and dev dependencies to rio-tiler>=3.0.0a0
"},{"location":"release-notes/#300-2021-09-30","title":"3.0.0 (2021-09-30)","text":"
  • no changes since 3.0.0a0
"},{"location":"release-notes/#300a0-2021-09-23","title":"3.0.0a0 (2021-09-23)","text":"
  • update to morecantile>=3.0
  • raise warning when using incompatible options for GDAL COG driver (cogeotiff/rio-cogeo!212)
"},{"location":"release-notes/#231-2021-07-06","title":"2.3.1 (2021-07-06)","text":"
  • update click version requirement to >=7.0 to make sure click.Choice supports the case_sensitive option.
"},{"location":"release-notes/#230-2021-06-25","title":"2.3.0 (2021-06-25)","text":"
  • allow external configuration (GDAL Env) for cog_validate (cogeotiff/rio-cogeo!206)
from rio_cogeo import cog_validate\n\nassert cog_validate(\"cog.tif\", congig={\"GDAL_DISABLE_READDIR_ON_OPEN\": \"EMPTY_DIR\"})[0]\n

In previous version we were forcing GDAL_DISABLE_READDIR_ON_OPEN=FALSE in cog_validate function to check for external overviews.

Starting with version 2.3, it's up to the user to set the wanted GDAL configuration (e.g EMPTY_DIR: no external file check, FALSE: check for external files)

"},{"location":"release-notes/#223-2021-06-18","title":"2.2.3 (2021-06-18)","text":"
  • use opened file for click progressbar (cogeotiff/rio-cogeo!204)
"},{"location":"release-notes/#222-2021-06-01","title":"2.2.2 (2021-06-01)","text":"
  • Add dictionary access to Info model (author @geospatial-jeff, cogeotiff/rio-cogeo!201)
  • remove unsupported resampling method for Warping in CLI options (author @drnextgis, cogeotiff/rio-cogeo!202)
"},{"location":"release-notes/#221-2021-05-19","title":"2.2.1 (2021-05-19)","text":"
  • replace missing rio-tiler dependencies with a custom BBox type definition (cogeotiff/rio-cogeo!198)
"},{"location":"release-notes/#220-2021-05-18","title":"2.2.0 (2021-05-18)","text":"
  • add pydantic models for info output (cogeotiff/rio-cogeo#191)
  • add use_cog_driver option to create COG using new GDAL COG Driver (cogeotiff/rio-cogeo!194)

Breaking Changes:

  • rio_cogeo.cogeo.cog_info now returns a pydantic model
from rio_cogeo.cogeo import cog_info\n\n# before\ninfo = cog_info(\"my.tif\")\nassert isinstance(info, dict)\nassert info[\"GEO\"][\"CRS\"]\n\n# now\nassert isinstance(info, rio_cogeo.models.Info)\nassert info.GEO.CRS\n
  • add TILING SCHEME in dataset namespaced metadata when creating WebOptimized COG (cogeotiff/rio-cogeo!193)
  • add more info in rio cogeo info Tags (cogeotiff/rio-cogeo!193)
# before\n$ rio cogeo create in.tif out.tif -w\n$ rio cogeo info out.tif | jq .Tags\n\n>>> {\n  \"AREA_OR_POINT\": \"Area\",\n  \"OVR_RESAMPLING_ALG\": \"NEAREST\"\n}\n\n# now\n$ rio cogeo create in.tif out.tif -w\n$ rio cogeo info out.tif | jq .Tags\n>> {\n  \"Image Metadata\": {\n    \"AREA_OR_POINT\": \"Area\",\n    \"DataType\": \"Generic\",\n    \"OVR_RESAMPLING_ALG\": \"NEAREST\"\n  },\n  \"Image Structure\": {\n    \"COMPRESSION\": \"DEFLATE\",\n    \"INTERLEAVE\": \"BAND\",\n    \"LAYOUT\": \"COG\"\n  },\n  \"Tiling Scheme\": {\n    \"NAME\": \"WEBMERCATORQUAD\",\n    \"ZOOM_LEVEL\": \"17\"\n  }\n}\n
  • update Web-Optimized configuration to match GDAL COG Driver (cogeotiff/rio-cogeo!193)

By default only the raw data will be aligned to the grid. To align overviews, the aligned_levels option can be used (wasn't really working in previous version).

  • rio_cogeo.utils.get_web_optimized_params has been refactored (cogeotiff/rio-cogeo!193)

  • cog_translate will now materialize Nodata or Alpha band to an internal mask automatically for JPEG compresssed output (cogeotiff/rio-cogeo!196)

# before\ncog_translate(raster_path_rgba, \"cogeo.tif\", jpeg_profile)\nwith rasterio.open(\"cogeo.tif\") as src:\n    assert src.count == 4\n    assert src.compression.value == \"JPEG\"\n    assert has_alpha_band(src)\n    assert not has_mask_band(src)\n\n# now\ncog_translate(raster_path_rgba, \"cogeo.tif\", jpeg_profile)\nwith rasterio.open(\"cogeo.tif\") as src:\n    assert src.count == 3\n    assert src.compression.value == \"JPEG\"\n    assert has_mask_band(src)\n
"},{"location":"release-notes/#214-2021-03-31","title":"2.1.4 (2021-03-31)","text":"
  • fix issue in validation when BLOCK_OFFSET_0 is None (cogeotiff/rio-cogeo#182)
"},{"location":"release-notes/#213-2021-03-03","title":"2.1.3 (2021-03-03)","text":"
  • add colormap options in cog_translate to allow a user to set or update a colormap
cmap = {0: (0, 0, 0, 0), 1: (1, 2, 3, 255)}\ncog_translate(\"boring.tif\", \"cogeo.tif\", deflate_profile, colormap=cmap)\nwith rasterio.open(\"cogeo.tif\") as cog:\n    print(cog.colormap(1)[1])\n\n>>> (1, 2, 3, 255)\n
  • add additional_cog_metadata options in cog_translate to allow the user to add more dataset metadatas
cog_translate(\"boring.tif\", \"cogeo.tif\", deflate_profile, additional_cog_metadata={\"comments\": \"I made this tiff with rio-cogeo\"})\n\nwith rasterio.open(\"cogeo.tif\") as cog:\n    print(cog.tags()[\"comment\"])\n\n>>> \"I made this tiff with rio-cogeo\"\n
"},{"location":"release-notes/#212-2021-02-10","title":"2.1.2 (2021-02-10)","text":"
  • remove useless path translation to pathlib and avoid side effect when using a URL (cogeotiff/rio-cogeo#178)
"},{"location":"release-notes/#211-2021-01-27","title":"2.1.1 (2021-01-27)","text":"
  • drop support for Python 3.5 (cogeotiff/rio-cogeo#173)
  • allow pathlib.PurePath object as input and output (cogeotiff/rio-cogeo#173)
  • add top-level exports (cogeotiff/rio-cogeo#169)
# before\nfrom rio_cogeo.cogeo import cog_translate, cog_validate, cog_info\nfrom rio_cogeo.profiles import cog_profiles\n\n# now\nfrom rio_cogeo import cog_translate, cog_validate, cog_info, cog_profiles\n
"},{"location":"release-notes/#210-2020-12-18","title":"2.1.0 (2020-12-18)","text":"
  • switch to morecantile and update the web-optimized creation method to better match GDAL 3.2.
  • add zoom_level_strategy options to match GDAL 3.2 COG driver.
  • add aligned_levels (cli and api) to select the level of overview to align with the TMS grid.

Breaking Changes: * removed --latitude-adjustment/--global-maxzoom option in the CLI * removed latitude_adjustment option in rio_cogeo.cogeo.cog_translate * updated overview blocksize to match the blocksize of the high resolution data (instead of default to 128) * for web-optimized COG, the highest overview level will be aligned with the TMS grid.

"},{"location":"release-notes/#201-2020-10-07","title":"2.0.1 (2020-10-07)","text":"
  • remove pkg_resources (pypa/setuptools#510)
"},{"location":"release-notes/#200-2020-10-05","title":"2.0.0 (2020-10-05)","text":"

There have been no changes since 2.0a9

"},{"location":"release-notes/#20a9-2020-10-03","title":"2.0a9 (2020-10-03)","text":"
  • Update max IFD offset to 300 bytes (cogeotiff/rio-cogeo#158)
"},{"location":"release-notes/#20a8-2020-09-28","title":"2.0a8 (2020-09-28)","text":"
  • Make sure Alpha band isn't considered as an internal mask by utils.has_mask_band (#156)
"},{"location":"release-notes/#20a7post1-2020-09-23","title":"2.0a7.post1 (2020-09-23)","text":"
  • Fix wrong min-zoom calculation in rio_cogeo.cogeo.cog_info
"},{"location":"release-notes/#20a7-2020-09-23","title":"2.0a7 (2020-09-23)","text":"
  • remove duplicate count information in rio_cogeo.cogeo.cog_info output (#150)
  • allow COG with IFD offset up to 200 bytes to accomodate with GDAL 3.1 changes (#151)
  • fix zoom level calculation in rio_cogeo.cogeo.cog_info
"},{"location":"release-notes/#20a6-2020-08-18","title":"2.0a6 (2020-08-18)","text":"
  • fix bug in cogeo.info when CRS in not set.
  • add minzoom/maxzoom in cogeo.info output.

Breaking Changes: * rio_cogeo.utils.get_max_zoom renamed rio_cogeo.utils.get_zooms and now return min/max zoom.

"},{"location":"release-notes/#20a5-2020-07-31","title":"2.0a5 (2020-07-31)","text":"
  • move most of the cogeo info code in rio_cogeo.cogeo.cog_info api
  • add cog_validation info in cogeo info result
  • cog_validate returns a tuple (is_valid, errors, warnings) (#142, co-author with @geospatial-jeff)
  • add scale, offset, image tags and band color interpretation in cog_info (#145, #146 and #147)
"},{"location":"release-notes/#20a4-2020-06-15","title":"2.0a4 (2020-06-15)","text":"
  • Force output width and height (#140)
"},{"location":"release-notes/#20a3-2020-06-15","title":"2.0a3 (2020-06-15)","text":"
  • add info CLI (#134)
  • use Deflate as default temporary compression (#137)
"},{"location":"release-notes/#20a2-2020-05-20","title":"2.0a2 (2020-05-20)","text":"
  • add --config CLI option to pass additional GDAL Configuration options (#135)
"},{"location":"release-notes/#20a1-2020-05-07","title":"2.0a1 (2020-05-07)","text":"
  • Dropping python 2 (#128)
  • use new mercantile xy_bounds for better web-optimized file (#126)
  • Allow temporary file on disk when using MemoryFile output
  • add --blocksize option in CLI (#131)
  • depreciate rio_cogeo.utils.get_maximum_overview_level and use rasterio.rio.overview.get_maximum_overview_level (#132)
"},{"location":"release-notes/#1110-2020-02-21","title":"1.1.10 (2020-02-21)","text":"
  • Transfer colormap (#121)
"},{"location":"release-notes/#119-2020-02-06","title":"1.1.9 (2020-02-06)","text":"
  • Transfer scale and offset values to output COG (#118)
"},{"location":"release-notes/#118-2020-01-08","title":"1.1.8 (2020-01-08)","text":"
  • Transfer color interpretation value to output COG (#113) * Thanks @pierotofy
  • Cast dataset_mask returned by rasterio to uint8 to overcome a bug in rasterio 1.1.2 (#115)
"},{"location":"release-notes/#117-2019-12-02","title":"1.1.7 (2019-12-02)","text":"
  • add strict option to cog_validate to treat warnings as error (#109) * Thanks @pierotofy
  • add documentation examples using MemoryFiles (#108 #107)
  • Switch to PHOTOMETRIC=MINISBLACK when PHOTOMETRIC is set to YCBCR for 1 band dataset (#41)
"},{"location":"release-notes/#116-2019-11-13","title":"1.1.6 (2019-11-13)","text":"
  • add -forward-band-tags options (#115)
"},{"location":"release-notes/#115-2019-10-04","title":"1.1.5 (2019-10-04)","text":"
  • add --allow-intermediate-compression option to reduce the memory/disk footprint (#103)
"},{"location":"release-notes/#114-2019-10-03","title":"1.1.4 (2019-10-03)","text":"
  • Fix support for optimizing open datasets, memfiles, and VRTs (#100 from j08lue)
"},{"location":"release-notes/#113-2019-09-16","title":"1.1.3 (2019-09-16)","text":"
  • Add lzma/lerc/lerc_deflate/lerc_zstd profiles (#97)
  • Add warnings and notes for non-standard compression (#97)
  • fix THREADS definition for GDAL config
"},{"location":"release-notes/#112-2019-09-12","title":"1.1.2 (2019-09-12)","text":"
  • Fix incorrect context behavior closing input Dataset (#94)
"},{"location":"release-notes/#111-2019-09-10","title":"1.1.1 (2019-09-10)","text":"
  • add safeguard to keep datatype from input to output files (#85)

CLI Changes: * add -t, --dtype datatype option.

API Changes: * add datatype option * update for rasterio>=1.0.28 * allow rasterio.io.DatasetReader input (#89)

Note: This release was deleted in PyPi.

"},{"location":"release-notes/#110-2019-07-16","title":"1.1.0 (2019-07-16)","text":"
  • check internal blocksize and adapt if raster is too small (#80)
"},{"location":"release-notes/#100-2019-04-19","title":"1.0.0 (2019-04-19)","text":"
  • add --web-optimized option to create a web optimized COG (#10)
  • add --latitude-adjustment/--global-maxzoom option to adjust MAX_ZOOM for global datasets
  • Web-optimized tests needs python3.6 (cogdumper)
  • add --resampling option to select the resampling algorithm when using --web-optimized
  • add --in-memory/--no-in-memory options to use temporyNamedd file instead of in-memory temp file.
"},{"location":"release-notes/#10b3-2019-03-30","title":"1.0b3 (2019-03-30)","text":"

Breaking Changes:

  • remove deprecated YCBCR profile
  • 512x512 dataset without internal tiling are valid
"},{"location":"release-notes/#10b2-2019-03-27","title":"1.0b2 (2019-03-27)","text":"

Breaking Changes:

  • Switch from JPEG to DEFLATE as default profile in CLI (#66)
"},{"location":"release-notes/#10b1-2019-03-25","title":"1.0b1 (2019-03-25)","text":"

Breaking Changes:

  • refactor utils.get_maximum_overview_level to get rasterio dataset as input and reduce the number of dataset opennings (#61)
"},{"location":"release-notes/#10b0-2019-03-15","title":"1.0b0 (2019-03-15)","text":"
  • add more logging and --quiet option (#46)
  • add --overview-blocksize to set overview's internal tile size (#60)

Bug fixes:

  • copy tags and description from input to output (#19)
  • copy input mask band to output mask

Breaking Changes:

  • rio cogeo now has subcommands: 'create' and 'validate' (#6).
  • internal mask creation is now optional (--add-mask).
  • internal nodata or alpha channel can be forwarded to the output dataset.
  • removed default overview blocksize to be equal to the raw data blocksize (#60)
"},{"location":"release-notes/#10dev10-2019-02-12","title":"1.0dev10 (2019-02-12)","text":"
  • allow non integer nodata value (#51)
  • fix GDAL blocksize options casting for overview calculation (#50)
"},{"location":"release-notes/#10dev9-2019-02-11","title":"1.0dev9 (2019-02-11)","text":"
  • Renamed \"ycbcr\" profile's name to \"jpeg\" to reflect the compression name. \"ycbcr\" profile will raise a \"DeprecationWarning\" (#44)
  • \"webp\" profile has been added to COG profiles. Exploitation of this new compression mode will require GDAL 2.4 (#27)
  • Rio-cogeo can calculate the overview level based on the internal tile size and the dataset width/height (#37)
"},{"location":"release-notes/#10dev8-2018-10-02","title":"1.0dev8 (2018-10-02)","text":"
  • write tags in output file (#31)
  • add bilinear, cubic spline, lanczos resampling modes for overviews
"},{"location":"release-notes/#10dev7-2018-09-12","title":"1.0dev7 (2018-09-12)","text":"
  • add resampling option for overviews (#28)
"},{"location":"release-notes/#10dev6-2018-08-23","title":"1.0dev6 (2018-08-23)","text":"
  • Remove unnecessary compression for in-memory step (reduce runtime and memory usage) (#25)
"},{"location":"release-notes/#10dev4-2018-07-16","title":"1.0dev4 (2018-07-16)","text":"
  • rasterio 1.0
"},{"location":"release-notes/#10dev3-2018-07-05","title":"1.0dev3 (2018-07-05)","text":"
  • remove default bidx in cli (#17)
"},{"location":"release-notes/#10dev2-2018-06-28","title":"1.0dev2 (2018-06-28)","text":"
  • Add ZSTD compressed COG profile (#14)
  • Fix warnings for useless boundless=True option (#13)
  • add BIGTIFF=IF_SAFER to COG profile (if BIGTIFF not set otherwise in the env)

Breaking Changes: * replace \"BAND\" by \"PIXEL\" interleave in PACKBITS profile (#16)

"},{"location":"release-notes/#10dev12018-16-13","title":"1.0dev1(2018-16-13)","text":"
  • Initial release. Requires Rasterio >= 1.0b1.
"}]} \ No newline at end of file diff --git a/sitemap.xml b/sitemap.xml new file mode 100644 index 00000000..5861ebc7 --- /dev/null +++ b/sitemap.xml @@ -0,0 +1,43 @@ + + + + https://cogeotiff.github.io/rio-cogeo/ + 2023-07-25 + daily + + + https://cogeotiff.github.io/rio-cogeo/API/ + 2023-07-25 + daily + + + https://cogeotiff.github.io/rio-cogeo/Advanced/ + 2023-07-25 + daily + + + https://cogeotiff.github.io/rio-cogeo/CLI/ + 2023-07-25 + daily + + + https://cogeotiff.github.io/rio-cogeo/Is_it_a_COG/ + 2023-07-25 + daily + + + https://cogeotiff.github.io/rio-cogeo/contributing/ + 2023-07-25 + daily + + + https://cogeotiff.github.io/rio-cogeo/profile/ + 2023-07-25 + daily + + + https://cogeotiff.github.io/rio-cogeo/release-notes/ + 2023-07-25 + daily + + \ No newline at end of file diff --git a/sitemap.xml.gz b/sitemap.xml.gz new file mode 100644 index 0000000000000000000000000000000000000000..7ff0ff66f43951778f04a799c23fde5804e2ab2d GIT binary patch literal 283 zcmV+$0p$K4iwFpb>c3u_l(oD^yTmAN?-9`2+2%XDh9xsm{flRUe>TPlaPX=Adu6V{0a2jjl+LC>| zKc#nUD>udHEkQ`4*-^>55QYaKrfK420`zJij=mM7yEu?Iiz4IqOm31`bHM4eRAEue zIfY`3#uhM`rs1s#-FV;zg*TWkx+ui#y}YU@^jOP0%dgYyHqCFM<*Z%Ubf;VkjfYQJ zD`US4aiN@;#4ps}@gCpyt4FMl%4w+A&bfP8{ZsC#GNDq{?)7=?s2W}H<}il%lh@8V hcx;S?wPSj)pa@cj0qFl>mln6K`~h|T?bf9Q005Yskn8{e literal 0 HcmV?d00001