---
title: "Custom geometry: district-level NTL with custom boundaries"
description: >
  Extract zonal NTL statistics over custom sf polygons (districts,
  constituencies, or any user-supplied geometry).
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Custom geometry: district-level NTL with custom boundaries}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r setup, include = FALSE}
library(lightson)
# Live downloads write to the user cache, so skip them on CRAN.
live_ok <- identical(Sys.getenv("NOT_CRAN"), "true")
if (live_ok) {
  rasters <- tryCatch(bhuvan_raster("IND", years = 2020:2022), error = function(e) list())
  live_ok <- length(rasters) > 0
}

knitr::opts_chunk$set(
  collapse = TRUE,
  comment  = "#>",
  dev.args = list(bg = "transparent"),
  eval     = live_ok
)
```

```{r offline-notice, echo = FALSE, results = "asis", eval = !live_ok}
cat("_Live data were not downloaded when this vignette was built, so its examples were not run. Run this vignette locally to see the output._")
```

`lightson` accepts any `sf` polygon layer. The workflow below starts with the
bundled LGD state boundaries, then swaps in district-level GeoJSONs from
[bharatviz](https://github.com/saketlab/bharatviz).

## State-level workflow (bundled boundaries)

```{r state-boundaries}
library(sf)

states <- get_india_admin("state")
nrow(states)
head(states[, c("state_name", "state_code")])
```

Download Bhuvan WMS rasters for a subset of years. `bhuvan_raster()` derives
the bounding box from the geometry:

```{r state-rasters}
names(rasters)
rasters[["2022"]]
```

Bhuvan WMS returns a classed map with four colours (< 5, 5-25,
26-200 and > 200 nW/cm^2/sr). `bhuvan_raster()` converts each class to a representative
radiance (2.5, 15, 112.5 and 200), so values are banded rather than
continuous, and the brightest class is a floor.

```{r state-panel}
panel <- extract_panel(rasters, states, id_col = "state_name")
head(panel)
```

```{r state-trend, fig.width = 7, fig.height = 4}
library(ggplot2)
sel <- c("Bihar", "Maharashtra", "Tamil Nadu", "Uttar Pradesh")
plot_ntl_trend(
  panel[panel$region_id %in% sel, ],
  region   = sel,
  caption  = "Source: ISRO Bhuvan NTL portal"
)
```

```{r state-map, fig.width = 7, fig.height = 6}
plot_ntl_map(
  rasters[["2022"]],
  polygons = states,
  title    = "India nighttime lights, 2022"
)
```


## District-level workflow

```{r district-boundaries, eval = FALSE}
BHARATVIZ <- "https://bharatviz.org"

districts <- sf::read_sf(
  file.path(BHARATVIZ, "India-bhuvan-districts.geojson")
)
nrow(districts)
```

```{r download-rasters, eval = FALSE}
rasters_dist <- bhuvan_raster(districts, years = 2018:2023)
names(rasters_dist)
```

```{r extract-panel, eval = FALSE}
panel_dist <- extract_panel(rasters_dist, districts, id_col = "district_name")
head(panel_dist)
```

```{r plot-trend, eval = FALSE, fig.width = 7, fig.height = 4}
plot_ntl_trend(panel_dist, region = c("Mumbai", "Delhi", "Chennai", "Bengaluru"))
```

```{r plot-map, eval = FALSE, fig.width = 7, fig.height = 6}
plot_ntl_map(rasters_dist[["2022"]], polygons = districts)
```

### LGD boundaries

```{r lgd, eval = FALSE}
lgd <- sf::read_sf(file.path(BHARATVIZ, "India_LGD_districts.geojson"))
panel_lgd <- extract_panel(rasters_dist, lgd, id_col = "district_name")
head(panel_lgd)
```

### Historical census boundaries

```{r historical, eval = FALSE}
dist_2011 <- sf::read_sf(file.path(BHARATVIZ, "India-2011-districts.geojson"))
panel_2011 <- extract_panel(rasters_dist, dist_2011)
head(panel_2011)
```

`extract_panel()` picks the first character column as `region_id` automatically,
or pass `id_col` explicitly.

---

## VIIRS path

To use NASA VIIRS rasters, supply an [Earthdata token](https://urs.earthdata.nasa.gov/):

```{r viirs, eval = FALSE}
token <- earthdata_token()
rasters_viirs <- ntl_download(region = districts, years = 2018:2023, token = token)
if (length(rasters_viirs) > 0) {
  panel_viirs <- extract_panel(rasters_viirs, districts, id_col = "district_name")
  head(panel_viirs)
}
```
