Skip to content

Instantly share code, notes, and snippets.

@moloned
Created November 4, 2024 09:54
Show Gist options
  • Save moloned/a35ae4d8cc682edef7e5a260113a742b to your computer and use it in GitHub Desktop.
Save moloned/a35ae4d8cc682edef7e5a260113a742b to your computer and use it in GitHub Desktop.
downloadsentinel2images.ipynb
Display the source blob
Display the rendered blob
Raw
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"provenance": [],
"authorship_tag": "ABX9TyPs1MeLADV0vEQml4djR8bN",
"include_colab_link": true
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
},
"language_info": {
"name": "python"
}
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "view-in-github",
"colab_type": "text"
},
"source": [
"<a href=\"https://colab.research.google.com/gist/moloned/a35ae4d8cc682edef7e5a260113a742b/downloadsentinel2images.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
]
},
{
"cell_type": "markdown",
"source": [
"# **Python notebook downloads Sentinel2 imagery using OpenEO portal/API**\n",
"\n",
"Rather than using username/password the program opens an authentication window for access so watch out for the dialogue box to pop up and click on the link"
],
"metadata": {
"id": "vRdztmkdi8qT"
}
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "3lzzpw0uiNJh",
"outputId": "64571783-62a2-4b13-c43f-71c62afcd701"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Collecting openeo\n",
" Downloading openeo-0.34.0-py3-none-any.whl.metadata (7.2 kB)\n",
"Collecting rasterio\n",
" Downloading rasterio-1.4.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (9.1 kB)\n",
"Requirement already satisfied: requests>=2.26.0 in /usr/local/lib/python3.10/dist-packages (from openeo) (2.32.3)\n",
"Requirement already satisfied: shapely>=1.6.4 in /usr/local/lib/python3.10/dist-packages (from openeo) (2.0.6)\n",
"Requirement already satisfied: numpy>=1.17.0 in /usr/local/lib/python3.10/dist-packages (from openeo) (1.26.4)\n",
"Requirement already satisfied: xarray>=0.12.3 in /usr/local/lib/python3.10/dist-packages (from openeo) (2024.10.0)\n",
"Requirement already satisfied: pandas>0.20.0 in /usr/local/lib/python3.10/dist-packages (from openeo) (2.2.2)\n",
"Collecting pystac>=1.5.0 (from openeo)\n",
" Downloading pystac-1.11.0-py3-none-any.whl.metadata (4.5 kB)\n",
"Requirement already satisfied: deprecated>=1.2.12 in /usr/local/lib/python3.10/dist-packages (from openeo) (1.2.14)\n",
"Collecting affine (from rasterio)\n",
" Downloading affine-2.4.0-py3-none-any.whl.metadata (4.0 kB)\n",
"Requirement already satisfied: attrs in /usr/local/lib/python3.10/dist-packages (from rasterio) (24.2.0)\n",
"Requirement already satisfied: certifi in /usr/local/lib/python3.10/dist-packages (from rasterio) (2024.8.30)\n",
"Requirement already satisfied: click>=4.0 in /usr/local/lib/python3.10/dist-packages (from rasterio) (8.1.7)\n",
"Collecting cligj>=0.5 (from rasterio)\n",
" Downloading cligj-0.7.2-py3-none-any.whl.metadata (5.0 kB)\n",
"Collecting click-plugins (from rasterio)\n",
" Downloading click_plugins-1.1.1-py2.py3-none-any.whl.metadata (6.4 kB)\n",
"Requirement already satisfied: pyparsing in /usr/local/lib/python3.10/dist-packages (from rasterio) (3.2.0)\n",
"Requirement already satisfied: wrapt<2,>=1.10 in /usr/local/lib/python3.10/dist-packages (from deprecated>=1.2.12->openeo) (1.16.0)\n",
"Requirement already satisfied: python-dateutil>=2.8.2 in /usr/local/lib/python3.10/dist-packages (from pandas>0.20.0->openeo) (2.8.2)\n",
"Requirement already satisfied: pytz>=2020.1 in /usr/local/lib/python3.10/dist-packages (from pandas>0.20.0->openeo) (2024.2)\n",
"Requirement already satisfied: tzdata>=2022.7 in /usr/local/lib/python3.10/dist-packages (from pandas>0.20.0->openeo) (2024.2)\n",
"Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.10/dist-packages (from requests>=2.26.0->openeo) (3.4.0)\n",
"Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.10/dist-packages (from requests>=2.26.0->openeo) (3.10)\n",
"Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.10/dist-packages (from requests>=2.26.0->openeo) (2.2.3)\n",
"Requirement already satisfied: packaging>=23.1 in /usr/local/lib/python3.10/dist-packages (from xarray>=0.12.3->openeo) (24.1)\n",
"Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.10/dist-packages (from python-dateutil>=2.8.2->pandas>0.20.0->openeo) (1.16.0)\n",
"Downloading openeo-0.34.0-py3-none-any.whl (277 kB)\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m277.5/277.5 kB\u001b[0m \u001b[31m4.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[?25hDownloading rasterio-1.4.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (22.2 MB)\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m22.2/22.2 MB\u001b[0m \u001b[31m59.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[?25hDownloading cligj-0.7.2-py3-none-any.whl (7.1 kB)\n",
"Downloading pystac-1.11.0-py3-none-any.whl (183 kB)\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m183.9/183.9 kB\u001b[0m \u001b[31m12.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[?25hDownloading affine-2.4.0-py3-none-any.whl (15 kB)\n",
"Downloading click_plugins-1.1.1-py2.py3-none-any.whl (7.5 kB)\n",
"Installing collected packages: cligj, click-plugins, affine, rasterio, pystac, openeo\n",
"Successfully installed affine-2.4.0 click-plugins-1.1.1 cligj-0.7.2 openeo-0.34.0 pystac-1.11.0 rasterio-1.4.2\n"
]
}
],
"source": [
"# install required python packages\n",
"#\n",
"!pip install openeo rasterio"
]
},
{
"cell_type": "code",
"source": [
"# python program - opens an authentication window for access so watch out for the dialogue box to pop up and click on the link\n",
"#\n",
"import openeo\n",
"import re\n",
"from datetime import date, timedelta\n",
"import rasterio\n",
"import matplotlib.pyplot as plt\n",
"import math\n",
"\n",
"# First, we connect to the back-end and authenticate\n",
"#\n",
"con = openeo.connect(\"openeo.dataspace.copernicus.eu\")\n",
"con.authenticate_oidc()\n",
"\n",
"# Given location - Singapore in this case\n",
"#\n",
"latitude = 1.2873932\n",
"longitude = 104.1466046\n",
"\n",
"# Calculate corners of bounding box around GPS location\n",
"#\n",
"swath = 200 # km (290km bounding box - sentinel2 swath)\n",
"\n",
"# cloud-cover maximum for EO imagery search over data-range and bounding-box\n",
"#\n",
"ccover = 30\n",
"\n",
"# Sentinel2 image bands to download\n",
"#\n",
"bands = [\"B02\", \"B03\", \"B04\"] # B02 = Blue, B03 = Green, B04 = Red\n",
"\n",
"# calculate offset distance to a GPS location given the bearing\n",
"#\n",
"def gps_offset(latitude, longitude, distance_km, bearing_deg):\n",
"\n",
" R = 6378.1 # Radius of the Earth in kilometers\n",
"\n",
" bearing_rad = math.radians(bearing_deg)\n",
" latitude_rad = math.radians(latitude)\n",
" longitude_rad = math.radians(longitude)\n",
"\n",
" distance_rad = distance_km / R\n",
"\n",
" new_latitude_rad = math.asin(\n",
" math.sin(latitude_rad) * math.cos(distance_rad) +\n",
" math.cos(latitude_rad) * math.sin(distance_rad) * math.cos(bearing_rad)\n",
" )\n",
"\n",
" new_longitude_rad = longitude_rad + math.atan2(\n",
" math.sin(bearing_rad) * math.sin(distance_rad) * math.cos(latitude_rad),\n",
" math.cos(distance_rad) - math.sin(latitude_rad) * math.sin(new_latitude_rad)\n",
" )\n",
"\n",
" new_latitude = math.degrees(new_latitude_rad)\n",
" new_longitude = math.degrees(new_longitude_rad)\n",
"\n",
" return new_latitude, new_longitude\n",
"\n",
"# calculate bounding box around current GPS location to download\n",
"#\n",
"north_lat, _ = gps_offset(latitude, longitude, swath/2, 0) # North\n",
"south_lat, _ = gps_offset(latitude, longitude, swath/2, 180) # South\n",
"_, east_lon = gps_offset(latitude, longitude, swath/2, 90) # East\n",
"_, west_lon = gps_offset(latitude, longitude, swath/2, 270) # West\n",
"\n",
"# Set date range\n",
"#\n",
"end_date = date.today()\n",
"start_date = end_date - timedelta(days=30)\n",
"drange = (start_date, end_date)\n",
"\n",
"# Define bounding box (replace with your desired coordinates)\n",
"#\n",
"bbox = {\n",
" \"west\": west_lon,\n",
" \"south\": south_lat,\n",
" \"east\": east_lon,\n",
" \"north\": north_lat\n",
"}\n",
"\n",
"# Load Sentinel-2 L2A collection\n",
"#\n",
"s2_cube = con.load_collection(\n",
" \"SENTINEL2_L2A\",\n",
" temporal_extent=drange,\n",
" spatial_extent=bbox,\n",
" bands=bands,\n",
" max_cloud_cover=ccover # Filter by cloud cover\n",
")\n",
"\n",
"# Download data as GeoTIFF\n",
"#\n",
"s2_cube.download(\"sentinel2_data.tiff\")\n",
"\n",
"# display downloaded image\n",
"#\n",
"img2 = rasterio.open(\"sentinel2_data.tiff\").read()\n",
"plt.imshow(img2[0])\n",
"plt.show()"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "mOI6jUMYiS4E",
"outputId": "58108743-b226-4e4b-cf8c-bb5cc0be81cb"
},
"execution_count": null,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Authenticated using refresh token.\n"
]
}
]
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment