#!/usr/bin/env python # coding: utf-8 # # Aircraft Detection # # - Get Pleiades imagery for the given airports # - Execute tiling and aircraft detection blocks via parallel jobs # - Visualize the results # # - The example costs around 1700 UP42 credits # ## Setup # # Import required libraries # In[2]: import up42 import geopandas as gpd import rasterio from rasterio.plot import show import matplotlib.pyplot as plt from shapely.geometry import box # Configure areas of interest # In[3]: aoi_txl = {"type":"FeatureCollection","features":[{"type":"Feature","properties":{}, "geometry":{"type":"Polygon","coordinates":[[[13.286740779876709,52.5509016976356], [13.300495147705078,52.5509016976356], [13.300495147705078,52.556890079685594], [13.286740779876709,52.556890079685594], [13.286740779876709,52.5509016976356]]]}}]} aoi_muc = {"type":"FeatureCollection","features":[{"type":"Feature","properties":{}, "geometry":{"type":"Polygon","coordinates":[[[11.789016723632812,48.348577346994944], [11.809401512145996,48.348577346994944], [11.809401512145996,48.360155725059116], [11.789016723632812,48.360155725059116], [11.789016723632812,48.348577346994944]]]}}]} aois = [{'title': 'TXL', 'geometry': aoi_txl}, {'title': 'MUC', 'geometry': aoi_muc}] # Authenticate with UP42 # In[4]: #up42.authenticate(project_id="123", project_api_key="456") up42.authenticate(cfg_file="config.json") up42.settings(log=False) # ## Catalog Search # # Search cloudfree Pleiades image for the two aois and visualise the quicklooks. # In[5]: catalog = up42.initialize_catalog() for aoi in aois: print("\n---------" + aoi["title"] + "---------\n") search_paramaters = catalog.construct_parameters(geometry=aoi['geometry'], start_date="2020-04-01", end_date="2020-04-30", sensors=["pleiades"], max_cloudcover=10, sortby="acquisitionDate", ascending=False, limit=3) search_results = catalog.search(search_paramaters) # Download & Visualise quicklooks catalog.download_quicklooks(image_ids=search_results.id.to_list(), sensor="pleiades") display(search_results.head()) catalog.plot_quicklooks(figsize=(18,5), titles=search_results.scene_id.to_list()) # Select least cloud scene for further workflow aoi["scene_id"] = search_results.scene_id.to_list()[0] # In[10]: # Optional: Select ideal scenes manually aois[0]["scene_id"] = "DS_PHR1B_202004281031350_FR1_PX_E013N52_0513_01239" aois[1]["scene_id"] = "DS_PHR1B_202004161025425_FR1_PX_E011N48_1009_00822" # ## Download selected Pleiades images for aois # In[14]: up42.settings(log=True) project = up42.initialize_project() # Increase the parallel job limit for the project. #project.update_project_settings(max_concurrent_jobs=10) # Create or update a workflow for the aircraft detection # In[15]: workflow = project.create_workflow("Aircraft detection", use_existing=True) # Add or update workflows tasks # In[23]: #up42.get_blocks(basic=True) input_tasks= ['oneatlas-pleiades-aoiclipped', 'tiling', 'orbital_pleiades_aircraft'] workflow.add_workflow_tasks(input_tasks=input_tasks) workflow # ### Run jobs in parallel # # Construct workflow input parameters & run jobs # In[24]: input_parameters_list = [] for aoi in aois: input_parameters = workflow.construct_parameters(geometry=aoi['geometry'], geometry_operation="bbox", scene_ids=[aoi["scene_id"]]) input_parameters['tiling:1']['tile_width'] = 1024 input_parameters['tiling:1']['tile_height'] = 1024 input_parameters_list.append(input_parameters) input_parameters_list # In[25]: jobs = workflow.run_jobs_parallel(input_parameters_list=input_parameters_list) # ### Download & Visualise results # In[43]: data_results_paths, detection_results = [], [] for job in jobs: data_task, _, detection_task = job.get_jobtasks() data_paths = data_task.download_results() data_results_paths.append([p for p in data_paths if p.endswith(".tif")]) detection_results.append(detection_task.get_results_json()) # In[48]: for i, (paths, detection) in enumerate(zip(data_results_paths, detection_results)): with rasterio.open(paths[0]) as src: fig, ax = plt.subplots(figsize=(18, 18)) planes = gpd.GeoDataFrame.from_features(detection, crs={'init': "EPSG:4326"}) planes = planes.to_crs(epsg=3857) planes.geometry = planes.geometry.buffer(0.0001) planes.geometry = planes.geometry.apply(lambda geo:box(*geo.bounds)) show(src.read(), transform=src.transform, ax=ax, title=f"{aois[i]['title']}: {planes.shape[0]} planes detected") planes.plot(ax=ax, facecolor=(0,0,0,0), edgecolor='red', linewidth=2) plt.show() # In[ ]: