Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding collection_to_atlas for exporting images from a collection. #154

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

lopezvoliver
Copy link
Member

@lopezvoliver lopezvoliver commented Sep 10, 2024

This pull request adds a new feature to the ee_plugin that makes it easy to export images from an image collection, while allowing the user to leverage all the features of the QGIS Print Layout.

Background and motivation

The ee.ImageCollection.getVideoThumbURL is a convenient method to export an animation of a collection. While it has some flexibility in terms of framesPerSecond and dimensions, the animation is limited in the sense that only the image appears on the map, and that it has a request size limit (which grows with the requested region and size of the image collection; the current limit is 26214400 pixels).

In QGIS, we can import a ee.Image using Map.addLayer provided by ee_plugin. We can also create a Print Layout, add a Map Item to the Layout, customize it, and then export it as an image. If there was a way to automatize this process, we could export the images as frames for an animation (the animation from frames can be done easily with tools such as ImageMagick).

Introducing the collection_to_atlas feature for ee_plugin

The new utility prepares a Print Layout that can be used to export the images from a collection easily.

Example

Consider the following EE code to generate an image collection of 12 monthly NDVI images from MODIS/061/MOD13A3:

collection = (ee.ImageCollection('MODIS/061/MOD13A3')
        .filterDate('2023-01-01', '2024-01-01')
        .select('NDVI')
        .map(lambda img: img.divide(10000))
)

Using getVideoThumbURL

Here's an example code (link to code editor snapshot) to generate the animation over a large region (for example, a rectangle from longitude -85 to -30, and latitude from -43 to 15) using getVideoThumbURL and the following visParams:

visParams = {
  'min': 0,
  'max': 1,
  'palette': [
    'ffffff', 'ce7e45', 'df923d', 'f1b555', 'fcd163', '99b718', '74a901',
    '66a000', '529400', '3e8601', '207401', '056201', '004c00', '023b01',
    '012e01', '011d01', '011301'
  ],
}

and here is the resulting animation:

Animation from getVideoThumbURL

Using collection_to_atlas

Here's the same example using the new proposed feature:

import ee
from ee_plugin.contrib import utils
ee.Initialize()
collection = (ee.ImageCollection('MODIS/061/MOD13A3')
        .filterDate('2023-01-01', '2024-01-01')
        .select('NDVI')
        .map(lambda img: img.divide(10000))
)
visParams = {
  'min': 0,
  'max': 1,
  'palette': [
    'ffffff', 'ce7e45', 'df923d', 'f1b555', 'fcd163', '99b718', '74a901',
    '66a000', '529400', '3e8601', '207401', '056201', '004c00', '023b01',
    '012e01', '011d01', '011301'
  ],
}

w, e, s, n = -85, -30, -43, 15  # Region of interest (rectangular bounds)
utils.collection_to_atlas(collection, 
                          xmin=w, xmax = e, ymin=s, ymax= n, 
                          visParams = visParams,
                          transparent_bg = True
                          )

After running the script in QGIS, the user can open the generated Print Layout named atlas-layout, optionally customize the Map Item, and finally export the Atlas using Atlas -> Export Atlas as images. Here's an example with a resolution close to the one created with the Code Editor above. However, note that the user may export at higher resolutions (e.g. 300 dpi).

Animation from collection_to_atlas

The animation was created from the exported frames using magick -dispose previous -loop 0 -delay 20 *.png ndvi.gif

More details

The collection_to_atlas utility prepares a Print Layout with a single Map Item which is controlled by Atlas. The utility loads images from a collection and creates one Map theme for each image, with the Map theme simply making the current image visible (and other images invisible). The user can then optionally customize the Print Layout and finally export the Atlas as images.

In detail, collection_to_atlas:

  • Adds each image as a Layer into the project.
  • Adds 1 rectangular vector layer named atlas-bounds
  • Adds one Map theme for each image into the project.
  • Creates one Print Layout with one Map Item.
  • The Layout has Atlas enabled and the Map is linked to atlas.

Here is what the user sees after running the example script above:

QGIS Project view after running example script

Here's a view of the Map themes:

Map themes

Here's an example of applying one Map theme:

QGIS Project view after applying one theme

Here's a view of the Layout Manager showing the created atlas-layout:

image

Finally, here's a view of the Layout showing the possibility of adding other elements to the Map, such as a grid:

atlas-layout example

The parameters for collection_to_atlas are:

  • collection: The ee.ImageCollection
  • xmin, xmax, ymin, ymax: The rectangular extent to be set to the Map in the Layout.
  • index: name of a unique index to identify each ee.Image. Defaults to "system:index"
  • visParams: Visualization parameters. Defaults to {}
  • width: Width (in millimeters) for the Map in the Layout.
  • margin: Margin (%) around the extent to leave blank in the Map within the Layout.
  • transparent_bg: Whether to make the background transparent.
  • layout_name: Name of the Layout created in the Project. Defaults to "atlas-layout"
  • poly_name: Name of the Vector Polygon that is created in the Map. Defaults to "atlas-bounds"
  • layer_attr: Name of the attribute to create in the vector Polygon. Defaults to "image"

@XavierCLL XavierCLL self-requested a review September 10, 2024 20:54
@XavierCLL
Copy link
Collaborator

Hi @lopezvoliver,

This is a remarkable contribution! Thanks you! Tested and works like a charm. LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants