Introduction¶
This notebook contains a short demo on how to use the WorldCereal system to generate a cropland extent map for your area and season of interest.
The map is generated using a default model trained by the WorldCereal consortium to distinguish cropland from all other land use.
Before you start¶
In order to run WorldCereal crop mapping jobs from this notebook, you need to create an account on the Copernicus Data Space Ecosystem. This is free of charge and will grant you a number of free openEO processing credits to continue this demo.
1. Define your region of interest¶
When running the code snippet below, an interactive map will be visualized. Click the Rectangle button on the left hand side of the map to start drawing your region of interest. The widget will automatically store the coordinates of the last rectangle you drew on the map.
Processing areas beyond 2500 km² are currently not supported to avoid excessive credit usage and long processing times.
Upon exceeding this limit, an error will be shown, and you will need to draw a new rectangle.
For testing purposes, we recommend you to select a small area (< 250 km²) in order to limit processing time and credit usage.
A run of 250 km² will typically consume 40 credits and last around 20 mins.
A run of 750 km² will typically consume 90 credits and last around 50 mins.
A run of 2500 km² will typically consume 250 credits and last around 1h 40 mins.
from worldcereal.utils.map import ui_map
map = ui_map()
map.show_map()
VBox(children=(Map(center=[51.1872, 5.1154], controls=(ZoomControl(options=['position', 'zoom_in_text', 'zoom_…
2. Define your year of interest¶
The default WorldCereal cropland model always uses a time series of exactly one year as input for the model.
However, instead of just using a calendar year (January 1st - December 31st), we recommend to define the exact start and end date of your time series, or processing period, based on the timing of the local growing seasons.
Take the following example for Western Europe, where we typically have a winter season (s1) and summer season (s2):
The best timing to start and end the time series in this case would be October (green vertical line), as for both seasons this would result in nicely capturing the growing season within the time series. It would not make sense in this case to define the year from June to June (red vertical line), as you will miss the start of the summer season and the end of the winter season in your time series.
So if you would like to map temporary crops in Western Europe for the year 2021, we would recommend to define your processing period as October 1st 2020 - September 30th 2021.
In case you do not know the typical seasonality of crops in your area of interest, you can consult the WorldCereal crop calendars using the function below.
Note that in case your area of interest is located in an extremely heterogeneous part of the world, the WorldCereal seasons cannot be retrieved at the moment. As a fall-back, please consult the USDA crop calendars.
from utils import retrieve_worldcereal_seasons
spatial_extent = map.get_processing_extent()
seasons = retrieve_worldcereal_seasons(spatial_extent)
2024-10-17 09:54:15.772 | INFO | worldcereal.utils.map:get_processing_extent:123 - Your processing extent: (106.948242, -6.965126, 107.035103, -6.909915)
Execute the next cell to select your processing period:
from utils import date_slider
slider = date_slider()
slider.show_slider()
VBox(children=(HTML(value="\n <div style='text-align: center;'>\n <div style='font-s…
3. Set some other options¶
import os
from pathlib import Path
from utils import get_input
# Specify the local directory where the resulting maps should be downloaded to.
run = get_input('model run')
output_dir = Path(os.getcwd()) / f'CROPLAND_default_{run}'
print(f"Output directory: {output_dir}")
Output directory: /home/jeroendegerickx/worldcereal-classification/notebooks/CROPLAND_default_idn_cianjur
4. Generate your map¶
We now have all information we need to generate our map!
The next cell will submit a map inference job on CDSE through OpenEO.
The first time you run this, you will be asked to authenticate with your CDSE account by clicking the link provided below the cell.
Then sit back and wait untill your map is ready...
from worldcereal.job import generate_map, PostprocessParameters
processing_period = slider.get_processing_period()
processing_extent = map.get_processing_extent()
# Launch the job on CDSE through OpenEO
results = generate_map(
processing_extent,
processing_period,
output_dir=output_dir,
postprocess_parameters=PostprocessParameters(),
)
2024-10-17 09:55:00.274 | INFO | utils:get_processing_period:101 - Selected processing period: 2021-11-01 to 2022-10-31 2024-10-17 09:55:00.333 | INFO | worldcereal.utils.map:get_processing_extent:123 - Your processing extent: (106.948242, -6.965126, 107.035103, -6.909915)
Authenticated using refresh token.
2024-10-17 09:55:17,752 - openeo_gfmap.utils - INFO - Selected orbit state: ASCENDING. Reason: Only orbit with temporal gap under the threshold. 23 days < 60 days
0:00:00 Job 'j-241017ea73e4452c8d805ab66f067d45': send 'start' 0:00:14 Job 'j-241017ea73e4452c8d805ab66f067d45': created (progress 0%) 0:00:20 Job 'j-241017ea73e4452c8d805ab66f067d45': created (progress 0%) 0:00:26 Job 'j-241017ea73e4452c8d805ab66f067d45': created (progress 0%) 0:00:34 Job 'j-241017ea73e4452c8d805ab66f067d45': created (progress 0%) 0:00:44 Job 'j-241017ea73e4452c8d805ab66f067d45': running (progress N/A) 0:00:57 Job 'j-241017ea73e4452c8d805ab66f067d45': running (progress N/A) 0:01:12 Job 'j-241017ea73e4452c8d805ab66f067d45': running (progress N/A) 0:01:31 Job 'j-241017ea73e4452c8d805ab66f067d45': running (progress N/A) 0:01:56 Job 'j-241017ea73e4452c8d805ab66f067d45': running (progress N/A) 0:02:26 Job 'j-241017ea73e4452c8d805ab66f067d45': running (progress N/A) 0:03:03 Job 'j-241017ea73e4452c8d805ab66f067d45': running (progress N/A) 0:03:50 Job 'j-241017ea73e4452c8d805ab66f067d45': running (progress N/A) 0:04:48 Job 'j-241017ea73e4452c8d805ab66f067d45': running (progress N/A) 0:05:49 Job 'j-241017ea73e4452c8d805ab66f067d45': running (progress N/A) 0:06:49 Job 'j-241017ea73e4452c8d805ab66f067d45': running (progress N/A) 0:07:49 Job 'j-241017ea73e4452c8d805ab66f067d45': running (progress N/A) 0:08:50 Job 'j-241017ea73e4452c8d805ab66f067d45': running (progress N/A) 0:09:50 Job 'j-241017ea73e4452c8d805ab66f067d45': finished (progress 100%)
INFO:openeo.rest.job:Downloading Job result asset 'cropland_2021-11-01_2022-10-31.tif' from https://openeo.creo.vito.be/openeo/jobs/j-241017ea73e4452c8d805ab66f067d45/results/assets/ZGNjYWI2ZDktODQ2Yy00OGE5LTlkOTQtNDk3MTQ2Y2IyMjg1/22f4b20919d68b5b40d4a64398d0f724/cropland_2021-11-01_2022-10-31.tif?expires=1729764321 to /home/jeroendegerickx/worldcereal-classification/notebooks/CROPLAND_default_idn_cianjur/cropland_2021-11-01_2022-10-31.tif
# The results contain the openeo job id...
print(f"Job id: {results.job_id}")
print(f"Location of metadata: {results.metadata}")
#... a list of products that were downloaded...
print(f"Products: {results.products.keys()}")
# ... for each product:
print('-- For each product --')
print(f"Type: {results.products['cropland']['type']}")
print(f"Temporal extent: {results.products['cropland']['temporal_extent']}")
print(f"Look-up table: {results.products['cropland']['lut']}")
print(f"URL: {results.products['cropland']['url']}")
print(f"Local path: {results.products['cropland']['path']}")
Job id: j-241017ea73e4452c8d805ab66f067d45 Location of metadata: /home/jeroendegerickx/worldcereal-classification/notebooks/CROPLAND_default_idn_cianjur/job-results.json Products: dict_keys(['cropland']) -- For each product -- Type: WorldCerealProductType.CROPLAND Temporal extent: TemporalContext(start_date='2021-11-01', end_date='2022-10-31') Look-up table: {'other': 0, 'cropland': 1} URL: https://openeo.creo.vito.be/openeo/jobs/j-241017ea73e4452c8d805ab66f067d45/results/assets/ZGNjYWI2ZDktODQ2Yy00OGE5LTlkOTQtNDk3MTQ2Y2IyMjg1/22f4b20919d68b5b40d4a64398d0f724/cropland_2021-11-01_2022-10-31.tif?expires=1729764321 Local path: /home/jeroendegerickx/worldcereal-classification/notebooks/CROPLAND_default_idn_cianjur/cropland_2021-11-01_2022-10-31.tif
The classification results will be automatically downloaded to your output_dir in .tif format.
The result will be a raster file containing two bands:
- The label of the winning class
- The probability of the winning class [0 - 100]
Using the function below, we split all this information into separate .tif files, thereby adding metadata and a color map, to ease interpretation and visualization:
- "cropland_classification_start-date_end-date.tif" --> contains the classification labels. The class look-up table is included in the .tif metadata.
- "cropland_probability_start-date_end-date.tif" --> contains the probability associated with the predicted class
from utils import prepare_visualization
filepaths = prepare_visualization(results)
filepaths
{'cropland': {'classification': PosixPath('/home/jeroendegerickx/worldcereal-classification/notebooks/CROPLAND_default_idn_cianjur/cropland_classification_2021-11-01_2022-10-31.tif'), 'probability': PosixPath('/home/jeroendegerickx/worldcereal-classification/notebooks/CROPLAND_default_idn_cianjur/cropland_probability_2021-11-01_2022-10-31.tif')}}
The resulting raster files can be visualized in QGIS.
To get a quick idea of what the result looks like, you can use the cell below to plot the resulting map.
In case you run this notebook through the Terrascope environment, ALWAYS make sure you download the resulting files to your local system!
The Terrascope environment will be cleaned automatically upon exit!
from utils import visualize_classification
visualize_classification(filepaths, "cropland")
5. Final notes¶
Both the quantity and quality of training data are main drivers affecting the quality of the cropland extent map.
Using the figure below, you get a relative indication how much training data was available for training our current default cropland model:
In case you own good quality reference data on land cover and/or crop types, consider contributing these data to the WorldCereal project through our Reference Data Module.