def download_sentinel_data(item, bands): # get paths w.r.t. id paths = file_paths_wrt_id(item._data["id"]) # get meta info on path, to be used by boto3 info_response = requests.get(item.assets["info"]["href"]) info_response_json = json.loads(info_response.text) # save bands generically for band in bands: # pass band id in metadata info_response_json["band_id"] = band band_filename = paths["b%s" % band] if not data_file_exists(band_filename): save_to_file( item.assets["B0{}".format(band)]["href"], band_filename, item._data["id"], "✗ required data doesn't exist, downloading %s %s" % (band_tag_map["b" + str(band)], "band"), meta=info_response_json, ) else: rprint( "[green] ✓ ", "required data exists for {} band".format( band_tag_map["b" + str(band)] ), ) return item._data["id"]
def process_landsat_vegetation(id, bands): # get paths of files related to this id paths = file_paths_wrt_id(id) # stack NIR, R, G bands # open files from the paths, and save it as stack b5 = rio.open(paths["b5"]) b4 = rio.open(paths["b4"]) b3 = rio.open(paths["b3"]) # read as numpy ndarrays nir = b5.read(1) r = b4.read(1) g = b3.read(1) with rio.open( paths["stack"], "w", driver="Gtiff", width=b4.width, height=b4.height, count=3, crs=b4.crs, transform=b4.transform, dtype=b4.dtypes[0], photometric="RGB", ) as rgb: rgb.write(nir, 1) rgb.write(r, 2) rgb.write(g, 3) rgb.close() source_path_for_rio_color = paths["stack"] rprint("Let's make our 🌍 imagery a bit more colorful for a human eye!") # apply rio-color correction ops_string = "sigmoidal rgb 20 0.2" # refer to felicette.utils.color.py to see the parameters of this function # Bug: number of jobs if greater than 1, fails the job color( 1, "uint16", source_path_for_rio_color, paths["vegetation_path"], ops_string.split(","), {"photometric": "RGB"}, ) # resize and save as jpeg image print("Generated 🌍 images!🎉") rprint("[yellow]Please wait while I resize and crop the image :) [/yellow]") process_sat_image(paths["vegetation_path"], paths["vegetation_path_jpeg"]) rprint("[blue]GeoTIFF saved at:[/blue]") print(paths["vegetation_path"]) rprint("[blue]JPEG image saved at:[/blue]") print(paths["vegetation_path_jpeg"]) # display generated image display_file(paths["vegetation_path_jpeg"])
def main(coordinates, location_name, pan_enhancement, no_preview, vegetation, version, product): """Satellite imagery for dummies.""" if version: version_no = pkg_resources.require("felicette")[0].version exit_cli(print, f"felicette {version_no}.") 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 item = search_satellite_data(coordinates, 10, product=product) # check if directory exists to save the data for this product id check_sat_path(item._data["id"]) # if preview option is set, download and preview image if not no_preview: preview_satellite_image(item) # set bands to process bands = [2, 3, 4] if pan_enhancement and (product != "sentinel"): bands.append(8) if vegetation: bands = [3, 4, 5] # NB: can't enable pan-enhancement with vegetation # NB: can't enable pan-enhancement with sentinel try: trigger_download_and_processing(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(item._data["id"]) remove_dir(file_paths["base"]) # retry downloading and processing image with a clean directory trigger_download_and_processing(item, bands) elif response in ["n", "N"]: exit_cli(print, "")
def preview_satellite_image(item): paths = file_paths_wrt_id(item._data["id"]) # download image and save it in directory if not data_file_exists(paths["preview"]): save_to_file( item.assets["thumbnail"]["href"], paths["preview"], item._data["id"], "✗ preview data doesn't exist, downloading image", ) else: rprint("[green] ✓ ", "required data exists for preview image") # print success info rprint("[blue]Preview image saved at:[/blue]") print(paths["preview"]) # prompt a confirm option response = input( "Are you sure you want to see an enhanced version of the image at the path shown above? [Y/n]" ) return handle_prompt_response(response)
def download_landsat_data(landsat_item, bands): # get paths w.r.t. id paths = file_paths_wrt_id(landsat_item._data["id"]) # save bands generically for band in bands: band_filename = paths["b%s" % band] if not data_file_exists(band_filename): save_to_file( landsat_item.assets["B{}".format(band)]["href"], band_filename, landsat_item._data["id"], "✗ required data doesn't exist, downloading %s %s" % (band_tag_map["b" + str(band)], "band"), ) else: rprint( "[green] ✓ ", "required data exists for {} band".format( band_tag_map["b" + str(band)]), ) return landsat_item._data["id"]
def process_landsat_rgb(id, bands): # get paths of files related to this id paths = file_paths_wrt_id(id) # stack R,G,B bands # open files from the paths, and save it as stack b4 = rio.open(paths["b4"]) b3 = rio.open(paths["b3"]) b2 = rio.open(paths["b2"]) # read as numpy ndarrays r = b4.read(1) g = b3.read(1) b = b2.read(1) with rio.open( paths["stack"], "w", driver="Gtiff", width=b4.width, height=b4.height, count=3, crs=b4.crs, transform=b4.transform, dtype=b4.dtypes[0], photometric="RGB", ) as rgb: rgb.write(r, 1) rgb.write(g, 2) rgb.write(b, 3) rgb.close() source_path_for_rio_color = paths["stack"] # check if band 8, i.e panchromatic band has to be processed if 8 in bands: # pansharpen the image rprint( "Pansharpening image, get ready for some serious resolution enhancement! ✨" ) gdal_pansharpen(["", paths["b8"], paths["stack"], paths["pan_sharpened"]]) # set color operation's path to the pansharpened-image's path source_path_for_rio_color = paths["pan_sharpened"] rprint("Let's make our 🌍 imagery a bit more colorful for a human eye!") # apply rio-color correction ops_string = "sigmoidal rgb 20 0.2" # refer to felicette.utils.color.py to see the parameters of this function # Bug: number of jobs if greater than 1, fails the job color( 1, "uint16", source_path_for_rio_color, paths["output_path"], ops_string.split(","), {"photometric": "RGB"}, ) # resize and save as jpeg image print("Generated 🌍 images!🎉") rprint("[yellow]Please wait while I resize and crop the image :) [/yellow]") process_sat_image(paths["output_path"], paths["output_path_jpeg"]) rprint("[blue]GeoTIFF saved at:[/blue]") print(paths["output_path"]) rprint("[blue]JPEG image saved at:[/blue]") print(paths["output_path_jpeg"]) # display generated image display_file(paths["output_path_jpeg"])