Downloading Quads from a Mosaic using Basemaps API


Overview

The purpose of this tutorial is to provide a user-friendly way to use Planet's Basemaps API to download all quads to a folder in their directory.

How To Get Started

Before we jump into downloading the quads, let's quickly review the required packages for utilizing this tutorial.

Imports

  • requests
  • os
  • json
  • Your Planet API Key
  • urllib.request

Setup Session Using Basemaps API

The first step is to setup a session to access the basemaps API. The basemaps API can be used to download full mosaics, or in our case, to download individual parts of the mosaic known as quads.

Create Session to Access API

In order to access the basemaps API, we need a Planet API key for successful authentication. In this case, the API key is saved to a config file and imported into the python script, but feel free to use your API key directly in the notebook if you are following along.

import requests
import config

#setup API KEY
PLANET_API_KEY = '' # <= insert API key here 
#setup Planet base URL
API_URL = "https://api.planet.com/basemaps/v1/mosaics"
#setup session
session = requests.Session()
#authenticate
session.auth = (config.PLANET_API_KEY, "") #<= change to match variable for API Key if needed

Send Request and Check Status Code

When sending the request, we will provide one parameter. Assuming we know the name of the mosaic, we can include those details in the request to access the corresponding metadata. After sending the request, let's check the status code to ensure it was successful.

#set params for search using name of mosaic
parameters = {
    "name__is" :"nsw_ps_1month_date_ramp_L15_mosaic" # <= customize to your use case
}
#make get request to access mosaic from basemaps API
res = session.get(API_URL, params = parameters)
#response status code
print(res.status_code)
200

Access Mosaic MetaData

The metadata for each mosaic is necessary to access the quads. Specifically, we need to extract the mosaic id and bbox to search for the quads within our area of interest. In this tutorial we are using the AOI from the entire mosaic to download all quads, but those values can be customized for your use case.

Further Examine the JSON Object

import json

#print metadata for mosaic
mosaic = res.json()
print(json.dumps(mosaic, indent=2))
{
  "_links": {
    "_self": "https://api.planet.com/basemaps/v1/mosaics?api_key=06755eb6ce744dd08d99604c52d2dbc5"
  },
  "mosaics": [
    {
      "_links": {
        "_self": "https://api.planet.com/basemaps/v1/mosaics/e8cd50a5-e9dc-4278-a8f3-1c2475b452c5?api_key=06755eb6ce744dd08d99604c52d2dbc5",
        "quads": "https://api.planet.com/basemaps/v1/mosaics/e8cd50a5-e9dc-4278-a8f3-1c2475b452c5/quads?api_key=06755eb6ce744dd08d99604c52d2dbc5&bbox={lx},{ly},{ux},{uy}",
        "tiles": "https://tiles.planet.com/basemaps/v1/planet-tiles/nsw_ps_1month_date_ramp_L15_mosaic/gmap/{z}/{x}/{y}.png?api_key=06755eb6ce744dd08d99604c52d2dbc5"
      },
      "bbox": [
        141,
        -38,
        154,
        -28
      ],
      "coordinate_system": "EPSG:3857",
      "datatype": "byte",
      "first_acquired": "2017-08-25T00:00:00.000Z",
      "grid": {
        "quad_size": 2048,
        "resolution": 4.777314267823516
      },
      "id": "e8cd50a5-e9dc-4278-a8f3-1c2475b452c5",
      "item_types": [
        "PSScene3Band"
      ],
      "last_acquired": "2017-09-25T00:00:00.000Z",
      "level": 15,
      "name": "nsw_ps_1month_date_ramp_L15_mosaic",
      "product_type": "basemap",
      "quad_download": true
    }
  ]
}

Get ID and Bbox Values from Mosaic

#get id
mosaic_id = mosaic['mosaics'][0]['id']
#get bbox for entire mosaic
mosaic_bbox = mosaic['mosaics'][0]['bbox']
#converting bbox to string for search params
string_bbox = ','.join(map(str, mosaic_bbox))

print('Mosaic id: '+ mosaic_id)
print('Mosaic bbox: '+ string_bbox)
Mosaic id: e8cd50a5-e9dc-4278-a8f3-1c2475b452c5
Mosaic bbox: 141,-38,154,-28

Search for Mosaic Quads using AOI

Now that we have the required metadata, we can send a request to the API for the mosaic's quads. Each quad comes with a download link that we use to save them to our local directory.

Setup Request for Quads to Basemaps API

We will provide two parameters, a string of bbox values and minimal set to "True". The bbox values are required to send the request. The minimal parameter is optional, but we included it because it hides the metadata we don't need for this use case. Lastly, we include the mosaic id in the request url to access quads for this specific mosaic.

#search for mosaic quad using AOI
search_parameters = {
    'bbox': string_bbox,
    'minimal': True
}
#accessing quads using metadata from mosaic
quads_url = "{}/{}/quads".format(API_URL, mosaic_id)
res = session.get(quads_url, params=search_parameters, stream=True)
print(res.status_code)
200

Quads Metadata

The quad response object contains the download link and bbox values for each portion of the grid. Each quad also has a unique identifier which we will use to name the quads as we save them to our local directory.

quads = res.json()
items = quads['items']
#printing an example of quad metadata
print(json.dumps(items[0], indent=2))
{
  "_links": {
    "download": "https://api.planet.com/basemaps/v1/mosaics/e8cd50a5-e9dc-4278-a8f3-1c2475b452c5/quads/3794-1715/full?api_key=06755eb6ce744dd08d99604c52d2dbc5"
  },
  "bbox": [
    153.45703125,
    -28.07198030177986,
    153.544921875,
    -27.994401411046145
  ],
  "id": "3794-1715",
  "percent_covered": null
}

Download Quads to Local Directory

The final step to this tutorial is taking the download link from the metadata and saving those files to your local directory by id number. We do this by iterating over the json object and using urllib to retrieve the file via the download link.

import os
import urllib.request

#iterate over quad download links and saving to folder by id
for i in items:
    link = i['_links']['download']
    name = i['id']
    name = name + '.tiff'
    DIR = 'quads/' # <= a directory i created, feel free to customize
    filename = os.path.join(DIR, name)

    #checks if file already exists before s
    if not os.path.isfile(filename):
        urllib.request.urlretrieve(link, filename)

Conclusion

After a few simple steps, we now have a folder full of quads within our local directory. Check out our Planet Basemaps API Documentation to learn more. If you'd like to access the full .py script, follow this link.

Questions or comments about this guide? Join the conversation at Planet Community.