# NJ shipping locations

This directory under `public/` owns all shipping generation code, tests, browser logic, and four generated GeoJSON datasets.

| File | Sources |
| --- | --- |
| shipping.geojson | New Jersey OSM shipping points, USGS post offices, and ATP USPS collection boxes |
| shipping_extra.geojson | ATP UPS Stores and CVS UPS Access Points verified against CVS city pages |
| shipping_fedex.geojson | FedEx locator records collected by ATP |
| shipping_ups_boxes.geojson | Explicit UPS drop-box listings and numeric map coordinates from MailingLocations |

Install `osmium` and `beautifulsoup4`, then run from the repository root:

```sh
python public/shipping/test_fedex
python public/shipping/test_shipping_geometry
python public/shipping/test_mailinglocations
python public/shipping/test_usps
python public/shipping/test_shipping_extra
node public/shipping/test_shipping.cjs
python public/shipping/validate_data
```

The separate **Refresh NJ shipping locations** workflow downloads the checksum-verified OSM extract from the shared `nj-osm` GitHub Release to `/tmp/new-jersey.osm.pbf`, runs the importers, validates and commits the data, then publishes a versioned shipping Release. The separate **Publish mapping pages** workflow assembles the shipping and contour releases with `public/` and deploys the site. Data and `shipping.js` are published at https://mapping.mbligh.org/shipping/.

Run `python public/shipping/build_usps` after `build_shipping.py` to append USPS collection boxes to the shared `shipping.geojson`. It reads ATP's dedicated `usps_collection_boxes` output, selects NJ, preserves collection times, indoor/lobby indicators, notes, and box IDs, and refuses incomplete or invalid results. An optional positional input file reuses a downloaded ATP snapshot. Refreshing replaces existing USPS boxes by their source references, preserving all other features; boxes remain distinct from post offices at the same address. Collection times are pickup schedules, not opening hours.

Each importer writes beside its own script, so it also works from another working directory. The MailingLocations importer supports `--city-url`, `--cache-dir`, and `--output` for targeted checks. Its directory records retain source links, retrieval timestamps, and unverified freshness/position labels.

If live CVS verification is unavailable, the extras importer refreshes UPS Stores and retains only the CVS access points already verified in the tracked dataset, marking their verification status as unavailable for this refresh. It adds no new CVS candidates in this case and fails if no verified CVS history exists. A successful live check with zero matches still fails validation.

If ATP's FedEx output is unavailable or has fewer than 100 NJ staffed locations or 100 NJ drop boxes, `build_fedex` retains the entire previously validated FedEx snapshot. It does not blend partial new results into history. History must pass source, carrier, unique-reference, NJ geometry, and count checks; absent or invalid history fails without overwriting the file. Retained points preserve address corrections and other metadata. A workflow warning, collection-level `source_refresh` report, and per-point **Refresh** popup label identify the unsuccessful attempt. `last_successful_at` is preserved across failures (or null for legacy data with no recorded timestamp); a successful source refresh resets the status. Explicit positional input-file imports remain strict and fail on incomplete data. Writes replace the file atomically.

## Browser integration

```js
import {initShipping} from 'https://mbligh.github.io/mapping/shipping/shipping.js';
initShipping(map, maplibregl);
```

The page supplies checkboxes with IDs `shipping`, `fedex-boxes`, `ups-boxes`, `usps-boxes`, and a status element `shipping-status`. USPS collection boxes use a separate blue point layer and checkbox backed by the shared shipping source. The module resolves data relative to its own URL, restores layers after style changes, and merges conservative same-location matches while retaining source details. Drop boxes remain distinct from staffed counters. Tests can override `dataBaseUrl`.

Contour and shipping refreshes are independent; the single Pages publisher assembles both datasets and serializes deployments.

## Shared coordinate cleanup

Feeders retain structured `address_parts` for `scripts/clean_locations` and the reusable `mapping_quality` package. The workflow checks directory coordinates against independent NJ address points before committing data. Corrections over 250 metres are labeled estimates and retain original coordinates; unresolved lookups retain their source positions. GeoJSON contains per-point provenance and collection-level counts, and popups show the position-check label. The same pass covers USPS, FedEx, UPS/CVS, and MailingLocations with a shared cache. OSM/USGS points and separate source identities are preserved. See `mapping_quality/README.md` at the repository root.
