def main(coordinates, location_name, pan_enhancement, preview_image, vegetation): """Satellite imagery for dummies.""" if not coordinates and not location_name: exit_cli(print, "Please specify either --coordinates or --location-name") if location_name: coordinates = geocoder_util(location_name) # unless specified, cloud_cover_lt is 10 landsat_item = search_landsat_data(coordinates, 10) # check if directory exists to save the data for this product id check_sat_path(landsat_item._data["id"]) # if preview option is set, download and preview image if preview_image: preview_landsat_image(landsat_item) # set bands to process bands = [2, 3, 4] if pan_enhancement: bands.append(8) if vegetation: bands = [3, 4, 5] # NB: can't enable pan-enhancement with vegetation # download data data_id = download_landsat_data(landsat_item, bands) # process data process_landsat_data(data_id, bands)
def search_satellite_data(coordinates, cloud_cover_lt, product="landsat"): """ coordinates: bounding box's coordinates cloud_cover_lt: maximum cloud cover product: landsat, sentinel """ if product == "landsat": product = "landsat-8-l1" elif product == "sentinel": product = "sentinel-2-l1c" search = Search( bbox=get_tiny_bbox(coordinates), query={ "eo:cloud_cover": {"lt": cloud_cover_lt}, "collection": {"eq": product}, }, sort=[{"field": "eo:cloud_cover", "direction": "asc"}], ) # improvement: filter by date, cloud cover here search_items = search.items() if not len(search_items): exit_cli(print, "No data matched your search, please try different parameters.") # return the first result item = search_items[0] return item
def search_landsat_data(coordinates, cloud_cover_lt): search = Search( bbox=get_tiny_bbox(coordinates), query={ "eo:cloud_cover": { "lt": cloud_cover_lt }, "collection": { "eq": "landsat-8-l1" }, }, sort=[{ "field": "eo:cloud_cover", "direction": "asc" }], ) # improvement: filter by date, cloud cover here search_items = search.items() if not len(search_items): exit_cli( print, "No data matched your search, please try different parameters.") landsat_item = search_items[0] return landsat_item
def handle_prompt_response(response): if response in ["n", "N"]: exit_cli( "Why not try a different location next time? I'd suggest [link=https://en.wikipedia.org/wiki/Svalbard]Svalbard[/link] :)" ) elif response in ["y", "Y", ""]: return None else: exit_cli("[red]Sorry, invalid response. Exiting :([/red]")
def geocoder_util(location_name): # call nominatim api r = requests.get( "https://nominatim.openstreetmap.org/search?city={}&format=json". format(location_name)) r_json = r.json() if len(r_json) == 0: exit_cli( print, "Oops, couldn't geocode this location's name. Could you please try with coordinates(-c) option?" ) # return lat, lon return (float(r_json[0]["lon"]), float(r_json[0]["lat"]))
def save_to_file(url, filename, id, info_message, meta=None): product_type = get_product_type_from_id(id) data_path = os.path.join(workdir, id) data_id = filename.split("/")[-1].split("-")[1].split(".")[0] rprint(info_message) file_path = os.path.join(data_path, filename) if product_type == "sentinel" and meta: aws_access_key_id = os.environ.get("AWS_ACCESS_KEY_ID", None) aws_secret_access_key=os.environ.get("AWS_SECRET_ACCESS_KEY", None) # if access key or secret isn't defined, print error message and exit if (not aws_access_key_id) or (not aws_secret_access_key): exit_cli(rprint, "Error: [red]AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY[/red] must be set in environment variables to access Sentinel data.") # prepare boto3 client s3_client = boto3.Session().client( "s3", aws_access_key_id=aws_access_key_id, aws_secret_access_key=aws_secret_access_key, ) band = os.path.join(meta["path"], "B0%s.jp2" % (meta["band_id"])) filesize = s3_client.head_object( Bucket="sentinel-s2-l1c", Key=band, RequestPayer="requester" ).get("ContentLength") with tqdm(total=filesize, unit="B", unit_scale=True, desc=data_id) as t: response = s3_client.download_file( Bucket="sentinel-s2-l1c", Key=band, Filename=file_path, ExtraArgs={"RequestPayer": "requester"}, Callback=hook(t), ) else: # for landsat, and preview images - resources which can be downloaded via http response = requests.get(url, stream=True) with tqdm.wrapattr( open(file_path, "wb"), "write", miniters=1, desc=data_id, total=int(response.headers.get("content-length", 0)), ) as fout: for chunk in response.iter_content(chunk_size=4096): fout.write(chunk) fout.close()
def main(coordinates, location_name, pan_enhancement, no_preview, vegetation): """Satellite imagery for dummies.""" if not coordinates and not location_name: exit_cli(print, "Please specify either --coordinates or --location-name") if location_name: coordinates = geocoder_util(location_name) # unless specified, cloud_cover_lt is 10 landsat_item = search_landsat_data(coordinates, 10) # check if directory exists to save the data for this product id check_sat_path(landsat_item._data["id"]) # if preview option is set, download and preview image if not no_preview: preview_landsat_image(landsat_item) # set bands to process bands = [2, 3, 4] if pan_enhancement: bands.append(8) if vegetation: bands = [3, 4, 5] # NB: can't enable pan-enhancement with vegetation try: trigger_download_and_processing(landsat_item, bands) except RasterioIOError: response = input( "Local data for this location is corrupted, felicette will remove existing data to proceed, are you sure? [Y/n]" ) if response in ["y", "Y", ""]: # remove file dir file_paths = file_paths_wrt_id(landsat_item._data["id"]) remove_dir(file_paths["base"]) # retry downloading and processing image with a clean directory trigger_download_and_processing(landsat_item, bands) elif response in ["n", "N"]: exit_cli(print, "")