|
7 | 7 | "source": [
|
8 | 8 | "## Vegetation Monitoring with HLS Data on the Planetary Computer\n",
|
9 | 9 | "\n",
|
10 |
| - "\n", |
11 |
| - "\n", |
12 | 10 | "Monitoring vegetation over time is critical for understanding land health, agricultural productivity, and environmental change. This notebook uses Harmonized Landsat and Sentinel-2 (HLS) data to analyze vegetation patterns and detect unexpected changes across a selected agricultural region.\n",
|
13 | 11 | "\n",
|
| 12 | + "<p align=\"center\">\n", |
| 13 | + " <img src=\"./images/ndvi-anomalies.png\" width=\"400\"/>\n", |
| 14 | + "</p>\n", |
| 15 | + "\n", |
14 | 16 | "### Objective\n",
|
15 |
| - "**This tutorial demonstrates how to detect vegetation anomalies in agricultural areas using satellite imagery.** You'll learn to identify pixels where crops experienced unexpected declines in vegetation health compared to regional trends, which could indicate issues like pest damage, disease, drought stress, or other disturbances.\n", |
| 17 | + "**This tutorial uses satellite imagery to demonstrate how to detect vegetation anomalies in agricultural areas.** You'll learn to identify pixels where crops experienced unexpected declines in vegetation health compared to regional trends, which could indicate issues like pest damage, disease, drought stress, or other disturbances.\n", |
16 | 18 | "\n",
|
17 |
| - "**What you'll build:** An automated system that processes multi-temporal satellite data to flag locations and dates where vegetation health deviated significantly from expected patterns.\n", |
| 19 | + "**What you'll build:** An automated system that processes multi-temporal satellite data to flag locations and dates where vegetation health deviates significantly from expected patterns.\n", |
18 | 20 | "\n",
|
19 | 21 | "### Analysis Workflow\n",
|
20 | 22 | "This notebook will guide you through these key steps:\n",
|
|
133 | 135 | "source": [
|
134 | 136 | "### Define an area of interest\n",
|
135 | 137 | "\n",
|
136 |
| - "This example shows how to query a `geoparquet` copy of the [USDA Crop Sequence Boundaries dataset](https://source.coop/repositories/fiboa/us-usda-cropland/description) for a given bounding box. You can also provide your own set of field boundaries here:" |
| 138 | + "This example shows how to query a `geoparquet` copy of the [USDA Crop Sequence Boundaries dataset](https://source.coop/repositories/fiboa/us-usda-cropland/description) for a bounding box. You can also provide your own set of field boundaries here:" |
137 | 139 | ]
|
138 | 140 | },
|
139 | 141 | {
|
|
470 | 472 | "source": [
|
471 | 473 | "### Search for Harmonized Landsat Sentinel-2 data using the Planetary Computer STAC API\n",
|
472 | 474 | "\n",
|
473 |
| - "The Planetary Computer maintains a copy of the [Harmonized Landsat Sentinel-2 dataset](https://planetarycomputer.microsoft.com/dataset/group/hls2) and has made it available in via the STAC API." |
| 475 | + "The Planetary Computer maintains a copy of the [Harmonized Landsat Sentinel-2 dataset](https://planetarycomputer.microsoft.com/dataset/group/hls2) and has made it available in the STAC API." |
474 | 476 | ]
|
475 | 477 | },
|
476 | 478 | {
|
|
853 | 855 | "metadata": {},
|
854 | 856 | "source": [
|
855 | 857 | "### odc-stac\n",
|
856 |
| - "[odc-stac](https://github.com/opendatacube/odc-stac) is a tool for creating an xarray datacube from a STAC ItemCollection. This is a handy tool because (if the STAC metadata is well structured) you don't have to think about file paths or projections among other details. `odc-stac` will create a lazily-evaluated datacube that represents a mosaic of STAC items. When you call the `.compute()` method on an `xarray` object, it will read actual bytes from the assets.\n", |
| 858 | + "[odc-stac](https://github.com/opendatacube/odc-stac) is a tool for creating an xarray datacube from a STAC ItemCollection. This is a handy tool because (if the STAC metadata is well structured), you don't have to think about file paths or projections among other details. `odc-stac` will create a lazily-evaluated datacube that represents a mosaic of STAC items. When you call the `.compute()` method on an `xarray` object, it will read actual bytes from the assets.\n", |
857 | 859 | "\n",
|
858 | 860 | "You can provide some configuration details for a datacube in the form of a dictionary like this:"
|
859 | 861 | ]
|
|
896 | 898 | "id": "58d197a6-fac7-4f8e-b79b-657068b58694",
|
897 | 899 | "metadata": {},
|
898 | 900 | "source": [
|
899 |
| - "By default, STAC items from the same day will be combined into a single time coordinate in your datacube. Since we want to consider observations from Landsat and Sentinel-2 as separate observations even if they were collected on the same day, we can provide a function that will return the grouping key for odc-stac. " |
| 901 | + "By default, STAC items from the same day will be combined into a single time coordinate in your datacube. Since we want to consider observations from Landsat and Sentinel-2 as separate observations, even if they were collected on the same day, we can provide a function that will return the grouping key for odc-stac. " |
900 | 902 | ]
|
901 | 903 | },
|
902 | 904 | {
|
|
927 | 929 | "source": [
|
928 | 930 | "You can pass the STAC ItemCollection straight to odc.stac.load, but if you want to limit your analysis to a particular area of interest, you can provide a bounding box in the form of the `x` and `y` coordinate tuples. This is particularly useful because often your area of interest will not cover the entirety of the STAC item footprint, and therefore, you can selectively read chunks of the assets. You can also specify the output CRS and resolution for the array.\n",
|
929 | 931 | "\n",
|
930 |
| - "`odc.stac.load` will create a 4-dimensional data cube: band (variables in the Dataset), time, x, and y." |
| 932 | + "`odc.stac.load` will create a 4-dimensional datacube: band (variables in the Dataset), time, x, and y." |
931 | 933 | ]
|
932 | 934 | },
|
933 | 935 | {
|
|
2350 | 2352 | "id": "ad6a3db2-ce1e-4bf6-a5c5-e0a2cad23166",
|
2351 | 2353 | "metadata": {},
|
2352 | 2354 | "source": [
|
2353 |
| - "`cloud_free_stack` is a filtered version of the full imagery stack, where mostly cloudy images have been excluded and invalid pixels masked out. We are calling the `compute()` method to load the data into memory since we will use it for several subsequent plotting and analytical operations, but you could skip it for applications where you want to prioritize memory efficiency." |
| 2355 | + "`cloud_free_stack` is a filtered version of the full imagery stack, where mostly cloudy images have been excluded and invalid pixels masked out. We are calling the `compute()` method to load the data into memory since we will use it for several subsequent plotting and analytical operations. Still, you could skip it for applications where you want to prioritize memory efficiency." |
2354 | 2356 | ]
|
2355 | 2357 | },
|
2356 | 2358 | {
|
|
3094 | 3096 | "metadata": {},
|
3095 | 3097 | "source": [
|
3096 | 3098 | "### Land cover data\n",
|
3097 |
| - "Our crop monitoring analysis would be much simpler if we used an existing dataset to identify pixels in croplands. The Planetary Computer catalog contains a 10-meter resolution annual land cover dataset for 2017-2023. We can create a data cube from this dataset that can be easily combined with our satellite imagery data cube." |
| 3099 | + "Our crop monitoring analysis would be much simpler if we used an existing dataset to identify pixels in croplands. The Planetary Computer catalog contains a 10-meter resolution annual land cover dataset for 2017-2023. We can create a datacube from this dataset that can be easily combined with our satellite imagery datacube." |
3098 | 3100 | ]
|
3099 | 3101 | },
|
3100 | 3102 | {
|
|
4167 | 4169 | "id": "d0fc95c9-1350-4fbd-8640-947e9bf023bf",
|
4168 | 4170 | "metadata": {},
|
4169 | 4171 | "source": [
|
4170 |
| - "One clever thing we can do is add the land cover values as coordinates to the imagery data cube! This will make summarization more convenient later on." |
| 4172 | + "One clever thing we can do is add the land cover values as coordinates to the imagery datacube! This will make summarization more convenient later on." |
4171 | 4173 | ]
|
4172 | 4174 | },
|
4173 | 4175 | {
|
|
4684 | 4686 | "\n",
|
4685 | 4687 | "To continue learning about site monitoring workflows, check out the next notebook:\n",
|
4686 | 4688 | "\n",
|
4687 |
| - "👉 (climate-risk.ipynb)[tutorial/climate-risk.ipynb] \n", |
4688 |
| - "This advanced notebook focuses on extreme weather conditions that could lead to wildfire events. It explores using additional indices, temporal filtering, and geospatial joins to infrastructure data." |
| 4689 | + "👉 [climate-risk.ipynb](tutorial/climate-risk.ipynb): this advanced notebook focuses on extreme weather conditions that could lead to wildfire events. It explores using additional indices, temporal filtering, and geospatial joins to infrastructure data." |
4689 | 4690 | ]
|
4690 |
| - }, |
4691 |
| - { |
4692 |
| - "cell_type": "code", |
4693 |
| - "execution_count": null, |
4694 |
| - "id": "4546a343-c8b5-4427-be4e-3deafbabb170", |
4695 |
| - "metadata": {}, |
4696 |
| - "outputs": [], |
4697 |
| - "source": [] |
4698 | 4691 | }
|
4699 | 4692 | ],
|
4700 | 4693 | "metadata": {
|
|
0 commit comments