@chrtco/sdk 0.10.30 → 0.10.32
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 +479 -468
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +479 -468
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -28618,466 +28618,149 @@ function worldMinusBboxPolygon(bbox) {
|
|
|
28618
28618
|
};
|
|
28619
28619
|
}
|
|
28620
28620
|
|
|
28621
|
-
// src/atlas/
|
|
28622
|
-
var
|
|
28623
|
-
var
|
|
28624
|
-
|
|
28625
|
-
|
|
28626
|
-
var FADE_BANDS = 16;
|
|
28627
|
-
function fadeAlpha(r) {
|
|
28628
|
-
return Math.max(0, Math.min(1, (FADE_PX / 2 - Math.abs(r)) / FADE_PX));
|
|
28629
|
-
}
|
|
28630
|
-
function landBaseColor(palette) {
|
|
28631
|
-
return (LAND_THEMES[palette] ?? LAND_THEMES.DAY).base;
|
|
28621
|
+
// src/atlas/base-layers.ts
|
|
28622
|
+
var NOCOVERAGE_PATTERN = "chrt:hatch-nocoverage";
|
|
28623
|
+
var UNCHARTED_PATTERN = "chrt:hatch-uncharted";
|
|
28624
|
+
function inlandWaterColor(palette) {
|
|
28625
|
+
return (BASE_THEMES[palette] ?? BASE_THEMES.DAY).inlandWater;
|
|
28632
28626
|
}
|
|
28633
|
-
var
|
|
28627
|
+
var BASE_THEMES = {
|
|
28634
28628
|
DAY: {
|
|
28635
|
-
|
|
28636
|
-
|
|
28637
|
-
|
|
28638
|
-
|
|
28639
|
-
|
|
28640
|
-
|
|
28641
|
-
|
|
28642
|
-
|
|
28643
|
-
|
|
28644
|
-
|
|
28645
|
-
|
|
28646
|
-
//
|
|
28647
|
-
|
|
28648
|
-
|
|
28649
|
-
|
|
28650
|
-
|
|
28651
|
-
|
|
28629
|
+
// ── `earth` is the jurisdiction tan DIMMED (~0.55), not a blue-grey ──
|
|
28630
|
+
// Outside the jurisdiction the map still owes the reader "what is land".
|
|
28631
|
+
// State 3 in the header is "the geography, under a crosshatch", and until
|
|
28632
|
+
// 2026-08-31 that geography was unreadable: earth #2A3439 against sea
|
|
28633
|
+
// #1B2328 measured 1.25:1, so Hispaniola showed charted boxes with tan
|
|
28634
|
+
// land inside and nothing recognisable around them (owner report: "no
|
|
28635
|
+
// land painting down near the DR at some zooms"). Land is warm and sea is
|
|
28636
|
+
// cool because that is what land and sea are; dimming the JURISDICTION
|
|
28637
|
+
// tan rather than inventing a colour says the true thing — this is the
|
|
28638
|
+
// same land, we simply do not carry charts for it. Held against BOTH
|
|
28639
|
+
// neighbours: legible over sea, and never mistakable for the full tan of
|
|
28640
|
+
// a country we do carry. DAY 3.59:1 vs sea, 3.17:1 vs tan.
|
|
28641
|
+
earth: "#807761",
|
|
28642
|
+
water: "#1B2328",
|
|
28643
|
+
river: "#24313A",
|
|
28644
|
+
boundary: "#4A575E",
|
|
28645
|
+
jurisdiction: "#D4C69D",
|
|
28646
|
+
// CHRTland's own tan — one land colour
|
|
28647
|
+
inlandWater: "#B9CFDD",
|
|
28648
|
+
// muted, unmistakably not a charted blue
|
|
28649
|
+
// State furniture. These three were referenced by the layers but missing
|
|
28650
|
+
// from this table (and its type — the long-standing TS2339 trio), so the
|
|
28651
|
+
// lines shipped on MapLibre's DEFAULT black. Now deliberate: a hairline
|
|
28652
|
+
// a shade deeper than the tan, quiet caps, tan halo.
|
|
28653
|
+
stateLine: "#B1A077",
|
|
28654
|
+
stateLabel: "#8E8468",
|
|
28655
|
+
stateHalo: "#D4C69D",
|
|
28656
|
+
// Rough-lake furniture (owner ask 2026-08-28: "the lakes need labels,
|
|
28657
|
+
// and shorelines drawn"): a shoreline a shade deeper than the rough
|
|
28658
|
+
// water, and a name in the water's own voice, haloed by the water.
|
|
28659
|
+
inlandShore: "#8FA9BA",
|
|
28660
|
+
inlandLabel: "#54707F",
|
|
28661
|
+
inlandHalo: "#B9CFDD"
|
|
28652
28662
|
},
|
|
28653
28663
|
DUSK: {
|
|
28654
|
-
|
|
28655
|
-
|
|
28656
|
-
|
|
28657
|
-
|
|
28658
|
-
|
|
28659
|
-
|
|
28660
|
-
|
|
28661
|
-
|
|
28662
|
-
|
|
28663
|
-
|
|
28664
|
-
|
|
28665
|
-
|
|
28666
|
-
|
|
28664
|
+
// ── Re-derived 2026-09-01: the basemap sits UNDER the chart ──────────
|
|
28665
|
+
// These were the DAY tones scaled by a constant, never measured against
|
|
28666
|
+
// the DUSK chart — so `jurisdiction` came out at L=0.506 against a chart
|
|
28667
|
+
// whose own land (LANDA #8a7d5e) is L=0.209, i.e. the context layer was
|
|
28668
|
+
// 2.4x brighter than the data layer. Now capped at the chart's own land.
|
|
28669
|
+
// The rest of the block rides the same 0.666 channel factor so every
|
|
28670
|
+
// relationship the palette already chose is preserved, only moved down.
|
|
28671
|
+
// `water` is deliberately NOT scaled: it is the reference the land/sea
|
|
28672
|
+
// floor is measured against.
|
|
28673
|
+
earth: "#544E3E",
|
|
28674
|
+
water: "#161D21",
|
|
28675
|
+
river: "#141B20",
|
|
28676
|
+
boundary: "#293135",
|
|
28677
|
+
jurisdiction: "#867D64",
|
|
28678
|
+
inlandWater: "#62717A",
|
|
28679
|
+
// Label stays DARK here — the halo is still mid-toned, so 3:1 is reachable
|
|
28680
|
+
// downward and a bright label would be a new light source at dusk.
|
|
28681
|
+
stateLine: "#B5A987",
|
|
28682
|
+
stateLabel: "#38342A",
|
|
28683
|
+
stateHalo: "#867D64",
|
|
28684
|
+
inlandShore: "#4D5B67",
|
|
28685
|
+
inlandLabel: "#212629",
|
|
28686
|
+
inlandHalo: "#62717A"
|
|
28667
28687
|
},
|
|
28668
28688
|
NIGHT: {
|
|
28669
|
-
|
|
28670
|
-
|
|
28671
|
-
|
|
28672
|
-
|
|
28673
|
-
|
|
28674
|
-
|
|
28675
|
-
|
|
28676
|
-
|
|
28677
|
-
|
|
28678
|
-
|
|
28679
|
-
|
|
28680
|
-
//
|
|
28681
|
-
//
|
|
28682
|
-
//
|
|
28683
|
-
//
|
|
28684
|
-
|
|
28689
|
+
// ── Re-derived 2026-09-01 — the owner-reported night defect ──────────
|
|
28690
|
+
// `jurisdiction` was L=0.240 against a chart whose own land (LANDA
|
|
28691
|
+
// #3a3020) is L=0.031: the world basemap was 7.7x BRIGHTER than the chart
|
|
28692
|
+
// it sits under, so at z<11 the uncharted interior read as a pale
|
|
28693
|
+
// continent-sized slab on a night chart. Capped at the chart's own land.
|
|
28694
|
+
//
|
|
28695
|
+
// ⚠ `earth` AND `jurisdiction` CONVERGE HERE, and that is forced, not
|
|
28696
|
+
// sloppy. Holding earth 2:1 above the ocean AND 2:1 below the jurisdiction
|
|
28697
|
+
// tan requires jurisdiction >= L 0.174 — 5.6x the chart's own land. At
|
|
28698
|
+
// night the range between the ocean (L 0.006) and the cap (L 0.031) is too
|
|
28699
|
+
// compressed to carry two land tones. COVERAGE IS STILL SAID, by the
|
|
28700
|
+
// `chrt:hatch-nocoverage` crosshatch, which is a stronger signal than tone
|
|
28701
|
+
// and is the one thing that cannot be lost to palette compression.
|
|
28702
|
+
//
|
|
28703
|
+
// Labels invert to light-on-dark: 3:1 downward is unreachable off a halo
|
|
28704
|
+
// this close to black, and CHRTland's own night town labels already sit at
|
|
28705
|
+
// L=0.177 for exactly this reason.
|
|
28706
|
+
earth: "#333026",
|
|
28707
|
+
water: "#10161A",
|
|
28708
|
+
river: "#090D0F",
|
|
28709
|
+
boundary: "#131719",
|
|
28710
|
+
jurisdiction: "#353128",
|
|
28711
|
+
inlandWater: "#232A30",
|
|
28712
|
+
stateLine: "#484236",
|
|
28713
|
+
stateLabel: "#837963",
|
|
28714
|
+
stateHalo: "#353128",
|
|
28715
|
+
inlandShore: "#1C2227",
|
|
28716
|
+
inlandLabel: "#617484",
|
|
28717
|
+
inlandHalo: "#232A30"
|
|
28685
28718
|
}
|
|
28686
28719
|
};
|
|
28687
|
-
|
|
28688
|
-
var ANCHOR = ["coalesce", ["get", "anchor"], "top"];
|
|
28689
|
-
var anchorOffset = (em) => [
|
|
28690
|
-
"match",
|
|
28691
|
-
["get", "anchor"],
|
|
28692
|
-
"left",
|
|
28693
|
-
["literal", [0.6, 0]],
|
|
28694
|
-
"right",
|
|
28695
|
-
["literal", [-0.6, 0]],
|
|
28696
|
-
"bottom",
|
|
28697
|
-
["literal", [0, -em]],
|
|
28698
|
-
["literal", [0, em]]
|
|
28699
|
-
];
|
|
28700
|
-
var FONT = ["Open Sans Regular"];
|
|
28701
|
-
var FONT_ITALIC = ["Open Sans Italic"];
|
|
28702
|
-
function landLayers(opts = {}) {
|
|
28720
|
+
function baseLayers(opts = {}) {
|
|
28703
28721
|
const palette = opts.palette ?? "DAY";
|
|
28704
|
-
const T =
|
|
28705
|
-
const src = opts.sourceId ??
|
|
28706
|
-
const demSrc = opts.reliefSourceId ?? RELIEF_REGION;
|
|
28722
|
+
const T = BASE_THEMES[palette] ?? BASE_THEMES.DAY;
|
|
28723
|
+
const src = opts.sourceId ?? BASE_REGION;
|
|
28707
28724
|
const L = (o) => o;
|
|
28708
|
-
|
|
28709
|
-
// 1.
|
|
28725
|
+
return [
|
|
28726
|
+
// 1. Geography — the world as it is, in the quiet dark voice. The OCEAN
|
|
28727
|
+
// is a background, not a polygon: the archive ships land and lakes,
|
|
28728
|
+
// and "everything else is sea" is exactly what a background expresses
|
|
28729
|
+
// — geometry-free, gap-free at every antimeridian and pole. Without
|
|
28730
|
+
// it the sea outside coverage was bare S-52 NODTA, a light grey that
|
|
28731
|
+
// read as "charted ground" with a hatch on it.
|
|
28710
28732
|
L({
|
|
28711
|
-
id: "
|
|
28733
|
+
id: "chrtbase-ocean",
|
|
28734
|
+
type: "background",
|
|
28735
|
+
paint: { "background-color": T.water }
|
|
28736
|
+
}),
|
|
28737
|
+
L({
|
|
28738
|
+
id: "chrtbase-earth",
|
|
28712
28739
|
type: "fill",
|
|
28713
28740
|
source: src,
|
|
28714
|
-
"source-layer": "
|
|
28715
|
-
paint: { "fill-color": T.
|
|
28716
|
-
})
|
|
28717
|
-
|
|
28718
|
-
|
|
28719
|
-
|
|
28720
|
-
|
|
28721
|
-
|
|
28722
|
-
|
|
28723
|
-
|
|
28724
|
-
|
|
28725
|
-
"
|
|
28726
|
-
|
|
28727
|
-
|
|
28728
|
-
|
|
28729
|
-
|
|
28730
|
-
"wetland",
|
|
28731
|
-
T.cover.wetland,
|
|
28732
|
-
"urban",
|
|
28733
|
-
T.cover.urban,
|
|
28734
|
-
"sand",
|
|
28735
|
-
T.cover.sand,
|
|
28736
|
-
T.base
|
|
28737
|
-
],
|
|
28738
|
-
"fill-opacity": 0.85
|
|
28739
|
-
}
|
|
28740
|
-
}));
|
|
28741
|
-
if (opts.relief) {
|
|
28742
|
-
layers.push(L({
|
|
28743
|
-
// No minzoom here: LAND_SURFACE_LAYERS floors it with the rest of the
|
|
28744
|
-
// surface, so the two can never drift apart again.
|
|
28745
|
-
id: "chrtland-hillshade",
|
|
28746
|
-
type: "hillshade",
|
|
28747
|
-
source: demSrc,
|
|
28741
|
+
"source-layer": "base_earth",
|
|
28742
|
+
paint: { "fill-color": T.earth }
|
|
28743
|
+
}),
|
|
28744
|
+
L({
|
|
28745
|
+
id: "chrtbase-water",
|
|
28746
|
+
type: "fill",
|
|
28747
|
+
source: src,
|
|
28748
|
+
"source-layer": "base_water",
|
|
28749
|
+
paint: { "fill-color": T.water }
|
|
28750
|
+
}),
|
|
28751
|
+
L({
|
|
28752
|
+
id: "chrtbase-river",
|
|
28753
|
+
type: "line",
|
|
28754
|
+
source: src,
|
|
28755
|
+
"source-layer": "base_river",
|
|
28756
|
+
minzoom: 9,
|
|
28748
28757
|
paint: {
|
|
28749
|
-
"
|
|
28750
|
-
"
|
|
28751
|
-
"hillshade-highlight-color": T.highlight,
|
|
28752
|
-
"hillshade-accent-color": T.shadow
|
|
28758
|
+
"line-color": T.river,
|
|
28759
|
+
"line-width": ["interpolate", ["linear"], ["zoom"], 9, 0.6, 14, 1.6]
|
|
28753
28760
|
}
|
|
28754
|
-
})
|
|
28755
|
-
|
|
28756
|
-
|
|
28757
|
-
"any",
|
|
28758
|
-
["<=", ["coalesce", ["get", "index_z"], 99], ["zoom"]],
|
|
28759
|
-
["==", ["get", "is_index"], 1]
|
|
28760
|
-
];
|
|
28761
|
-
layers.push(L({
|
|
28762
|
-
id: "chrtland-contour",
|
|
28763
|
-
type: "line",
|
|
28764
|
-
source: src,
|
|
28765
|
-
"source-layer": "land_contour",
|
|
28766
|
-
filter: ["<=", ["coalesce", ["get", "min_z"], 0], ["zoom"]],
|
|
28767
|
-
paint: {
|
|
28768
|
-
"line-color": ["case", isIndexContour, T.contourIndex, T.contour],
|
|
28769
|
-
"line-width": ["case", isIndexContour, 0.8, 0.4],
|
|
28770
|
-
"line-opacity": 0.7
|
|
28771
|
-
}
|
|
28772
|
-
}));
|
|
28773
|
-
const d = FADE_PX / 2 / FADE_BANDS;
|
|
28774
|
-
for (let k = 0; k < FADE_BANDS; k++) {
|
|
28775
|
-
const width = k === 0 ? { "line-width": 2 * d } : { "line-width": d, "line-gap-width": 2 * k * d };
|
|
28776
|
-
layers.push(L({
|
|
28777
|
-
id: `chrtland-fade-${k}`,
|
|
28778
|
-
type: "line",
|
|
28779
|
-
source: src,
|
|
28780
|
-
"source-layer": "land_edge",
|
|
28781
|
-
layout: { "line-join": "bevel" },
|
|
28782
|
-
paint: { "line-color": T.fade, "line-blur": 0, "line-opacity": fadeAlpha(k * d + d / 2), ...width }
|
|
28783
|
-
}));
|
|
28784
|
-
}
|
|
28785
|
-
layers.push(L({
|
|
28786
|
-
id: "chrtland-road",
|
|
28787
|
-
type: "line",
|
|
28788
|
-
source: src,
|
|
28789
|
-
"source-layer": "land_road",
|
|
28790
|
-
minzoom: 10,
|
|
28791
|
-
paint: {
|
|
28792
|
-
"line-color": ["match", ["get", "kind"], "highway", T.roadMajor, T.road],
|
|
28793
|
-
"line-width": [
|
|
28794
|
-
"interpolate",
|
|
28795
|
-
["linear"],
|
|
28796
|
-
["zoom"],
|
|
28797
|
-
10,
|
|
28798
|
-
["match", ["get", "kind"], "highway", 0.8, 0.4],
|
|
28799
|
-
14,
|
|
28800
|
-
["match", ["get", "kind"], "highway", 2.4, 1.2]
|
|
28801
|
-
],
|
|
28802
|
-
"line-opacity": 0.8
|
|
28803
|
-
}
|
|
28804
|
-
}));
|
|
28805
|
-
layers.push(L({
|
|
28806
|
-
id: "chrtland-city-major",
|
|
28807
|
-
type: "symbol",
|
|
28808
|
-
source: src,
|
|
28809
|
-
"source-layer": "land_town",
|
|
28810
|
-
minzoom: 6.5,
|
|
28811
|
-
filter: [">=", ["coalesce", ["get", "prank"], 0], 10],
|
|
28812
|
-
layout: {
|
|
28813
|
-
"text-field": [
|
|
28814
|
-
"case",
|
|
28815
|
-
["==", ["get", "upcase"], true],
|
|
28816
|
-
["upcase", ["get", "name"]],
|
|
28817
|
-
["get", "name"]
|
|
28818
|
-
],
|
|
28819
|
-
"text-font": FONT,
|
|
28820
|
-
"text-size": [
|
|
28821
|
-
"interpolate",
|
|
28822
|
-
["linear"],
|
|
28823
|
-
["zoom"],
|
|
28824
|
-
6.5,
|
|
28825
|
-
11.5,
|
|
28826
|
-
9,
|
|
28827
|
-
["+", 10, ["*", 0.4, ["coalesce", ["get", "prank"], 10]]],
|
|
28828
|
-
13,
|
|
28829
|
-
["+", 13, ["*", 0.5, ["coalesce", ["get", "prank"], 10]]]
|
|
28830
|
-
],
|
|
28831
|
-
"text-letter-spacing": ["case", ["==", ["get", "upcase"], true], 0.14, 0.02],
|
|
28832
|
-
"text-offset": anchorOffset(0.75),
|
|
28833
|
-
"text-anchor": ANCHOR,
|
|
28834
|
-
"text-padding": 10,
|
|
28835
|
-
"text-allow-overlap": false,
|
|
28836
|
-
"symbol-sort-key": ["*", -1, ["coalesce", ["get", "pop"], 0]]
|
|
28837
|
-
},
|
|
28838
|
-
paint: { "text-color": T.label, "text-halo-color": T.halo, "text-halo-width": 1.6 }
|
|
28839
|
-
}));
|
|
28840
|
-
layers.push(L({
|
|
28841
|
-
id: "chrtland-town-port",
|
|
28842
|
-
type: "symbol",
|
|
28843
|
-
source: src,
|
|
28844
|
-
"source-layer": "land_town",
|
|
28845
|
-
minzoom: 8.5,
|
|
28846
|
-
filter: [
|
|
28847
|
-
"all",
|
|
28848
|
-
["==", ["get", "enc_dup"], true],
|
|
28849
|
-
["<", ["coalesce", ["get", "prank"], 0], 10]
|
|
28850
|
-
],
|
|
28851
|
-
layout: {
|
|
28852
|
-
"text-field": ["get", "name"],
|
|
28853
|
-
"text-font": FONT,
|
|
28854
|
-
"text-size": ["interpolate", ["linear"], ["zoom"], 8.5, 11, 12, 13.5],
|
|
28855
|
-
"text-offset": anchorOffset(0.75),
|
|
28856
|
-
"text-anchor": ANCHOR,
|
|
28857
|
-
"text-padding": 8,
|
|
28858
|
-
"text-allow-overlap": false,
|
|
28859
|
-
// Within the tier, the bigger place wins the space: without this the
|
|
28860
|
-
// tie broke on data order and "West Gloucester" beat Gloucester.
|
|
28861
|
-
"symbol-sort-key": ["*", -1, ["coalesce", ["get", "pop"], 0]]
|
|
28862
|
-
},
|
|
28863
|
-
paint: { "text-color": T.label, "text-halo-color": T.halo, "text-halo-width": 1.4 }
|
|
28864
|
-
}));
|
|
28865
|
-
layers.push(L({
|
|
28866
|
-
id: "chrtland-town",
|
|
28867
|
-
type: "symbol",
|
|
28868
|
-
source: src,
|
|
28869
|
-
"source-layer": "land_town",
|
|
28870
|
-
minzoom: 9,
|
|
28871
|
-
filter: [
|
|
28872
|
-
"all",
|
|
28873
|
-
FITS,
|
|
28874
|
-
["<", ["coalesce", ["get", "prank"], 0], 10],
|
|
28875
|
-
["!=", ["get", "enc_dup"], true]
|
|
28876
|
-
],
|
|
28877
|
-
layout: {
|
|
28878
|
-
"text-field": [
|
|
28879
|
-
"case",
|
|
28880
|
-
["==", ["get", "upcase"], true],
|
|
28881
|
-
["upcase", ["get", "name"]],
|
|
28882
|
-
["get", "name"]
|
|
28883
|
-
],
|
|
28884
|
-
"text-font": FONT,
|
|
28885
|
-
"text-size": ["interpolate", ["linear"], ["zoom"], 9, 10, 14, 13.5],
|
|
28886
|
-
"text-letter-spacing": ["case", ["==", ["get", "upcase"], true], 0.14, 0],
|
|
28887
|
-
"text-offset": anchorOffset(0.75),
|
|
28888
|
-
"text-anchor": ANCHOR,
|
|
28889
|
-
"text-padding": 6,
|
|
28890
|
-
"text-allow-overlap": false,
|
|
28891
|
-
"symbol-sort-key": 2
|
|
28892
|
-
},
|
|
28893
|
-
paint: { "text-color": T.label, "text-halo-color": T.halo, "text-halo-width": 1.2 }
|
|
28894
|
-
}));
|
|
28895
|
-
layers.push(L({
|
|
28896
|
-
id: "chrtland-summit",
|
|
28897
|
-
type: "symbol",
|
|
28898
|
-
source: src,
|
|
28899
|
-
"source-layer": "land_summit",
|
|
28900
|
-
minzoom: 11.5,
|
|
28901
|
-
filter: ["all", FITS, [">=", ["get", "peak_m"], 40]],
|
|
28902
|
-
layout: {
|
|
28903
|
-
"text-field": ["concat", ["get", "name"], "\n", ["to-string", ["get", "peak_m"]], " m"],
|
|
28904
|
-
"text-font": FONT,
|
|
28905
|
-
"text-size": ["interpolate", ["linear"], ["zoom"], 11.5, 8.5, 14, 11],
|
|
28906
|
-
"text-offset": anchorOffset(0.8),
|
|
28907
|
-
"text-anchor": ANCHOR,
|
|
28908
|
-
"text-padding": 5,
|
|
28909
|
-
"text-allow-overlap": false,
|
|
28910
|
-
"symbol-sort-key": 3
|
|
28911
|
-
},
|
|
28912
|
-
paint: { "text-color": T.label, "text-halo-color": T.halo, "text-halo-width": 1.2 }
|
|
28913
|
-
}));
|
|
28914
|
-
layers.push(L({
|
|
28915
|
-
id: "chrtland-poi",
|
|
28916
|
-
type: "symbol",
|
|
28917
|
-
source: src,
|
|
28918
|
-
"source-layer": "land_poi",
|
|
28919
|
-
minzoom: 13,
|
|
28920
|
-
filter: FITS,
|
|
28921
|
-
layout: {
|
|
28922
|
-
"text-field": ["get", "name"],
|
|
28923
|
-
"text-font": FONT_ITALIC,
|
|
28924
|
-
"text-size": ["interpolate", ["linear"], ["zoom"], 13, 8, 14, 9.5],
|
|
28925
|
-
"text-offset": anchorOffset(0.7),
|
|
28926
|
-
"text-anchor": ANCHOR,
|
|
28927
|
-
"text-padding": 5,
|
|
28928
|
-
"text-allow-overlap": false,
|
|
28929
|
-
"symbol-sort-key": 5
|
|
28930
|
-
},
|
|
28931
|
-
paint: { "text-color": T.label, "text-halo-color": T.halo, "text-halo-width": 1.2 }
|
|
28932
|
-
}));
|
|
28933
|
-
for (const layer of layers) {
|
|
28934
|
-
const l = layer;
|
|
28935
|
-
if (!LAND_SURFACE_LAYERS(l.id)) continue;
|
|
28936
|
-
l.minzoom = Math.max(l.minzoom ?? 0, LAND_SURFACE_MINZOOM);
|
|
28937
|
-
}
|
|
28938
|
-
return layers;
|
|
28939
|
-
}
|
|
28940
|
-
|
|
28941
|
-
// src/atlas/base-layers.ts
|
|
28942
|
-
var NOCOVERAGE_PATTERN = "chrt:hatch-nocoverage";
|
|
28943
|
-
var UNCHARTED_PATTERN = "chrt:hatch-uncharted";
|
|
28944
|
-
var BASE_THEMES = {
|
|
28945
|
-
DAY: {
|
|
28946
|
-
// ── `earth` is the jurisdiction tan DIMMED (~0.55), not a blue-grey ──
|
|
28947
|
-
// Outside the jurisdiction the map still owes the reader "what is land".
|
|
28948
|
-
// State 3 in the header is "the geography, under a crosshatch", and until
|
|
28949
|
-
// 2026-08-31 that geography was unreadable: earth #2A3439 against sea
|
|
28950
|
-
// #1B2328 measured 1.25:1, so Hispaniola showed charted boxes with tan
|
|
28951
|
-
// land inside and nothing recognisable around them (owner report: "no
|
|
28952
|
-
// land painting down near the DR at some zooms"). Land is warm and sea is
|
|
28953
|
-
// cool because that is what land and sea are; dimming the JURISDICTION
|
|
28954
|
-
// tan rather than inventing a colour says the true thing — this is the
|
|
28955
|
-
// same land, we simply do not carry charts for it. Held against BOTH
|
|
28956
|
-
// neighbours: legible over sea, and never mistakable for the full tan of
|
|
28957
|
-
// a country we do carry. DAY 3.59:1 vs sea, 3.17:1 vs tan.
|
|
28958
|
-
earth: "#807761",
|
|
28959
|
-
water: "#1B2328",
|
|
28960
|
-
river: "#24313A",
|
|
28961
|
-
boundary: "#4A575E",
|
|
28962
|
-
jurisdiction: "#E8D9B0",
|
|
28963
|
-
// CHRTland's own tan — one land colour
|
|
28964
|
-
inlandWater: "#B9CFDD",
|
|
28965
|
-
// muted, unmistakably not a charted blue
|
|
28966
|
-
// State furniture. These three were referenced by the layers but missing
|
|
28967
|
-
// from this table (and its type — the long-standing TS2339 trio), so the
|
|
28968
|
-
// lines shipped on MapLibre's DEFAULT black. Now deliberate: a hairline
|
|
28969
|
-
// a shade deeper than the tan, quiet caps, tan halo.
|
|
28970
|
-
stateLine: "#C4B389",
|
|
28971
|
-
stateLabel: "#8E8468",
|
|
28972
|
-
stateHalo: "#E8D9B0",
|
|
28973
|
-
// Rough-lake furniture (owner ask 2026-08-28: "the lakes need labels,
|
|
28974
|
-
// and shorelines drawn"): a shoreline a shade deeper than the rough
|
|
28975
|
-
// water, and a name in the water's own voice, haloed by the water.
|
|
28976
|
-
inlandShore: "#8FA9BA",
|
|
28977
|
-
inlandLabel: "#54707F",
|
|
28978
|
-
inlandHalo: "#B9CFDD"
|
|
28979
|
-
},
|
|
28980
|
-
DUSK: {
|
|
28981
|
-
// ── Re-derived 2026-09-01: the basemap sits UNDER the chart ──────────
|
|
28982
|
-
// These were the DAY tones scaled by a constant, never measured against
|
|
28983
|
-
// the DUSK chart — so `jurisdiction` came out at L=0.506 against a chart
|
|
28984
|
-
// whose own land (LANDA #8a7d5e) is L=0.209, i.e. the context layer was
|
|
28985
|
-
// 2.4x brighter than the data layer. Now capped at the chart's own land.
|
|
28986
|
-
// The rest of the block rides the same 0.666 channel factor so every
|
|
28987
|
-
// relationship the palette already chose is preserved, only moved down.
|
|
28988
|
-
// `water` is deliberately NOT scaled: it is the reference the land/sea
|
|
28989
|
-
// floor is measured against.
|
|
28990
|
-
earth: "#544E3E",
|
|
28991
|
-
water: "#161D21",
|
|
28992
|
-
river: "#141B20",
|
|
28993
|
-
boundary: "#293135",
|
|
28994
|
-
jurisdiction: "#867D64",
|
|
28995
|
-
inlandWater: "#62717A",
|
|
28996
|
-
// Label stays DARK here — the halo is still mid-toned, so 3:1 is reachable
|
|
28997
|
-
// downward and a bright label would be a new light source at dusk.
|
|
28998
|
-
stateLine: "#B5A987",
|
|
28999
|
-
stateLabel: "#38342A",
|
|
29000
|
-
stateHalo: "#867D64",
|
|
29001
|
-
inlandShore: "#4D5B67",
|
|
29002
|
-
inlandLabel: "#212629",
|
|
29003
|
-
inlandHalo: "#62717A"
|
|
29004
|
-
},
|
|
29005
|
-
NIGHT: {
|
|
29006
|
-
// ── Re-derived 2026-09-01 — the owner-reported night defect ──────────
|
|
29007
|
-
// `jurisdiction` was L=0.240 against a chart whose own land (LANDA
|
|
29008
|
-
// #3a3020) is L=0.031: the world basemap was 7.7x BRIGHTER than the chart
|
|
29009
|
-
// it sits under, so at z<11 the uncharted interior read as a pale
|
|
29010
|
-
// continent-sized slab on a night chart. Capped at the chart's own land.
|
|
29011
|
-
//
|
|
29012
|
-
// ⚠ `earth` AND `jurisdiction` CONVERGE HERE, and that is forced, not
|
|
29013
|
-
// sloppy. Holding earth 2:1 above the ocean AND 2:1 below the jurisdiction
|
|
29014
|
-
// tan requires jurisdiction >= L 0.174 — 5.6x the chart's own land. At
|
|
29015
|
-
// night the range between the ocean (L 0.006) and the cap (L 0.031) is too
|
|
29016
|
-
// compressed to carry two land tones. COVERAGE IS STILL SAID, by the
|
|
29017
|
-
// `chrt:hatch-nocoverage` crosshatch, which is a stronger signal than tone
|
|
29018
|
-
// and is the one thing that cannot be lost to palette compression.
|
|
29019
|
-
//
|
|
29020
|
-
// Labels invert to light-on-dark: 3:1 downward is unreachable off a halo
|
|
29021
|
-
// this close to black, and CHRTland's own night town labels already sit at
|
|
29022
|
-
// L=0.177 for exactly this reason.
|
|
29023
|
-
earth: "#333026",
|
|
29024
|
-
water: "#10161A",
|
|
29025
|
-
river: "#090D0F",
|
|
29026
|
-
boundary: "#131719",
|
|
29027
|
-
jurisdiction: "#353128",
|
|
29028
|
-
inlandWater: "#232A30",
|
|
29029
|
-
stateLine: "#484236",
|
|
29030
|
-
stateLabel: "#837963",
|
|
29031
|
-
stateHalo: "#353128",
|
|
29032
|
-
inlandShore: "#1C2227",
|
|
29033
|
-
inlandLabel: "#617484",
|
|
29034
|
-
inlandHalo: "#232A30"
|
|
29035
|
-
}
|
|
29036
|
-
};
|
|
29037
|
-
function baseLayers(opts = {}) {
|
|
29038
|
-
const palette = opts.palette ?? "DAY";
|
|
29039
|
-
const T = BASE_THEMES[palette] ?? BASE_THEMES.DAY;
|
|
29040
|
-
const src = opts.sourceId ?? BASE_REGION;
|
|
29041
|
-
const L = (o) => o;
|
|
29042
|
-
return [
|
|
29043
|
-
// 1. Geography — the world as it is, in the quiet dark voice. The OCEAN
|
|
29044
|
-
// is a background, not a polygon: the archive ships land and lakes,
|
|
29045
|
-
// and "everything else is sea" is exactly what a background expresses
|
|
29046
|
-
// — geometry-free, gap-free at every antimeridian and pole. Without
|
|
29047
|
-
// it the sea outside coverage was bare S-52 NODTA, a light grey that
|
|
29048
|
-
// read as "charted ground" with a hatch on it.
|
|
29049
|
-
L({
|
|
29050
|
-
id: "chrtbase-ocean",
|
|
29051
|
-
type: "background",
|
|
29052
|
-
paint: { "background-color": T.water }
|
|
29053
|
-
}),
|
|
29054
|
-
L({
|
|
29055
|
-
id: "chrtbase-earth",
|
|
29056
|
-
type: "fill",
|
|
29057
|
-
source: src,
|
|
29058
|
-
"source-layer": "base_earth",
|
|
29059
|
-
paint: { "fill-color": T.earth }
|
|
29060
|
-
}),
|
|
29061
|
-
L({
|
|
29062
|
-
id: "chrtbase-water",
|
|
29063
|
-
type: "fill",
|
|
29064
|
-
source: src,
|
|
29065
|
-
"source-layer": "base_water",
|
|
29066
|
-
paint: { "fill-color": T.water }
|
|
29067
|
-
}),
|
|
29068
|
-
L({
|
|
29069
|
-
id: "chrtbase-river",
|
|
29070
|
-
type: "line",
|
|
29071
|
-
source: src,
|
|
29072
|
-
"source-layer": "base_river",
|
|
29073
|
-
minzoom: 9,
|
|
29074
|
-
paint: {
|
|
29075
|
-
"line-color": T.river,
|
|
29076
|
-
"line-width": ["interpolate", ["linear"], ["zoom"], 9, 0.6, 14, 1.6]
|
|
29077
|
-
}
|
|
29078
|
-
}),
|
|
29079
|
-
L({
|
|
29080
|
-
id: "chrtbase-boundary",
|
|
28761
|
+
}),
|
|
28762
|
+
L({
|
|
28763
|
+
id: "chrtbase-boundary",
|
|
29081
28764
|
type: "line",
|
|
29082
28765
|
source: src,
|
|
29083
28766
|
"source-layer": "base_boundary",
|
|
@@ -29344,32 +29027,360 @@ function baseInlandWaterLayers(opts = {}) {
|
|
|
29344
29027
|
}
|
|
29345
29028
|
}),
|
|
29346
29029
|
L({
|
|
29347
|
-
id: "chrtbase-inland-label",
|
|
29348
|
-
type: "symbol",
|
|
29030
|
+
id: "chrtbase-inland-label",
|
|
29031
|
+
type: "symbol",
|
|
29032
|
+
source: src,
|
|
29033
|
+
"source-layer": "inland_water_label",
|
|
29034
|
+
minzoom: 5,
|
|
29035
|
+
layout: {
|
|
29036
|
+
"text-field": ["get", "name"],
|
|
29037
|
+
"text-font": ["Open Sans Regular"],
|
|
29038
|
+
"text-size": ["interpolate", ["linear"], ["zoom"], 5, 9.5, 10, 12],
|
|
29039
|
+
"text-max-width": 7,
|
|
29040
|
+
"text-allow-overlap": false,
|
|
29041
|
+
// Zoom-scaled spacing for the anchor GRID: at z8.9 the 0.08-deg
|
|
29042
|
+
// anchors sit ~54 px apart and a flat padding let six copies of
|
|
29043
|
+
// "Lake Ontario" crowd one screen (owner-reported 2026-08-30).
|
|
29044
|
+
// Wide collision boxes at low zoom thin the grid to the repeat-
|
|
29045
|
+
// by-convention cadence; by z12 the anchors are ~850 px apart and
|
|
29046
|
+
// the padding relaxes to normal.
|
|
29047
|
+
"text-padding": ["interpolate", ["linear"], ["zoom"], 5, 80, 9, 64, 12, 16]
|
|
29048
|
+
},
|
|
29049
|
+
paint: {
|
|
29050
|
+
"text-color": T.inlandLabel,
|
|
29051
|
+
"text-halo-color": T.inlandHalo,
|
|
29052
|
+
"text-halo-width": 1.1
|
|
29053
|
+
}
|
|
29054
|
+
})
|
|
29055
|
+
];
|
|
29056
|
+
}
|
|
29057
|
+
|
|
29058
|
+
// src/atlas/land-layers.ts
|
|
29059
|
+
var LAND_SURFACE_MINZOOM = BAND_PRIORITY_RANGES["5"].minzoom;
|
|
29060
|
+
var LAND_SURFACE_LAYERS = (id) => id === "chrtland-base" || id === "chrtland-cover" || id === "chrtland-contour" || id === "chrtland-hillshade" || id === "chrtland-water" || id.startsWith("chrtland-fade-");
|
|
29061
|
+
var isLandOverlay = (id) => id.startsWith("chrtland-") && id !== "chrtland-base";
|
|
29062
|
+
var FADE_PX = 80;
|
|
29063
|
+
var FADE_BANDS = 16;
|
|
29064
|
+
function fadeAlpha(r) {
|
|
29065
|
+
return Math.max(0, Math.min(1, (FADE_PX / 2 - Math.abs(r)) / FADE_PX));
|
|
29066
|
+
}
|
|
29067
|
+
function landBaseColor(palette) {
|
|
29068
|
+
return (LAND_THEMES[palette] ?? LAND_THEMES.DAY).base;
|
|
29069
|
+
}
|
|
29070
|
+
var LAND_THEMES = {
|
|
29071
|
+
DAY: {
|
|
29072
|
+
base: "#d4c69d",
|
|
29073
|
+
cover: { wood: "#bcc5a1", wetland: "#b6c0b1", urban: "#cac6bf", sand: "#dbd0af" },
|
|
29074
|
+
contour: "#958666",
|
|
29075
|
+
contourIndex: "#78694b",
|
|
29076
|
+
road: "#c5b691",
|
|
29077
|
+
roadMajor: "#beaa7c",
|
|
29078
|
+
label: "#5b4f3a",
|
|
29079
|
+
halo: "#ded6c3",
|
|
29080
|
+
shadow: "#6b5a3e",
|
|
29081
|
+
highlight: "#fffaf0",
|
|
29082
|
+
fade: "#e8f2f8",
|
|
29083
|
+
// Raised from 0.45 on 2026-08-23. ⚠ Above the ~0.5 that
|
|
29084
|
+
// hillshade-style.mjs warns "starts competing with depth areas" — a
|
|
29085
|
+
// deliberate, sighted choice made against rendered evidence, not a
|
|
29086
|
+
// default. If soundings or DEPARE ever read as fighting the terrain,
|
|
29087
|
+
// this number is the first thing to walk back.
|
|
29088
|
+
exaggeration: 0.8
|
|
29089
|
+
},
|
|
29090
|
+
DUSK: {
|
|
29091
|
+
base: "#4a4433",
|
|
29092
|
+
cover: { wood: "#414a38", wetland: "#3f4740", urban: "#4e4a42", sand: "#544c39" },
|
|
29093
|
+
contour: "#6b6250",
|
|
29094
|
+
contourIndex: "#837961",
|
|
29095
|
+
road: "#565040",
|
|
29096
|
+
roadMajor: "#63594440",
|
|
29097
|
+
label: "#c3b898",
|
|
29098
|
+
halo: "#2b2820",
|
|
29099
|
+
shadow: "#2e2a20",
|
|
29100
|
+
highlight: "#8a8068",
|
|
29101
|
+
fade: "#16202a",
|
|
29102
|
+
// Unchanged. DUSK was not the palette the 0.8 decision was made against.
|
|
29103
|
+
exaggeration: 0.45
|
|
29104
|
+
},
|
|
29105
|
+
NIGHT: {
|
|
29106
|
+
base: "#2a2620",
|
|
29107
|
+
cover: { wood: "#242a20", wetland: "#232823", urban: "#2c2925", sand: "#302b22" },
|
|
29108
|
+
contour: "#413b30",
|
|
29109
|
+
contourIndex: "#524a3b",
|
|
29110
|
+
road: "#332f27",
|
|
29111
|
+
roadMajor: "#3d382d",
|
|
29112
|
+
label: "#7d745e",
|
|
29113
|
+
halo: "#15130f",
|
|
29114
|
+
shadow: "#1a1712",
|
|
29115
|
+
highlight: "#4a4436",
|
|
29116
|
+
fade: "#07090b",
|
|
29117
|
+
// ⚠ DELIBERATELY NOT RAISED. See the type's note: a strong hillshade
|
|
29118
|
+
// under red night vision is a grey haze over exactly the contrast a
|
|
29119
|
+
// skipper is navigating by. Left at the shipped value rather than
|
|
29120
|
+
// lowered, because lowering it is a separate decision from this one.
|
|
29121
|
+
exaggeration: 0.45
|
|
29122
|
+
}
|
|
29123
|
+
};
|
|
29124
|
+
var FITS = ["<=", ["coalesce", ["get", "min_z"], 0], ["zoom"]];
|
|
29125
|
+
var ANCHOR = ["coalesce", ["get", "anchor"], "top"];
|
|
29126
|
+
var anchorOffset = (em) => [
|
|
29127
|
+
"match",
|
|
29128
|
+
["get", "anchor"],
|
|
29129
|
+
"left",
|
|
29130
|
+
["literal", [0.6, 0]],
|
|
29131
|
+
"right",
|
|
29132
|
+
["literal", [-0.6, 0]],
|
|
29133
|
+
"bottom",
|
|
29134
|
+
["literal", [0, -em]],
|
|
29135
|
+
["literal", [0, em]]
|
|
29136
|
+
];
|
|
29137
|
+
var FONT = ["Open Sans Regular"];
|
|
29138
|
+
var FONT_ITALIC = ["Open Sans Italic"];
|
|
29139
|
+
function landLayers(opts = {}) {
|
|
29140
|
+
const palette = opts.palette ?? "DAY";
|
|
29141
|
+
const T = LAND_THEMES[palette] ?? LAND_THEMES.DAY;
|
|
29142
|
+
const src = opts.sourceId ?? LAND_REGION;
|
|
29143
|
+
const demSrc = opts.reliefSourceId ?? RELIEF_REGION;
|
|
29144
|
+
const L = (o) => o;
|
|
29145
|
+
const layers = [
|
|
29146
|
+
// 1. The land itself — LNDARE ∩ coverage, so it can never outrun the chart.
|
|
29147
|
+
L({
|
|
29148
|
+
id: "chrtland-base",
|
|
29149
|
+
type: "fill",
|
|
29349
29150
|
source: src,
|
|
29350
|
-
"source-layer": "
|
|
29351
|
-
|
|
29352
|
-
|
|
29353
|
-
|
|
29354
|
-
|
|
29355
|
-
|
|
29356
|
-
|
|
29357
|
-
|
|
29358
|
-
|
|
29359
|
-
|
|
29360
|
-
|
|
29361
|
-
|
|
29362
|
-
|
|
29363
|
-
|
|
29364
|
-
"
|
|
29365
|
-
|
|
29151
|
+
"source-layer": "land_base",
|
|
29152
|
+
paint: { "fill-color": T.base }
|
|
29153
|
+
})
|
|
29154
|
+
];
|
|
29155
|
+
layers.push(L({
|
|
29156
|
+
id: "chrtland-cover",
|
|
29157
|
+
type: "fill",
|
|
29158
|
+
source: src,
|
|
29159
|
+
"source-layer": "land_cover",
|
|
29160
|
+
filter: ["<=", ["coalesce", ["get", "min_z"], 0], ["zoom"]],
|
|
29161
|
+
paint: {
|
|
29162
|
+
"fill-color": [
|
|
29163
|
+
"match",
|
|
29164
|
+
["get", "class"],
|
|
29165
|
+
"wood",
|
|
29166
|
+
T.cover.wood,
|
|
29167
|
+
"wetland",
|
|
29168
|
+
T.cover.wetland,
|
|
29169
|
+
"urban",
|
|
29170
|
+
T.cover.urban,
|
|
29171
|
+
"sand",
|
|
29172
|
+
T.cover.sand,
|
|
29173
|
+
T.base
|
|
29174
|
+
],
|
|
29175
|
+
"fill-opacity": 0.85
|
|
29176
|
+
}
|
|
29177
|
+
}));
|
|
29178
|
+
if (opts.relief) {
|
|
29179
|
+
layers.push(L({
|
|
29180
|
+
// No minzoom here: LAND_SURFACE_LAYERS floors it with the rest of the
|
|
29181
|
+
// surface, so the two can never drift apart again.
|
|
29182
|
+
id: "chrtland-hillshade",
|
|
29183
|
+
type: "hillshade",
|
|
29184
|
+
source: demSrc,
|
|
29366
29185
|
paint: {
|
|
29367
|
-
"
|
|
29368
|
-
"
|
|
29369
|
-
"
|
|
29186
|
+
"hillshade-exaggeration": T.exaggeration,
|
|
29187
|
+
"hillshade-shadow-color": T.shadow,
|
|
29188
|
+
"hillshade-highlight-color": T.highlight,
|
|
29189
|
+
"hillshade-accent-color": T.shadow
|
|
29370
29190
|
}
|
|
29371
|
-
})
|
|
29191
|
+
}));
|
|
29192
|
+
}
|
|
29193
|
+
const isIndexContour = [
|
|
29194
|
+
"any",
|
|
29195
|
+
["<=", ["coalesce", ["get", "index_z"], 99], ["zoom"]],
|
|
29196
|
+
["==", ["get", "is_index"], 1]
|
|
29372
29197
|
];
|
|
29198
|
+
layers.push(L({
|
|
29199
|
+
id: "chrtland-contour",
|
|
29200
|
+
type: "line",
|
|
29201
|
+
source: src,
|
|
29202
|
+
"source-layer": "land_contour",
|
|
29203
|
+
filter: ["<=", ["coalesce", ["get", "min_z"], 0], ["zoom"]],
|
|
29204
|
+
paint: {
|
|
29205
|
+
"line-color": ["case", isIndexContour, T.contourIndex, T.contour],
|
|
29206
|
+
"line-width": ["case", isIndexContour, 0.8, 0.4],
|
|
29207
|
+
"line-opacity": 0.7
|
|
29208
|
+
}
|
|
29209
|
+
}));
|
|
29210
|
+
layers.push(L({
|
|
29211
|
+
id: "chrtland-water",
|
|
29212
|
+
type: "fill",
|
|
29213
|
+
source: src,
|
|
29214
|
+
"source-layer": "land_water",
|
|
29215
|
+
filter: ["<=", ["coalesce", ["get", "min_z"], 0], ["zoom"]],
|
|
29216
|
+
paint: { "fill-color": inlandWaterColor(palette) }
|
|
29217
|
+
}));
|
|
29218
|
+
const d = FADE_PX / 2 / FADE_BANDS;
|
|
29219
|
+
for (let k = 0; k < FADE_BANDS; k++) {
|
|
29220
|
+
const width = k === 0 ? { "line-width": 2 * d } : { "line-width": d, "line-gap-width": 2 * k * d };
|
|
29221
|
+
layers.push(L({
|
|
29222
|
+
id: `chrtland-fade-${k}`,
|
|
29223
|
+
type: "line",
|
|
29224
|
+
source: src,
|
|
29225
|
+
"source-layer": "land_edge",
|
|
29226
|
+
layout: { "line-join": "bevel" },
|
|
29227
|
+
paint: { "line-color": T.fade, "line-blur": 0, "line-opacity": fadeAlpha(k * d + d / 2), ...width }
|
|
29228
|
+
}));
|
|
29229
|
+
}
|
|
29230
|
+
layers.push(L({
|
|
29231
|
+
id: "chrtland-road",
|
|
29232
|
+
type: "line",
|
|
29233
|
+
source: src,
|
|
29234
|
+
"source-layer": "land_road",
|
|
29235
|
+
minzoom: 10,
|
|
29236
|
+
paint: {
|
|
29237
|
+
"line-color": ["match", ["get", "kind"], "highway", T.roadMajor, T.road],
|
|
29238
|
+
"line-width": [
|
|
29239
|
+
"interpolate",
|
|
29240
|
+
["linear"],
|
|
29241
|
+
["zoom"],
|
|
29242
|
+
10,
|
|
29243
|
+
["match", ["get", "kind"], "highway", 0.8, 0.4],
|
|
29244
|
+
14,
|
|
29245
|
+
["match", ["get", "kind"], "highway", 2.4, 1.2]
|
|
29246
|
+
],
|
|
29247
|
+
"line-opacity": 0.8
|
|
29248
|
+
}
|
|
29249
|
+
}));
|
|
29250
|
+
layers.push(L({
|
|
29251
|
+
id: "chrtland-city-major",
|
|
29252
|
+
type: "symbol",
|
|
29253
|
+
source: src,
|
|
29254
|
+
"source-layer": "land_town",
|
|
29255
|
+
minzoom: 6.5,
|
|
29256
|
+
filter: [">=", ["coalesce", ["get", "prank"], 0], 10],
|
|
29257
|
+
layout: {
|
|
29258
|
+
"text-field": [
|
|
29259
|
+
"case",
|
|
29260
|
+
["==", ["get", "upcase"], true],
|
|
29261
|
+
["upcase", ["get", "name"]],
|
|
29262
|
+
["get", "name"]
|
|
29263
|
+
],
|
|
29264
|
+
"text-font": FONT,
|
|
29265
|
+
"text-size": [
|
|
29266
|
+
"interpolate",
|
|
29267
|
+
["linear"],
|
|
29268
|
+
["zoom"],
|
|
29269
|
+
6.5,
|
|
29270
|
+
11.5,
|
|
29271
|
+
9,
|
|
29272
|
+
["+", 10, ["*", 0.4, ["coalesce", ["get", "prank"], 10]]],
|
|
29273
|
+
13,
|
|
29274
|
+
["+", 13, ["*", 0.5, ["coalesce", ["get", "prank"], 10]]]
|
|
29275
|
+
],
|
|
29276
|
+
"text-letter-spacing": ["case", ["==", ["get", "upcase"], true], 0.14, 0.02],
|
|
29277
|
+
"text-offset": anchorOffset(0.75),
|
|
29278
|
+
"text-anchor": ANCHOR,
|
|
29279
|
+
"text-padding": 10,
|
|
29280
|
+
"text-allow-overlap": false,
|
|
29281
|
+
"symbol-sort-key": ["*", -1, ["coalesce", ["get", "pop"], 0]]
|
|
29282
|
+
},
|
|
29283
|
+
paint: { "text-color": T.label, "text-halo-color": T.halo, "text-halo-width": 1.6 }
|
|
29284
|
+
}));
|
|
29285
|
+
layers.push(L({
|
|
29286
|
+
id: "chrtland-town-port",
|
|
29287
|
+
type: "symbol",
|
|
29288
|
+
source: src,
|
|
29289
|
+
"source-layer": "land_town",
|
|
29290
|
+
minzoom: 8.5,
|
|
29291
|
+
filter: [
|
|
29292
|
+
"all",
|
|
29293
|
+
["==", ["get", "enc_dup"], true],
|
|
29294
|
+
["<", ["coalesce", ["get", "prank"], 0], 10]
|
|
29295
|
+
],
|
|
29296
|
+
layout: {
|
|
29297
|
+
"text-field": ["get", "name"],
|
|
29298
|
+
"text-font": FONT,
|
|
29299
|
+
"text-size": ["interpolate", ["linear"], ["zoom"], 8.5, 11, 12, 13.5],
|
|
29300
|
+
"text-offset": anchorOffset(0.75),
|
|
29301
|
+
"text-anchor": ANCHOR,
|
|
29302
|
+
"text-padding": 8,
|
|
29303
|
+
"text-allow-overlap": false,
|
|
29304
|
+
// Within the tier, the bigger place wins the space: without this the
|
|
29305
|
+
// tie broke on data order and "West Gloucester" beat Gloucester.
|
|
29306
|
+
"symbol-sort-key": ["*", -1, ["coalesce", ["get", "pop"], 0]]
|
|
29307
|
+
},
|
|
29308
|
+
paint: { "text-color": T.label, "text-halo-color": T.halo, "text-halo-width": 1.4 }
|
|
29309
|
+
}));
|
|
29310
|
+
layers.push(L({
|
|
29311
|
+
id: "chrtland-town",
|
|
29312
|
+
type: "symbol",
|
|
29313
|
+
source: src,
|
|
29314
|
+
"source-layer": "land_town",
|
|
29315
|
+
minzoom: 9,
|
|
29316
|
+
filter: [
|
|
29317
|
+
"all",
|
|
29318
|
+
FITS,
|
|
29319
|
+
["<", ["coalesce", ["get", "prank"], 0], 10],
|
|
29320
|
+
["!=", ["get", "enc_dup"], true]
|
|
29321
|
+
],
|
|
29322
|
+
layout: {
|
|
29323
|
+
"text-field": [
|
|
29324
|
+
"case",
|
|
29325
|
+
["==", ["get", "upcase"], true],
|
|
29326
|
+
["upcase", ["get", "name"]],
|
|
29327
|
+
["get", "name"]
|
|
29328
|
+
],
|
|
29329
|
+
"text-font": FONT,
|
|
29330
|
+
"text-size": ["interpolate", ["linear"], ["zoom"], 9, 10, 14, 13.5],
|
|
29331
|
+
"text-letter-spacing": ["case", ["==", ["get", "upcase"], true], 0.14, 0],
|
|
29332
|
+
"text-offset": anchorOffset(0.75),
|
|
29333
|
+
"text-anchor": ANCHOR,
|
|
29334
|
+
"text-padding": 6,
|
|
29335
|
+
"text-allow-overlap": false,
|
|
29336
|
+
"symbol-sort-key": 2
|
|
29337
|
+
},
|
|
29338
|
+
paint: { "text-color": T.label, "text-halo-color": T.halo, "text-halo-width": 1.2 }
|
|
29339
|
+
}));
|
|
29340
|
+
layers.push(L({
|
|
29341
|
+
id: "chrtland-summit",
|
|
29342
|
+
type: "symbol",
|
|
29343
|
+
source: src,
|
|
29344
|
+
"source-layer": "land_summit",
|
|
29345
|
+
minzoom: 11.5,
|
|
29346
|
+
filter: ["all", FITS, [">=", ["get", "peak_m"], 40]],
|
|
29347
|
+
layout: {
|
|
29348
|
+
"text-field": ["concat", ["get", "name"], "\n", ["to-string", ["get", "peak_m"]], " m"],
|
|
29349
|
+
"text-font": FONT,
|
|
29350
|
+
"text-size": ["interpolate", ["linear"], ["zoom"], 11.5, 8.5, 14, 11],
|
|
29351
|
+
"text-offset": anchorOffset(0.8),
|
|
29352
|
+
"text-anchor": ANCHOR,
|
|
29353
|
+
"text-padding": 5,
|
|
29354
|
+
"text-allow-overlap": false,
|
|
29355
|
+
"symbol-sort-key": 3
|
|
29356
|
+
},
|
|
29357
|
+
paint: { "text-color": T.label, "text-halo-color": T.halo, "text-halo-width": 1.2 }
|
|
29358
|
+
}));
|
|
29359
|
+
layers.push(L({
|
|
29360
|
+
id: "chrtland-poi",
|
|
29361
|
+
type: "symbol",
|
|
29362
|
+
source: src,
|
|
29363
|
+
"source-layer": "land_poi",
|
|
29364
|
+
minzoom: 13,
|
|
29365
|
+
filter: FITS,
|
|
29366
|
+
layout: {
|
|
29367
|
+
"text-field": ["get", "name"],
|
|
29368
|
+
"text-font": FONT_ITALIC,
|
|
29369
|
+
"text-size": ["interpolate", ["linear"], ["zoom"], 13, 8, 14, 9.5],
|
|
29370
|
+
"text-offset": anchorOffset(0.7),
|
|
29371
|
+
"text-anchor": ANCHOR,
|
|
29372
|
+
"text-padding": 5,
|
|
29373
|
+
"text-allow-overlap": false,
|
|
29374
|
+
"symbol-sort-key": 5
|
|
29375
|
+
},
|
|
29376
|
+
paint: { "text-color": T.label, "text-halo-color": T.halo, "text-halo-width": 1.2 }
|
|
29377
|
+
}));
|
|
29378
|
+
for (const layer of layers) {
|
|
29379
|
+
const l = layer;
|
|
29380
|
+
if (!LAND_SURFACE_LAYERS(l.id)) continue;
|
|
29381
|
+
l.minzoom = Math.max(l.minzoom ?? 0, LAND_SURFACE_MINZOOM);
|
|
29382
|
+
}
|
|
29383
|
+
return layers;
|
|
29373
29384
|
}
|
|
29374
29385
|
|
|
29375
29386
|
// src/atlas/band-collapse.ts
|
|
@@ -30089,7 +30100,7 @@ function generateStyle(palette = "DAY", opts = {}) {
|
|
|
30089
30100
|
const surface = [];
|
|
30090
30101
|
const kept = [];
|
|
30091
30102
|
assembled.forEach((l, i) => {
|
|
30092
|
-
if (i < lastRepaint &&
|
|
30103
|
+
if (i < lastRepaint && isLandOverlay(idOf(l))) surface.push(l);
|
|
30093
30104
|
else kept.push(l);
|
|
30094
30105
|
});
|
|
30095
30106
|
if (surface.length === 0) return assembled;
|