/**
 * Southern California — Los Angeles, Orange County and Riverside, as one Tera
 * city pack.
 *
 * Pure data, and traced by hand from scratch for the same reason San Francisco
 * was: OpenStreetMap is ODbL, ODbL is share-alike, and a share-alike obligation
 * cannot live inside an Apache-2.0 repo without infecting it. Every coastline,
 * ridge and district boundary below is original expression. See
 * ARCHITECTURE.md §3.2.
 *
 * **This is not San Francisco with more rows.** SF is 0.20° × 0.36°, a city you
 * can hold in one frame at 45 m cells. The frame that actually holds Malibu,
 * Catalina, the San Gabriel crest and downtown Riverside is 1.08° × 1.66° — a
 * little over twenty-five times the area. ARCHITECTURE.md §5 estimated fourteen
 * from a tighter box; the argument only gets stronger with the real one. A
 * uniform 45 m lattice over this would be close to nine million points and a
 * mesh nobody can load, so the pack declares seven `focusRegions` at 80 m and
 * lets the basin between them run at 480 m. That is the whole reason those two
 * fields exist.
 *
 * The second thing that does not transfer is scale. The engine's camera is
 * capped at 340 units from its target and its fog closes at 460, so a city has
 * to fit inside roughly the same scene footprint whatever its size on the
 * ground. San Francisco gets 94 m to the scene unit; Southern California gets
 * 391. Everything downstream follows from that one number: a building lot is
 * 164 m rather than 40, a "building" is really a city block, and the towers are
 * small because at this remove they genuinely are. LA's story from above is not
 * its skyline. It is a basin ninety kilometres across with a three-kilometre
 * wall along the north side of it, and that is what this file is arranged to
 * show.
 */

import type { Airport } from "../engine/airports.ts";
import type {
  Bridge,
  City,
  District,
  FocusRegion,
  Hill,
  Landmark,
  LatLng,
  Port,
} from "../engine/types.ts";

// ---- Coastlines -----------------------------------------------------------

/**
 * The mainland, traced west to east along the shore and then closed off-frame.
 *
 * The order of the coast is the order of the drive: down the Malibu shelf,
 * around the curve of Santa Monica Bay, out onto the Palos Verdes headland, in
 * through the harbour, along the Long Beach and Orange County strand, and off
 * at San Mateo Point where the county line is.
 *
 * Two features carry the whole silhouette. **Santa Monica Bay** is a genuine
 * arc — the shore turns roughly sixty degrees between the Malibu shelf, which
 * runs almost due east, and the South Bay strand, which runs almost due south —
 * and getting that curve wrong makes the map read as anywhere. **Palos Verdes**
 * is the blunt headland that closes the bay's south end; without it Los Angeles
 * has no southern edge at all and the harbour makes no sense.
 *
 * The last three vertices are deliberately outside `bounds`. The world's
 * coastal falloff ramps relief to zero near *any* polygon edge, including an
 * artificial one, so a boundary drawn on the frame line would leave a flattened
 * band of basin along the north and east of the map. Pushed off-frame, the
 * falloff lands on lattice points that are never sampled.
 */
export const SOUTHLAND: LatLng[] = [
  // North-west, off-frame
  [34.4, -119.02],

  // The Malibu shelf, west -> east. The mountains come straight down to the
  // water here, which is why there is one road and no city.
  [34.06, -118.98], // the Ventura county line, at Leo Carrillo
  [34.038, -118.93],
  [34.023, -118.87], // Nicholas Canyon
  [34.017, -118.828], // Zuma
  [33.996, -118.806], // Point Dume — the only headland on this stretch
  [34.01, -118.79], // Paradise Cove
  [34.026, -118.76],
  [34.034, -118.72],
  [34.036, -118.678], // Malibu Pier and the lagoon
  [34.039, -118.635],
  [34.04, -118.585], // Topanga Canyon meets the sea
  [34.038, -118.56],
  [34.037, -118.525], // Will Rogers

  // Santa Monica Bay. The shore swings from east-west to north-south over
  // about twenty kilometres; this is the curve the eye recognises.
  [34.028, -118.51],
  [34.009, -118.498], // Santa Monica Pier
  [33.99, -118.482],
  [33.977, -118.472], // Venice Pier
  [33.965, -118.458],
  [33.958, -118.452], // the Marina and Ballona Creek mouth
  [33.945, -118.44], // Dockweiler, directly under LAX's departures
  [33.928, -118.433],
  [33.905, -118.421], // El Segundo
  [33.884, -118.411], // Manhattan Beach Pier
  [33.862, -118.403], // Hermosa Pier
  [33.844, -118.393], // Redondo and King Harbor
  [33.822, -118.392],

  // The Palos Verdes peninsula: uplifted marine terraces, a blunt nose to the
  // south-west, and cliffs the whole way round.
  [33.806, -118.396], // Malaga Cove — the terraces begin
  [33.79, -118.406],
  [33.771, -118.412], // Bluff Cove
  [33.752, -118.416],
  [33.742, -118.41], // Point Vicente
  [33.735, -118.39],
  [33.733, -118.365], // Portuguese Bend
  [33.727, -118.34],
  [33.718, -118.318], // Royal Palms
  [33.708, -118.3],
  [33.705, -118.294], // Point Fermin, the southern tip of the mainland

  // The Port of Los Angeles and Long Beach. The trace runs up the main channel
  // to Wilmington and back down the far side, which leaves the outer harbour as
  // open water with Terminal Island sitting in the middle of it.
  [33.712, -118.282], // Cabrillo Beach
  [33.726, -118.278],
  [33.746, -118.276], // the San Pedro waterfront
  [33.762, -118.274],
  [33.774, -118.27], // the head of the main channel, at Wilmington
  [33.778, -118.25],
  [33.776, -118.232], // west Long Beach and the Dominguez Channel
  [33.766, -118.222],
  [33.76, -118.213], // the Long Beach container terminals
  [33.766, -118.198], // Queensway
  [33.762, -118.186],
  [33.76, -118.17],
  [33.759, -118.15],
  [33.757, -118.135], // Belmont Shore
  [33.748, -118.12],
  [33.742, -118.112], // the mouth of Alamitos Bay
  [33.74, -118.1], // Seal Beach

  // The Orange County strand: forty kilometres of almost unbroken sand, then
  // the coast turns and climbs into the San Joaquin Hills.
  [33.734, -118.078],
  [33.722, -118.068], // Surfside and Sunset Beach
  [33.706, -118.058],
  [33.69, -118.044], // Bolsa Chica
  [33.672, -118.02],
  [33.656, -118.0], // Huntington Beach Pier
  [33.64, -117.978],
  [33.63, -117.96], // the Santa Ana River mouth
  [33.618, -117.942],
  [33.608, -117.929], // Newport Pier
  [33.598, -117.9],
  [33.593, -117.881], // the harbour entrance, off the end of the Balboa peninsula
  [33.59, -117.872], // Corona del Mar
  [33.583, -117.855],
  [33.57, -117.833], // Crystal Cove
  [33.556, -117.806],
  [33.542, -117.783], // Laguna Beach, where the hills reach the water
  [33.526, -117.766],
  [33.51, -117.753], // Aliso Beach
  [33.494, -117.732],
  [33.488, -117.725], // Salt Creek
  [33.47, -117.712],
  [33.462, -117.706], // Dana Point — the last headland on this map
  [33.46, -117.69], // Doheny, at the mouth of San Juan Creek
  [33.446, -117.667],
  [33.428, -117.63],
  [33.418, -117.615], // the San Clemente pier
  [33.4, -117.598],
  [33.386, -117.593], // San Mateo Point, the San Diego county line

  // Off-frame, closing round the east and north. Camp Pendleton, the high
  // desert and San Bernardino are all past the edge of this board.
  [33.24, -117.5],
  [33.2, -117.16],
  [34.4, -117.14],
];

/**
 * Terminal Island: dredge spoil, container cranes and a federal prison, sitting
 * 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[] = [
  // 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],
];

/**
 * Santa Catalina, thirty-five kilometres offshore.
 *
 * It earns its place twice over: it is the one thing in the south-west quarter
 * of the frame that is not empty water, and on the days you can actually see it
 * from the mainland it is the reason anyone believes the basin has a horizon.
 * Long and thin, north-west to south-east, pinched almost in two at the isthmus
 * above Two Harbors.
 */
export const CATALINA: LatLng[] = [
  [33.475, -118.6], // the West End
  [33.462, -118.565],
  [33.4425, -118.5], // the isthmus at Two Harbors
  [33.428, -118.462],
  [33.408, -118.428],
  [33.39, -118.395], // Long Point
  [33.362, -118.348],
  [33.3425, -118.328], // Avalon
  [33.318, -118.305], // the East End
  [33.308, -118.322],
  [33.332, -118.362],
  [33.36, -118.408],
  [33.388, -118.452],
  [33.412, -118.492],
  [33.432, -118.535],
  [33.455, -118.592],
];

/** Everything the buildings may stand on. */
export const LANDMASSES = [SOUTHLAND, TERMINAL_ISLAND, CATALINA];

// ---- Parks and open space -------------------------------------------------

/**
 * Open space does two jobs here. It paints the ranges green, and — because
 * `blocks.ts` refuses to build inside a park — it is what keeps the procedural
 * scatter off the mountains without needing a slope test in the engine.
 *
 * These polygons are drawn to the *shape of the wild land*, not to any agency's
 * boundary. The Angeles National Forest polygon is really "the San Gabriels",
 * and its southern edge is the range front: the line where the suburbs stop
 * dead and the mountain starts, which in this metro is a line you can see from
 * space.
 */

/** The San Gabriels. The south edge is the range front, Sylmar to Cajon. */
export const ANGELES_FOREST: LatLng[] = [
  [34.38, -118.52],
  [34.38, -117.32],
  [34.22, -117.38],
  [34.18, -117.45],
  [34.155, -117.57],
  [34.145, -117.7],
  [34.16, -117.79],
  [34.17, -117.9],
  [34.175, -117.99],
  [34.185, -118.05],
  [34.21, -118.13],
  [34.235, -118.2],
  [34.27, -118.3],
  [34.305, -118.4],
  [34.32, -118.47],
];

/** The Santa Susanas, closing the San Fernando Valley off to the north-west. */
export const SANTA_SUSANA: LatLng[] = [
  [34.33, -118.72],
  [34.33, -118.56],
  [34.25, -118.57],
  [34.24, -118.7],
];

/**
 * The Santa Monica Mountains, Malibu to Griffith Park.
 *
 * A single east-west band forty kilometres long and rarely more than eight
 * wide. It matters structurally: this is the wall that separates the coastal
 * plain from the San Fernando Valley, and every crossing of it — Sepulveda,
 * Cahuenga, Topanga — is a pass with a freeway or a boulevard in it.
 */
export const SANTA_MONICA_MOUNTAINS: LatLng[] = [
  [34.132, -118.93],
  [34.135, -118.7],
  [34.138, -118.56],
  [34.132, -118.5],
  [34.125, -118.455],
  [34.118, -118.42],
  [34.108, -118.38],
  [34.092, -118.345],
  [34.08, -118.36],
  [34.076, -118.425],
  [34.072, -118.472],
  [34.062, -118.525],
  [34.043, -118.6],
  [34.04, -118.7],
  [34.045, -118.82],
  [34.05, -118.93],
];

/** Griffith Park — the east end of the Santa Monicas, inside the city. */
export const GRIFFITH_PARK: LatLng[] = [
  [34.15, -118.32],
  [34.148, -118.28],
  [34.11, -118.28],
  [34.105, -118.32],
];

/** Elysian Park, the ridge Dodger Stadium sits on top of. */
export const ELYSIAN_PARK: LatLng[] = [
  [34.09, -118.25],
  [34.089, -118.232],
  [34.07, -118.235],
  [34.072, -118.252],
];

export const EXPOSITION_PARK: LatLng[] = [
  [34.021, -118.292],
  [34.0205, -118.279],
  [34.01, -118.28],
  [34.011, -118.293],
];

/**
 * The Baldwin Hills: a low dome of oil derricks and scrub between Culver City
 * and the airport, and the only relief on the whole coastal plain.
 */
export const BALDWIN_HILLS: LatLng[] = [
  [34.013, -118.39],
  [34.012, -118.35],
  [33.988, -118.354],
  [33.99, -118.393],
];

/** The Sepulveda Basin — a flood-control bowl doubling as the Valley's park. */
export const SEPULVEDA_BASIN: LatLng[] = [
  [34.185, -118.505],
  [34.184, -118.46],
  [34.16, -118.462],
  [34.162, -118.506],
];

export const HANSEN_DAM: LatLng[] = [
  [34.28, -118.4],
  [34.279, -118.365],
  [34.255, -118.367],
  [34.257, -118.402],
];

/** The Arroyo Seco, running south out of the range through Pasadena. */
export const ARROYO_SECO: LatLng[] = [
  [34.2, -118.185],
  [34.199, -118.16],
  [34.125, -118.168],
  [34.126, -118.19],
];

/** The Puente Hills — the ridge that divides the basin from the inland valleys. */
export const PUENTE_HILLS: LatLng[] = [
  [33.995, -118.06],
  [33.99, -117.86],
  [33.945, -117.87],
  [33.95, -118.065],
];

export const SAN_JOSE_HILLS: LatLng[] = [
  [34.055, -117.88],
  [34.05, -117.77],
  [34.005, -117.78],
  [34.01, -117.89],
];

export const CHINO_HILLS: LatLng[] = [
  [33.97, -117.78],
  [33.96, -117.63],
  [33.86, -117.66],
  [33.88, -117.8],
];

/**
 * The Santa Ana Mountains — Cleveland National Forest, and the reason Orange
 * County ends where it does. Traced down the western flank and back up the
 * eastern one, so the band follows the ridge instead of boxing it.
 */
export const SANTA_ANA_MOUNTAINS: LatLng[] = [
  [33.9, -117.68],
  [33.8, -117.63],
  [33.7, -117.585],
  [33.61, -117.52],
  [33.53, -117.47],
  [33.49, -117.36],
  [33.59, -117.39],
  [33.69, -117.43],
  [33.79, -117.48],
  [33.89, -117.545],
];

/** The San Joaquin Hills, which is why Laguna is a cove town and not a grid. */
export const SAN_JOAQUIN_HILLS: LatLng[] = [
  [33.63, -117.85],
  [33.62, -117.74],
  [33.55, -117.72],
  [33.54, -117.81],
  [33.58, -117.85],
];

/** Loma Ridge and the Irvine Ranch open space, along the back of Irvine. */
export const LOMA_RIDGE: LatLng[] = [
  [33.79, -117.76],
  [33.78, -117.66],
  [33.72, -117.69],
  [33.73, -117.79],
];

/** The seaward slope of Palos Verdes, above the terraces. */
export const PALOS_VERDES_OPEN: LatLng[] = [
  [33.77, -118.405],
  [33.762, -118.36],
  [33.73, -118.3355],
  [33.715, -118.36],
  [33.735, -118.4],
];

/** Catalina's interior, which is conservancy land nearly end to end. */
export const CATALINA_INTERIOR: LatLng[] = [
  [33.47, -118.59],
  [33.44, -118.5],
  [33.39, -118.42],
  [33.34, -118.34],
  [33.33, -118.355],
  [33.38, -118.44],
  [33.43, -118.52],
  [33.455, -118.595],
];

/** Mount Rubidoux and Fairmount Park, downtown Riverside's green edge. */
export const RUBIDOUX: LatLng[] = [
  [33.995, -117.398],
  [33.993, -117.378],
  [33.975, -117.38],
  [33.977, -117.4],
];

/** Box Springs Mountain, the brown lump east of Riverside. */
export const BOX_SPRINGS: LatLng[] = [
  [33.97, -117.3],
  [33.965, -117.24],
  [33.915, -117.25],
  [33.92, -117.31],
];

export const JURUPA_HILLS: LatLng[] = [
  [34.015, -117.49],
  [34.01, -117.42],
  [33.985, -117.425],
  [33.99, -117.495],
];

export const EL_DORADO_PARK: LatLng[] = [
  [33.81, -118.09],
  [33.809, -118.075],
  [33.79, -118.076],
  [33.791, -118.091],
];

export const PARKS = [
  ANGELES_FOREST,
  SANTA_SUSANA,
  SANTA_MONICA_MOUNTAINS,
  GRIFFITH_PARK,
  ELYSIAN_PARK,
  EXPOSITION_PARK,
  BALDWIN_HILLS,
  SEPULVEDA_BASIN,
  HANSEN_DAM,
  ARROYO_SECO,
  PUENTE_HILLS,
  SAN_JOSE_HILLS,
  CHINO_HILLS,
  SANTA_ANA_MOUNTAINS,
  SAN_JOAQUIN_HILLS,
  LOMA_RIDGE,
  PALOS_VERDES_OPEN,
  CATALINA_INTERIOR,
  RUBIDOUX,
  BOX_SPRINGS,
  JURUPA_HILLS,
  EL_DORADO_PARK,
];

// ---- Rivers and inland water ----------------------------------------------

/**
 * The Los Angeles River, from the Glendale Narrows to the sea.
 *
 * Two compromises are baked into this polygon and both are worth stating.
 *
 * The channel is drawn about four times its true width. At 391 m to the scene
 * unit the real thing is narrower than a single coarse terrain cell, and a
 * feature narrower than the lattice does not render as a thin line — it renders
 * as a dotted one, appearing only where a cell corner happens to land inside
 * it. Five hundred metres is the smallest width that guarantees every lattice
 * row crossing the river has a point inside it.
 *
 * And it is only traced from the Narrows down. The engine has no river
 * primitive, so inland water sits at sea level and the terrain around it does
 * not, which means a channel reads as a trench as deep as the local ground is
 * high. Below downtown the plain is under a hundred metres and the trench looks
 * like a floodplain, which is fair. Through the San Fernando Valley the ground
 * is over two hundred, and the same trick would have cut a canyon across the
 * Valley floor. The Valley reach is a soft-bottom wash anyway; leaving it out
 * costs the map less than drawing it wrong.
 */
export const LA_RIVER: LatLng[] = [
  // east bank, north -> south
  [34.125, -118.267],
  [34.1, -118.242],
  [34.075, -118.227],
  [34.05, -118.222],
  [34.02, -118.212],
  [33.99, -118.202],
  [33.96, -118.192],
  [33.92, -118.187],
  [33.88, -118.187],
  [33.84, -118.192],
  [33.8, -118.195],
  [33.775, -118.202],
  [33.76, -118.202],
  // west bank, south -> north
  [33.76, -118.208],
  [33.775, -118.208],
  [33.8, -118.201],
  [33.84, -118.198],
  [33.88, -118.193],
  [33.92, -118.193],
  [33.96, -118.198],
  [33.99, -118.208],
  [34.02, -118.218],
  [34.05, -118.228],
  [34.075, -118.233],
  [34.1, -118.248],
  [34.125, -118.273],
];

/**
 * The Santa Ana River, out of the Prado basin and across Orange County.
 *
 * It is on the map because it is the organising line of the whole county: the
 * ranchos were surveyed off it, the cities sit on it, and it explains why the
 * grid on one side of Anaheim does not match the grid on the other.
 */
export const SANTA_ANA_RIVER: LatLng[] = [
  [33.945, -117.545],
  [33.895, -117.62],
  [33.878, -117.69],
  [33.868, -117.77],
  [33.852, -117.83],
  [33.81, -117.875],
  [33.762, -117.895],
  [33.71, -117.925],
  [33.665, -117.95],
  [33.633, -117.963],
  [33.627, -117.957],
  [33.66, -117.944],
  [33.705, -117.919],
  [33.757, -117.889],
  [33.805, -117.869],
  [33.847, -117.824],
  [33.863, -117.764],
  [33.873, -117.684],
  [33.89, -117.614],
  [33.94, -117.539],
];

/** Upper Newport Bay and the harbour — Orange County's one real estuary. */
export const NEWPORT_BAY: LatLng[] = [
  [33.665, -117.888],
  [33.66, -117.879],
  [33.63, -117.883],
  [33.615, -117.89],
  [33.598, -117.89],
  [33.596, -117.899],
  [33.612, -117.908],
  [33.625, -117.908],
  [33.642, -117.896],
  [33.66, -117.896],
];

export const ALAMITOS_BAY: LatLng[] = [
  [33.748, -118.118],
  [33.746, -118.105],
  [33.738, -118.106],
  [33.74, -118.12],
];

export const MARINA_DEL_REY: LatLng[] = [
  [33.98, -118.452],
  [33.979, -118.438],
  [33.97, -118.439],
  [33.971, -118.453],
];

export const BALLONA_WETLANDS: LatLng[] = [
  [33.967, -118.44],
  [33.966, -118.418],
  [33.956, -118.419],
  [33.957, -118.441],
];

export const BOLSA_CHICA: LatLng[] = [
  [33.705, -118.06],
  [33.702, -118.04],
  [33.685, -118.045],
  [33.688, -118.064],
];

/** Silver Lake Reservoir. Small, but a chapter is named after it. */
export const SILVER_LAKE: LatLng[] = [
  [34.098, -118.273],
  [34.097, -118.267],
  [34.086, -118.268],
  [34.087, -118.274],
];

export const SEPULVEDA_LAKE: LatLng[] = [
  [34.176, -118.488],
  [34.175, -118.477],
  [34.168, -118.478],
  [34.169, -118.489],
];

export const PUDDINGSTONE: LatLng[] = [
  [34.093, -117.815],
  [34.092, -117.802],
  [34.085, -117.803],
  [34.086, -117.816],
];

export const SANTIAGO_RESERVOIR: LatLng[] = [
  [33.77, -117.725],
  [33.768, -117.705],
  [33.745, -117.71],
  [33.748, -117.73],
];

export const PRADO_BASIN: LatLng[] = [
  [33.9, -117.66],
  [33.895, -117.63],
  [33.87, -117.635],
  [33.875, -117.665],
];

export const LAKE_MATHEWS: LatLng[] = [
  [33.87, -117.46],
  [33.868, -117.42],
  [33.838, -117.425],
  [33.842, -117.465],
];

export const LAKE_ELSINORE: LatLng[] = [
  [33.7, -117.39],
  [33.69, -117.335],
  [33.64, -117.32],
  [33.63, -117.355],
  [33.66, -117.395],
];

export const INLAND_WATER = [
  LA_RIVER,
  SANTA_ANA_RIVER,
  NEWPORT_BAY,
  ALAMITOS_BAY,
  MARINA_DEL_REY,
  BALLONA_WETLANDS,
  BOLSA_CHICA,
  SILVER_LAKE,
  SEPULVEDA_LAKE,
  PUDDINGSTONE,
  SANTIAGO_RESERVOIR,
  PRADO_BASIN,
  LAKE_MATHEWS,
  LAKE_ELSINORE,
];

// ---- Relief ---------------------------------------------------------------

/**
 * The mountains, and the reason Los Angeles is a basin at all.
 *
 * San Francisco's relief is hills every four blocks. Southern California's is
 * the opposite shape: a flat floor a hundred kilometres wide with ranges around
 * the rim. Read clockwise from the north-west, the rim is the Santa Susanas,
 * the San Gabriels — three thousand metres and effectively a wall — the San
 * Bernardino front off the east edge of the frame, the Santa Anas behind Orange
 * County, and the San Joaquin Hills coming back to the sea at Laguna. Inside
 * the rim, only four things break the floor: the Santa Monica Mountains running
 * east-west through the middle of the city, the Verdugos, the Puente Hills, and
 * Palos Verdes out on its own.
 *
 * **Spacing is a constraint, not an accident.** `World.elevationAt` combines
 * overlapping peaks as `tallest + 35% of the rest`, which is what stops a ridge
 * having a notch in the middle of it — but it also means two summits closer
 * together than their radii will read taller than either. The San Gabriel crest
 * is therefore laid out as well-separated peaks with generous radii: neighbours
 * still overlap enough to build a continuous wall, but no summit is inflated by
 * more than about fifteen per cent. Where you see a peak missing that ought to
 * be there — Cahuenga next to Mount Lee, Ontario next to Baldy — it was left
 * out on purpose, because including it would have grown a mountain that is not
 * there.
 *
 * The five entries at the end are not hills. They are the basins themselves,
 * declared as very broad, very low domes so the map keeps the tilt that Los
 * Angeles actually has: the beach is at sea level, downtown is at ninety
 * metres, the Valley is at two hundred and Riverside is at two hundred and
 * sixty. Being broad, they contribute almost nothing to the summits above them.
 */
export const HILLS: Hill[] = [
  // ---- The San Gabriels: the wall ----
  {
    name: "Mount Gleason",
    lat: 34.335,
    lng: -118.185,
    elevation: 1901,
    radius: 0.105,
  },
  {
    name: "Mount Lukens",
    lat: 34.278,
    lng: -118.243,
    elevation: 1547,
    radius: 0.085,
  },
  {
    name: "Josephine Peak",
    lat: 34.268,
    lng: -118.148,
    elevation: 1710,
    radius: 0.075,
  },
  {
    name: "Mount Wilson",
    lat: 34.226,
    lng: -118.062,
    elevation: 1742,
    radius: 0.09,
  },
  {
    name: "Mount Waterman",
    lat: 34.328,
    lng: -117.94,
    elevation: 2440,
    radius: 0.105,
  },
  {
    name: "Mount Islip",
    lat: 34.315,
    lng: -117.85,
    elevation: 2469,
    radius: 0.085,
  },
  {
    name: "Mount Baden-Powell",
    lat: 34.356,
    lng: -117.765,
    elevation: 2867,
    radius: 0.095,
  },
  // Mount Baldy is the high point of the whole map and the thing you look for
  // from anywhere in the basin on a clear day.
  {
    name: "Mount Baldy",
    lat: 34.289,
    lng: -117.646,
    elevation: 3068,
    radius: 0.13,
  },
  {
    name: "Cucamonga Peak",
    lat: 34.221,
    lng: -117.59,
    elevation: 2670,
    radius: 0.095,
  },
  {
    name: "Cajon Shoulder",
    lat: 34.235,
    lng: -117.42,
    elevation: 1500,
    radius: 0.085,
  },

  // The front-range foothills, so the wall has a toe. Without these the range
  // starts abruptly in mid-air above Pasadena, which is exactly wrong: the
  // whole drama of the San Gabriel front is how little runway it takes.
  {
    name: "Altadena Front",
    lat: 34.202,
    lng: -118.13,
    elevation: 900,
    radius: 0.05,
  },
  {
    name: "Monrovia Peak",
    lat: 34.213,
    lng: -117.98,
    elevation: 1600,
    radius: 0.065,
  },
  {
    name: "Glendora Ridge",
    lat: 34.18,
    lng: -117.83,
    elevation: 1100,
    radius: 0.06,
  },
  {
    name: "Claremont Front",
    lat: 34.172,
    lng: -117.68,
    elevation: 1000,
    radius: 0.055,
  },
  {
    name: "Oat Mountain",
    lat: 34.305,
    lng: -118.615,
    elevation: 1128,
    radius: 0.07,
  },
  {
    name: "Santa Susana Knolls",
    lat: 34.268,
    lng: -118.66,
    elevation: 640,
    radius: 0.045,
  },

  // ---- The Verdugos and the San Rafaels ----
  // A compact ridge standing alone in the middle of the metro, which is why
  // Glendale and Burbank are two cities and not one.
  {
    name: "Verdugo Peak",
    lat: 34.228,
    lng: -118.285,
    elevation: 940,
    radius: 0.048,
  },
  {
    // Moved north-east, from 34.205/-118.33 with a 0.04 radius, when Burbank
    // Airport went onto the board and stood on a hillside. A 700 m peak whose
    // falloff is 4.4 km across, sited half a kilometre north of runway 08/26,
    // put 478 m of mountain on the 26 threshold and 191 m on the 08 threshold —
    // a nine-degree slope across a field that is, in life, flat. It also had
    // downtown Burbank sitting 165 m up a ramp. The ridge crest above Burbank
    // really is at about 34.22, and this is where it belongs; the change reads
    // as the Verdugos ending in the right place rather than leaning on the
    // Valley floor. `socalAirports.test.ts` holds every field to the relief it
    // may stand on, so this cannot quietly come back.
    name: "Mount Thom",
    lat: 34.221,
    lng: -118.318,
    elevation: 720,
    radius: 0.036,
  },
  {
    name: "San Rafael Hills",
    lat: 34.17,
    lng: -118.215,
    elevation: 500,
    radius: 0.04,
  },

  // ---- The Santa Monica Mountains ----
  {
    name: "Castro Peak",
    lat: 34.073,
    lng: -118.755,
    elevation: 787,
    radius: 0.048,
  },
  {
    name: "Saddle Peak",
    lat: 34.086,
    lng: -118.648,
    elevation: 878,
    radius: 0.045,
  },
  {
    name: "Topanga Ridge",
    lat: 34.093,
    lng: -118.598,
    elevation: 700,
    radius: 0.04,
  },
  {
    name: "Temescal Peak",
    lat: 34.09,
    lng: -118.545,
    elevation: 692,
    radius: 0.042,
  },
  // Held west of the pass and kept tight. The Sepulveda Pass is the gap the 405
  // uses to get from the Westside to the Valley, and a hill spilling into it
  // would close the only door in a forty-kilometre wall.
  {
    name: "San Vicente Mountain",
    lat: 34.108,
    lng: -118.5,
    elevation: 590,
    radius: 0.03,
  },
  {
    name: "Getty Ridge",
    lat: 34.081,
    lng: -118.477,
    elevation: 280,
    radius: 0.024,
  },
  {
    name: "Stone Canyon",
    lat: 34.104,
    lng: -118.44,
    elevation: 380,
    radius: 0.03,
  },
  {
    name: "Franklin Canyon",
    lat: 34.115,
    lng: -118.41,
    elevation: 420,
    radius: 0.03,
  },
  // Mount Lee carries the Hollywood sign on its south face. Cahuenga Peak is
  // nine hundredths of a degree away and is deliberately absent: summed in, the
  // pair would have made an eight-hundred-metre mountain over Hollywood.
  {
    name: "Mount Lee",
    lat: 34.134,
    lng: -118.321,
    elevation: 517,
    radius: 0.03,
  },
  {
    name: "Mount Hollywood",
    lat: 34.128,
    lng: -118.3,
    elevation: 500,
    radius: 0.032,
  },
  {
    name: "Elysian Hills",
    lat: 34.083,
    lng: -118.24,
    elevation: 160,
    radius: 0.022,
  },

  // ---- Inside the basin ----
  {
    name: "Baldwin Hills",
    lat: 34.0,
    lng: -118.372,
    elevation: 156,
    radius: 0.03,
  },
  {
    name: "Repetto Hills",
    lat: 34.03,
    lng: -118.12,
    elevation: 180,
    radius: 0.032,
  },
  {
    name: "Dominguez Hills",
    lat: 33.865,
    lng: -118.243,
    elevation: 65,
    radius: 0.018,
  },
  // Signal Hill is tiny and it is here anyway: a bare oil-derrick knob rising
  // straight out of flat Long Beach, and one of the few points in the south of
  // the basin you can orient off.
  {
    name: "Signal Hill",
    lat: 33.804,
    lng: -118.167,
    elevation: 111,
    radius: 0.013,
  },

  // ---- Palos Verdes ----
  {
    name: "San Pedro Hill",
    lat: 33.748,
    lng: -118.352,
    elevation: 448,
    radius: 0.035,
  },
  {
    name: "Palos Verdes Bluff",
    lat: 33.766,
    lng: -118.398,
    elevation: 240,
    radius: 0.022,
  },
  {
    name: "Point Fermin Rise",
    lat: 33.716,
    lng: -118.302,
    elevation: 130,
    radius: 0.018,
  },

  // ---- The Puente, San Jose and Chino hills ----
  {
    name: "Whittier Hills",
    lat: 33.975,
    lng: -118.03,
    elevation: 400,
    radius: 0.038,
  },
  {
    name: "Workman Hill",
    lat: 33.96,
    lng: -117.9,
    elevation: 430,
    radius: 0.042,
  },
  {
    name: "San Jose Hills",
    lat: 34.03,
    lng: -117.83,
    elevation: 470,
    radius: 0.038,
  },
  {
    name: "Chino Hills",
    lat: 33.925,
    lng: -117.72,
    elevation: 500,
    radius: 0.055,
  },

  // ---- The Santa Anas ----
  {
    name: "Sierra Peak",
    lat: 33.878,
    lng: -117.635,
    elevation: 1120,
    radius: 0.055,
  },
  {
    name: "Pleasants Peak",
    lat: 33.795,
    lng: -117.578,
    elevation: 1200,
    radius: 0.05,
  },
  {
    name: "Santiago Peak",
    lat: 33.71,
    lng: -117.532,
    elevation: 1734,
    radius: 0.075,
  },
  {
    name: "Trabuco Peak",
    lat: 33.66,
    lng: -117.49,
    elevation: 1370,
    radius: 0.055,
  },
  {
    name: "Ortega Ridge",
    lat: 33.6,
    lng: -117.44,
    elevation: 1100,
    radius: 0.055,
  },
  {
    name: "Loma Ridge",
    lat: 33.76,
    lng: -117.72,
    elevation: 480,
    radius: 0.045,
  },
  {
    name: "Anaheim Hills",
    lat: 33.85,
    lng: -117.74,
    elevation: 350,
    radius: 0.04,
  },

  // ---- The San Joaquin Hills ----
  {
    name: "Signal Peak",
    lat: 33.605,
    lng: -117.815,
    elevation: 320,
    radius: 0.038,
  },
  {
    name: "Laguna Ridge",
    lat: 33.56,
    lng: -117.76,
    elevation: 300,
    radius: 0.032,
  },
  {
    name: "San Onofre Hills",
    lat: 33.43,
    lng: -117.57,
    elevation: 280,
    radius: 0.04,
  },

  // ---- The Inland Empire ----
  {
    name: "Box Springs Mountain",
    lat: 33.94,
    lng: -117.27,
    elevation: 1030,
    radius: 0.045,
  },
  {
    name: "Jurupa Hills",
    lat: 34.0,
    lng: -117.46,
    elevation: 550,
    radius: 0.035,
  },
  {
    name: "Mount Rubidoux",
    lat: 33.984,
    lng: -117.386,
    elevation: 395,
    radius: 0.014,
  },
  {
    name: "Sycamore Canyon",
    lat: 33.93,
    lng: -117.32,
    elevation: 480,
    radius: 0.025,
  },
  {
    name: "La Sierra Hills",
    lat: 33.9,
    lng: -117.47,
    elevation: 400,
    radius: 0.03,
  },
  {
    name: "Norco Hills",
    lat: 33.92,
    lng: -117.52,
    elevation: 350,
    radius: 0.03,
  },
  {
    name: "Slover Mountain",
    lat: 34.055,
    lng: -117.33,
    elevation: 400,
    radius: 0.02,
  },

  // ---- Catalina ----
  {
    name: "Mount Orizaba",
    lat: 33.383,
    lng: -118.418,
    elevation: 648,
    radius: 0.042,
  },
  {
    name: "Silver Peak",
    lat: 33.455,
    lng: -118.56,
    elevation: 486,
    radius: 0.03,
  },
  {
    name: "Avalon Ridge",
    lat: 33.352,
    lng: -118.345,
    elevation: 400,
    radius: 0.022,
  },

  // ---- The floors ----
  // Not mountains. Broad low domes that give each basin the elevation it really
  // has, so the map keeps its inland tilt instead of rendering ninety
  // kilometres of dead flat at sea level.
  {
    name: "Los Angeles Plain",
    lat: 34.03,
    lng: -118.23,
    elevation: 95,
    radius: 0.16,
  },
  {
    name: "San Fernando Valley Floor",
    lat: 34.195,
    lng: -118.45,
    elevation: 220,
    radius: 0.18,
  },
  {
    name: "San Gabriel Valley Floor",
    lat: 34.08,
    lng: -117.94,
    elevation: 140,
    radius: 0.18,
  },
  {
    name: "Inland Empire Floor",
    lat: 33.95,
    lng: -117.4,
    elevation: 260,
    radius: 0.17,
  },
  {
    name: "Orange County Plain",
    lat: 33.76,
    lng: -117.88,
    elevation: 45,
    radius: 0.14,
  },
];

// ---- Streets and freeways -------------------------------------------------

/**
 * In San Francisco the line that had to be drawn first was Market Street. Here
 * it is the freeways, all of them, because in this metro they are the only
 * lines long enough to tie two hundred square kilometres of identical grid
 * together. Nobody navigates Los Angeles by neighbourhood; they navigate it by
 * which freeway they are on.
 *
 * Widths are smaller than San Francisco's for the same paths because they are
 * in scene units and a scene unit here is four times as long: 0.14 is a
 * fifty-metre freeway and 0.1 a thirty-seven-metre boulevard, which is about
 * right for both.
 */

/** I-405, Sylmar to El Toro, through the Sepulveda Pass. */
export const I405: LatLng[] = [
  [34.282, -118.468],
  [34.24, -118.472],
  [34.2, -118.47],
  [34.16, -118.468],
  [34.13, -118.472],
  [34.1, -118.472], // the Sepulveda Pass
  [34.07, -118.456],
  [34.04, -118.43],
  [34.01, -118.403],
  [33.98, -118.39],
  // Moved east from -118.386 when LAX went onto the board: at that longitude the
  // freeway ran across the 25R touchdown zone, and the real 405 passes about
  // three kilometres east of the airport, not through it.
  [33.945, -118.3765], // past LAX
  [33.91, -118.372],
  [33.875, -118.35],
  [33.85, -118.315],
  [33.834, -118.272],
  [33.826, -118.23],
  [33.82, -118.19],
  [33.8, -118.13],
  [33.775, -118.075],
  [33.745, -118.01],
  [33.72, -117.955],
  [33.69, -117.9],
  // Added when John Wayne went onto the board: without it this leg cut the
  // corner and drew a freeway straight across runway 02L/20R. The real 405
  // passes about a kilometre north-west of the field and meets the 55 beyond it.
  [33.6885, -117.87],
  [33.678, -117.845],
  [33.66, -117.78],
  [33.63, -117.7],
];

/** I-5, Sylmar to San Clemente. The one road that crosses the whole board. */
export const I5: LatLng[] = [
  [34.32, -118.46],
  [34.27, -118.42],
  [34.23, -118.39],
  // These two replace a single vertex at 34.19/-118.36, which ran the Golden
  // State diagonally across Burbank's runway 08/26. The real 5 comes down the
  // far side of Hollywood Way, north-east of the field — which is why the
  // airport's north-east corner is cut off the way it is, and why `BUR`'s 08/26
  // stops 700 m short of the freeway.
  [34.222, -118.368],
  [34.196, -118.338],
  [34.16, -118.335],
  [34.13, -118.28],
  [34.105, -118.25],
  [34.08, -118.235],
  [34.055, -118.225],
  [34.035, -118.205],
  [34.01, -118.17],
  [33.98, -118.13],
  [33.94, -118.09],
  [33.9, -118.06],
  [33.87, -118.025],
  [33.84, -117.98],
  [33.8, -117.92],
  [33.76, -117.87],
  [33.72, -117.82],
  [33.68, -117.78],
  [33.63, -117.7],
  [33.58, -117.66],
  [33.52, -117.63],
  [33.46, -117.63],
  [33.42, -117.61],
  [33.39, -117.59],
];

/** US-101, Woodland Hills to downtown, over the Cahuenga Pass. */
export const US101: LatLng[] = [
  [34.165, -118.62],
  [34.16, -118.56],
  [34.155, -118.5],
  [34.15, -118.44],
  [34.145, -118.39],
  [34.138, -118.355],
  [34.125, -118.34], // the Cahuenga Pass
  [34.105, -118.33],
  [34.095, -118.31],
  [34.085, -118.29],
  [34.075, -118.265],
  [34.06, -118.24],
];

/** I-10, the pier at Santa Monica to Colton. */
export const I10: LatLng[] = [
  [34.018, -118.493],
  [34.025, -118.46],
  [34.03, -118.42],
  [34.033, -118.38],
  [34.038, -118.34],
  [34.04, -118.3],
  [34.038, -118.265],
  [34.04, -118.235],
  [34.045, -118.2],
  [34.052, -118.15],
  [34.06, -118.1],
  [34.065, -118.04],
  [34.068, -117.96],
  [34.065, -117.88],
  [34.06, -117.8],
  [34.062, -117.7],
  [34.065, -117.6],
  [34.068, -117.5],
  [34.07, -117.4],
  [34.072, -117.3],
];

/** I-110, the Arroyo Seco Parkway down to the harbour. */
export const I110: LatLng[] = [
  [34.135, -118.165],
  [34.115, -118.19],
  [34.098, -118.213],
  [34.08, -118.228],
  [34.065, -118.257],
  [34.045, -118.267],
  [34.02, -118.276],
  [33.99, -118.281],
  [33.95, -118.283],
  [33.91, -118.283],
  [33.87, -118.284],
  [33.83, -118.287],
  [33.8, -118.29],
  [33.77, -118.29],
  [33.745, -118.287],
];

/** I-210, the Foothill Freeway, running the whole length of the range front. */
export const I210: LatLng[] = [
  [34.3, -118.45],
  [34.27, -118.38],
  [34.25, -118.32],
  [34.235, -118.25],
  [34.21, -118.19],
  [34.175, -118.14],
  [34.15, -118.09],
  [34.135, -118.03],
  [34.13, -117.95],
  [34.125, -117.87],
  [34.115, -117.8],
  [34.108, -117.72],
  [34.105, -117.64],
  [34.11, -117.56],
  [34.115, -117.46],
  [34.118, -117.38],
  [34.115, -117.3],
];

/** SR-91, Torrance to Riverside. The commute the Inland Empire was built on. */
export const SR91: LatLng[] = [
  [33.87, -118.38],
  [33.87, -118.32],
  [33.868, -118.26],
  [33.865, -118.2],
  [33.862, -118.14],
  [33.86, -118.07],
  [33.858, -118.0],
  [33.86, -117.93],
  [33.862, -117.86],
  [33.865, -117.79],
  [33.87, -117.72],
  [33.875, -117.64],
  [33.89, -117.56], // the Santa Ana Canyon
  [33.92, -117.49],
  [33.945, -117.44],
  [33.96, -117.38],
  [33.965, -117.32],
];

/** SR-60, downtown to Riverside the inland way, over the Puente Hills. */
export const SR60: LatLng[] = [
  [34.04, -118.22],
  [34.033, -118.18],
  [34.028, -118.13],
  [34.02, -118.07],
  [34.015, -118.0],
  [34.01, -117.93],
  [33.995, -117.86],
  [33.98, -117.8],
  [33.97, -117.72],
  [33.955, -117.64],
  [33.945, -117.56],
  [33.94, -117.48],
  [33.94, -117.4],
  [33.945, -117.32],
];

/** SR-57, Anaheim to Pomona. */
export const SR57: LatLng[] = [
  [33.79, -117.88],
  [33.82, -117.885],
  [33.86, -117.885],
  [33.9, -117.88],
  [33.94, -117.875],
  [33.98, -117.86],
  [34.02, -117.84],
  [34.06, -117.83],
];

/** I-605, along the San Gabriel River. */
export const I605: LatLng[] = [
  [34.14, -117.99],
  [34.1, -118.0],
  [34.05, -118.04],
  [34.0, -118.07],
  [33.95, -118.09],
  [33.9, -118.105],
  [33.85, -118.11],
  [33.8, -118.105],
  [33.77, -118.1],
];

/** I-105, the Century Freeway, LAX to Norwalk. */
export const I105: LatLng[] = [
  [33.928, -118.39],
  [33.927, -118.34],
  [33.926, -118.29],
  [33.925, -118.24],
  [33.924, -118.19],
  [33.922, -118.14],
  [33.92, -118.09],
];

/** I-15, Lake Elsinore to the mouth of Cajon Pass. */
export const I15: LatLng[] = [
  [33.72, -117.46],
  [33.78, -117.49],
  [33.84, -117.52],
  [33.9, -117.53],
  [33.96, -117.54],
  [34.02, -117.55],
  [34.08, -117.55],
  [34.14, -117.51],
  [34.2, -117.46],
  [34.26, -117.44],
];

/**
 * SR-1, Pacific Coast Highway. It hugs the shore from Malibu to Redondo, cuts
 * inland across the neck of the Palos Verdes peninsula because there is no room
 * to go round it, and picks the coast back up in Long Beach.
 */
export const PCH: LatLng[] = [
  [34.043, -118.87],
  [34.03, -118.83],
  [34.0, -118.805],
  [34.03, -118.75],
  [34.036, -118.68],
  [34.039, -118.6],
  [34.037, -118.53],
  [34.018, -118.5],
  [33.995, -118.483],
  [33.97, -118.462],
  [33.942, -118.44],
  [33.92, -118.43],
  [33.89, -118.415],
  [33.86, -118.4],
  [33.84, -118.392],
  [33.81, -118.39],
  [33.79, -118.36],
  [33.78, -118.32],
  [33.775, -118.29],
  [33.78, -118.24],
  [33.775, -118.2],
  [33.77, -118.16],
  [33.76, -118.12],
  [33.745, -118.1],
  [33.725, -118.07],
  [33.7, -118.05],
  [33.67, -118.01],
  [33.64, -117.97],
  [33.62, -117.93],
  [33.6, -117.88],
  [33.58, -117.84],
  [33.55, -117.79],
  [33.52, -117.75],
  [33.48, -117.72],
  [33.46, -117.69],
  [33.43, -117.63],
];

/**
 * Wilshire Boulevard, downtown to the pier. Twenty-six kilometres, four grids,
 * and the only street that connects every part of the Westside to the core.
 */
export const WILSHIRE: LatLng[] = [
  [34.048, -118.256],
  [34.057, -118.276],
  [34.061, -118.3],
  [34.062, -118.33],
  [34.063, -118.36],
  [34.067, -118.39],
  [34.067, -118.415],
  [34.06, -118.44],
  [34.053, -118.455],
  [34.043, -118.47],
  [34.03, -118.483],
  [34.018, -118.493],
];

/** Sunset Boulevard, Echo Park to the sea, along the foot of the hills. */
export const SUNSET: LatLng[] = [
  [34.062, -118.238],
  [34.078, -118.26],
  [34.085, -118.285],
  [34.098, -118.31],
  [34.098, -118.34],
  [34.095, -118.37],
  [34.09, -118.39],
  [34.085, -118.415],
  [34.078, -118.44],
  [34.07, -118.47],
  [34.06, -118.5],
  [34.045, -118.52],
  [34.038, -118.53],
];

/** Ventura Boulevard, running the south edge of the Valley under the hills. */
export const VENTURA_BLVD: LatLng[] = [
  [34.156, -118.64],
  [34.155, -118.58],
  [34.152, -118.52],
  [34.15, -118.46],
  [34.148, -118.4],
  [34.142, -118.37],
];

/** Colorado Boulevard. Dead straight and due east-west, unlike downtown. */
export const COLORADO_BLVD: LatLng[] = [
  [34.146, -118.198],
  [34.146, -118.165],
  [34.1465, -118.135],
  [34.147, -118.105],
  [34.147, -118.07],
];

/** Katella Avenue — one rung of Orange County's mile grid, past the parks. */
export const KATELLA: LatLng[] = [
  [33.803, -118.01],
  [33.803, -117.96],
  [33.8025, -117.92],
  [33.802, -117.88],
  [33.802, -117.84],
  [33.8015, -117.79],
];

/**
 * ## The runways are no longer roads
 *
 * `LAX_RUNWAYS_NORTH` and `LAX_RUNWAYS_SOUTH` used to live here: two hand-typed
 * two-point paths lying on **33.9535 and 33.9405 due east–west**, handed to
 * `createRoads` as `kind: "street"`, because a pale strip on flat ground was as
 * close as the road builder could get to an airport. Both numbers were wrong in
 * the same way. LAX's runways are not due east–west — they run **82.9° true**,
 * which over three and a half kilometres is four hundred metres of drift the
 * pair did not have — and there are four of them, not two. `AIRPORTS` below
 * draws the real ones, with the paint on them, the fill under them and the
 * horseshoe between them.
 *
 * **The two cannot both be present.** A road ribbon drapes 0.14 units above the
 * terrain — fifty-five metres at this board's scale — while a runway quad sits
 * flush on it, so a board carrying both floats a dark stripe over every runway
 * in Westchester. The Bay Area pack hit this first and photographed it.
 *
 * `runwayCentreline()` in `engine/airports.ts` reproduces a runway as a
 * two-point path, if anything ever wants one as a line again.
 */

export const ROADS: City["roads"] = [
  { path: I405, width: 0.14, kind: "freeway" },
  { path: I5, width: 0.14, kind: "freeway" },
  { path: US101, width: 0.13, kind: "freeway" },
  { path: I10, width: 0.14, kind: "freeway" },
  { path: I110, width: 0.13, kind: "freeway" },
  { path: I210, width: 0.13, kind: "freeway" },
  { path: SR91, width: 0.13, kind: "freeway" },
  { path: SR60, width: 0.12, kind: "freeway" },
  { path: SR57, width: 0.11, kind: "freeway" },
  { path: I605, width: 0.12, kind: "freeway" },
  { path: I105, width: 0.11, kind: "freeway" },
  { path: I15, width: 0.13, kind: "freeway" },
  { path: PCH, width: 0.1, kind: "street" },
  { path: WILSHIRE, width: 0.09, kind: "street" },
  { path: SUNSET, width: 0.08, kind: "street" },
  { path: VENTURA_BLVD, width: 0.08, kind: "street" },
  { path: COLORADO_BLVD, width: 0.08, kind: "street" },
  { path: KATELLA, width: 0.08, kind: "street" },
];

// ---- Bridges --------------------------------------------------------------

/**
 * Two harbour crossings, and they are the only bridges on this map that are
 * worth the geometry — nothing else in the metro spans water rather than
 * freeway.
 *
 * A caveat for whoever renders these. `bridges.ts` now sizes members in metres
 * over metres-per-unit rather than in the fixed scene-unit constants that were
 * tuned at San Francisco's 94 m per unit, so these are no longer four times too
 * heavy — but the legibility floor under that arithmetic still is a floor, and
 * at 391 m per unit it is what makes this pair read a little chunkier than life.
 * They are kept because the port is one of the three or four silhouettes that
 * say Southern California from above.
 */

/** The Vincent Thomas, over the main channel. Green, and suspension. */
export const VINCENT_THOMAS: Bridge = {
  name: "Vincent Thomas Bridge",
  path: [
    [33.748, -118.285],
    [33.75, -118.276],
    [33.7515, -118.268],
    [33.7535, -118.258],
  ],
  towers: [
    [33.75, -118.276],
    [33.7515, -118.268],
  ],
  towerHeight: 111,
  deckHeight: 56,
  sag: 0.5,
  color: 0x3f7d55,
};

/**
 * The Long Beach International Gateway, over the back channel. Cable-stayed
 * rather than suspension, so the sag is a third of the Vincent Thomas's — the
 * cables here run straight to the deck instead of hanging from a catenary.
 */
export const LONG_BEACH_GATEWAY: Bridge = {
  name: "Long Beach International Gateway",
  path: [
    [33.752, -118.232],
    [33.7555, -118.222],
    [33.759, -118.213],
    [33.762, -118.204],
  ],
  towers: [
    [33.7555, -118.222],
    [33.759, -118.213],
  ],
  towerHeight: 157,
  deckHeight: 62,
  sag: 0.3,
  color: 0xdfe3e6,
};

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 -------------------------------------------------------------

/**
 * The Southland fields, and why these six.
 *
 * ## The headings, first, because they are the whole of the recognition
 *
 * A runway designator is **magnetic** and rounded to the nearest ten degrees.
 * Los Angeles's declination is about 11.8° east, so a runway painted "25" is
 * pointing somewhere near 262° true and one painted "16" near 172°. Building
 * from the painted numbers lays a whole airport twelve degrees out of true —
 * over LAX's longest runway that is seven hundred metres of drift — so every
 * `heading` below is a **true** bearing and every one of them is checked against
 * its designator in `socalAirports.test.ts`.
 *
 * Only LAX gets its bearing from a surveyed figure. The other five are
 * `designator × 10 + 11.8°`, which is accurate to about half of the five degrees
 * the rounding already allows and is invisible at 391 m to the scene unit. That
 * is stated rather than hidden: it is the difference between a number that was
 * looked up and a number that was derived, and the next person deserves to know
 * which is which.
 *
 * ## Six, and the ones that were left out
 *
 * The live ADS-B layer over this board carries a hundred and sixty-odd aircraft
 * in the middle of a weekday. Sampled at 02:40 Pacific — which is what the feed
 * would give me while this was written, and is therefore a thin sample rather
 * than a survey — twenty-two aircraft were airborne over the basin and six of
 * the eleven flying below eight thousand feet near any field were in LAX's
 * pattern, with Van Nuys and Burbank next. That ordering matches the annual
 * operations counts, which is what actually decided the list: LAX at ~700,000
 * movements, Van Nuys at ~220,000 (the busiest general-aviation field in the
 * world), John Wayne and Long Beach around ~300,000 each with their flight
 * schools, Burbank ~130,000, Ontario ~70,000 but the region's freight door.
 *
 * Deliberately absent, and all of them real airports: **Santa Monica**, whose
 * single 3,500 ft strip disappears into the Westside grid at this scale;
 * **Chino**, nine kilometres from Ontario, which would read as a smudge beside
 * it; **Torrance**, **Hawthorne**, **Fullerton**, **El Monte** and **Whiteman**,
 * which are one short runway each; and **March Air Reserve Base**, whose
 * 13,300 ft runway is the second longest in Southern California but sits three
 * kilometres from the eastern edge of the board with thirty thousand movements a
 * year. An airport nobody flies into is scenery, and scenery costs triangles.
 *
 * ## Every one of them is a hole cut in a district
 *
 * `blocks.ts` has never heard of an airport. It scatters lots across a district
 * polygon and the only thing that keeps houses off a runway is the polygon
 * stopping short. Four of these — LAX, Van Nuys, John Wayne and the western half
 * of Burbank — sit on a district edge and are cut out with a notch. Long Beach
 * and Ontario sit in the middle of continuously built ground, so each is a hole
 * reached by a **narrow corridor** to the nearest district edge: Cherry Avenue
 * north out of Long Beach, Haven Avenue south out of Ontario. The corridor
 * costs one column of lots, which at 164 m to the lot reads as the six-lane
 * arterial that is genuinely there. `socalAirports.test.ts` sweeps the whole of
 * every field against every district and every park, because checking the
 * corners is what lets a runway keep a housing tract in the middle of it.
 */

/**
 * Los Angeles International: four parallels in two pairs, either side of the
 * horseshoe.
 *
 * From the altitude this board is looked at, LAX **is** that pattern — two long
 * bars, a gap with buildings in it, two more long bars — and it is as
 * recognisable as the Hollywood sign. Everything below is placed as a metre
 * offset from the airport reference point at 33.9425, −118.4081 and converted,
 * rather than typed as four independent thresholds, because four hand-typed
 * pairs of coordinates will not be consistent with each other and the
 * consistency is the shape.
 *
 * ### The bearing, and how the numbers check out
 *
 * All four runways are on **82.9° true**. That single number is why the whole
 * field is drawn from one frame, and it survives two independent checks.
 * Subtract the 11.8° east declination and it is 71.1° magnetic, which rounds to
 * **07** — and the south pair is 07L/25R and 07R/25L. The FAA does not allow
 * four parallels to share a number, so the north pair takes the next one down
 * and is 06L/24R and 06R/24L, which is why LAX has runways called both 24 and
 * 25 lying exactly parallel to each other. Any reading that makes the 24s a
 * different bearing from the 25s is wrong about LAX.
 *
 * ### The relative geometry
 *
 * Lateral offsets are from the reference point, positive to the south:
 *
 *   - **06L/24R** at −853 m, 8,926 ft (2,721 m) long. **06R/24L** 213 m — 700 ft
 *     — south of it, 10,285 ft (3,135 m).
 *   - **07L/25R** at +610 m, 12,091 ft (3,685 m) and the longest on the field.
 *     **07R/25L** 244 m — 800 ft — south of it, 11,095 ft (3,382 m).
 *
 * That leaves 1,250 m of airport between 24L and 25R, and the horseshoe is what
 * fills it: the Tom Bradley International Terminal closing the west end across
 * the axis, Terminals 1–3 as the north arm and 4–8 as the south arm, the parking
 * structures in the court. `gates` puts the stands on the **outside** of both
 * arms, which is where LAX's are — the court holds roadway and cars and nothing
 * that needs a wingspan.
 *
 * Terminal heights are the real ones. The board exaggerates its vertical 3.4×
 * and makes a 17 m concourse stand fifty-eight metres tall; trimming that would
 * put the airport on a different vertical scale from every house in Westchester
 * behind it, and the eye notices the mismatch long before it notices a tall
 * terminal.
 *
 * No `tower` is declared: this pack draws LAX's as a labelled `Landmark`,
 * because `label: true` is what puts the airport on the minimap and
 * `minimap.ts` reads `city.landmarks` rather than `city.airports`.
 */
export const LAX: Airport = {
  id: "KLAX",
  name: "Los Angeles International",
  lat: 33.9425,
  lng: -118.4081,
  // 125 ft. Carried because it is a fact about the place; the kit grades the
  // field onto the terrain rather than lifting it to this. See
  // `engine/airports.ts`.
  elevation: 38,

  /**
   * The property, and it is **square to Westchester rather than to the
   * runways**, which is the detail that makes LAX look like LAX from above: a
   * cardinal rectangle with a pattern seven degrees off it inside. Westchester
   * Parkway is the north fence, Imperial Highway the south, Aviation Boulevard
   * the east, and the dunes above Dockweiler the west.
   */
  field: [
    [33.9545, -118.433],
    [33.9545, -118.382],
    [33.931, -118.382],
    [33.931, -118.433],
  ],

  runways: [
    // 06L [33.94845, -118.42526] -> 24R [33.95147, -118.39602]
    { id: "06L/24R", lat: 33.94996, lng: -118.41064, heading: 82.9, length: 2721, width: 46, designators: ["06L", "24R"] },
    // 06R [33.94636, -118.42685] -> 24L [33.94984, -118.39317]
    { id: "06R/24L", lat: 33.9481, lng: -118.41001, heading: 82.9, length: 3135, width: 46, designators: ["06R", "24L"] },
    // 07L [33.93515, -118.42571] -> 25R [33.93925, -118.38611]
    { id: "07L/25R", lat: 33.9372, lng: -118.40591, heading: 82.9, length: 3685, width: 61, designators: ["07L", "25R"] },
    // 07R [33.93311, -118.42417] -> 25L [33.93687, -118.38783]
    { id: "07R/25L", lat: 33.93499, lng: -118.406, heading: 82.9, length: 3382, width: 61, designators: ["07R", "25L"] },
  ],

  /**
   * The four outer parallels, B and C on the north complex and D and E on the
   * south.
   *
   * Typed as coordinates rather than computed here, because a city pack is data
   * and `airports.ts` imports three.js. `parallelTaxiway()` produced them and
   * `socalAirports.test.ts` asserts they are still what it produces, so the
   * derivation is checked without the pack having to run it.
   */
  taxiways: [
    { id: "B", path: [[33.94989, -118.42449], [33.95271, -118.39719]] },
    { id: "C", path: [[33.94521, -118.4257], [33.94849, -118.39395]] },
    { id: "D", path: [[33.9365, -118.42493], [33.94039, -118.38727]] },
    { id: "E", path: [[33.93188, -118.423], [33.93543, -118.3886]] },
  ],

  aprons: [
    { id: "terminal", polygon: [[33.94524, -118.41833], [33.94709, -118.4005], [33.9396, -118.39937], [33.93776, -118.41721]] },
    // The Imperial Cargo Complex, on the south side under the 25L approach.
    { id: "cargo", polygon: [[33.93628, -118.39298], [33.937, -118.386], [33.9337, -118.3855], [33.93298, -118.39248]] },
    { id: "maintenance", polygon: [[33.94571, -118.43051], [33.94631, -118.42471], [33.94354, -118.4243], [33.94294, -118.4301]] },
  ],

  terminals: [
    { id: "tbit", lat: 33.94192, lng: -118.41369, length: 560, width: 130, height: 30, heading: 352.9, gates: { count: 8, side: -1 } },
    { id: "north-arm", lat: 33.94517, lng: -118.4085, length: 850, width: 85, height: 17, heading: 82.9, gates: { count: 8, side: -1 } },
    { id: "south-arm", lat: 33.93989, lng: -118.40705, length: 950, width: 85, height: 17, heading: 82.9, gates: { count: 9, side: 1 } },
    // The central terminal area's parking structures, as three blocks rather
    // than one. A single 700 m mass filled the court, and a filled court is not
    // a horseshoe — the U only reads because there is a gap with something
    // smaller in it.
    { id: "parking-west", lat: 33.94221, lng: -118.41089, length: 230, width: 120, height: 20, heading: 82.9 },
    { id: "parking-centre", lat: 33.94246, lng: -118.40853, length: 230, width: 120, height: 20, heading: 82.9 },
    { id: "parking-east", lat: 33.9427, lng: -118.40617, length: 230, width: 120, height: 20, heading: 82.9 },
    // The west maintenance base, square to the runways rather than to the
    // horseshoe, which is what stops it reading as more of the same building.
    { id: "maintenance", lat: 33.94456, lng: -118.42761, length: 280, width: 130, height: 26, heading: 82.9 },
    { id: "cargo", lat: 33.93492, lng: -118.3895, length: 400, width: 110, height: 14, heading: 82.9, gates: { count: 4, side: -1 } },
  ],
};

/**
 * Hollywood Burbank, in the gap between the Verdugos and the Valley floor.
 *
 * Two runways crossing at seventy degrees, which is the shape here: 15/33 is the
 * long one running down out of the Verdugo gap, 08/26 is the short one along the
 * north fence, and they cross west of the terminal. Everything at Burbank is
 * small — 6,886 ft and 5,802 ft, a terminal that is genuinely two storeys — and
 * that is the point of drawing it beside LAX rather than instead of it.
 *
 * The bearings are the designators plus the 11.8° east declination: 161.8° and
 * 91.8° true. See the section comment.
 */
export const BUR: Airport = {
  id: "KBUR",
  name: "Hollywood Burbank",
  lat: 34.2007,
  lng: -118.3585,
  elevation: 237,
  /**
   * Held inside 34.190–34.2115 and −118.3735 to −118.349 on purpose: that is the
   * gap `van-nuys` and `burbank` were reshaped to leave, and a field that
   * crossed into either would have tract houses on the runway.
   */
  /**
   * Both diagonals are the fence, not tidiness. The **north-east** cut is
   * Hollywood Way and the Golden State beyond it: I-5 passes about 700 m
   * north-east of the 26 threshold, and a square corner there put a freeway
   * ribbon across the runway. The **south-west** cut is the Burbank industrial
   * quarter, which is city and not airport, and every square metre of field that
   * is not holding a runway up is a square metre of plate standing proud of the
   * ground at the low end — see `Mount Thom` in `HILLS` for what that cost here.
   */
  field: [
    [34.2108, -118.3715],
    [34.2108, -118.361],
    [34.205, -118.3505],
    [34.1915, -118.3505],
    [34.1915, -118.36],
    [34.2, -118.3715],
  ],
  runways: [
    // 15 [34.20993, -118.3638] -> 33 [34.19201, -118.35668]
    { id: "15/33", lat: 34.20097, lng: -118.36024, heading: 161.8, length: 2099, width: 46, designators: ["15", "33"] },
    // 08 [34.20526, -118.37082] -> 26 [34.20476, -118.35162]
    { id: "08/26", lat: 34.20501, lng: -118.36122, heading: 91.8, length: 1769, width: 46, designators: ["08", "26"] },
  ],
  taxiways: [
    { id: "A", path: [[34.20955, -118.36205], [34.19317, -118.35554]] },
    { id: "C", path: [[34.20407, -118.37], [34.20362, -118.35253]] },
  ],
  aprons: [{ id: "terminal", polygon: [[34.20032, -118.35469], [34.19716, -118.35343], [34.19643, -118.35612], [34.19959, -118.35737]] }],
  // Terminals A and B as one frontage east of 15/33, where Hollywood Way runs,
  // with the stands facing back at the runway.
  terminals: [
    { id: "ab", lat: 34.1985, lng: -118.35524, length: 340, width: 70, height: 12, heading: 161.8, gates: { count: 6, side: 1 } },
    { id: "cargo", lat: 34.20366, lng: -118.35383, length: 260, width: 80, height: 13, heading: 91.8 },
  ],
};

/**
 * Van Nuys: two parallels down the middle of the Valley, and no airline at all.
 *
 * It is on this board because it is the busiest general-aviation airport in the
 * world and because the aircraft over the Valley are largely its — not because
 * anything about it is famous. So it is drawn as what it is: a long thin field
 * with an 8,000 ft runway, a 4,000 ft one beside it, and hangar rows down the
 * east side instead of a terminal. No `gates` anywhere on it, because the kit
 * parks airliners and nothing that lives here is one.
 *
 * The north fence is pulled in to 34.227 — Van Nuys really reaches Roscoe at
 * 34.232 — because `north-valley` starts at 34.2316 at this longitude and a
 * field that crossed it would have houses on runway 16R.
 */
export const VNY: Airport = {
  id: "KVNY",
  name: "Van Nuys",
  lat: 34.2098,
  lng: -118.4899,
  elevation: 244,
  // Trimmed in at the north and west from 34.227/-118.499 — Van Nuys really does
  // reach Roscoe — because the Valley floor rises about a metre in a hundred
  // across this field and the kit grades a plate to the highest ground it
  // covers. Every metre of field that is not holding a runway up is a metre of
  // lip standing proud at the low end. What is left spans 33 m.
  field: [
    [34.2235, -118.4955],
    [34.2235, -118.481],
    [34.1975, -118.481],
    [34.1975, -118.4955],
  ],
  runways: [
    // 16R [34.22064, -118.49298] -> 34L [34.19896, -118.4892]
    { id: "16R/34L", lat: 34.2098, lng: -118.49109, heading: 171.8, length: 2439, width: 46, designators: ["16R", "34L"] },
    // 16L [34.2121, -118.48971] -> 34R [34.20122, -118.48781]
    { id: "16L/34R", lat: 34.20666, lng: -118.48876, heading: 171.8, length: 1223, width: 23, designators: ["16L", "34R"] },
  ],
  taxiways: [{ id: "A", path: [[34.22011, -118.49135], [34.19985, -118.48782]] }],
  /**
   * The east ramp runs the whole length of the field, Saticoy to Sherman Way,
   * which is what Van Nuys's east side is. It is drawn that long for a second
   * reason as well: `airports.ts` grades the field to the highest of the
   * airport's own authored coordinates, and an apron corner is one of them. The
   * Valley floor's high point inside this fence is under the middle of this
   * ramp, so a short ramp graded the plate to ground lower than the ground it
   * covers. See the note on `FIELD_LIFT` in the section comment.
   */
  aprons: [{ id: "east-ramp", polygon: [[34.21511, -118.48797], [34.19991, -118.48532], [34.2004, -118.48124], [34.2156, -118.48389]] }],
  terminals: [
    { id: "east-hangars", lat: 34.20872, lng: -118.48523, length: 780, width: 90, height: 14, heading: 171.8 },
    { id: "west-hangars", lat: 34.21411, lng: -118.49446, length: 420, width: 80, height: 13, heading: 171.8 },
  ],
};

/**
 * Long Beach, and the one field on this board that is a genuine X.
 *
 * 12/30 runs 10,003 ft south-east across the whole property and the 08s cross
 * it near their western ends, which is what gives Long Beach the crossed-strip
 * plan that reads from any altitude. The terminal is the small 1941 one on the
 * south-west side; the very large building on the north fence is the old
 * Douglas plant, which is a real 420 m shed and the largest single mass on the
 * field.
 *
 * Bearings are the designators plus declination: 131.8° and 91.8° true.
 */
export const LGB: Airport = {
  id: "KLGB",
  name: "Long Beach",
  lat: 33.8177,
  lng: -118.1516,
  elevation: 18,
  /**
   * The south-west corner is cut off, and that is not tidiness: **Signal Hill**
   * is 111 m of real oil-field hill 1.9 km south-west of the airport, and a
   * rectangle reaching -118.169 at 33.8055 put its flank inside the field. The
   * kit grades a field to the highest ground it covers, so that one corner
   * lifted the whole plate a hundred metres and stood Long Beach Airport on a
   * table. Cut back, the field spans 21 m of relief and lies flat.
   */
  field: [
    [33.8305, -118.1665],
    [33.8305, -118.1375],
    [33.8065, -118.1375],
    [33.8065, -118.148],
    [33.816, -118.1665],
  ],
  runways: [
    // 12 [33.82683, -118.16389] -> 30 [33.80857, -118.13931]
    { id: "12/30", lat: 33.8177, lng: -118.1516, heading: 131.8, length: 3049, width: 61, designators: ["12", "30"] },
    // 08L [33.823, -118.16018] -> 26R [33.82246, -118.13978]
    { id: "08L/26R", lat: 33.82273, lng: -118.14998, heading: 91.8, length: 1887, width: 46, designators: ["08L", "26R"] },
    // 08R [33.82089, -118.15891] -> 26L [33.82043, -118.14105]
    { id: "08R/26L", lat: 33.82066, lng: -118.14998, heading: 91.8, length: 1653, width: 46, designators: ["08R", "26L"] },
  ],
  taxiways: [
    { id: "D", path: [[33.82529, -118.16409], [33.80823, -118.14113]] },
    { id: "B", path: [[33.82414, -118.15927], [33.82365, -118.1406]] },
  ],
  aprons: [{ id: "terminal", polygon: [[33.81745, -118.15694], [33.81356, -118.1517], [33.81041, -118.15509], [33.8143, -118.16033]] }],
  terminals: [
    { id: "terminal", lat: 33.81303, lng: -118.15722, length: 260, width: 60, height: 12, heading: 131.8, gates: { count: 5, side: -1 } },
    { id: "douglas", lat: 33.82803, lng: -118.14836, length: 420, width: 160, height: 20, heading: 91.8 },
  ],
};

/**
 * John Wayne, pointing north-east at the hills, which is the whole reason
 * anyone in Newport Beach has an opinion about it.
 *
 * 02L/20R is 5,701 ft with the short 02R/20L general-aviation strip beside it,
 * and the Riley terminal on the south-east side along MacArthur with the stands
 * facing back across at the runway. On 31.8° true — the designators plus
 * declination.
 */
export const SNA: Airport = {
  id: "KSNA",
  name: "John Wayne",
  lat: 33.6757,
  lng: -117.8682,
  elevation: 17,
  /**
   * Square to the runways rather than to the compass, which is the one field on
   * this board that is: John Wayne is a diagonal parcel wedged between MacArthur
   * Boulevard and the 405, and a cardinal rectangle around it left two-thirds of
   * the plate as empty green with the runways pushed into one corner.
   */
  field: [
    [33.66833, -117.87686],
    [33.68513, -117.86435],
    [33.68073, -117.85582],
    [33.66393, -117.86833],
  ],
  runways: [
    // 02L [33.66907, -117.87379] -> 20R [33.68233, -117.86391]
    { id: "02L/20R", lat: 33.6757, lng: -117.86885, heading: 31.8, length: 1738, width: 46, designators: ["02L", "20R"] },
    // 02R [33.67081, -117.8687] -> 20L [33.67753, -117.8637]
    { id: "02R/20L", lat: 33.67417, lng: -117.8662, heading: 31.8, length: 880, width: 23, designators: ["02R", "20L"] },
  ],
  taxiways: [{ id: "A", path: [[33.66901, -117.87205], [33.68106, -117.86308]] }],
  aprons: [{ id: "terminal", polygon: [[33.6756, -117.86637], [33.67988, -117.86318], [33.67855, -117.86061], [33.67428, -117.8638]] }],
  terminals: [
    { id: "riley", lat: 33.67866, lng: -117.86356, length: 420, width: 85, height: 16, heading: 31.8, gates: { count: 6, side: -1 } },
  ],
};

/**
 * Ontario, the freight door, out where the basin runs into the Inland Empire.
 *
 * Two long parallels 560 m apart with the passenger terminals and the cargo
 * ramp between them — which is the layout, and the reason Ontario looks like a
 * much bigger airport than its passenger numbers suggest. 12,198 ft and
 * 10,200 ft on 91.8° true.
 *
 * It is the only field on this board that had to be reached by a corridor cut
 * south to the district edge rather than notched from one; see the section
 * comment.
 */
export const ONT: Airport = {
  id: "KONT",
  name: "Ontario International",
  lat: 34.056,
  lng: -117.6012,
  elevation: 288,
  field: [
    [34.063, -117.625],
    [34.063, -117.577],
    [34.049, -117.577],
    [34.049, -117.625],
  ],
  runways: [
    // 08L [34.05904, -117.62135] -> 26R [34.058, -117.58105]
    { id: "08L/26R", lat: 34.05852, lng: -117.6012, heading: 91.8, length: 3718, width: 61, designators: ["08L", "26R"] },
    // 08R [34.05392, -117.61642] -> 26L [34.05304, -117.58272]
    { id: "08R/26L", lat: 34.05348, lng: -117.59957, heading: 91.8, length: 3109, width: 46, designators: ["08R", "26L"] },
  ],
  taxiways: [
    { id: "A", path: [[34.05776, -117.62031], [34.05677, -117.58218]] },
    { id: "B", path: [[34.05515, -117.61528], [34.05433, -117.58376]] },
  ],
  aprons: [{ id: "terminal", polygon: [[34.05779, -117.60764], [34.05748, -117.59572], [34.05406, -117.59585], [34.05437, -117.60777]] }],
  terminals: [
    { id: "t2-t4", lat: 34.056, lng: -117.60228, length: 700, width: 110, height: 16, heading: 91.8, gates: { count: 8, side: -1 } },
    { id: "cargo", lat: 34.05474, lng: -117.5871, length: 500, width: 130, height: 16, heading: 91.8, gates: { count: 5, side: 1 } },
  ],
};

/** Every airport on this board, biggest first. */
export const AIRPORTS: Airport[] = [LAX, BUR, VNY, LGB, SNA, ONT];

// ---- Landmarks ------------------------------------------------------------

/**
 * The buildings placed by hand, because the eye goes looking for them.
 *
 * `footprint` is a half-width in degrees of longitude, which works out — at any
 * `latScale`, since the two cancel — as roughly `metres / 185000`. Like San
 * Francisco's, these are drawn about half again wider than life: a tower at its
 * true footprint and this vertical exaggeration is a nineteen-to-one needle,
 * and real towers do not look like that.
 *
 * A few of these are not buildings at all. LAX and Disneyland are flat pads
 * standing in for a footprint, because what the eye is actually looking for in
 * Westchester and Anaheim is a shape on the ground rather than anything with a
 * height.
 */
export const LANDMARKS: Landmark[] = [
  // ---- The downtown cluster ----
  {
    name: "U.S. Bank Tower",
    lat: 34.0509,
    lng: -118.2545,
    height: 310,
    footprint: 0.00045,
    shape: "tower",
    label: true,
  },
  {
    name: "Wilshire Grand Center",
    lat: 34.0512,
    lng: -118.2605,
    height: 335,
    footprint: 0.0004,
    shape: "tower",
    label: true,
  },
  {
    name: "Aon Center",
    lat: 34.0505,
    lng: -118.2585,
    height: 262,
    footprint: 0.00042,
    shape: "box",
    color: 0xb0a08c,
  },
  {
    name: "Two California Plaza",
    lat: 34.0535,
    lng: -118.251,
    height: 229,
    footprint: 0.0004,
    shape: "box",
  },
  // The 1928 ziggurat that was the only building in the city allowed to break
  // the height limit for forty years, and still the shape people draw when they
  // draw Los Angeles.
  {
    name: "Los Angeles City Hall",
    lat: 34.0537,
    lng: -118.2427,
    height: 138,
    footprint: 0.00048,
    shape: "tower",
    color: 0xe0d8c4,
    label: true,
  },
  {
    name: "Walt Disney Concert Hall",
    lat: 34.0553,
    lng: -118.2498,
    height: 40,
    footprint: 0.00055,
    shape: "cylinder",
    color: 0xc9cdd2,
    label: true,
  },
  {
    name: "Union Station",
    lat: 34.0561,
    lng: -118.2365,
    height: 40,
    footprint: 0.0006,
    shape: "box",
    color: 0xd9c8ab,
    label: true,
  },
  {
    name: "Crypto.com Arena",
    lat: 34.043,
    lng: -118.2673,
    height: 45,
    footprint: 0.0006,
    shape: "cylinder",
    color: 0x9aa4ad,
  },
  {
    name: "Dodger Stadium",
    lat: 34.0739,
    lng: -118.24,
    height: 35,
    footprint: 0.0009,
    shape: "cylinder",
    color: 0x5c7fa0,
    label: true,
  },
  {
    name: "Los Angeles Memorial Coliseum",
    lat: 34.0141,
    lng: -118.2879,
    height: 38,
    footprint: 0.00095,
    shape: "cylinder",
    color: 0xc0a882,
    label: true,
  },

  // ---- Hollywood and the hills ----
  // Fourteen-metre letters on a five-hundred-metre hillside. The hill does the
  // work; the landmark just puts something white on the ridge where the eye is
  // already looking.
  {
    name: "Hollywood Sign",
    lat: 34.1341,
    lng: -118.3215,
    height: 15,
    footprint: 0.0005,
    shape: "box",
    color: 0xf2f0ea,
    label: true,
  },
  {
    name: "Griffith Observatory",
    lat: 34.1184,
    lng: -118.3004,
    height: 22,
    footprint: 0.0004,
    shape: "cylinder",
    color: 0xdcd8cc,
    label: true,
  },
  {
    name: "Capitol Records Building",
    lat: 34.1024,
    lng: -118.3264,
    height: 46,
    footprint: 0.00022,
    shape: "cylinder",
    color: 0xd8cfc0,
    label: true,
  },

  // ---- The Westside ----
  {
    name: "Getty Center",
    lat: 34.078,
    lng: -118.4741,
    height: 32,
    footprint: 0.0008,
    shape: "box",
    color: 0xe8e2d2,
    label: true,
  },
  {
    name: "Century Plaza Towers",
    lat: 34.0585,
    lng: -118.4146,
    height: 173,
    footprint: 0.00038,
    shape: "box",
    color: 0xb8bfc6,
    label: true,
  },
  {
    name: "Century Plaza Towers (south)",
    lat: 34.0568,
    lng: -118.4118,
    height: 173,
    footprint: 0.00038,
    shape: "box",
    color: 0xb8bfc6,
  },
  {
    name: "Fox Plaza",
    lat: 34.0556,
    lng: -118.4131,
    height: 150,
    footprint: 0.0003,
    shape: "tower",
  },
  {
    name: "Santa Monica Pier",
    lat: 34.0086,
    lng: -118.4977,
    height: 30,
    footprint: 0.0004,
    shape: "cylinder",
    color: 0xd6c9a8,
    label: true,
  },
  {
    name: "SoFi Stadium",
    lat: 33.9535,
    lng: -118.3392,
    height: 48,
    footprint: 0.0013,
    shape: "cylinder",
    color: 0x9fa8b0,
    label: true,
  },

  // ---- LAX ----
  // This used to be a flat two-kilometre pad of a landmark standing in for an
  // airport, beside two runway-shaped roads. `LAX` in `AIRPORTS` draws the real
  // thing now and the pad would sit on top of its own field, so what is left
  // here is the one piece of LAX the kit does not draw: the tower, at its real
  // 277 ft.
  //
  // It is a landmark rather than the airport's own `tower` because `label: true`
  // is what puts LAX on the minimap — `minimap.ts` reads `city.landmarks` and
  // has never heard of `city.airports`. Declaring both would stand two towers
  // four hundred metres apart, which is how the Bay Area pack found this out.
  {
    name: "LAX Control Tower",
    lat: 33.9421,
    lng: -118.4022,
    height: 84,
    footprint: 0.00028,
    shape: "cylinder",
    color: 0xc9ccce,
    label: true,
  },
  {
    name: "LAX Theme Building",
    lat: 33.9448,
    lng: -118.402,
    height: 41,
    footprint: 0.00035,
    shape: "cylinder",
    color: 0xe4e1d8,
  },

  // ---- The Valley ----
  {
    name: "Warner Center",
    lat: 34.172,
    lng: -118.601,
    height: 95,
    footprint: 0.00045,
    shape: "box",
    label: true,
  },

  // ---- Pasadena ----
  {
    name: "Pasadena City Hall",
    lat: 34.1478,
    lng: -118.1445,
    height: 63,
    footprint: 0.00045,
    shape: "tower",
    color: 0xd9c9a8,
    label: true,
  },
  {
    name: "Rose Bowl",
    lat: 34.1613,
    lng: -118.1676,
    height: 26,
    footprint: 0.0011,
    shape: "cylinder",
    color: 0xc4bda8,
    label: true,
  },

  // ---- The harbour ----
  // Three gantry cranes on Terminal Island. They are the tallest things for
  // fifteen kilometres and they are what makes the port look like a port rather
  // than an empty basin.
  {
    name: "Long Beach Cranes",
    lat: 33.7535,
    lng: -118.2385,
    height: 78,
    footprint: 0.00022,
    shape: "box",
    color: 0x8c9298,
    label: true,
  },
  {
    name: "Long Beach Cranes (2)",
    lat: 33.7515,
    lng: -118.2345,
    height: 78,
    footprint: 0.00022,
    shape: "box",
    color: 0x8c9298,
  },
  {
    name: "Long Beach Cranes (3)",
    lat: 33.7495,
    lng: -118.2305,
    height: 78,
    footprint: 0.00022,
    shape: "box",
    color: 0x8c9298,
  },
  {
    name: "Queen Mary",
    lat: 33.7525,
    lng: -118.19,
    height: 55,
    footprint: 0.00055,
    shape: "box",
    color: 0x33506a,
    label: true,
  },
  {
    name: "Watts Towers",
    lat: 33.939,
    lng: -118.2415,
    height: 30,
    footprint: 0.00012,
    shape: "tower",
    color: 0xb08a5a,
    label: true,
  },

  // ---- Orange County ----
  // Disneyland as a footprint, which is what the brief of this map is: a
  // kilometre of green in the middle of Anaheim's flat grid, with one white
  // peak in it. The Matterhorn is forty-four metres of chicken wire and plaster
  // and it is still the only mountain in the OC basin.
  {
    name: "Disneyland",
    lat: 33.8121,
    lng: -117.919,
    height: 10,
    footprint: 0.0052,
    shape: "box",
    color: 0x5f7a52,
    label: true,
  },
  {
    name: "Matterhorn",
    lat: 33.8129,
    lng: -117.9178,
    height: 46,
    footprint: 0.00024,
    shape: "pyramid",
    color: 0xeceff2,
    label: true,
  },
  {
    name: "Angel Stadium",
    lat: 33.8003,
    lng: -117.8827,
    height: 38,
    footprint: 0.0009,
    shape: "cylinder",
    color: 0xa8b0b8,
    label: true,
  },
  {
    name: "Honda Center",
    lat: 33.8078,
    lng: -117.8766,
    height: 35,
    footprint: 0.0006,
    shape: "cylinder",
    color: 0x9aa4ad,
  },
  {
    name: "Fashion Island",
    lat: 33.618,
    lng: -117.876,
    height: 90,
    footprint: 0.0004,
    shape: "box",
  },
  {
    name: "Park Place, Irvine",
    lat: 33.68,
    lng: -117.857,
    height: 100,
    footprint: 0.0004,
    shape: "box",
  },

  // ---- Riverside ----
  {
    name: "Mission Inn",
    lat: 33.982,
    lng: -117.3745,
    height: 42,
    footprint: 0.0005,
    shape: "tower",
    color: 0xd8c4a0,
    label: true,
  },
  {
    name: "Riverside County Administrative Center",
    lat: 33.98,
    lng: -117.376,
    height: 60,
    footprint: 0.0003,
    shape: "box",
  },
];

// ---- Districts ------------------------------------------------------------

/**
 * Where buildings go, how tall, and on what bearing.
 *
 * **The bearings are the point of this section.** Southern California is one
 * continuous field of low buildings for a hundred kilometres, and if it were
 * laid out on one grid it would render as a single grey sheet. It is not: it is
 * a dozen surveys that never agreed with each other, and the seams between them
 * are the most legible thing on the ground plan. `gridAngle` is in radians, and
 * the convention works out as *the compass bearing of the north-south street
 * axis*, so 0 is a true cardinal grid and 0.63 is thirty-six degrees clockwise
 * of one. Only the value modulo a right angle matters, since a square lattice
 * is symmetric under a quarter turn.
 *
 * The six that carry the map:
 *
 *   - **Downtown at 0.63**, thirty-six degrees off north. Laid out under the
 *     Laws of the Indies so that every building would get sun on more than one
 *     face, and never corrected since. This is the local equivalent of Market
 *     Street: the rotated core is why the freeway interchanges around downtown
 *     are the shape they are, and it is the first thing that tells you this is
 *     not Phoenix.
 *   - **The San Fernando Valley at 0.0**, dead cardinal, over four hundred
 *     square kilometres. The single largest uninterrupted grid on the map, and
 *     the reason the Valley reads as a different city from the one south of the
 *     hills.
 *   - **Pasadena at 0.02**, also effectively cardinal — which is why Colorado
 *     Boulevard runs arrow-straight due east and downtown's streets do not.
 *   - **The Westside around 0.5**, twenty-nine degrees, inherited from the
 *     Spanish ranchos it was subdivided out of.
 *   - **Santa Monica and Venice at 0.88**, aligned to the beach rather than to
 *     the compass, which is why the Westside grid hits the coastal grid at a
 *     visible angle somewhere around Centinela.
 *   - **Irvine at 0.60** against Anaheim's cardinal 0.02. Two master plans
 *     twenty kilometres apart, drawn a century apart, and the seam runs right
 *     through Santa Ana.
 *
 * Two things about the numbers are not obvious and were both got wrong on the
 * first pass.
 *
 * **Coverage stays high.** The instinct is to thin the suburbs out, since a
 * tract lot is mostly driveway, pool and strip-mall car park. That is an
 * argument about a forty-metre lot. At a hundred and sixty-four there is
 * something standing on essentially every lot in the basin, and dropping
 * coverage to a half produced a metro that read as scattered debris. It is held
 * near San Francisco's 0.88 through the continuously built districts and pulled
 * down only where the ground genuinely is empty: Malibu at 0.14, the Palos
 * Verdes and Palisades hillsides at 0.4.
 *
 * **Minimum heights are higher than they look like they should be**, for the
 * same reason. One instance here is a city block, not a building, and a block
 * reads as its tallest thing.
 *
 * The whole set comes to about fifty-five thousand instances, against the
 * Bay Area's eighty-three. Fewer buildings over twenty times the district area is
 * the arithmetic working correctly, not a gap to be filled: a scene unit is
 * four times longer, so a lot covers sixteen times the ground.
 */
export const DISTRICTS: District[] = [
  // ---- Downtown and the core ----
  {
    id: "dtla",
    name: "Downtown Los Angeles",
    polygon: [
      [34.068, -118.272],
      [34.06, -118.228],
      [34.03, -118.233],
      [34.037, -118.278],
    ],
    minHeight: 30,
    maxHeight: 240,
    gridAngle: 0.63,
    palette: "downtown",
    towerChance: 0.11,
    coverage: 0.88,
  },
  {
    id: "arts-district",
    name: "Arts District & Vernon",
    polygon: [
      [34.048, -118.228],
      [34.043, -118.19],
      [34.0, -118.198],
      [34.008, -118.238],
    ],
    minHeight: 12,
    maxHeight: 48,
    gridAngle: 0.63,
    palette: "industrial",
    towerChance: 0.006,
    coverage: 0.84,
  },
  {
    id: "usc-exposition",
    name: "South Park & Exposition",
    polygon: [
      [34.038, -118.3],
      [34.033, -118.25],
      [33.998, -118.256],
      [34.005, -118.306],
    ],
    minHeight: 14,
    maxHeight: 90,
    gridAngle: 0.02,
    palette: "residential",
    towerChance: 0.02,
    coverage: 0.86,
  },
  {
    id: "koreatown",
    name: "Koreatown & Mid-Wilshire",
    polygon: [
      [34.08, -118.345],
      [34.076, -118.272],
      [34.044, -118.28],
      [34.049, -118.352],
    ],
    minHeight: 16,
    maxHeight: 82,
    gridAngle: 0.02,
    palette: "residential",
    towerChance: 0.03,
    coverage: 0.88,
  },
  {
    id: "hollywood",
    name: "Hollywood",
    polygon: [
      [34.115, -118.375],
      [34.11, -118.298],
      [34.082, -118.305],
      [34.088, -118.38],
    ],
    minHeight: 14,
    maxHeight: 68,
    gridAngle: 0.03,
    palette: "residential",
    towerChance: 0.025,
    coverage: 0.86,
  },
  {
    id: "silver-lake",
    name: "Silver Lake & Echo Park",
    polygon: [
      [34.115, -118.3],
      [34.108, -118.236],
      [34.066, -118.243],
      [34.074, -118.307],
    ],
    minHeight: 12,
    maxHeight: 34,
    gridAngle: 0.12,
    palette: "residential",
    towerChance: 0.004,
    coverage: 0.8,
  },
  // Northeast LA is on its own bearing because it was subdivided along the
  // Arroyo Seco and the Santa Fe line rather than off any city survey — which
  // is why Figueroa runs diagonally out of downtown and nothing up here lines
  // up with either Hollywood or Pasadena.
  {
    id: "highland-park",
    name: "Highland Park & Eagle Rock",
    polygon: [
      [34.145, -118.25],
      [34.14, -118.155],
      [34.085, -118.163],
      [34.092, -118.258],
    ],
    minHeight: 11,
    maxHeight: 32,
    gridAngle: 0.35,
    palette: "residential",
    towerChance: 0.003,
    coverage: 0.8,
  },
  {
    id: "west-hollywood",
    name: "West Hollywood & Beverly Hills",
    polygon: [
      [34.098, -118.42],
      [34.094, -118.345],
      [34.058, -118.352],
      [34.063, -118.427],
    ],
    minHeight: 13,
    maxHeight: 62,
    gridAngle: 0.32,
    palette: "residential",
    towerChance: 0.015,
    coverage: 0.84,
  },

  // ---- The Westside ----
  {
    id: "century-city",
    name: "Century City",
    polygon: [
      [34.07, -118.43],
      [34.067, -118.398],
      [34.048, -118.402],
      [34.052, -118.434],
    ],
    minHeight: 35,
    maxHeight: 170,
    gridAngle: 0.5,
    palette: "downtown",
    towerChance: 0.2,
    coverage: 0.88,
  },
  {
    id: "westwood",
    name: "Westwood & Brentwood",
    polygon: [
      [34.078, -118.5],
      [34.073, -118.42],
      [34.044, -118.428],
      [34.051, -118.508],
    ],
    minHeight: 13,
    maxHeight: 78,
    gridAngle: 0.5,
    palette: "residential",
    towerChance: 0.02,
    coverage: 0.76,
  },
  {
    id: "santa-monica",
    name: "Santa Monica",
    polygon: [
      [34.042, -118.52],
      [34.034, -118.462],
      [33.998, -118.472],
      [34.007, -118.526],
    ],
    minHeight: 15,
    maxHeight: 62,
    gridAngle: 0.88,
    palette: "downtown",
    towerChance: 0.025,
    coverage: 0.86,
  },
  {
    id: "venice",
    name: "Venice & the Marina",
    polygon: [
      [34.002, -118.484],
      [33.996, -118.432],
      [33.958, -118.44],
      [33.966, -118.492],
    ],
    minHeight: 12,
    maxHeight: 36,
    gridAngle: 0.88,
    palette: "residential",
    towerChance: 0.006,
    coverage: 0.84,
  },
  {
    id: "culver-city",
    name: "Culver City & Palms",
    polygon: [
      [34.038, -118.436],
      [34.033, -118.36],
      [33.996, -118.368],
      [34.002, -118.443],
    ],
    minHeight: 13,
    maxHeight: 60,
    gridAngle: 0.5,
    palette: "downtown",
    towerChance: 0.018,
    coverage: 0.84,
  },
  // Everything from here west is hillside: a road, a canyon and whatever will
  // stand on the slope. Sparse on purpose.
  {
    id: "palisades",
    name: "Pacific Palisades",
    polygon: [
      [34.068, -118.562],
      [34.063, -118.502],
      [34.036, -118.51],
      [34.041, -118.568],
    ],
    minHeight: 10,
    maxHeight: 26,
    gridAngle: 0.62,
    palette: "residential",
    towerChance: 0.001,
    coverage: 0.4,
  },
  {
    id: "malibu",
    name: "Malibu",
    polygon: [
      [34.042, -118.94],
      [34.038, -118.6],
      [34.02, -118.606],
      [34.024, -118.946],
    ],
    minHeight: 9,
    maxHeight: 18,
    gridAngle: 0.12,
    palette: "residential",
    towerChance: 0.001,
    coverage: 0.14,
  },

  // ---- The San Fernando Valley ----
  {
    id: "sherman-oaks",
    name: "Sherman Oaks & Encino",
    polygon: [
      [34.182, -118.55],
      [34.178, -118.4],
      [34.138, -118.406],
      [34.142, -118.556],
    ],
    minHeight: 12,
    maxHeight: 44,
    gridAngle: 0.0,
    palette: "residential",
    towerChance: 0.008,
    coverage: 0.82,
  },
  {
    id: "van-nuys",
    // Two airports come out of this one polygon. Vertices 3-6 are the notch for
    // Burbank, cut in from the east boundary; vertices 9-12 are the notch for
    // Van Nuys, cut in from the west, where the ground it also gives up is the
    // Sepulveda Basin and already open. `burbank` picks up the eastern strip
    // that the first notch removes, so nothing is left unbuilt but the fields.
    name: "Van Nuys & North Hollywood",
    polygon: [
      [34.24, -118.5],
      [34.235, -118.34],
      [34.2125, -118.3423],
      [34.2125, -118.3745],
      [34.189, -118.3745],
      [34.189, -118.3447],
      [34.176, -118.346],
      [34.181, -118.506],
      [34.194, -118.5047],
      [34.194, -118.48],
      [34.229, -118.48],
      [34.229, -118.5011],
    ],
    minHeight: 12,
    maxHeight: 48,
    gridAngle: 0.0,
    palette: "residential",
    towerChance: 0.007,
    coverage: 0.84,
  },
  {
    id: "warner-center",
    name: "Warner Center & Woodland Hills",
    polygon: [
      [34.205, -118.65],
      [34.2, -118.545],
      [34.152, -118.552],
      [34.157, -118.657],
    ],
    minHeight: 13,
    maxHeight: 98,
    gridAngle: 0.0,
    palette: "downtown",
    towerChance: 0.035,
    coverage: 0.8,
  },
  {
    id: "north-valley",
    name: "Northridge & Sylmar",
    polygon: [
      [34.3, -118.58],
      [34.294, -118.38],
      [34.228, -118.388],
      [34.235, -118.588],
    ],
    minHeight: 11,
    maxHeight: 30,
    gridAngle: 0.0,
    palette: "residential",
    towerChance: 0.002,
    coverage: 0.8,
  },
  {
    id: "burbank",
    // The north-west corner is cut back from -118.368 to -118.348, which is
    // Hollywood Way and the east fence of the airport. What that leaves out is
    // the eastern half of Burbank's field; `van-nuys` gives up the western
    // half, and between them the two polygons leave one clean hole.
    name: "Burbank",
    polygon: [
      [34.2125, -118.348],
      [34.206, -118.282],
      [34.15, -118.29],
      [34.157, -118.375],
      [34.189, -118.3709],
      [34.189, -118.348],
    ],
    minHeight: 13,
    maxHeight: 62,
    gridAngle: 0.61,
    palette: "residential",
    towerChance: 0.02,
    coverage: 0.82,
  },
  {
    id: "glendale",
    name: "Glendale",
    polygon: [
      [34.18, -118.29],
      [34.175, -118.212],
      [34.118, -118.22],
      [34.124, -118.298],
    ],
    minHeight: 14,
    maxHeight: 92,
    gridAngle: 0.28,
    palette: "downtown",
    towerChance: 0.035,
    coverage: 0.82,
  },

  // ---- Pasadena and the San Gabriel Valley ----
  {
    id: "pasadena",
    name: "Pasadena",
    polygon: [
      [34.185, -118.19],
      [34.18, -118.07],
      [34.12, -118.078],
      [34.126, -118.198],
    ],
    minHeight: 14,
    maxHeight: 78,
    gridAngle: 0.02,
    palette: "downtown",
    towerChance: 0.03,
    coverage: 0.8,
  },
  {
    id: "sgv-west",
    name: "Alhambra & El Monte",
    polygon: [
      [34.118, -118.17],
      [34.113, -117.99],
      [34.03, -118.0],
      [34.036, -118.18],
    ],
    minHeight: 11,
    maxHeight: 36,
    gridAngle: 0.1,
    palette: "residential",
    towerChance: 0.004,
    coverage: 0.8,
  },
  {
    id: "sgv-east",
    name: "West Covina & Pomona",
    polygon: [
      [34.125, -117.985],
      [34.12, -117.72],
      [34.015, -117.732],
      [34.021, -117.995],
    ],
    minHeight: 11,
    maxHeight: 32,
    gridAngle: 0.05,
    palette: "residential",
    towerChance: 0.003,
    coverage: 0.78,
  },
  {
    id: "ontario",
    // Ontario International, cut out the same way Long Beach is: a hole with a
    // corridor, here running south to the boundary along Haven Avenue. Nothing
    // on the eastern half of this board is close enough to a district edge to
    // notch, and a warehouse district with a runway drawn through it is worse
    // than one arterial's worth of missing lots.
    name: "Ontario & Rancho Cucamonga",
    polygon: [
      [34.125, -117.69],
      [34.12, -117.48],
      [34.015, -117.492],
      [34.0181, -117.601],
      [34.0475, -117.601],
      [34.0475, -117.5755],
      [34.0645, -117.5755],
      [34.0645, -117.6265],
      [34.0475, -117.6265],
      [34.0475, -117.606],
      [34.0182, -117.606],
      [34.021, -117.702],
    ],
    minHeight: 11,
    maxHeight: 30,
    gridAngle: 0.01,
    palette: "industrial",
    towerChance: 0.002,
    coverage: 0.66,
  },
  {
    id: "chino",
    name: "Chino & Diamond Bar",
    polygon: [
      [34.02, -117.79],
      [34.015, -117.61],
      [33.94, -117.622],
      [33.946, -117.802],
    ],
    minHeight: 10,
    maxHeight: 26,
    gridAngle: 0.02,
    palette: "industrial",
    towerChance: 0.002,
    coverage: 0.6,
  },

  // ---- South Los Angeles, the South Bay and the harbour ----
  {
    id: "south-la",
    name: "South Los Angeles",
    polygon: [
      [34.0, -118.35],
      [33.996, -118.2],
      [33.925, -118.212],
      [33.93, -118.36],
    ],
    minHeight: 10,
    maxHeight: 28,
    gridAngle: 0.01,
    palette: "residential",
    towerChance: 0.002,
    coverage: 0.88,
  },
  {
    id: "inglewood",
    // The last four vertices are the LAX notch: the polygon runs up the west
    // boundary, turns in along the airport's south fence, round the east and
    // north fences, and back out to the boundary. `blocks.ts` has never heard
    // of an airport, so this notch is the only thing keeping tract houses off
    // the 25R touchdown zone. The strip it also gives up — between the fence at
    // -118.433 and the boundary — is the Dockweiler dunes, which are genuinely
    // unbuilt, and that is why the notch opens west rather than east.
    name: "Inglewood & Hawthorne",
    polygon: [
      [33.985, -118.43],
      [33.98, -118.32],
      [33.915, -118.33],
      [33.92, -118.438],
      [33.929, -118.4369],
      [33.929, -118.38],
      [33.9565, -118.38],
      [33.9565, -118.4335],
    ],
    minHeight: 11,
    maxHeight: 50,
    gridAngle: 0.02,
    palette: "residential",
    towerChance: 0.008,
    coverage: 0.84,
  },
  {
    id: "south-bay",
    name: "Torrance & the Beach Cities",
    polygon: [
      [33.918, -118.415],
      [33.912, -118.3],
      [33.815, -118.312],
      [33.822, -118.422],
    ],
    minHeight: 11,
    maxHeight: 40,
    gridAngle: 0.72,
    palette: "residential",
    towerChance: 0.006,
    coverage: 0.8,
  },
  {
    id: "palos-verdes",
    name: "Palos Verdes",
    polygon: [
      [33.802, -118.412],
      [33.797, -118.305],
      [33.728, -118.315],
      [33.734, -118.418],
    ],
    minHeight: 10,
    maxHeight: 22,
    gridAngle: 0.3,
    palette: "residential",
    towerChance: 0.001,
    coverage: 0.4,
  },
  {
    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.7745, -118.238],
      [33.7745, -118.272],
      [33.708, -118.276],
      [33.713, -118.31],
    ],
    minHeight: 11,
    maxHeight: 44,
    gridAngle: 0.05,
    palette: "industrial",
    towerChance: 0.005,
    coverage: 0.76,
  },
  {
    id: "carson",
    name: "Compton & Carson",
    polygon: [
      [33.94, -118.29],
      [33.935, -118.145],
      [33.85, -118.156],
      [33.856, -118.3],
    ],
    minHeight: 10,
    maxHeight: 28,
    gridAngle: 0.02,
    palette: "industrial",
    towerChance: 0.002,
    coverage: 0.8,
  },
  {
    id: "long-beach",
    // Long Beach Airport sits three and a half kilometres inside this polygon in
    // every direction, so it cannot be notched from an edge — it is a hole
    // reached by a corridor running north to the boundary along Cherry Avenue.
    // The corridor is 460 m wide and takes about one column of lots with it,
    // which at 164 m to the lot is what a six-lane arterial looks like here in
    // 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],
      [33.832, -118.166],
      [33.832, -118.169],
      [33.8055, -118.169],
      [33.8055, -118.136],
      [33.832, -118.136],
      [33.832, -118.161],
      [33.865, -118.161],
      [33.862, -118.09],
      [33.752, -118.102],
      [33.7695, -118.24],
    ],
    minHeight: 12,
    maxHeight: 124,
    gridAngle: 0.2,
    palette: "downtown",
    towerChance: 0.014,
    coverage: 0.8,
  },
  {
    id: "downey",
    name: "Downey & Lakewood",
    polygon: [
      [33.96, -118.19],
      [33.955, -118.045],
      [33.845, -118.058],
      [33.852, -118.2],
    ],
    minHeight: 10,
    maxHeight: 28,
    gridAngle: 0.04,
    palette: "residential",
    towerChance: 0.002,
    coverage: 0.8,
  },
  {
    id: "whittier",
    name: "Whittier & La Mirada",
    polygon: [
      [33.948, -118.055],
      [33.943, -117.93],
      [33.895, -117.94],
      [33.9, -118.065],
    ],
    minHeight: 10,
    maxHeight: 28,
    gridAngle: 0.06,
    palette: "residential",
    towerChance: 0.002,
    coverage: 0.82,
  },

  // ---- Orange County ----
  {
    id: "anaheim",
    name: "Anaheim & Fullerton",
    polygon: [
      [33.885, -118.06],
      [33.879, -117.86],
      [33.8, -117.872],
      [33.806, -118.072],
    ],
    minHeight: 11,
    maxHeight: 64,
    gridAngle: 0.02,
    palette: "residential",
    towerChance: 0.012,
    coverage: 0.82,
  },
  {
    id: "yorba-linda",
    name: "Brea & Yorba Linda",
    polygon: [
      [33.935, -117.87],
      [33.93, -117.72],
      [33.86, -117.73],
      [33.866, -117.88],
    ],
    minHeight: 10,
    maxHeight: 28,
    gridAngle: 0.08,
    palette: "residential",
    towerChance: 0.002,
    coverage: 0.68,
  },
  {
    id: "santa-ana",
    name: "Santa Ana",
    polygon: [
      [33.795, -117.925],
      [33.79, -117.82],
      [33.705, -117.832],
      [33.711, -117.937],
    ],
    minHeight: 11,
    maxHeight: 60,
    gridAngle: 0.05,
    palette: "downtown",
    towerChance: 0.018,
    coverage: 0.86,
  },
  {
    id: "garden-grove",
    name: "Garden Grove & Westminster",
    polygon: [
      [33.8, -118.055],
      [33.795, -117.92],
      [33.72, -117.93],
      [33.726, -118.065],
    ],
    minHeight: 10,
    maxHeight: 26,
    gridAngle: 0.02,
    palette: "residential",
    towerChance: 0.002,
    coverage: 0.8,
  },
  {
    id: "huntington-beach",
    name: "Huntington Beach & Fountain Valley",
    polygon: [
      [33.735, -118.075],
      [33.73, -117.95],
      [33.64, -117.962],
      [33.646, -118.087],
    ],
    minHeight: 10,
    maxHeight: 30,
    gridAngle: 0.05,
    palette: "residential",
    towerChance: 0.003,
    coverage: 0.82,
  },
  {
    id: "newport-beach",
    name: "Newport Beach & Costa Mesa",
    polygon: [
      [33.665, -117.94],
      [33.66, -117.82],
      [33.58, -117.832],
      [33.586, -117.952],
    ],
    minHeight: 11,
    maxHeight: 68,
    gridAngle: 0.35,
    palette: "residential",
    towerChance: 0.015,
    coverage: 0.72,
  },
  {
    id: "irvine",
    // John Wayne straddles this polygon's west boundary, so the last four
    // vertices notch it out from that edge. `newport-beach` stops at about
    // 33.662 under the field and `santa-ana` starts at 33.705 above it, so this
    // is the only district the airport touches.
    name: "Irvine",
    polygon: [
      [33.735, -117.865],
      [33.73, -117.71],
      [33.63, -117.722],
      [33.636, -117.877],
      [33.662, -117.8739],
      [33.662, -117.854],
      [33.6935, -117.854],
      [33.6935, -117.87],
    ],
    minHeight: 12,
    maxHeight: 84,
    gridAngle: 0.6,
    palette: "downtown",
    towerChance: 0.03,
    coverage: 0.76,
  },
  {
    id: "saddleback",
    name: "Mission Viejo & Laguna",
    polygon: [
      [33.64, -117.75],
      [33.634, -117.59],
      [33.505, -117.612],
      [33.515, -117.762],
    ],
    minHeight: 10,
    maxHeight: 26,
    gridAngle: 0.42,
    palette: "residential",
    towerChance: 0.002,
    coverage: 0.6,
  },
  {
    id: "dana-point",
    name: "Dana Point & San Clemente",
    polygon: [
      [33.5, -117.72],
      [33.482, -117.62],
      [33.415, -117.575],
      [33.435, -117.695],
    ],
    minHeight: 10,
    maxHeight: 24,
    gridAngle: 0.55,
    palette: "residential",
    towerChance: 0.002,
    coverage: 0.5,
  },

  // ---- Riverside and the Inland Empire ----
  {
    id: "riverside",
    name: "Downtown Riverside",
    polygon: [
      [34.008, -117.42],
      [34.002, -117.325],
      [33.94, -117.333],
      [33.947, -117.428],
    ],
    minHeight: 12,
    maxHeight: 70,
    gridAngle: 0.79,
    palette: "downtown",
    towerChance: 0.03,
    coverage: 0.74,
  },
  {
    id: "moreno-valley",
    name: "Moreno Valley & Arlington",
    polygon: [
      [33.985, -117.33],
      [33.978, -117.225],
      [33.87, -117.238],
      [33.877, -117.343],
    ],
    minHeight: 10,
    maxHeight: 24,
    gridAngle: 0.05,
    palette: "residential",
    towerChance: 0.002,
    coverage: 0.62,
  },
  {
    id: "corona",
    name: "Corona & Norco",
    polygon: [
      [33.93, -117.64],
      [33.924, -117.5],
      [33.84, -117.512],
      [33.847, -117.652],
    ],
    minHeight: 10,
    maxHeight: 26,
    gridAngle: 0.03,
    palette: "residential",
    towerChance: 0.002,
    coverage: 0.62,
  },
];

// ---- Focus regions --------------------------------------------------------

/**
 * The two rectangles that get fine terrain, at about 80 m; everywhere else is
 * ten times coarser, at about 800 m.
 *
 * This is the trade ARCHITECTURE.md §5 asked for, and the arithmetic is worth
 * writing down because it is the whole argument for the feature existing.
 * Uniform 80 m cells over this frame would be 1.08° / 0.00072 by 1.66° /
 * 0.00086 — just under 2.9 million lattice points, several seconds of build,
 * and a mesh with nothing in most of it. What ships is 0.13 million, and the
 * whole city builds in about 2.3 seconds.
 *
 * It was seven boxes when this pack was written, and that did not survive
 * contact with the engine. `buildAxis` in world.ts refines **per axis**, not
 * per rectangle: a focus region sharpens its whole row *and* its whole column,
 * so seven boxes scattered across a basin this wide refine most of the basin
 * between them. Measured, on this data: seven regions came to 0.73 million
 * points and a 6.6 second field build; two come to 0.13 million and 1.3. The
 * boxes that stayed are the two the camera spends its time in.
 *
 * Where a box is *not* is as considered as where it is. The San Fernando
 * Valley and the harbour both get chapters and neither gets a box, because
 * both are flat: fine cells there would buy several thousand extra triangles
 * of absolutely level ground. The relief that matters at those two stops is
 * the range behind the Valley and the coastline around the port, and neither
 * is inside the frame the camera is pointed at.
 */
export const FOCUS_REGIONS: FocusRegion[] = [
  { minLat: 34.01, maxLat: 34.09, minLng: -118.3, maxLng: -118.19 },
  { minLat: 34.075, maxLat: 34.15, minLng: -118.37, maxLng: -118.25 },
];

// ---- Chapters -------------------------------------------------------------

/**
 * The tour. Eight stops rather than the seven the basin strictly needs, because
 * the port is one of the four or five things on this coast that is unmistakably
 * itself and a chapter is the only way a viewer gets to look at it.
 *
 * Camera notes, since the numbers are less obvious here than in a city that
 * fits in one frame. `rotation` places the camera and the target is looked at
 * from there, so a negative rotation puts the eye to the south-west — out over
 * the water — looking back north-east into the basin. That is the standard
 * Southern California view and six of these eight use it. The whole-board
 * stop deliberately sits closer than the frame's true half-width, because the
 * engine's fog closes at 460 units and at 391 m to the unit that is a hundred
 * and eighty kilometres: pull the camera back far enough to see every corner
 * and the San Gabriels dissolve into haze. Which is, to be fair, what they
 * usually do.
 */
const WHOLE_BOARD: City["chapters"][number] = {
  id: "all",
  number: "01",
  label: "The Whole Board",
  shortLabel: "Whole Board",
  focus: {
    lat: 34.02,
    lng: -118.12,
    distance: 236,
    height: 148,
    rotation: -0.55,
  },
  description:
    "A hundred kilometres of basin between the Pacific and a three-thousand-metre wall, with Catalina offshore and the Santa Anas closing the south-east. Everything on this map is inside one mountain rim.",
};

export const CHAPTERS: City["chapters"] = [
  WHOLE_BOARD,
  {
    id: "dtla",
    number: "02",
    label: "Downtown Los Angeles",
    shortLabel: "DTLA",
    focus: {
      lat: 34.05,
      lng: -118.248,
      distance: 19,
      height: 13.5,
      rotation: 0.63,
    },
    description:
      "The one cluster of real towers in the basin, on a grid turned thirty-six degrees off north since 1781. The camera is lined up with that grid, which is why everything else in the frame looks crooked.",
  },
  {
    id: "westside",
    number: "03",
    label: "The Westside",
    shortLabel: "Westside",
    focus: {
      lat: 34.025,
      lng: -118.435,
      distance: 46,
      height: 30,
      rotation: -0.6,
    },
    description:
      "Santa Monica, Venice, Culver City and Century City, seen from over the bay. Three different street grids meet in this frame and none of them agree; the seams are visible from here.",
  },
  {
    id: "hollywood",
    number: "04",
    label: "Hollywood & Silver Lake",
    shortLabel: "Hollywood",
    focus: {
      lat: 34.108,
      lng: -118.305,
      distance: 34,
      height: 24,
      rotation: 0.1,
    },
    description:
      "The flats run north on a cardinal grid until they hit the Santa Monica Mountains and stop. The sign is on Mount Lee at the top of the frame; the reservoir below it is Silver Lake.",
  },
  {
    id: "valley",
    number: "05",
    label: "The San Fernando Valley",
    shortLabel: "The Valley",
    focus: {
      lat: 34.19,
      lng: -118.43,
      distance: 66,
      height: 40,
      rotation: -0.15,
    },
    description:
      "Four hundred square kilometres of the most uninterrupted cardinal grid in the country, in a bowl with the Santa Monicas behind the camera and the San Gabriels across the top.",
  },
  {
    id: "harbour",
    number: "06",
    label: "The Harbour & Palos Verdes",
    shortLabel: "Harbour",
    focus: {
      lat: 33.76,
      lng: -118.24,
      distance: 40,
      height: 26,
      rotation: -0.9,
    },
    description:
      "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",
    number: "07",
    label: "Orange County",
    shortLabel: "Orange County",
    focus: {
      lat: 33.73,
      lng: -117.87,
      distance: 84,
      height: 52,
      rotation: -0.5,
    },
    description:
      "Anaheim's mile grid against Irvine's rotated master plan, with the Santa Ana River running diagonally through both of them and the Santa Anas standing up behind.",
  },
  {
    id: "inland-empire",
    number: "08",
    label: "Riverside & the Inland Empire",
    shortLabel: "Riverside",
    focus: {
      lat: 33.97,
      lng: -117.42,
      distance: 62,
      height: 40,
      rotation: -0.35,
    },
    description:
      "Ninety kilometres inland and two hundred and sixty metres up, on a grid rotated forty-five degrees to the Santa Ana River. Box Springs Mountain to the east, Mount Baldy on the skyline north.",
  },
];

// ---- The pack ------------------------------------------------------------

export const SOCAL_CITY: City = {
  id: "socal",
  name: "Southern California",

  // The centre of the frame rather than the centre of anything civic — it lands
  // out past Los Alamitos, roughly equidistant from downtown, Riverside and
  // Dana Point. Putting the scene origin at the middle of the board keeps the
  // projection symmetric, which matters more on a board this wide than being
  // able to say the origin is City Hall.
  center: { lat: 33.82, lng: -118.05 },
  bounds: { minLat: 33.28, maxLat: 34.36, minLng: -118.88, maxLng: -117.22 },

  /**
   * 391 m to the scene unit, against San Francisco's 94.
   *
   * The board this produces is 393 by 308 units, against the Bay Area's 1003 by
   * 830 — a metro four times the area rendered on a third of the board, which is
   * why one instance here is a city block rather than a building.
   *
   * This used to be forced rather than chosen: `scene.ts` capped the orbit at
   * 340 units and `cityDaylight` closed its fog at 460, both tuned when San
   * Francisco was the only city, so however large a place was on the ground it
   * had to come out roughly San Francisco's size in scene units or it could not
   * be looked at. Both now derive from the board, so a pack is free to pick its
   * own scale. This one keeps 285 because the numbers below — lot size, hill
   * radii, bridge spans — were all authored against it, not because the engine
   * still insists.
   */
  latScale: 285,

  /**
   * Lower than San Francisco's 3.6, because the relief here does not need the
   * help and cannot take it. The San Gabriel front rises three kilometres in
   * eight, which is already twenty degrees; multiplying its tangent by 3.6 puts
   * it past fifty-five and turns the most dramatic range front in North America
   * into an obvious cartoon. 3.4 keeps it a wall without making it a cliff.
   */
  verticalExaggeration: 3.4,

  // ~80 m inside a focus region, ~800 m outside one. See FOCUS_REGIONS for the
  // arithmetic; the short version is that this is the difference between
  // 200,000 lattice points and 2.8 million.
  cellLat: 0.00072,
  cellLng: 0.00086,
  coarseFactor: 10,
  focusRegions: FOCUS_REGIONS,

  /**
   * ~500 m, against San Francisco's 200.
   *
   * The falloff exists to ramp the terrain grid's stair-stepped rim down to the
   * smooth shore plate underneath it, so it has to be at least one cell wide or
   * the steps survive. Out in the basin a cell is 480 m. The cost is that the
   * Palos Verdes sea cliffs get a flat shelf in front of them, which is a fair
   * price for a coastline that reads cleanly along its whole length.
   */
  coastFalloff: 0.0045,

  landmasses: LANDMASSES,
  parks: PARKS,
  inlandWater: INLAND_WATER,
  hills: HILLS,
  districts: DISTRICTS,

  /**
   * The basin's six fields, drawn by `engine/airports.ts`. LAX's runways-as-
   * roads are gone from `ROADS` above and must stay gone: a board carrying both
   * 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,
  chapters: CHAPTERS,

  /**
   * Drier and hazier than the default. San Francisco's palette is a cool grey-
   * green coast; this one is chaparral and decomposed granite, with a warm
   * horizon because the fog planes here are standing in for the basin's haze
   * rather than for marine layer.
   */
  palette: {
    skyTop: 0x8db2d4,
    skyHorizon: 0xe6ded0,
    sea: 0x3f7391,
    lake: 0x4e7d99,
    shore: 0xc2b393,
    sand: 0xd2c3a3,
    flats: 0xa9a291,
    upland: 0x9a8d74,
    park: 0x6d7f52,
    parkHigh: 0x4e6440,
  },
};

export default SOCAL_CITY;
