Spaces:
Runtime error
Runtime error
compute action
Browse files- .devcontainer/devcontainer.json +22 -0
- .github/compute.yml +22 -0
- fire.py +61 -0
.devcontainer/devcontainer.json
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"image": "ghcr.io/boettiger-lab/solara-geospatial:latest",
|
| 3 |
+
"name": "Solara Geospatial Environment",
|
| 4 |
+
// build image as a github-action and grab instead; faster.
|
| 5 |
+
// "build": {
|
| 6 |
+
// "dockerfile": "Dockerfile"
|
| 7 |
+
//},
|
| 8 |
+
"waitFor": "onCreateCommand",
|
| 9 |
+
"updateContentCommand": "python3 -m pip install -r requirements.txt",
|
| 10 |
+
"postCreateCommand": "",
|
| 11 |
+
"customizations": {
|
| 12 |
+
"codespaces": {
|
| 13 |
+
"openFiles": ["README.md"]
|
| 14 |
+
},
|
| 15 |
+
"vscode": {
|
| 16 |
+
"extensions": [
|
| 17 |
+
"ms-toolsai.jupyter",
|
| 18 |
+
"ms-python.python"
|
| 19 |
+
]
|
| 20 |
+
}
|
| 21 |
+
}
|
| 22 |
+
}
|
.github/compute.yml
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
on:
|
| 2 |
+
#schedule:
|
| 3 |
+
# - cron: '0 23 * * *'
|
| 4 |
+
workflow_dispatch:
|
| 5 |
+
|
| 6 |
+
name: compute
|
| 7 |
+
|
| 8 |
+
jobs:
|
| 9 |
+
docker:
|
| 10 |
+
runs-on: ubuntu-latest
|
| 11 |
+
#container: rocker/geospatial:latest
|
| 12 |
+
container: docker pull ghcr.io/boettiger-lab/solara-geospatial:latest
|
| 13 |
+
steps:
|
| 14 |
+
- name: config
|
| 15 |
+
run: git config --system --add safe.directory '*'
|
| 16 |
+
- name: checkout
|
| 17 |
+
uses: actions/checkout@v3
|
| 18 |
+
with:
|
| 19 |
+
fetch-depth: 0
|
| 20 |
+
set-safe-directory: '*'
|
| 21 |
+
- name: compute
|
| 22 |
+
run: python fire.py
|
fire.py
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import leafmap
|
| 2 |
+
import solara
|
| 3 |
+
import pystac_client
|
| 4 |
+
import planetary_computer
|
| 5 |
+
import odc.stac
|
| 6 |
+
import geopandas as gpd
|
| 7 |
+
import dask.distributed
|
| 8 |
+
import matplotlib.pyplot as plt
|
| 9 |
+
import rioxarray
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
nps = gpd.read_file("/vsicurl/https://huggingface.co/datasets/cboettig/biodiversity/resolve/main/data/NPS.gdb")
|
| 13 |
+
calfire = gpd.read_file("/vsicurl/https://huggingface.co/datasets/cboettig/biodiversity/resolve/main/data/fire22_1.gdb", layer = "firep22_1")
|
| 14 |
+
# fire = gpd.read_file("/vsizip/vsicurl/https://edcintl.cr.usgs.gov/downloads/sciweb1/shared/MTBS_Fire/data/composite_data/burned_area_extent_shapefile/mtbs_perimeter_data.zip"
|
| 15 |
+
|
| 16 |
+
# extract and reproject the Joshua Tree NP Polygon
|
| 17 |
+
jtree = nps[nps.PARKNAME == "Joshua Tree"].to_crs(calfire.crs)
|
| 18 |
+
# All Fires in the DB that intersect the Park
|
| 19 |
+
jtree_fires = jtree.overlay(calfire, how="intersection")
|
| 20 |
+
|
| 21 |
+
# Extract a polygon if interest. > 2015 for Sentinel, otherwise we can use LandSat
|
| 22 |
+
recent = jtree_fires[jtree_fires.YEAR_ > "2015"]
|
| 23 |
+
big = recent[recent.Shape_Area == recent.Shape_Area.max()].to_crs("EPSG:4326")
|
| 24 |
+
datetime = big.ALARM_DATE.item() + "/" + big.CONT_DATE.item()
|
| 25 |
+
box = big.buffer(0.005).bounds.to_numpy()[0] # Fire bbox + buffer
|
| 26 |
+
#box = jtree.to_crs("EPSG:4326").bounds.to_numpy()[0] # Park bbox
|
| 27 |
+
|
| 28 |
+
# STAC Search for this imagery in space/time window
|
| 29 |
+
items = (
|
| 30 |
+
pystac_client.Client.
|
| 31 |
+
open("https://planetarycomputer.microsoft.com/api/stac/v1",
|
| 32 |
+
modifier=planetary_computer.sign_inplace).
|
| 33 |
+
search(collections=["sentinel-2-l2a"],
|
| 34 |
+
bbox=box,
|
| 35 |
+
datetime=datetime,
|
| 36 |
+
query={"eo:cloud_cover": {"lt": 10}}).
|
| 37 |
+
item_collection())
|
| 38 |
+
|
| 39 |
+
|
| 40 |
+
# Time to compute:
|
| 41 |
+
client = dask.distributed.Client()
|
| 42 |
+
# landsat_bands = ["nir08", "swir16"]
|
| 43 |
+
sentinel_bands = ["B08", "B12", "SCL"]
|
| 44 |
+
|
| 45 |
+
# The magic of gdalwarper. Can also resample, reproject, and aggregate on the fly
|
| 46 |
+
data = odc.stac.load(items,
|
| 47 |
+
bands=sentinel_bands,
|
| 48 |
+
bbox=box
|
| 49 |
+
)
|
| 50 |
+
|
| 51 |
+
swir = data["B12"].astype("float")
|
| 52 |
+
nir = data["B08"].astype("float")
|
| 53 |
+
|
| 54 |
+
# can resample and aggregate in xarray. compute with dask
|
| 55 |
+
nbs = (((nir - swir) / (nir + swir)).
|
| 56 |
+
# resample(time="MS").
|
| 57 |
+
# median("time", keep_attrs=True).
|
| 58 |
+
compute()
|
| 59 |
+
)
|
| 60 |
+
|
| 61 |
+
nbs.rio.to_raster(raster_path="nbs.tif", driver="COG")
|