1
0

feat: the state becomes California, and the port fills with ships

**Stage 1 of one California.** The owner's complaint had two halves and this is
the first: the state board was a CROPPED SLAB. `california.ts` stopped at 38.05 N,
so the board disagreed with its own minimap about the shape of California in a
single frame, and Bug Fire's 93,733 acres burned off-frame while the panel said
all clear. Bounds now run 32.50-42.05 N / -124.50 to -114.0 W — Cape Mendocino,
the ruled Oregon parallel, the 120th-meridian corner into the Nevada diagonal.

**And it got cheaper.** 391,169 triangles to 375,351, while gaining the North
Coast, the Sacramento Valley, the Klamath knot, the Cascade arc, Shasta at 4,320 m
and Lassen at 3,190 m. Extending the bounds alone would have doubled the lattice
to 168,813 points and blown the mobile cap; coarsening cellLat 0.022 -> 0.0312 and
cellLng 0.027 -> 0.0383 holds it at ~83,800. The cell as a FRACTION of the board
moves 0.0030 -> 0.0033 — unchanged in frame — because the camera retreats to frame
whatever it is given. That argument was already written in the pack's own comment.

The second half — three boards becoming one world you zoom through — is NOT here.
Merging at Bay density would be 34.04M triangles, 13x the highest budget, and
merging at SoCal density would downgrade San Francisco from 40 m lots to 164 m.
Both delete the board every marketing still is shot from. `sf.ts` and `socal.ts`
are untouched by design.

**Aerial perspective, which the state board could not have had before.** The old
fog started at 1.15 board spans = 944 km, on a board whose longest diagonal is
820 km — so no pixel could ever be fogged. Fog now responds to camera altitude,
clamped to the authored pair as a ceiling.

`Atmosphere.aerial(env, view)` is a second pure method returning `{ near, far }`
and **deliberately no colour**. That is structural, not stylistic: it is why a
future camera-dependent term cannot reach `environmentKey()`'s colour fingerprint
and start rebuilding the PMREM cubemap on every camera step. Coarsening the
fingerprint instead would have hidden one instance and armed the mechanism. A
mutation-tested seam guard fails if anyone merges the two paths back together.

**The port.** Terminal Island rendered as a bare tan polygon with generic white
blocks while the chapter text called it the busiest port complex in the
hemisphere. Now six container yards drawn as canvas atlases, 56 gantry cranes at
varied boom angles, the 13 km San Pedro breakwater, the dredged channel. Five
buckets merging ACROSS ports the way airports.ts merges across fields, so a
second complex costs no extra draws: +11 draws and +4,377 triangles for all of it.

At vertical exaggeration 3.4 a 130 m gantry is 1.132 units tall against a 400 m
ship's 1.024 long — the crane is the taller object, and it is what makes a port
read as a port from altitude.

**Ships, and the wake carries the information.** Moored hulls have no foam,
verified at three terminals; a tug under way in the Main Channel trails a clean
Kelvin V. One hull geometry, one InstancedMesh, orientation from the BERTH rather
than the wire. The AIS gate strips sog 102.3, heading 511 and cog 360 — all mean
"not available" — with an explicit test that cog 358.7 SURVIVES, because a naive
range check on cog eats real headings near north.

"Empty or full" is not in AIS position reports and is not invented per ship. The
honest answer is at port level and is a better story: 348,691 of 460,467 boxes
left Los Angeles empty in July 2026, corroborated by FBX01 $7,491 inbound against
FBX02 $347 outbound.

**Radar and birds ship dark, and say why.** California is 0.47% wet and migration
is nocturnal and seasonal, so both layers have nothing to say on most days. The
panel reads "No radar feed is configured, so this board draws no weather. That is
a fact about this box, not about the sky."

Also recorded, and it matters beyond this commit: **the GPU on amd-server never
leaves 500 MHz of a possible 2725**, traced across 80 seconds of sustained load.
`bay-area/desktop` is fragment-bound at that clock and sits on the vsync deadline,
so a trivial change in fragment work flips it between 16.8 and 33.3 with geometry
identical to the digit. Every frame-time number measured on this box is a floor.
Two investigations reached two different wrong conclusions from single-run
comparisons before this was traced. Geometry is the gate; frame time is advisory.
No cap was raised.

Tests 1,340 -> 1,540, server 280 -> 295.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-22 23:35:09 -07:00
parent b25f217e3e
commit acf4d1a510
52 changed files with 14436 additions and 142 deletions
+486 -11
View File
@@ -39,6 +39,7 @@ import type {
Hill,
Landmark,
LatLng,
Port,
} from "../engine/types.ts";
// ---- Coastlines -----------------------------------------------------------
@@ -176,16 +177,89 @@ export const SOUTHLAND: LatLng[] = [
/**
* Terminal Island: dredge spoil, container cranes and a federal prison, sitting
* between San Pedro and Long Beach. It is here because the harbour reads as a
* harbour only if there is something in it for the two bridges to land on.
* between San Pedro and Long Beach.
*
* ### Why this outline is thirty-one points and not six
*
* It used to be six, and its own comment said what those six were for: "the
* harbour reads as a harbour only if there is something in it for the two
* bridges to land on." A hexagon is enough to land a bridge on and it is not
* enough to be a port, because **the recognisable thing about this island is not
* its outline, it is the comb cut into it** — the West Basin and the East Basin
* opening north off the Cerritos Channel, Fish Harbor opening south, the Pier
* 400 fill hung off a causeway in the south-east, and a quay along the wall of
* every one of them. With six points there is nowhere for a quay to be that is
* both on land and on the water, which is the one thing a quay has to be.
*
* Traced by hand, like every other coordinate in this file, and per
* ARCHITECTURE §3.2 that means it is eyeball-accurate original expression rather
* than a copy of anybody's dataset. `ports.sqlite` cannot help: its seven rows
* all sit on an exact arc-minute grid, up to 1.3 km — 3.3 scene units here —
* from the water they claim to be on. See `engine/ports.ts`.
*
* ### What the shape has to satisfy
*
* - **The two bridges still land on it.** The Vincent Thomas's east abutment
* `[33.7535, -118.258]` and the Long Beach Gateway's west abutment
* `[33.752, -118.232]` are both inside this ring, and both of their mainland
* ends are still outside it. `socalPorts.test.ts` asserts all four.
* - **It does not touch the mainland.** The narrowest water left between the two
* is 425 m of Main Channel at the Vincent Thomas and about 500 m of Back
* Channel off Pier T, which is what those channels really are.
* - **Every authored quay vertex lies inside it.** That is the assertion that
* stops a quay floating on open water or being buried in the fill behind it,
* and it is why the basins are cut 900-1,000 m deep rather than token
* notches: a quay wall wants a kilometre of straight water frontage.
*
* Five and a half kilometres east to west, six north to south, which at 391 m to
* the scene unit is about 14 by 15 units on a 393-unit board.
*/
export const TERMINAL_ISLAND: LatLng[] = [
[33.769, -118.264],
[33.77, -118.242],
[33.76, -118.227],
[33.742, -118.228],
[33.735, -118.258],
[33.746, -118.268],
// The north shore, along the Cerritos (Back) Channel, west to east, with the
// two basins cut southward into it.
[33.7672, -118.2665], // the north-west corner, at the mouth of the West Basin
[33.759, -118.2618], // the West Basin, west wall
[33.7602, -118.2555], // the head of the West Basin
[33.769, -118.2582], // back out to the Cerritos Channel
[33.7688, -118.247], // the Badger Avenue rail bridge
[33.758, -118.2452], // the East Basin, west wall
[33.7588, -118.2382], // the head of the East Basin
[33.7672, -118.2378], // back out
[33.7635, -118.2295], // under the Long Beach International Gateway
[33.7595, -118.221], // Pier T, north-west
[33.7548, -118.2125], // Pier T, north-east, at the Middle Harbor slip
// The east end, on Queensway Bay.
[33.747, -118.2105],
[33.743, -118.216],
// The south shore, east to west, on the outer harbour.
[33.7405, -118.2245],
[33.7398, -118.233],
// The causeway down to the Pier 400 fill, and the fill itself. The neck is
// 556 m across, which is a road, two rail tracks and their shoulders.
[33.7345, -118.2352], // the causeway, east side
[33.729, -118.2372],
[33.7285, -118.23], // Pier 400, north-east
[33.7155, -118.233], // Pier 400, south-east
[33.715, -118.2495], // Pier 400, south-west
[33.729, -118.252], // Pier 400, north-west
[33.7288, -118.2432],
[33.7343, -118.2412], // the causeway, west side
[33.738, -118.244],
// Fish Harbor, cut in from the south. The cannery basin, and the one part of
// this island that predates the container.
[33.7378, -118.256],
[33.735, -118.2572],
[33.7352, -118.264],
[33.7398, -118.2652],
[33.742, -118.2698], // the south-west corner, at Reservation Point
// The west shore, up the Main Channel.
[33.7505, -118.2708], // under the Vincent Thomas
[33.759, -118.2692],
];
/**
@@ -1687,6 +1761,385 @@ export const LONG_BEACH_GATEWAY: Bridge = {
export const BRIDGES = [VINCENT_THOMAS, LONG_BEACH_GATEWAY];
// ---- Ports ----------------------------------------------------------------
/**
* San Pedro Bay: Los Angeles and Long Beach, one basin, two ports.
*
* Together they are the busiest container complex in the western hemisphere, and
* until this block existed the Harbour chapter said so over a picture of nothing
* at all. `engine/ports.ts` draws all of it in four draw calls; this is the data
* it draws.
*
* ### Everything below is hand-traced, and the store cannot help
*
* ARCHITECTURE §3.2 applies here exactly as it does to the coastline. Beyond
* that, the upstream `ports` table is unusable for placement even if the licence
* allowed it: all seven of its rows sit on an exact arc-minute grid — `lat*60`
* and `lon*60` are whole integers for every one — and one arc-minute at this
* latitude is 1,852 m of latitude and 1,540 m of longitude, so a quay placed
* from those columns lands as much as 3.3 scene units from the water. Its
* `channel_depth_ft` is worse: a binned WPI code that reports Los Angeles as
* fourteen feet deep against a real dredged channel near fifty-three.
* `socalPorts.test.ts` asserts that neither anchor below is on an arc-minute.
*
* The one column of that table which *is* load-bearing is `harbor_type`: USLAX
* and USLGB are both `CB`, coastal breakwater, and they share the federal
* breakwater declared on `LOS_ANGELES` below. Oakland is `CN`, coastal natural,
* and when the Bay board gets this kit it must not be given one.
*
* ### The empty boxes are the story, and they are a fact about a port
*
* The owner asked whether the ships are empty or full. They cannot be: there is
* no draught column in the vessel store, the AIS static message that would carry
* one is absent for most hulls most of the time, and a per-hull laden state
* would be an invention. The same question answered at the level where the data
* is real is far better anyway — in July 2026, **348,691 of the 460,467
* containers that left Los Angeles left empty**, which is 75.7 per cent, and a
* second collector explains it from the other side: a box costs $7,491 to bring
* east across the Pacific and $347 to send back. Nobody pays to repatriate an
* empty, so three quarters of them go home with nothing in them.
*
* That number is drawn, not just written: `Yard.emptyShare` is the proportion of
* stacks the yard atlas paints in the empty palette. **It is the empty share of
* the month's outbound boxes, not a census of what is standing in the yard
* today** — nobody counts that — and it is applied here because the export
* stacks are the large majority of what an American west-coast yard holds.
*
* ### Why Long Beach carries no `throughput` record
*
* Its export split is known and is nearly identical to LA's: 341,806 empty
* against 104,843 loaded, 76.5 per cent. Its *import* halves were never read.
* `PortThroughput` requires all four counts, and a record with two real numbers
* and two plausible ones is precisely the failure the fire layer nearly shipped,
* so Long Beach gets no record rather than half of one. Its yards still carry
* the 0.765 that is measured.
*/
/**
* The federal breakwater — three arms, two gates, 13.06 km of rubble.
*
* San Pedro (3.46 km) from the shore below Cabrillo out to the Angels Gate
* light; the Middle Breakwater (5.61 km); and the Long Beach arm (3.99 km)
* running east toward Alamitos Bay. The 589 m gap between the first two is
* Angels Gate, the main entrance, and the 703 m between the second and third is
* Queens Gate.
*
* This is the object that makes the whole board's south-west corner read as a
* harbour rather than a bay: 13.06 km is 33.4 scene units on a 393-unit board,
* about nine per cent of its width, and it is the only part of this port that is
* legible from the whole-board pose. It is drawn wider than life — see
* `BREAKWATER_BASE_M` and its floor in `engine/ports.ts` — for the reason the
* LA River polygon is drawn four times its true width a few hundred lines above:
* a feature narrower than a lattice cell does not render as a thin line, it
* renders as a dotted one.
*/
const SAN_PEDRO_BREAKWATER: LatLng[][] = [
[
[33.7065, -118.2885], // rooted off Cabrillo Beach
[33.7048, -118.274],
[33.707, -118.262],
[33.7083, -118.2517], // the Angels Gate light
],
[
[33.7095, -118.2455], // the Middle Breakwater, west end
[33.712, -118.227],
[33.7145, -118.206],
[33.7165, -118.1855], // Queens Gate, west side
],
[
[33.7175, -118.178], // the Long Beach arm, west end
[33.719, -118.156],
[33.72, -118.135],
],
];
/**
* The Port of Los Angeles.
*
* Four container terminals on the west and south of Terminal Island, forty
* gantries between them, and the Main Channel running up from Angels Gate past
* the Vincent Thomas to the turning basin at Wilmington.
*
* The crane bearings are the whole of the recognition and they are all
* different: Pier 400 leans west over the outer harbour, Pier 300 south, the
* East Basin west into its slip and the West Basin east into its own. A port
* where every boom points the same way reads as a fence.
*/
export const LOS_ANGELES: Port = {
id: "USLAX",
name: "Port of Los Angeles",
// The middle of Terminal Island, hand-placed. Deliberately not
// `ports.sqlite`'s 33.75 / -118.25, which is an arc-minute rounding.
lat: 33.7508,
lng: -118.2604,
harborType: "CB",
breakwater: SAN_PEDRO_BREAKWATER,
channel: [
[33.698, -118.247], // the approach, outside the breakwater
[33.709, -118.2486], // through Angels Gate
[33.72, -118.258],
[33.732, -118.267],
[33.743, -118.2731],
[33.751, -118.2732], // under the Vincent Thomas
[33.762, -118.2711],
[33.7688, -118.269], // the turning basin at the head
],
/**
* Quay polygons, **water edge first**.
*
* That ordering is a contract with `engine/ports.ts`, which takes the first
* two vertices as the wall and drops the skirt and the revetment toe from
* them. A polygon traced the other way round hangs its wall off the back of
* the terminal, where nothing can see it and the water edge is a bare cut.
*/
quays: [
{
id: "pier-400",
deckHeight: 4,
polygon: [
[33.7284, -118.2516],
[33.7157, -118.2493],
[33.7158, -118.2481],
[33.7286, -118.2503],
],
},
{
id: "pier-300",
deckHeight: 4,
polygon: [
[33.7382, -118.2448],
[33.738, -118.2552],
[33.7391, -118.2553],
[33.7393, -118.2448],
],
},
{
id: "east-basin",
deckHeight: 4,
polygon: [
[33.7594, -118.2379],
[33.7666, -118.2376],
[33.7665, -118.2363],
[33.7594, -118.2366],
],
},
{
id: "west-basin",
deckHeight: 4,
polygon: [
[33.7603, -118.2629],
[33.7655, -118.2658],
[33.7651, -118.267],
[33.7598, -118.264],
],
},
],
/**
* Berths, for the vessel layer that will lie hulls along them.
*
* `bearing` is the bow of a ship alongside, and it is authored here rather
* than read off the wire because the wire cannot answer it: of 150 vessels in
* the store sitting under half a knot, only 75 report a usable heading and 21
* report neither heading nor course. A berth has one answer and it never
* changes.
*/
berths: [
{ id: "lax-401", lat: 33.7268, lng: -118.2518, bearing: 171.6, maxLength: 400, quayId: "pier-400" },
{ id: "lax-402", lat: 33.7236, lng: -118.2512, bearing: 171.6, maxLength: 400, quayId: "pier-400" },
{ id: "lax-403", lat: 33.7204, lng: -118.2507, bearing: 171.6, maxLength: 400, quayId: "pier-400" },
{ id: "lax-404", lat: 33.7172, lng: -118.2501, bearing: 171.6, maxLength: 400, quayId: "pier-400" },
{ id: "lax-306", lat: 33.7378, lng: -118.2474, bearing: 268.9, maxLength: 366, quayId: "pier-300" },
{ id: "lax-305", lat: 33.7377, lng: -118.2526, bearing: 268.9, maxLength: 366, quayId: "pier-300" },
{ id: "lax-226", lat: 33.7612, lng: -118.2383, bearing: 2.3, maxLength: 335, quayId: "east-basin" },
{ id: "lax-232", lat: 33.7648, lng: -118.2381, bearing: 2.3, maxLength: 335, quayId: "east-basin" },
{ id: "lax-136", lat: 33.7618, lng: -118.2632, bearing: 334.9, maxLength: 366, quayId: "west-basin" },
{ id: "lax-142", lat: 33.7644, lng: -118.2646, bearing: 334.9, maxLength: 366, quayId: "west-basin" },
],
/**
* Crane rows. Forty gantries in four records.
*
* `height` is rail to the top of the portal beam; the raised boom tip stands
* about half as high again, which at this board's 3.4x exaggeration is 1.13
* scene units — taller than a 400 m ship is long. `idleFraction` is taken from
* the far end of each rail by `craneStations`, so a partly-worked berth looks
* like a block of booms down over a ship and the rest stood off, which is what
* one looks like.
*/
cranes: [
{
id: "pier-400",
from: [33.7284, -118.2514],
to: [33.7157, -118.2492],
count: 18,
bearing: 261.6,
height: 82,
outreach: 72,
idleFraction: 0.17,
},
{
id: "pier-300",
from: [33.7384, -118.2448],
to: [33.7382, -118.2553],
count: 8,
bearing: 178.9,
height: 78,
outreach: 68,
idleFraction: 0.38,
},
{
id: "east-basin",
from: [33.7594, -118.2377],
to: [33.7666, -118.2374],
count: 6,
bearing: 272.3,
height: 74,
outreach: 61,
idleFraction: 0.5,
},
{
id: "west-basin",
from: [33.7602, -118.263],
to: [33.7655, -118.266],
count: 8,
bearing: 64.9,
height: 78,
outreach: 68,
idleFraction: 0.25,
},
],
/**
* The yards. `emptyShare` is 0.757 on every one of them — 348,691 of 460,467
* — and it is the number the atlas paints, not a number in a caption.
*/
yards: [
{ id: "pier-400", lat: 33.7223, lng: -118.2433, length: 1420, width: 1130, bearing: 172, emptyShare: 0.757 },
{ id: "pier-300", lat: 33.7412, lng: -118.252, length: 1210, width: 600, bearing: 90, emptyShare: 0.757 },
{ id: "east-basin", lat: 33.761, lng: -118.2351, length: 820, width: 480, bearing: 2, emptyShare: 0.757 },
{ id: "west-basin", lat: 33.753, lng: -118.2649, length: 1260, width: 570, bearing: 350, emptyShare: 0.757 },
/**
* The on-dock rail yard in the middle of the island, and **the one rectangle
* here with no `emptyShare` on it**.
*
* Nobody publishes what is standing in it. `emptyShare` absent is what the
* type means by unknown, and `yardAtlas` draws an unknown yard in one flat
* colour rather than in a plausible-looking mix — so the board carries a
* visible difference between a number that was measured and a number that
* was not, which is the whole discipline this product is trying to keep.
*/
{ id: "rail-yard", lat: 33.7498, lng: -118.2502, length: 1150, width: 470, bearing: 350 },
],
/** July 2026. `asOf` is the month these counts describe and is never "now". */
throughput: {
asOf: "2026-07",
loadedExport: 111_776,
emptyExport: 348_691,
loadedImport: 499_552,
emptyImport: 446,
},
/**
* The explanation, from a different collector entirely.
*
* No timestamp, deliberately: the store's `observed_at` is our own read clock,
* Freightos publishes none, and a card that renders it as "as of" is lying
* about a precision nobody has.
*/
rates: [
{ id: "FBX01", lane: "China / East Asia to North America West Coast", usdPerFeu: 7_491 },
{ id: "FBX02", lane: "North America West Coast to China / East Asia", usdPerFeu: 347 },
],
};
/**
* The Port of Long Beach — Pier T, on the east end of Terminal Island.
*
* The former Naval Station, and the half of the island that is in a different
* city. It is here as much for what it proves as for what it shows: it shares
* every mesh with Los Angeles, so the second port on this board costs no extra
* draw call at all. See `createPorts`.
*
* No `breakwater` of its own — the arms on `LOS_ANGELES` are one federal
* structure across the whole bay and drawing them twice would double the
* geometry for an identical picture. No `throughput`, for the reason given at
* the head of this block.
*/
export const LONG_BEACH: Port = {
id: "USLGB",
name: "Port of Long Beach",
lat: 33.7529,
lng: -118.2181,
harborType: "CB",
channel: [
[33.7235, -118.1885], // in through Queens Gate
[33.736, -118.1955],
[33.746, -118.203],
[33.753, -118.206],
[33.758, -118.214],
[33.7637, -118.223], // under the Long Beach International Gateway
[33.7709, -118.233], // and away west up the Back Channel
],
quays: [
{
id: "pier-t",
deckHeight: 4,
polygon: [
[33.759, -118.2205],
[33.755, -118.2133],
[33.7541, -118.214],
[33.7581, -118.2212],
],
},
{
id: "pier-t-east",
deckHeight: 4,
polygon: [
[33.7541, -118.2126],
[33.7476, -118.2109],
[33.7473, -118.2122],
[33.7539, -118.2139],
],
},
],
berths: [
{ id: "lgb-t132", lat: 33.7586, lng: -118.219, bearing: 123.6, maxLength: 400, quayId: "pier-t" },
{ id: "lgb-t136", lat: 33.7573, lng: -118.2166, bearing: 123.6, maxLength: 400, quayId: "pier-t" },
{ id: "lgb-t140", lat: 33.756, lng: -118.2142, bearing: 123.6, maxLength: 400, quayId: "pier-t" },
{ id: "lgb-s101", lat: 33.7526, lng: -118.2117, bearing: 168, maxLength: 335, quayId: "pier-t-east" },
{ id: "lgb-s105", lat: 33.7493, lng: -118.2109, bearing: 168, maxLength: 335, quayId: "pier-t-east" },
],
cranes: [
{
id: "pier-t",
from: [33.7588, -118.2206],
to: [33.7548, -118.2134],
count: 10,
bearing: 33.6,
height: 84,
outreach: 74,
idleFraction: 0.2,
},
{
id: "pier-t-east",
from: [33.7541, -118.2128],
to: [33.7475, -118.2111],
count: 6,
bearing: 78,
height: 76,
outreach: 64,
// The quiet frontage. Five of six booms up is what an east-facing berth
// with nothing alongside looks like, and it is the cheapest way this board
// has of saying that a port is not uniformly busy.
idleFraction: 0.83,
},
],
yards: [
{ id: "pier-t", lat: 33.753, lng: -118.2214, length: 1210, width: 710, bearing: 124, emptyShare: 0.765 },
{ id: "pier-t-east", lat: 33.7484, lng: -118.2132, length: 480, width: 240, bearing: 168, emptyShare: 0.765 },
],
};
export const PORTS = [LOS_ANGELES, LONG_BEACH];
// ---- Airports -------------------------------------------------------------
/**
@@ -3129,11 +3582,21 @@ export const DISTRICTS: District[] = [
},
{
id: "san-pedro",
// The eastern edge is the Main Channel, and it is drawn that way on purpose.
// This polygon used to be a plain quad reaching to -118.235, which put the
// whole of Terminal Island inside it — so the busiest container terminal in
// the hemisphere came out as three dozen generic industrial blocks,
// indistinguishable from the housing across the water. `engine/ports.ts`
// draws what is actually there. Vertices 3 and 4 run the boundary down the
// middle of the channel: San Pedro's own waterfront at about -118.2755 stays
// inside it, Terminal Island's west shore at -118.2708 stays outside.
name: "San Pedro & Wilmington",
polygon: [
[33.795, -118.305],
[33.79, -118.235],
[33.708, -118.246],
[33.7745, -118.238],
[33.7745, -118.272],
[33.708, -118.276],
[33.713, -118.31],
],
minHeight: 11,
@@ -3169,6 +3632,11 @@ export const DISTRICTS: District[] = [
// any case. Vertices 2-9 walk down the corridor, round the field, and back
// up it.
name: "Long Beach",
// The last vertex moved north from 33.758 to 33.7695 for the reason the San
// Pedro polygon's east edge moved: at -118.238 the old south edge sat at
// 33.7579, which is below Terminal Island's East Basin and put lots on the
// Everport quay. Everything between the old line and the new one is water —
// the Long Beach shoreline there is at 33.766 — so nothing real was lost.
polygon: [
[33.868, -118.23],
[33.8653, -118.166],
@@ -3181,7 +3649,7 @@ export const DISTRICTS: District[] = [
[33.865, -118.161],
[33.862, -118.09],
[33.752, -118.102],
[33.758, -118.24],
[33.7695, -118.24],
],
minHeight: 12,
maxHeight: 124,
@@ -3570,7 +4038,7 @@ export const CHAPTERS: City["chapters"] = [
rotation: -0.9,
},
description:
"San Pedro, Terminal Island and Long Beach around one basin, with the peninsula rising behind them. The busiest port complex in the hemisphere, and the only two bridges on this map that cross water.",
"Three of every four boxes that left Los Angeles in July 2026 left empty \u2014 348,691 of 460,467 \u2014 because a container is worth $7,491 coming east across the Pacific and $347 going back. The pale stacks in these yards are that number. San Pedro, Terminal Island and Long Beach around one basin, behind thirteen kilometres of federal breakwater.",
},
{
id: "orange-county",
@@ -3676,6 +4144,13 @@ export const SOCAL_CITY: City = {
* floats a dark stripe over every runway the kit lays flush.
*/
airports: AIRPORTS,
/**
* San Pedro Bay, drawn by `engine/ports.ts`. Two ports, one federal
* breakwater, fifty-six gantries and six container yards — in four draw calls,
* because every bucket merges across both ports.
*/
ports: PORTS,
landmarks: LANDMARKS,
bridges: BRIDGES,
roads: ROADS,