gee-community / qgis-earthengine-plugin

Integrates Google Earth Engine and QGIS using Python API
http://qgis-ee-plugin.appspot.com
MIT License
454 stars 116 forks source link

Adding `collection_to_atlas` for exporting images from a collection. #154

Open lopezvoliver opened 2 months ago

lopezvoliver commented 2 months ago

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:

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:

XavierCLL commented 2 months ago

Hi @lopezvoliver,

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

gena commented 1 month ago

This looks like a nice functionality, thank you for contributing it!

LGTM except one comment related to region arguments.

We should probably move that contrib/ and examples/ out of this plugin in the future, to be able to change and release these code snippets more frequently, but it's probably ok for now, as far as users won't expect that this contrib/ code will work in the future versions of the plugin as-is.