# NWS Hazard Viewer Wrapper A small, **web-only** PHP script that takes a latitude/longitude, builds a [weather.gov Western Region](https://www.weather.gov/wrh/) hazards-map URL centered on that point, and redirects the browser to it. --- ## What "display the page" means here The target URL is an **interactive JavaScript map** (it loads map tiles and live observation data in the browser). It is *not* a static page, so this script does **not** fetch or echo its HTML — it issues an HTTP `302` redirect so the browser navigates straight to the map. --- ## Requirements - **PHP 7.1+** (uses `declare(strict_types=1)`, nullable handling, and array destructuring). - A web server with PHP enabled (Apache + mod_php, PHP-FPM, etc.). - The file has **no `#!` shebang line** — under mod_php a shebang is treated as page output, which breaks both `declare(strict_types=1)` and the redirect header. This is a browser-served script; it is not meant to be run from a terminal. --- ## Directory layout The default coordinate file is resolved as `__DIR__ . '/../trs2latlon/latest.txt'`, so `trs2latlon` is expected to be a **sibling** of the script's directory: ``` tools/ ├── nws_hazard_viewer_wrapper/ │ └── nws_hazard_viewer.php <- the script └── trs2latlon/ └── latest.txt <- the coordinate file (written by another script) ``` If your layout differs, change the `DEFAULT_FILE` constant near the top of the script (e.g. `__DIR__ . '/trs2latlon/latest.txt'` for a child directory, or an absolute path). --- ## Usage ### With an explicit location Pass a single `latlon` parameter — latitude, a comma, then longitude: ``` https://your-host/.../nws_hazard_viewer.php?latlon=45.5121,-122.6304 ``` `latlon` is the **only** recognized query parameter; anything else is ignored. ### With no parameters ``` https://your-host/.../nws_hazard_viewer.php ``` The script reads `../trs2latlon/latest.txt` and redirects to the coordinates on its single line. --- ## Behavior | Situation | Result | |-----------|--------| | Valid `?latlon=LAT,LON` | `302` redirect to the map | | No `latlon` parameter, file readable & well-formed | `302` redirect to the file's coordinates | | `latlon` present but not a valid `lat,lon` number pair (incl. empty) | `400` + plain text `Invalid latlon query` (not logged) | | File missing / unreadable / empty / malformed / bad coordinates | `500` + plain text `Location unavailable.` (reason written to the server error log) | The design principle: a coordinate the visitor *explicitly* supplies must be valid (no silent fallback to the file), and a server-side data problem fails loudly server-side rather than guessing at a location. ### Validation Coordinates must be numeric, with latitude in **−90…90** and longitude in **−180…180**. Values are carried as strings through to the URL so full precision is preserved. --- ## Coordinate file format A single line of three comma-separated fields — a label, then latitude, then longitude: ``` T1S R1E Section 1, 45.5121, -122.6304 ``` Only the 2nd and 3rd fields (lat, lon) are used; the label is ignored. **The label must not contain a comma** — every comma is a field separator, so a comma in the label would shift which fields are read as coordinates. (Blank lines are skipped; the first non-empty line is used.) --- ## Configuration Edit the constants near the top of the script: | Constant | Purpose | |----------|---------| | `DEFAULT_FILE` | Path to the coordinate file (default: `../trs2latlon/latest.txt`, a sibling directory of the script's folder). | | `URL_TEMPLATE` | The weather.gov URL. `%LAT%` and `%LON%` are substituted; every other map parameter (zoom, filters, displayed elements, etc.) is fixed here — adjust to taste. | The visitor-facing error strings (`Invalid latlon query`, `Location unavailable.`) are short literals in the `invalid_latlon()` and `fail()` functions if you want to reword them. --- ## Security notes - **No local-file-inclusion:** the only file read is the hardcoded `DEFAULT_FILE`. No file path can be supplied via the URL. - **No open redirect:** the redirect target is always built from the fixed `URL_TEMPLATE`, so a visitor can only ever be sent to weather.gov. - **No path disclosure:** file/server problems show a generic message to the visitor; the specific reason (including the file path) goes only to the server error log. - Because `trs2latlon` is a sibling of the served directory, confirm it isn't independently web-reachable if you don't intend it to be (e.g. an `.htaccess` deny, or keep the data outside the web root with an absolute `DEFAULT_FILE`). - The web user must have read access to `latest.txt` and traverse permission on `trs2latlon/`, or the file read fails (→ `500`). --- ## Alternative: the official NWS API If you ever want weather *data* rather than the interactive map, the National Weather Service publishes a JSON API at `https://api.weather.gov`. Hit `https://api.weather.gov/points/{lat},{lon}` to get the forecast office and grid, then pull current observations or the forecast as structured data — no scraping and no JavaScript-rendering problem.