Skip to content

Instantly share code, notes, and snippets.

@davidbernat
Last active January 26, 2019 04:59
Show Gist options
  • Save davidbernat/008d6f0490f40e4ccc52dff6bdb0a61f to your computer and use it in GitHub Desktop.
Save davidbernat/008d6f0490f40e4ccc52dff6bdb0a61f to your computer and use it in GitHub Desktop.
Starlight Aether SDK application example: Detection Video of GigaFactory Construction from (Freemium) Satellite Imagery
###############################################
#
# First things first.
#
# Please go to: network.runsonaether.com
#
# You will be prompted to log in with a
# gmail or email address.
#
# After log-in, you will see all the good
# stuff.
# 1) our Aether SDK documentation
# 2) our examples
# 3) your applications and UUID.
#
# Company url: www.runsonaether.com
# www.starlight.ai
#
# Demos, Pictures, & Videos:
# Posted to Twitter: https://twitter.com/astrorobotic
#
# Medium: https://medium.com/starlightteam
#
# Thank you,
# David Bernat
# @astrorobotic
#
###############################################
import aether as ae
import numpy as np
from aether.user_utils.HelpfulFilters import HelpfulFilters
import os
import logging
logger = logging.getLogger(__name__)
###############################################
#
#
# New & Historical Building Starts: Detection of
# Construction from (Freemium) Satellite Imagery:
# GigaFactory Video
#
# An example of the Starlight Aether SDK
# Starlight: starlight.ai
# Aether SDK docs: docs.runsonaether.com
# Get a UUID in one-click: apply.runsonaether.com
#
# Author: David Bernat
# Twitter: @astrorobotic
#
# It will help us if you follow us on Twitter
#
# Report Issues to:
# https://github.com/TeamStarlight/aether-alpha-program
#
###############################################
# To install Aether SDK, simply pip install aether
# For documentation: docs.runsonaether.com
# Get a UUID in one-click: Log in to apply.runsonaether.com
uuid = "YOUR_UUID"
ae.GlobalConfig.set_user(uuid)
job_name = "gigafactor"
out_dir = "ndbi"
center = [39.537845, -119.439024] # Gigafactory
# center = [34.553544, 113.857867] # Foxconn
# center = [32.8, -115.6] # Imperial, CA
# center = [40.17208, -75.07299] # Wawa at Bucks County, PA
w = 0.05 # degrees, about 150x150 px of LandSat and 450x450 of Sentinel-2
year_range = [2013, 2019]
cloud_limits = {"cloud": [0.0, 0.02], "cloud_shadow": [0.0, 0.02], "snowice": [0.0, 0.02]}
####################################
# DEMO START
####################################
coordinates = [[center[0] - w, center[1] - w],
[center[0] - w, center[1] + w],
[center[0] + w, center[1] + w],
[center[0] + w, center[1] - w],
[center[0] - w, center[1] - w]]
polygon = ae.AEPolygon(coordinates)
resource_name = "landsat"
query_parameters = dict(
bands=["SWIR1", "NIR", "QA"],
spacecraft_id=["LANDSAT_4", "LANDSAT_5", "LANDSAT_8"],
cloud_cover=[0.0, 100.0],
)
# Normalized Differential Build-Up Index
def ndbi(spacetime):
b_swir = spacetime.bands(0)
b_nir = spacetime.bands(1)
return spacetime.update((b_swir-b_nir) / (b_swir+b_nir))
###########
# App Start
###########
timestamps = []
stack = []
metadata = None
with ae.SkySession() as sky:
for year in range(year_range[0], year_range[1]):
query_parameters["date_acquired"] = ["{}-01-01".format(year), "{}-12-31".format(year)]
sb = sky.Resource(resource_name).search(polygon, query_parameters)
logger.info("Year {}: Number of images found: {}, {}".format(year, len(sb.timestamps), sb.timestamps.keys()))
to_keep = HelpfulFilters.LandSatCloudFilter(sky, sb, limits=cloud_limits, qa_index=2, polygon=polygon)
sb = HelpfulFilters.applyFilterResults(sb, to_keep)
logger.info("Year {}: Number of images passing cloud check: {}, {}".format(year, len(sb.timestamps), sb.timestamps.keys()))
if len(sb.timestamps) == 0:
continue
sb = sky.crop(sb)
if len(sb.timestamps) == 0:
continue
spacetime = sky.download(sb, run=[ndbi])
timestamps.extend(sorted(sb.timestamps))
stack.append(spacetime.bands())
if metadata is None:
metadata = spacetime.metadata()
# Order all the timestamps across searches
order_i = range(len(timestamps))
order_i = [x for _, x in sorted(zip(timestamps, order_i))]
stack = np.concatenate(stack, axis=0)[order_i]
timestamps = [timestamps[i] for i in order_i]
spacetime = ae.Spacetime(stack, timestamps, metadata)
# Write the essential data to file:
if not os.path.exists("{}/{}/".format(out_dir, job_name)):
os.makedirs("{}/{}/".format(out_dir, job_name))
with open("{}/{}/{}_timestamps.txt".format(out_dir, job_name, job_name), 'w') as f:
for ts in timestamps:
f.write("{}\n".format(ts))
np.save("{}/{}/{}_stack.npy".format(out_dir, job_name, job_name), stack)
spacetime.generate_gif(range(stack.shape[0]), [0], save_to="{}/{}/{}.gif".format(out_dir, job_name, job_name))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment