Skip to content

Commit 3fdf320

Browse files
committed
Simplify STAC generator: remove CLI args, JSON-only
1 parent da2ace4 commit 3fdf320

File tree

2 files changed

+34
-119
lines changed

2 files changed

+34
-119
lines changed

scripts/README.md

Lines changed: 2 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -61,45 +61,10 @@ Create a JSON file specifying which layers to generate:
6161
- Asset URLs and types
6262
- Layer metadata
6363

64-
## Legacy CLI Usage
65-
66-
The script also supports command-line arguments for backward compatibility:
67-
68-
```bash
69-
python3 scripts/stac-to-layers-config.py \
70-
--catalog https://s3-west.nrp-nautilus.io/public-data/stac/catalog.json \
71-
--output test-config.json \
72-
--layer cpad-2025b:cpad-units-pmtiles:cpad:"California Protected Areas (CPAD)"
73-
```
74-
75-
**Generate carbon layer config:**
76-
```bash
77-
python scripts/stac-to-layers-config.py \
78-
--catalog https://s3-west.nrp-nautilus.io/public-data/stac/catalog.json \
79-
--output test-config.json \
80-
--layer irrecoverable-carbon:vulnerable-total-2018-cog:carbon:"Vulnerable Carbon"
81-
```
82-
83-
**Generate both together:**
84-
```bash
85-
python scripts/stac-to-layers-config.py \
86-
--catalog https://s3-west.nrp-nautilus.io/public-data/stac/catalog.json \
87-
--output app/layers-config-generated.json \
88-
--layer cpad-2025b:cpad-units-pmtiles:cpad:"California Protected Areas (CPAD)" \
89-
--layer irrecoverable-carbon:vulnerable-total-2018-cog:carbon:"Vulnerable Carbon"
90-
```
91-
9264
## Arguments
9365

94-
- `--catalog`: URL to the STAC catalog.json file
95-
- `--output`: Path where the layers-config.json should be written
96-
- `--layer`: Layer specification in format `COLLECTION:ASSET:KEY:NAME` (can be repeated)
97-
- `COLLECTION`: STAC collection ID (e.g., `cpad-2025b`)
98-
- `ASSET`: Asset ID from the collection (e.g., `cpad-units-pmtiles`)
99-
- `KEY`: Layer key to use in the config (e.g., `cpad`)
100-
- `NAME`: Display name for the layer (optional, will use asset title if omitted)
101-
- `--titiler`: TiTiler base URL for COG tiles (default: `https://titiler.nrp-nautilus.io`)
102-
- `--colormap`: Default colormap for raster layers (default: `reds`)
66+
- `--input`: Path to input JSON file (required)
67+
- `--output`: Path where layers-config.json should be written (required)
10368

10469
## How It Works
10570

scripts/stac-to-layers-config.py

Lines changed: 32 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,16 @@
22
"""
33
Generate layers-config.json from STAC catalog entries.
44
5-
This script reads STAC collections and generates layer configurations
6-
for the CA Protected Lands maplibre application.
5+
This script reads a JSON input file specifying STAC collections and assets,
6+
then generates layer configurations for the CA Protected Lands maplibre application.
77
88
Usage:
9-
python stac-to-layers-config.py --catalog CATALOG_URL --output layers-config.json \
10-
--layer collection_id:asset_id:layer_key:display_name
9+
python3 stac-to-layers-config.py --input layers-input.json --output layers-config.json
1110
12-
Examples:
13-
# Generate config for CPAD and carbon layers
14-
python stac-to-layers-config.py \
15-
--catalog https://s3-west.nrp-nautilus.io/public-data/stac/catalog.json \
16-
--output app/layers-config.json \
17-
--layer cpad-2025b:cpad-units-pmtiles:cpad:"California Protected Areas (CPAD)" \
18-
--layer irrecoverable-carbon:vulnerable-total-2018-cog:carbon:"Vulnerable Carbon"
11+
Example:
12+
python3 stac-to-layers-config.py \
13+
--input scripts/layers-input-example.json \
14+
--output app/layers-config.json
1915
"""
2016

2117
import argparse
@@ -202,89 +198,39 @@ def main():
202198
formatter_class=argparse.RawDescriptionHelpFormatter,
203199
epilog=__doc__
204200
)
205-
206-
# Input method 1: JSON file
207201
parser.add_argument(
208202
"--input",
209-
help="Path to input JSON file specifying layers (recommended)"
210-
)
211-
212-
# Input method 2: Command line arguments (legacy)
213-
parser.add_argument(
214-
"--catalog",
215-
help="URL to STAC catalog.json (required if not using --input)"
203+
required=True,
204+
help="Path to input JSON file specifying layers"
216205
)
217206
parser.add_argument(
218207
"--output",
219208
required=True,
220209
help="Output path for layers-config.json"
221210
)
222-
parser.add_argument(
223-
"--layer",
224-
action="append",
225-
metavar="COLLECTION:ASSET:KEY:NAME",
226-
help="Layer specification: collection_id:asset_id:layer_key:display_name (can be specified multiple times)"
227-
)
228-
parser.add_argument(
229-
"--titiler",
230-
default="https://titiler.nrp-nautilus.io",
231-
help="TiTiler base URL for COG tiles (default: https://titiler.nrp-nautilus.io)"
232-
)
233-
parser.add_argument(
234-
"--colormap",
235-
default="reds",
236-
help="Default colormap for raster layers (default: reds)"
237-
)
238211

239212
args = parser.parse_args()
240213

241-
# Determine input method
242-
if args.input:
243-
# Load from JSON file
244-
input_path = Path(args.input)
245-
if not input_path.exists():
246-
print(f"Error: Input file '{args.input}' not found", file=sys.stderr)
247-
sys.exit(1)
248-
249-
with open(input_path) as f:
250-
input_config = json.load(f)
251-
252-
catalog_url = input_config.get("catalog")
253-
if not catalog_url:
254-
print("Error: 'catalog' field required in input JSON", file=sys.stderr)
255-
sys.exit(1)
256-
257-
titiler_url = input_config.get("titiler_url", args.titiler)
258-
layer_specs = input_config.get("layers", [])
259-
260-
if not layer_specs:
261-
print("Error: 'layers' array is empty in input JSON", file=sys.stderr)
262-
sys.exit(1)
214+
# Load JSON input file
215+
input_path = Path(args.input)
216+
if not input_path.exists():
217+
print(f"Error: Input file '{args.input}' not found", file=sys.stderr)
218+
sys.exit(1)
263219

264-
elif args.catalog and args.layer:
265-
# Use command-line arguments (legacy mode)
266-
catalog_url = args.catalog
267-
titiler_url = args.titiler
268-
layer_specs = []
269-
270-
for layer_spec in args.layer:
271-
parts = layer_spec.split(":", 3)
272-
if len(parts) < 3:
273-
print(f"Error: Invalid layer specification '{layer_spec}'", file=sys.stderr)
274-
print("Format: collection_id:asset_id:layer_key[:display_name]", file=sys.stderr)
275-
sys.exit(1)
276-
277-
layer_specs.append({
278-
"collection_id": parts[0],
279-
"asset_id": parts[1],
280-
"layer_key": parts[2],
281-
"display_name": parts[3] if len(parts) > 3 else None,
282-
"options": {}
283-
})
220+
with open(input_path) as f:
221+
input_config = json.load(f)
284222

285-
else:
286-
print("Error: Must specify either --input or both --catalog and --layer", file=sys.stderr)
287-
parser.print_help()
223+
catalog_url = input_config.get("catalog")
224+
if not catalog_url:
225+
print("Error: 'catalog' field required in input JSON", file=sys.stderr)
226+
sys.exit(1)
227+
228+
titiler_url = input_config.get("titiler_url", "https://titiler.nrp-nautilus.io")
229+
default_colormap = input_config.get("default_colormap", "reds")
230+
layer_specs = input_config.get("layers", [])
231+
232+
if not layer_specs:
233+
print("Error: 'layers' array is empty in input JSON", file=sys.stderr)
288234
sys.exit(1)
289235

290236
# Generate layers configuration
@@ -301,6 +247,10 @@ def main():
301247
display_name = spec.get("display_name")
302248
options = spec.get("options", {})
303249

250+
if not all([collection_id, asset_id, layer_key]):
251+
print(f"Error: Layer spec missing required fields: {spec}", file=sys.stderr)
252+
sys.exit(1)
253+
304254
print(f"Processing {collection_id}:{asset_id} -> {layer_key}...", file=sys.stderr)
305255

306256
# Find collection URL
@@ -313,7 +263,7 @@ def main():
313263
collection = fetch_json(collection_url)
314264

315265
# Get options with defaults
316-
colormap = options.get("colormap", args.colormap)
266+
colormap = options.get("colormap", default_colormap)
317267
rescale = options.get("rescale")
318268

319269
# Generate layer config

0 commit comments

Comments
 (0)