@chrtco/sdk 0.10.29 → 0.10.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -28842,328 +28842,12 @@ function worldMinusBboxPolygon(bbox) {
28842
28842
  };
28843
28843
  }
28844
28844
 
28845
- // src/atlas/land-layers.ts
28846
- var LAND_SURFACE_MINZOOM = BAND_PRIORITY_RANGES["5"].minzoom;
28847
- var LAND_SURFACE_LAYERS = (id) => id === "chrtland-base" || id === "chrtland-cover" || id === "chrtland-contour" || id === "chrtland-hillshade" || id.startsWith("chrtland-fade-");
28848
- var FADE_PX = 80;
28849
- var FADE_BANDS = 16;
28850
- function fadeAlpha(r) {
28851
- return Math.max(0, Math.min(1, (FADE_PX / 2 - Math.abs(r)) / FADE_PX));
28852
- }
28853
- function landBaseColor(palette) {
28854
- return (LAND_THEMES[palette] ?? LAND_THEMES.DAY).base;
28855
- }
28856
- var LAND_THEMES = {
28857
- DAY: {
28858
- base: "#e8d9b0",
28859
- cover: { wood: "#cfd8b4", wetland: "#c9d3c4", urban: "#dedad2", sand: "#efe4c2" },
28860
- contour: "#a89878",
28861
- contourIndex: "#8a7a5c",
28862
- road: "#d9c9a4",
28863
- roadMajor: "#d2bd8e",
28864
- label: "#5b4f3a",
28865
- halo: "#f2ead6",
28866
- shadow: "#6b5a3e",
28867
- highlight: "#fffaf0",
28868
- fade: "#e8f2f8",
28869
- // Raised from 0.45 on 2026-08-23. ⚠ Above the ~0.5 that
28870
- // hillshade-style.mjs warns "starts competing with depth areas" — a
28871
- // deliberate, sighted choice made against rendered evidence, not a
28872
- // default. If soundings or DEPARE ever read as fighting the terrain,
28873
- // this number is the first thing to walk back.
28874
- exaggeration: 0.8
28875
- },
28876
- DUSK: {
28877
- base: "#4a4433",
28878
- cover: { wood: "#414a38", wetland: "#3f4740", urban: "#4e4a42", sand: "#544c39" },
28879
- contour: "#6b6250",
28880
- contourIndex: "#837961",
28881
- road: "#565040",
28882
- roadMajor: "#63594440",
28883
- label: "#c3b898",
28884
- halo: "#2b2820",
28885
- shadow: "#2e2a20",
28886
- highlight: "#8a8068",
28887
- fade: "#16202a",
28888
- // Unchanged. DUSK was not the palette the 0.8 decision was made against.
28889
- exaggeration: 0.45
28890
- },
28891
- NIGHT: {
28892
- base: "#2a2620",
28893
- cover: { wood: "#242a20", wetland: "#232823", urban: "#2c2925", sand: "#302b22" },
28894
- contour: "#413b30",
28895
- contourIndex: "#524a3b",
28896
- road: "#332f27",
28897
- roadMajor: "#3d382d",
28898
- label: "#7d745e",
28899
- halo: "#15130f",
28900
- shadow: "#1a1712",
28901
- highlight: "#4a4436",
28902
- fade: "#07090b",
28903
- // ⚠ DELIBERATELY NOT RAISED. See the type's note: a strong hillshade
28904
- // under red night vision is a grey haze over exactly the contrast a
28905
- // skipper is navigating by. Left at the shipped value rather than
28906
- // lowered, because lowering it is a separate decision from this one.
28907
- exaggeration: 0.45
28908
- }
28909
- };
28910
- var FITS = ["<=", ["coalesce", ["get", "min_z"], 0], ["zoom"]];
28911
- var ANCHOR = ["coalesce", ["get", "anchor"], "top"];
28912
- var anchorOffset = (em) => [
28913
- "match",
28914
- ["get", "anchor"],
28915
- "left",
28916
- ["literal", [0.6, 0]],
28917
- "right",
28918
- ["literal", [-0.6, 0]],
28919
- "bottom",
28920
- ["literal", [0, -em]],
28921
- ["literal", [0, em]]
28922
- ];
28923
- var FONT = ["Open Sans Regular"];
28924
- var FONT_ITALIC = ["Open Sans Italic"];
28925
- function landLayers(opts = {}) {
28926
- const palette = opts.palette ?? "DAY";
28927
- const T = LAND_THEMES[palette] ?? LAND_THEMES.DAY;
28928
- const src = opts.sourceId ?? LAND_REGION;
28929
- const demSrc = opts.reliefSourceId ?? RELIEF_REGION;
28930
- const L = (o) => o;
28931
- const layers = [
28932
- // 1. The land itself — LNDARE ∩ coverage, so it can never outrun the chart.
28933
- L({
28934
- id: "chrtland-base",
28935
- type: "fill",
28936
- source: src,
28937
- "source-layer": "land_base",
28938
- paint: { "fill-color": T.base }
28939
- })
28940
- ];
28941
- layers.push(L({
28942
- id: "chrtland-cover",
28943
- type: "fill",
28944
- source: src,
28945
- "source-layer": "land_cover",
28946
- filter: ["<=", ["coalesce", ["get", "min_z"], 0], ["zoom"]],
28947
- paint: {
28948
- "fill-color": [
28949
- "match",
28950
- ["get", "class"],
28951
- "wood",
28952
- T.cover.wood,
28953
- "wetland",
28954
- T.cover.wetland,
28955
- "urban",
28956
- T.cover.urban,
28957
- "sand",
28958
- T.cover.sand,
28959
- T.base
28960
- ],
28961
- "fill-opacity": 0.85
28962
- }
28963
- }));
28964
- if (opts.relief) {
28965
- layers.push(L({
28966
- // No minzoom here: LAND_SURFACE_LAYERS floors it with the rest of the
28967
- // surface, so the two can never drift apart again.
28968
- id: "chrtland-hillshade",
28969
- type: "hillshade",
28970
- source: demSrc,
28971
- paint: {
28972
- "hillshade-exaggeration": T.exaggeration,
28973
- "hillshade-shadow-color": T.shadow,
28974
- "hillshade-highlight-color": T.highlight,
28975
- "hillshade-accent-color": T.shadow
28976
- }
28977
- }));
28978
- }
28979
- const isIndexContour = [
28980
- "any",
28981
- ["<=", ["coalesce", ["get", "index_z"], 99], ["zoom"]],
28982
- ["==", ["get", "is_index"], 1]
28983
- ];
28984
- layers.push(L({
28985
- id: "chrtland-contour",
28986
- type: "line",
28987
- source: src,
28988
- "source-layer": "land_contour",
28989
- filter: ["<=", ["coalesce", ["get", "min_z"], 0], ["zoom"]],
28990
- paint: {
28991
- "line-color": ["case", isIndexContour, T.contourIndex, T.contour],
28992
- "line-width": ["case", isIndexContour, 0.8, 0.4],
28993
- "line-opacity": 0.7
28994
- }
28995
- }));
28996
- const d = FADE_PX / 2 / FADE_BANDS;
28997
- for (let k = 0; k < FADE_BANDS; k++) {
28998
- const width = k === 0 ? { "line-width": 2 * d } : { "line-width": d, "line-gap-width": 2 * k * d };
28999
- layers.push(L({
29000
- id: `chrtland-fade-${k}`,
29001
- type: "line",
29002
- source: src,
29003
- "source-layer": "land_edge",
29004
- layout: { "line-join": "bevel" },
29005
- paint: { "line-color": T.fade, "line-blur": 0, "line-opacity": fadeAlpha(k * d + d / 2), ...width }
29006
- }));
29007
- }
29008
- layers.push(L({
29009
- id: "chrtland-road",
29010
- type: "line",
29011
- source: src,
29012
- "source-layer": "land_road",
29013
- minzoom: 10,
29014
- paint: {
29015
- "line-color": ["match", ["get", "kind"], "highway", T.roadMajor, T.road],
29016
- "line-width": [
29017
- "interpolate",
29018
- ["linear"],
29019
- ["zoom"],
29020
- 10,
29021
- ["match", ["get", "kind"], "highway", 0.8, 0.4],
29022
- 14,
29023
- ["match", ["get", "kind"], "highway", 2.4, 1.2]
29024
- ],
29025
- "line-opacity": 0.8
29026
- }
29027
- }));
29028
- layers.push(L({
29029
- id: "chrtland-city-major",
29030
- type: "symbol",
29031
- source: src,
29032
- "source-layer": "land_town",
29033
- minzoom: 6.5,
29034
- filter: [">=", ["coalesce", ["get", "prank"], 0], 10],
29035
- layout: {
29036
- "text-field": [
29037
- "case",
29038
- ["==", ["get", "upcase"], true],
29039
- ["upcase", ["get", "name"]],
29040
- ["get", "name"]
29041
- ],
29042
- "text-font": FONT,
29043
- "text-size": [
29044
- "interpolate",
29045
- ["linear"],
29046
- ["zoom"],
29047
- 6.5,
29048
- 11.5,
29049
- 9,
29050
- ["+", 10, ["*", 0.4, ["coalesce", ["get", "prank"], 10]]],
29051
- 13,
29052
- ["+", 13, ["*", 0.5, ["coalesce", ["get", "prank"], 10]]]
29053
- ],
29054
- "text-letter-spacing": ["case", ["==", ["get", "upcase"], true], 0.14, 0.02],
29055
- "text-offset": anchorOffset(0.75),
29056
- "text-anchor": ANCHOR,
29057
- "text-padding": 10,
29058
- "text-allow-overlap": false,
29059
- "symbol-sort-key": ["*", -1, ["coalesce", ["get", "pop"], 0]]
29060
- },
29061
- paint: { "text-color": T.label, "text-halo-color": T.halo, "text-halo-width": 1.6 }
29062
- }));
29063
- layers.push(L({
29064
- id: "chrtland-town-port",
29065
- type: "symbol",
29066
- source: src,
29067
- "source-layer": "land_town",
29068
- minzoom: 8.5,
29069
- filter: [
29070
- "all",
29071
- ["==", ["get", "enc_dup"], true],
29072
- ["<", ["coalesce", ["get", "prank"], 0], 10]
29073
- ],
29074
- layout: {
29075
- "text-field": ["get", "name"],
29076
- "text-font": FONT,
29077
- "text-size": ["interpolate", ["linear"], ["zoom"], 8.5, 11, 12, 13.5],
29078
- "text-offset": anchorOffset(0.75),
29079
- "text-anchor": ANCHOR,
29080
- "text-padding": 8,
29081
- "text-allow-overlap": false,
29082
- // Within the tier, the bigger place wins the space: without this the
29083
- // tie broke on data order and "West Gloucester" beat Gloucester.
29084
- "symbol-sort-key": ["*", -1, ["coalesce", ["get", "pop"], 0]]
29085
- },
29086
- paint: { "text-color": T.label, "text-halo-color": T.halo, "text-halo-width": 1.4 }
29087
- }));
29088
- layers.push(L({
29089
- id: "chrtland-town",
29090
- type: "symbol",
29091
- source: src,
29092
- "source-layer": "land_town",
29093
- minzoom: 9,
29094
- filter: [
29095
- "all",
29096
- FITS,
29097
- ["<", ["coalesce", ["get", "prank"], 0], 10],
29098
- ["!=", ["get", "enc_dup"], true]
29099
- ],
29100
- layout: {
29101
- "text-field": [
29102
- "case",
29103
- ["==", ["get", "upcase"], true],
29104
- ["upcase", ["get", "name"]],
29105
- ["get", "name"]
29106
- ],
29107
- "text-font": FONT,
29108
- "text-size": ["interpolate", ["linear"], ["zoom"], 9, 10, 14, 13.5],
29109
- "text-letter-spacing": ["case", ["==", ["get", "upcase"], true], 0.14, 0],
29110
- "text-offset": anchorOffset(0.75),
29111
- "text-anchor": ANCHOR,
29112
- "text-padding": 6,
29113
- "text-allow-overlap": false,
29114
- "symbol-sort-key": 2
29115
- },
29116
- paint: { "text-color": T.label, "text-halo-color": T.halo, "text-halo-width": 1.2 }
29117
- }));
29118
- layers.push(L({
29119
- id: "chrtland-summit",
29120
- type: "symbol",
29121
- source: src,
29122
- "source-layer": "land_summit",
29123
- minzoom: 11.5,
29124
- filter: ["all", FITS, [">=", ["get", "peak_m"], 40]],
29125
- layout: {
29126
- "text-field": ["concat", ["get", "name"], "\n", ["to-string", ["get", "peak_m"]], " m"],
29127
- "text-font": FONT,
29128
- "text-size": ["interpolate", ["linear"], ["zoom"], 11.5, 8.5, 14, 11],
29129
- "text-offset": anchorOffset(0.8),
29130
- "text-anchor": ANCHOR,
29131
- "text-padding": 5,
29132
- "text-allow-overlap": false,
29133
- "symbol-sort-key": 3
29134
- },
29135
- paint: { "text-color": T.label, "text-halo-color": T.halo, "text-halo-width": 1.2 }
29136
- }));
29137
- layers.push(L({
29138
- id: "chrtland-poi",
29139
- type: "symbol",
29140
- source: src,
29141
- "source-layer": "land_poi",
29142
- minzoom: 13,
29143
- filter: FITS,
29144
- layout: {
29145
- "text-field": ["get", "name"],
29146
- "text-font": FONT_ITALIC,
29147
- "text-size": ["interpolate", ["linear"], ["zoom"], 13, 8, 14, 9.5],
29148
- "text-offset": anchorOffset(0.7),
29149
- "text-anchor": ANCHOR,
29150
- "text-padding": 5,
29151
- "text-allow-overlap": false,
29152
- "symbol-sort-key": 5
29153
- },
29154
- paint: { "text-color": T.label, "text-halo-color": T.halo, "text-halo-width": 1.2 }
29155
- }));
29156
- for (const layer of layers) {
29157
- const l = layer;
29158
- if (!LAND_SURFACE_LAYERS(l.id)) continue;
29159
- l.minzoom = Math.max(l.minzoom ?? 0, LAND_SURFACE_MINZOOM);
29160
- }
29161
- return layers;
29162
- }
29163
-
29164
28845
  // src/atlas/base-layers.ts
29165
28846
  var NOCOVERAGE_PATTERN = "chrt:hatch-nocoverage";
29166
28847
  var UNCHARTED_PATTERN = "chrt:hatch-uncharted";
28848
+ function inlandWaterColor(palette) {
28849
+ return (BASE_THEMES[palette] ?? BASE_THEMES.DAY).inlandWater;
28850
+ }
29167
28851
  var BASE_THEMES = {
29168
28852
  DAY: {
29169
28853
  // ── `earth` is the jurisdiction tan DIMMED (~0.55), not a blue-grey ──
@@ -29182,7 +28866,7 @@ var BASE_THEMES = {
29182
28866
  water: "#1B2328",
29183
28867
  river: "#24313A",
29184
28868
  boundary: "#4A575E",
29185
- jurisdiction: "#E8D9B0",
28869
+ jurisdiction: "#D4C69D",
29186
28870
  // CHRTland's own tan — one land colour
29187
28871
  inlandWater: "#B9CFDD",
29188
28872
  // muted, unmistakably not a charted blue
@@ -29190,9 +28874,9 @@ var BASE_THEMES = {
29190
28874
  // from this table (and its type — the long-standing TS2339 trio), so the
29191
28875
  // lines shipped on MapLibre's DEFAULT black. Now deliberate: a hairline
29192
28876
  // a shade deeper than the tan, quiet caps, tan halo.
29193
- stateLine: "#C4B389",
28877
+ stateLine: "#B1A077",
29194
28878
  stateLabel: "#8E8468",
29195
- stateHalo: "#E8D9B0",
28879
+ stateHalo: "#D4C69D",
29196
28880
  // Rough-lake furniture (owner ask 2026-08-28: "the lakes need labels,
29197
28881
  // and shorelines drawn"): a shoreline a shade deeper than the rough
29198
28882
  // water, and a name in the water's own voice, haloed by the water.
@@ -29570,29 +29254,357 @@ function baseInlandWaterLayers(opts = {}) {
29570
29254
  id: "chrtbase-inland-label",
29571
29255
  type: "symbol",
29572
29256
  source: src,
29573
- "source-layer": "inland_water_label",
29574
- minzoom: 5,
29575
- layout: {
29576
- "text-field": ["get", "name"],
29577
- "text-font": ["Open Sans Regular"],
29578
- "text-size": ["interpolate", ["linear"], ["zoom"], 5, 9.5, 10, 12],
29579
- "text-max-width": 7,
29580
- "text-allow-overlap": false,
29581
- // Zoom-scaled spacing for the anchor GRID: at z8.9 the 0.08-deg
29582
- // anchors sit ~54 px apart and a flat padding let six copies of
29583
- // "Lake Ontario" crowd one screen (owner-reported 2026-08-30).
29584
- // Wide collision boxes at low zoom thin the grid to the repeat-
29585
- // by-convention cadence; by z12 the anchors are ~850 px apart and
29586
- // the padding relaxes to normal.
29587
- "text-padding": ["interpolate", ["linear"], ["zoom"], 5, 80, 9, 64, 12, 16]
29588
- },
29257
+ "source-layer": "inland_water_label",
29258
+ minzoom: 5,
29259
+ layout: {
29260
+ "text-field": ["get", "name"],
29261
+ "text-font": ["Open Sans Regular"],
29262
+ "text-size": ["interpolate", ["linear"], ["zoom"], 5, 9.5, 10, 12],
29263
+ "text-max-width": 7,
29264
+ "text-allow-overlap": false,
29265
+ // Zoom-scaled spacing for the anchor GRID: at z8.9 the 0.08-deg
29266
+ // anchors sit ~54 px apart and a flat padding let six copies of
29267
+ // "Lake Ontario" crowd one screen (owner-reported 2026-08-30).
29268
+ // Wide collision boxes at low zoom thin the grid to the repeat-
29269
+ // by-convention cadence; by z12 the anchors are ~850 px apart and
29270
+ // the padding relaxes to normal.
29271
+ "text-padding": ["interpolate", ["linear"], ["zoom"], 5, 80, 9, 64, 12, 16]
29272
+ },
29273
+ paint: {
29274
+ "text-color": T.inlandLabel,
29275
+ "text-halo-color": T.inlandHalo,
29276
+ "text-halo-width": 1.1
29277
+ }
29278
+ })
29279
+ ];
29280
+ }
29281
+
29282
+ // src/atlas/land-layers.ts
29283
+ var LAND_SURFACE_MINZOOM = BAND_PRIORITY_RANGES["5"].minzoom;
29284
+ var LAND_SURFACE_LAYERS = (id) => id === "chrtland-base" || id === "chrtland-cover" || id === "chrtland-contour" || id === "chrtland-hillshade" || id === "chrtland-water" || id.startsWith("chrtland-fade-");
29285
+ var isLandGroundOverlay = (id) => LAND_SURFACE_LAYERS(id) && id !== "chrtland-base" || id === "chrtland-road";
29286
+ var FADE_PX = 80;
29287
+ var FADE_BANDS = 16;
29288
+ function fadeAlpha(r) {
29289
+ return Math.max(0, Math.min(1, (FADE_PX / 2 - Math.abs(r)) / FADE_PX));
29290
+ }
29291
+ function landBaseColor(palette) {
29292
+ return (LAND_THEMES[palette] ?? LAND_THEMES.DAY).base;
29293
+ }
29294
+ var LAND_THEMES = {
29295
+ DAY: {
29296
+ base: "#d4c69d",
29297
+ cover: { wood: "#bcc5a1", wetland: "#b6c0b1", urban: "#cac6bf", sand: "#dbd0af" },
29298
+ contour: "#958666",
29299
+ contourIndex: "#78694b",
29300
+ road: "#c5b691",
29301
+ roadMajor: "#beaa7c",
29302
+ label: "#5b4f3a",
29303
+ halo: "#ded6c3",
29304
+ shadow: "#6b5a3e",
29305
+ highlight: "#fffaf0",
29306
+ fade: "#e8f2f8",
29307
+ // Raised from 0.45 on 2026-08-23. ⚠ Above the ~0.5 that
29308
+ // hillshade-style.mjs warns "starts competing with depth areas" — a
29309
+ // deliberate, sighted choice made against rendered evidence, not a
29310
+ // default. If soundings or DEPARE ever read as fighting the terrain,
29311
+ // this number is the first thing to walk back.
29312
+ exaggeration: 0.8
29313
+ },
29314
+ DUSK: {
29315
+ base: "#4a4433",
29316
+ cover: { wood: "#414a38", wetland: "#3f4740", urban: "#4e4a42", sand: "#544c39" },
29317
+ contour: "#6b6250",
29318
+ contourIndex: "#837961",
29319
+ road: "#565040",
29320
+ roadMajor: "#63594440",
29321
+ label: "#c3b898",
29322
+ halo: "#2b2820",
29323
+ shadow: "#2e2a20",
29324
+ highlight: "#8a8068",
29325
+ fade: "#16202a",
29326
+ // Unchanged. DUSK was not the palette the 0.8 decision was made against.
29327
+ exaggeration: 0.45
29328
+ },
29329
+ NIGHT: {
29330
+ base: "#2a2620",
29331
+ cover: { wood: "#242a20", wetland: "#232823", urban: "#2c2925", sand: "#302b22" },
29332
+ contour: "#413b30",
29333
+ contourIndex: "#524a3b",
29334
+ road: "#332f27",
29335
+ roadMajor: "#3d382d",
29336
+ label: "#7d745e",
29337
+ halo: "#15130f",
29338
+ shadow: "#1a1712",
29339
+ highlight: "#4a4436",
29340
+ fade: "#07090b",
29341
+ // ⚠ DELIBERATELY NOT RAISED. See the type's note: a strong hillshade
29342
+ // under red night vision is a grey haze over exactly the contrast a
29343
+ // skipper is navigating by. Left at the shipped value rather than
29344
+ // lowered, because lowering it is a separate decision from this one.
29345
+ exaggeration: 0.45
29346
+ }
29347
+ };
29348
+ var FITS = ["<=", ["coalesce", ["get", "min_z"], 0], ["zoom"]];
29349
+ var ANCHOR = ["coalesce", ["get", "anchor"], "top"];
29350
+ var anchorOffset = (em) => [
29351
+ "match",
29352
+ ["get", "anchor"],
29353
+ "left",
29354
+ ["literal", [0.6, 0]],
29355
+ "right",
29356
+ ["literal", [-0.6, 0]],
29357
+ "bottom",
29358
+ ["literal", [0, -em]],
29359
+ ["literal", [0, em]]
29360
+ ];
29361
+ var FONT = ["Open Sans Regular"];
29362
+ var FONT_ITALIC = ["Open Sans Italic"];
29363
+ function landLayers(opts = {}) {
29364
+ const palette = opts.palette ?? "DAY";
29365
+ const T = LAND_THEMES[palette] ?? LAND_THEMES.DAY;
29366
+ const src = opts.sourceId ?? LAND_REGION;
29367
+ const demSrc = opts.reliefSourceId ?? RELIEF_REGION;
29368
+ const L = (o) => o;
29369
+ const layers = [
29370
+ // 1. The land itself — LNDARE ∩ coverage, so it can never outrun the chart.
29371
+ L({
29372
+ id: "chrtland-base",
29373
+ type: "fill",
29374
+ source: src,
29375
+ "source-layer": "land_base",
29376
+ paint: { "fill-color": T.base }
29377
+ })
29378
+ ];
29379
+ layers.push(L({
29380
+ id: "chrtland-cover",
29381
+ type: "fill",
29382
+ source: src,
29383
+ "source-layer": "land_cover",
29384
+ filter: ["<=", ["coalesce", ["get", "min_z"], 0], ["zoom"]],
29385
+ paint: {
29386
+ "fill-color": [
29387
+ "match",
29388
+ ["get", "class"],
29389
+ "wood",
29390
+ T.cover.wood,
29391
+ "wetland",
29392
+ T.cover.wetland,
29393
+ "urban",
29394
+ T.cover.urban,
29395
+ "sand",
29396
+ T.cover.sand,
29397
+ T.base
29398
+ ],
29399
+ "fill-opacity": 0.85
29400
+ }
29401
+ }));
29402
+ if (opts.relief) {
29403
+ layers.push(L({
29404
+ // No minzoom here: LAND_SURFACE_LAYERS floors it with the rest of the
29405
+ // surface, so the two can never drift apart again.
29406
+ id: "chrtland-hillshade",
29407
+ type: "hillshade",
29408
+ source: demSrc,
29589
29409
  paint: {
29590
- "text-color": T.inlandLabel,
29591
- "text-halo-color": T.inlandHalo,
29592
- "text-halo-width": 1.1
29410
+ "hillshade-exaggeration": T.exaggeration,
29411
+ "hillshade-shadow-color": T.shadow,
29412
+ "hillshade-highlight-color": T.highlight,
29413
+ "hillshade-accent-color": T.shadow
29593
29414
  }
29594
- })
29415
+ }));
29416
+ }
29417
+ const isIndexContour = [
29418
+ "any",
29419
+ ["<=", ["coalesce", ["get", "index_z"], 99], ["zoom"]],
29420
+ ["==", ["get", "is_index"], 1]
29595
29421
  ];
29422
+ layers.push(L({
29423
+ id: "chrtland-contour",
29424
+ type: "line",
29425
+ source: src,
29426
+ "source-layer": "land_contour",
29427
+ filter: ["<=", ["coalesce", ["get", "min_z"], 0], ["zoom"]],
29428
+ paint: {
29429
+ "line-color": ["case", isIndexContour, T.contourIndex, T.contour],
29430
+ "line-width": ["case", isIndexContour, 0.8, 0.4],
29431
+ "line-opacity": 0.7
29432
+ }
29433
+ }));
29434
+ layers.push(L({
29435
+ id: "chrtland-water",
29436
+ type: "fill",
29437
+ source: src,
29438
+ "source-layer": "land_water",
29439
+ filter: ["<=", ["coalesce", ["get", "min_z"], 0], ["zoom"]],
29440
+ paint: { "fill-color": inlandWaterColor(palette) }
29441
+ }));
29442
+ const d = FADE_PX / 2 / FADE_BANDS;
29443
+ for (let k = 0; k < FADE_BANDS; k++) {
29444
+ const width = k === 0 ? { "line-width": 2 * d } : { "line-width": d, "line-gap-width": 2 * k * d };
29445
+ layers.push(L({
29446
+ id: `chrtland-fade-${k}`,
29447
+ type: "line",
29448
+ source: src,
29449
+ "source-layer": "land_edge",
29450
+ layout: { "line-join": "bevel" },
29451
+ paint: { "line-color": T.fade, "line-blur": 0, "line-opacity": fadeAlpha(k * d + d / 2), ...width }
29452
+ }));
29453
+ }
29454
+ layers.push(L({
29455
+ id: "chrtland-road",
29456
+ type: "line",
29457
+ source: src,
29458
+ "source-layer": "land_road",
29459
+ minzoom: 10,
29460
+ paint: {
29461
+ "line-color": ["match", ["get", "kind"], "highway", T.roadMajor, T.road],
29462
+ "line-width": [
29463
+ "interpolate",
29464
+ ["linear"],
29465
+ ["zoom"],
29466
+ 10,
29467
+ ["match", ["get", "kind"], "highway", 0.8, 0.4],
29468
+ 14,
29469
+ ["match", ["get", "kind"], "highway", 2.4, 1.2]
29470
+ ],
29471
+ "line-opacity": 0.8
29472
+ }
29473
+ }));
29474
+ layers.push(L({
29475
+ id: "chrtland-city-major",
29476
+ type: "symbol",
29477
+ source: src,
29478
+ "source-layer": "land_town",
29479
+ minzoom: 6.5,
29480
+ filter: [">=", ["coalesce", ["get", "prank"], 0], 10],
29481
+ layout: {
29482
+ "text-field": [
29483
+ "case",
29484
+ ["==", ["get", "upcase"], true],
29485
+ ["upcase", ["get", "name"]],
29486
+ ["get", "name"]
29487
+ ],
29488
+ "text-font": FONT,
29489
+ "text-size": [
29490
+ "interpolate",
29491
+ ["linear"],
29492
+ ["zoom"],
29493
+ 6.5,
29494
+ 11.5,
29495
+ 9,
29496
+ ["+", 10, ["*", 0.4, ["coalesce", ["get", "prank"], 10]]],
29497
+ 13,
29498
+ ["+", 13, ["*", 0.5, ["coalesce", ["get", "prank"], 10]]]
29499
+ ],
29500
+ "text-letter-spacing": ["case", ["==", ["get", "upcase"], true], 0.14, 0.02],
29501
+ "text-offset": anchorOffset(0.75),
29502
+ "text-anchor": ANCHOR,
29503
+ "text-padding": 10,
29504
+ "text-allow-overlap": false,
29505
+ "symbol-sort-key": ["*", -1, ["coalesce", ["get", "pop"], 0]]
29506
+ },
29507
+ paint: { "text-color": T.label, "text-halo-color": T.halo, "text-halo-width": 1.6 }
29508
+ }));
29509
+ layers.push(L({
29510
+ id: "chrtland-town-port",
29511
+ type: "symbol",
29512
+ source: src,
29513
+ "source-layer": "land_town",
29514
+ minzoom: 8.5,
29515
+ filter: [
29516
+ "all",
29517
+ ["==", ["get", "enc_dup"], true],
29518
+ ["<", ["coalesce", ["get", "prank"], 0], 10]
29519
+ ],
29520
+ layout: {
29521
+ "text-field": ["get", "name"],
29522
+ "text-font": FONT,
29523
+ "text-size": ["interpolate", ["linear"], ["zoom"], 8.5, 11, 12, 13.5],
29524
+ "text-offset": anchorOffset(0.75),
29525
+ "text-anchor": ANCHOR,
29526
+ "text-padding": 8,
29527
+ "text-allow-overlap": false,
29528
+ // Within the tier, the bigger place wins the space: without this the
29529
+ // tie broke on data order and "West Gloucester" beat Gloucester.
29530
+ "symbol-sort-key": ["*", -1, ["coalesce", ["get", "pop"], 0]]
29531
+ },
29532
+ paint: { "text-color": T.label, "text-halo-color": T.halo, "text-halo-width": 1.4 }
29533
+ }));
29534
+ layers.push(L({
29535
+ id: "chrtland-town",
29536
+ type: "symbol",
29537
+ source: src,
29538
+ "source-layer": "land_town",
29539
+ minzoom: 9,
29540
+ filter: [
29541
+ "all",
29542
+ FITS,
29543
+ ["<", ["coalesce", ["get", "prank"], 0], 10],
29544
+ ["!=", ["get", "enc_dup"], true]
29545
+ ],
29546
+ layout: {
29547
+ "text-field": [
29548
+ "case",
29549
+ ["==", ["get", "upcase"], true],
29550
+ ["upcase", ["get", "name"]],
29551
+ ["get", "name"]
29552
+ ],
29553
+ "text-font": FONT,
29554
+ "text-size": ["interpolate", ["linear"], ["zoom"], 9, 10, 14, 13.5],
29555
+ "text-letter-spacing": ["case", ["==", ["get", "upcase"], true], 0.14, 0],
29556
+ "text-offset": anchorOffset(0.75),
29557
+ "text-anchor": ANCHOR,
29558
+ "text-padding": 6,
29559
+ "text-allow-overlap": false,
29560
+ "symbol-sort-key": 2
29561
+ },
29562
+ paint: { "text-color": T.label, "text-halo-color": T.halo, "text-halo-width": 1.2 }
29563
+ }));
29564
+ layers.push(L({
29565
+ id: "chrtland-summit",
29566
+ type: "symbol",
29567
+ source: src,
29568
+ "source-layer": "land_summit",
29569
+ minzoom: 11.5,
29570
+ filter: ["all", FITS, [">=", ["get", "peak_m"], 40]],
29571
+ layout: {
29572
+ "text-field": ["concat", ["get", "name"], "\n", ["to-string", ["get", "peak_m"]], " m"],
29573
+ "text-font": FONT,
29574
+ "text-size": ["interpolate", ["linear"], ["zoom"], 11.5, 8.5, 14, 11],
29575
+ "text-offset": anchorOffset(0.8),
29576
+ "text-anchor": ANCHOR,
29577
+ "text-padding": 5,
29578
+ "text-allow-overlap": false,
29579
+ "symbol-sort-key": 3
29580
+ },
29581
+ paint: { "text-color": T.label, "text-halo-color": T.halo, "text-halo-width": 1.2 }
29582
+ }));
29583
+ layers.push(L({
29584
+ id: "chrtland-poi",
29585
+ type: "symbol",
29586
+ source: src,
29587
+ "source-layer": "land_poi",
29588
+ minzoom: 13,
29589
+ filter: FITS,
29590
+ layout: {
29591
+ "text-field": ["get", "name"],
29592
+ "text-font": FONT_ITALIC,
29593
+ "text-size": ["interpolate", ["linear"], ["zoom"], 13, 8, 14, 9.5],
29594
+ "text-offset": anchorOffset(0.7),
29595
+ "text-anchor": ANCHOR,
29596
+ "text-padding": 5,
29597
+ "text-allow-overlap": false,
29598
+ "symbol-sort-key": 5
29599
+ },
29600
+ paint: { "text-color": T.label, "text-halo-color": T.halo, "text-halo-width": 1.2 }
29601
+ }));
29602
+ for (const layer of layers) {
29603
+ const l = layer;
29604
+ if (!LAND_SURFACE_LAYERS(l.id)) continue;
29605
+ l.minzoom = Math.max(l.minzoom ?? 0, LAND_SURFACE_MINZOOM);
29606
+ }
29607
+ return layers;
29596
29608
  }
29597
29609
 
29598
29610
  // src/atlas/band-collapse.ts
@@ -30295,21 +30307,37 @@ function generateStyle(palette = "DAY", opts = {}) {
30295
30307
  ];
30296
30308
  }
30297
30309
  {
30298
- const hsAt = restFinal.findIndex(
30299
- (l) => l.type === "hillshade"
30300
- );
30310
+ const assembled = [
30311
+ restFinal[0],
30312
+ ...baseBlock,
30313
+ ...seaare,
30314
+ ...ordered,
30315
+ ...restFinal.slice(1)
30316
+ ];
30317
+ const idOf = (l) => l.id;
30318
+ const isRepaint = (l) => /-overpair(-|$)/.test(idOf(l));
30301
30319
  let lastRepaint = -1;
30302
- restFinal.forEach((l, i) => {
30303
- if (/-overpair(-|$)/.test(l.id)) lastRepaint = i;
30320
+ assembled.forEach((l, i) => {
30321
+ if (isRepaint(l)) lastRepaint = i;
30304
30322
  });
30305
- if (hsAt !== -1 && lastRepaint > hsAt) {
30306
- const reordered = [...restFinal];
30307
- const [hs] = reordered.splice(hsAt, 1);
30308
- reordered.splice(lastRepaint, 0, hs);
30309
- restFinal = reordered;
30310
- }
30323
+ if (lastRepaint === -1) return assembled;
30324
+ const surface = [];
30325
+ const kept = [];
30326
+ assembled.forEach((l, i) => {
30327
+ if (i < lastRepaint && isLandGroundOverlay(idOf(l))) surface.push(l);
30328
+ else kept.push(l);
30329
+ });
30330
+ if (surface.length === 0) return assembled;
30331
+ let landing = -1;
30332
+ kept.forEach((l, i) => {
30333
+ if (isRepaint(l)) landing = i;
30334
+ });
30335
+ return [
30336
+ ...kept.slice(0, landing + 1),
30337
+ ...surface,
30338
+ ...kept.slice(landing + 1)
30339
+ ];
30311
30340
  }
30312
- return [restFinal[0], ...baseBlock, ...seaare, ...ordered, ...restFinal.slice(1)];
30313
30341
  })() : layers;
30314
30342
  for (const id of [
30315
30343
  "chrtbase-country-boundary",