@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.cjs
CHANGED
|
@@ -28842,466 +28842,149 @@ function worldMinusBboxPolygon(bbox) {
|
|
|
28842
28842
|
};
|
|
28843
28843
|
}
|
|
28844
28844
|
|
|
28845
|
-
// src/atlas/
|
|
28846
|
-
var
|
|
28847
|
-
var
|
|
28848
|
-
|
|
28849
|
-
|
|
28850
|
-
var FADE_BANDS = 16;
|
|
28851
|
-
function fadeAlpha(r) {
|
|
28852
|
-
return Math.max(0, Math.min(1, (FADE_PX / 2 - Math.abs(r)) / FADE_PX));
|
|
28853
|
-
}
|
|
28854
|
-
function landBaseColor(palette) {
|
|
28855
|
-
return (LAND_THEMES[palette] ?? LAND_THEMES.DAY).base;
|
|
28845
|
+
// src/atlas/base-layers.ts
|
|
28846
|
+
var NOCOVERAGE_PATTERN = "chrt:hatch-nocoverage";
|
|
28847
|
+
var UNCHARTED_PATTERN = "chrt:hatch-uncharted";
|
|
28848
|
+
function inlandWaterColor(palette) {
|
|
28849
|
+
return (BASE_THEMES[palette] ?? BASE_THEMES.DAY).inlandWater;
|
|
28856
28850
|
}
|
|
28857
|
-
var
|
|
28851
|
+
var BASE_THEMES = {
|
|
28858
28852
|
DAY: {
|
|
28859
|
-
|
|
28860
|
-
|
|
28861
|
-
|
|
28862
|
-
|
|
28863
|
-
|
|
28864
|
-
|
|
28865
|
-
|
|
28866
|
-
|
|
28867
|
-
|
|
28868
|
-
|
|
28869
|
-
|
|
28870
|
-
//
|
|
28871
|
-
|
|
28872
|
-
|
|
28873
|
-
|
|
28874
|
-
|
|
28875
|
-
|
|
28853
|
+
// ── `earth` is the jurisdiction tan DIMMED (~0.55), not a blue-grey ──
|
|
28854
|
+
// Outside the jurisdiction the map still owes the reader "what is land".
|
|
28855
|
+
// State 3 in the header is "the geography, under a crosshatch", and until
|
|
28856
|
+
// 2026-08-31 that geography was unreadable: earth #2A3439 against sea
|
|
28857
|
+
// #1B2328 measured 1.25:1, so Hispaniola showed charted boxes with tan
|
|
28858
|
+
// land inside and nothing recognisable around them (owner report: "no
|
|
28859
|
+
// land painting down near the DR at some zooms"). Land is warm and sea is
|
|
28860
|
+
// cool because that is what land and sea are; dimming the JURISDICTION
|
|
28861
|
+
// tan rather than inventing a colour says the true thing — this is the
|
|
28862
|
+
// same land, we simply do not carry charts for it. Held against BOTH
|
|
28863
|
+
// neighbours: legible over sea, and never mistakable for the full tan of
|
|
28864
|
+
// a country we do carry. DAY 3.59:1 vs sea, 3.17:1 vs tan.
|
|
28865
|
+
earth: "#807761",
|
|
28866
|
+
water: "#1B2328",
|
|
28867
|
+
river: "#24313A",
|
|
28868
|
+
boundary: "#4A575E",
|
|
28869
|
+
jurisdiction: "#D4C69D",
|
|
28870
|
+
// CHRTland's own tan — one land colour
|
|
28871
|
+
inlandWater: "#B9CFDD",
|
|
28872
|
+
// muted, unmistakably not a charted blue
|
|
28873
|
+
// State furniture. These three were referenced by the layers but missing
|
|
28874
|
+
// from this table (and its type — the long-standing TS2339 trio), so the
|
|
28875
|
+
// lines shipped on MapLibre's DEFAULT black. Now deliberate: a hairline
|
|
28876
|
+
// a shade deeper than the tan, quiet caps, tan halo.
|
|
28877
|
+
stateLine: "#B1A077",
|
|
28878
|
+
stateLabel: "#8E8468",
|
|
28879
|
+
stateHalo: "#D4C69D",
|
|
28880
|
+
// Rough-lake furniture (owner ask 2026-08-28: "the lakes need labels,
|
|
28881
|
+
// and shorelines drawn"): a shoreline a shade deeper than the rough
|
|
28882
|
+
// water, and a name in the water's own voice, haloed by the water.
|
|
28883
|
+
inlandShore: "#8FA9BA",
|
|
28884
|
+
inlandLabel: "#54707F",
|
|
28885
|
+
inlandHalo: "#B9CFDD"
|
|
28876
28886
|
},
|
|
28877
28887
|
DUSK: {
|
|
28878
|
-
|
|
28879
|
-
|
|
28880
|
-
|
|
28881
|
-
|
|
28882
|
-
|
|
28883
|
-
|
|
28884
|
-
|
|
28885
|
-
|
|
28886
|
-
|
|
28887
|
-
|
|
28888
|
-
|
|
28889
|
-
|
|
28890
|
-
|
|
28888
|
+
// ── Re-derived 2026-09-01: the basemap sits UNDER the chart ──────────
|
|
28889
|
+
// These were the DAY tones scaled by a constant, never measured against
|
|
28890
|
+
// the DUSK chart — so `jurisdiction` came out at L=0.506 against a chart
|
|
28891
|
+
// whose own land (LANDA #8a7d5e) is L=0.209, i.e. the context layer was
|
|
28892
|
+
// 2.4x brighter than the data layer. Now capped at the chart's own land.
|
|
28893
|
+
// The rest of the block rides the same 0.666 channel factor so every
|
|
28894
|
+
// relationship the palette already chose is preserved, only moved down.
|
|
28895
|
+
// `water` is deliberately NOT scaled: it is the reference the land/sea
|
|
28896
|
+
// floor is measured against.
|
|
28897
|
+
earth: "#544E3E",
|
|
28898
|
+
water: "#161D21",
|
|
28899
|
+
river: "#141B20",
|
|
28900
|
+
boundary: "#293135",
|
|
28901
|
+
jurisdiction: "#867D64",
|
|
28902
|
+
inlandWater: "#62717A",
|
|
28903
|
+
// Label stays DARK here — the halo is still mid-toned, so 3:1 is reachable
|
|
28904
|
+
// downward and a bright label would be a new light source at dusk.
|
|
28905
|
+
stateLine: "#B5A987",
|
|
28906
|
+
stateLabel: "#38342A",
|
|
28907
|
+
stateHalo: "#867D64",
|
|
28908
|
+
inlandShore: "#4D5B67",
|
|
28909
|
+
inlandLabel: "#212629",
|
|
28910
|
+
inlandHalo: "#62717A"
|
|
28891
28911
|
},
|
|
28892
28912
|
NIGHT: {
|
|
28893
|
-
|
|
28894
|
-
|
|
28895
|
-
|
|
28896
|
-
|
|
28897
|
-
|
|
28898
|
-
|
|
28899
|
-
|
|
28900
|
-
|
|
28901
|
-
|
|
28902
|
-
|
|
28903
|
-
|
|
28904
|
-
//
|
|
28905
|
-
//
|
|
28906
|
-
//
|
|
28907
|
-
//
|
|
28908
|
-
|
|
28913
|
+
// ── Re-derived 2026-09-01 — the owner-reported night defect ──────────
|
|
28914
|
+
// `jurisdiction` was L=0.240 against a chart whose own land (LANDA
|
|
28915
|
+
// #3a3020) is L=0.031: the world basemap was 7.7x BRIGHTER than the chart
|
|
28916
|
+
// it sits under, so at z<11 the uncharted interior read as a pale
|
|
28917
|
+
// continent-sized slab on a night chart. Capped at the chart's own land.
|
|
28918
|
+
//
|
|
28919
|
+
// ⚠ `earth` AND `jurisdiction` CONVERGE HERE, and that is forced, not
|
|
28920
|
+
// sloppy. Holding earth 2:1 above the ocean AND 2:1 below the jurisdiction
|
|
28921
|
+
// tan requires jurisdiction >= L 0.174 — 5.6x the chart's own land. At
|
|
28922
|
+
// night the range between the ocean (L 0.006) and the cap (L 0.031) is too
|
|
28923
|
+
// compressed to carry two land tones. COVERAGE IS STILL SAID, by the
|
|
28924
|
+
// `chrt:hatch-nocoverage` crosshatch, which is a stronger signal than tone
|
|
28925
|
+
// and is the one thing that cannot be lost to palette compression.
|
|
28926
|
+
//
|
|
28927
|
+
// Labels invert to light-on-dark: 3:1 downward is unreachable off a halo
|
|
28928
|
+
// this close to black, and CHRTland's own night town labels already sit at
|
|
28929
|
+
// L=0.177 for exactly this reason.
|
|
28930
|
+
earth: "#333026",
|
|
28931
|
+
water: "#10161A",
|
|
28932
|
+
river: "#090D0F",
|
|
28933
|
+
boundary: "#131719",
|
|
28934
|
+
jurisdiction: "#353128",
|
|
28935
|
+
inlandWater: "#232A30",
|
|
28936
|
+
stateLine: "#484236",
|
|
28937
|
+
stateLabel: "#837963",
|
|
28938
|
+
stateHalo: "#353128",
|
|
28939
|
+
inlandShore: "#1C2227",
|
|
28940
|
+
inlandLabel: "#617484",
|
|
28941
|
+
inlandHalo: "#232A30"
|
|
28909
28942
|
}
|
|
28910
28943
|
};
|
|
28911
|
-
|
|
28912
|
-
var ANCHOR = ["coalesce", ["get", "anchor"], "top"];
|
|
28913
|
-
var anchorOffset = (em) => [
|
|
28914
|
-
"match",
|
|
28915
|
-
["get", "anchor"],
|
|
28916
|
-
"left",
|
|
28917
|
-
["literal", [0.6, 0]],
|
|
28918
|
-
"right",
|
|
28919
|
-
["literal", [-0.6, 0]],
|
|
28920
|
-
"bottom",
|
|
28921
|
-
["literal", [0, -em]],
|
|
28922
|
-
["literal", [0, em]]
|
|
28923
|
-
];
|
|
28924
|
-
var FONT = ["Open Sans Regular"];
|
|
28925
|
-
var FONT_ITALIC = ["Open Sans Italic"];
|
|
28926
|
-
function landLayers(opts = {}) {
|
|
28944
|
+
function baseLayers(opts = {}) {
|
|
28927
28945
|
const palette = opts.palette ?? "DAY";
|
|
28928
|
-
const T =
|
|
28929
|
-
const src = opts.sourceId ??
|
|
28930
|
-
const demSrc = opts.reliefSourceId ?? RELIEF_REGION;
|
|
28946
|
+
const T = BASE_THEMES[palette] ?? BASE_THEMES.DAY;
|
|
28947
|
+
const src = opts.sourceId ?? BASE_REGION;
|
|
28931
28948
|
const L = (o) => o;
|
|
28932
|
-
|
|
28933
|
-
// 1.
|
|
28949
|
+
return [
|
|
28950
|
+
// 1. Geography — the world as it is, in the quiet dark voice. The OCEAN
|
|
28951
|
+
// is a background, not a polygon: the archive ships land and lakes,
|
|
28952
|
+
// and "everything else is sea" is exactly what a background expresses
|
|
28953
|
+
// — geometry-free, gap-free at every antimeridian and pole. Without
|
|
28954
|
+
// it the sea outside coverage was bare S-52 NODTA, a light grey that
|
|
28955
|
+
// read as "charted ground" with a hatch on it.
|
|
28934
28956
|
L({
|
|
28935
|
-
id: "
|
|
28957
|
+
id: "chrtbase-ocean",
|
|
28958
|
+
type: "background",
|
|
28959
|
+
paint: { "background-color": T.water }
|
|
28960
|
+
}),
|
|
28961
|
+
L({
|
|
28962
|
+
id: "chrtbase-earth",
|
|
28936
28963
|
type: "fill",
|
|
28937
28964
|
source: src,
|
|
28938
|
-
"source-layer": "
|
|
28939
|
-
paint: { "fill-color": T.
|
|
28940
|
-
})
|
|
28941
|
-
|
|
28942
|
-
|
|
28943
|
-
|
|
28944
|
-
|
|
28945
|
-
|
|
28946
|
-
|
|
28947
|
-
|
|
28948
|
-
|
|
28949
|
-
"
|
|
28950
|
-
|
|
28951
|
-
|
|
28952
|
-
|
|
28953
|
-
|
|
28954
|
-
"wetland",
|
|
28955
|
-
T.cover.wetland,
|
|
28956
|
-
"urban",
|
|
28957
|
-
T.cover.urban,
|
|
28958
|
-
"sand",
|
|
28959
|
-
T.cover.sand,
|
|
28960
|
-
T.base
|
|
28961
|
-
],
|
|
28962
|
-
"fill-opacity": 0.85
|
|
28963
|
-
}
|
|
28964
|
-
}));
|
|
28965
|
-
if (opts.relief) {
|
|
28966
|
-
layers.push(L({
|
|
28967
|
-
// No minzoom here: LAND_SURFACE_LAYERS floors it with the rest of the
|
|
28968
|
-
// surface, so the two can never drift apart again.
|
|
28969
|
-
id: "chrtland-hillshade",
|
|
28970
|
-
type: "hillshade",
|
|
28971
|
-
source: demSrc,
|
|
28965
|
+
"source-layer": "base_earth",
|
|
28966
|
+
paint: { "fill-color": T.earth }
|
|
28967
|
+
}),
|
|
28968
|
+
L({
|
|
28969
|
+
id: "chrtbase-water",
|
|
28970
|
+
type: "fill",
|
|
28971
|
+
source: src,
|
|
28972
|
+
"source-layer": "base_water",
|
|
28973
|
+
paint: { "fill-color": T.water }
|
|
28974
|
+
}),
|
|
28975
|
+
L({
|
|
28976
|
+
id: "chrtbase-river",
|
|
28977
|
+
type: "line",
|
|
28978
|
+
source: src,
|
|
28979
|
+
"source-layer": "base_river",
|
|
28980
|
+
minzoom: 9,
|
|
28972
28981
|
paint: {
|
|
28973
|
-
"
|
|
28974
|
-
"
|
|
28975
|
-
"hillshade-highlight-color": T.highlight,
|
|
28976
|
-
"hillshade-accent-color": T.shadow
|
|
28982
|
+
"line-color": T.river,
|
|
28983
|
+
"line-width": ["interpolate", ["linear"], ["zoom"], 9, 0.6, 14, 1.6]
|
|
28977
28984
|
}
|
|
28978
|
-
})
|
|
28979
|
-
|
|
28980
|
-
|
|
28981
|
-
"any",
|
|
28982
|
-
["<=", ["coalesce", ["get", "index_z"], 99], ["zoom"]],
|
|
28983
|
-
["==", ["get", "is_index"], 1]
|
|
28984
|
-
];
|
|
28985
|
-
layers.push(L({
|
|
28986
|
-
id: "chrtland-contour",
|
|
28987
|
-
type: "line",
|
|
28988
|
-
source: src,
|
|
28989
|
-
"source-layer": "land_contour",
|
|
28990
|
-
filter: ["<=", ["coalesce", ["get", "min_z"], 0], ["zoom"]],
|
|
28991
|
-
paint: {
|
|
28992
|
-
"line-color": ["case", isIndexContour, T.contourIndex, T.contour],
|
|
28993
|
-
"line-width": ["case", isIndexContour, 0.8, 0.4],
|
|
28994
|
-
"line-opacity": 0.7
|
|
28995
|
-
}
|
|
28996
|
-
}));
|
|
28997
|
-
const d = FADE_PX / 2 / FADE_BANDS;
|
|
28998
|
-
for (let k = 0; k < FADE_BANDS; k++) {
|
|
28999
|
-
const width = k === 0 ? { "line-width": 2 * d } : { "line-width": d, "line-gap-width": 2 * k * d };
|
|
29000
|
-
layers.push(L({
|
|
29001
|
-
id: `chrtland-fade-${k}`,
|
|
29002
|
-
type: "line",
|
|
29003
|
-
source: src,
|
|
29004
|
-
"source-layer": "land_edge",
|
|
29005
|
-
layout: { "line-join": "bevel" },
|
|
29006
|
-
paint: { "line-color": T.fade, "line-blur": 0, "line-opacity": fadeAlpha(k * d + d / 2), ...width }
|
|
29007
|
-
}));
|
|
29008
|
-
}
|
|
29009
|
-
layers.push(L({
|
|
29010
|
-
id: "chrtland-road",
|
|
29011
|
-
type: "line",
|
|
29012
|
-
source: src,
|
|
29013
|
-
"source-layer": "land_road",
|
|
29014
|
-
minzoom: 10,
|
|
29015
|
-
paint: {
|
|
29016
|
-
"line-color": ["match", ["get", "kind"], "highway", T.roadMajor, T.road],
|
|
29017
|
-
"line-width": [
|
|
29018
|
-
"interpolate",
|
|
29019
|
-
["linear"],
|
|
29020
|
-
["zoom"],
|
|
29021
|
-
10,
|
|
29022
|
-
["match", ["get", "kind"], "highway", 0.8, 0.4],
|
|
29023
|
-
14,
|
|
29024
|
-
["match", ["get", "kind"], "highway", 2.4, 1.2]
|
|
29025
|
-
],
|
|
29026
|
-
"line-opacity": 0.8
|
|
29027
|
-
}
|
|
29028
|
-
}));
|
|
29029
|
-
layers.push(L({
|
|
29030
|
-
id: "chrtland-city-major",
|
|
29031
|
-
type: "symbol",
|
|
29032
|
-
source: src,
|
|
29033
|
-
"source-layer": "land_town",
|
|
29034
|
-
minzoom: 6.5,
|
|
29035
|
-
filter: [">=", ["coalesce", ["get", "prank"], 0], 10],
|
|
29036
|
-
layout: {
|
|
29037
|
-
"text-field": [
|
|
29038
|
-
"case",
|
|
29039
|
-
["==", ["get", "upcase"], true],
|
|
29040
|
-
["upcase", ["get", "name"]],
|
|
29041
|
-
["get", "name"]
|
|
29042
|
-
],
|
|
29043
|
-
"text-font": FONT,
|
|
29044
|
-
"text-size": [
|
|
29045
|
-
"interpolate",
|
|
29046
|
-
["linear"],
|
|
29047
|
-
["zoom"],
|
|
29048
|
-
6.5,
|
|
29049
|
-
11.5,
|
|
29050
|
-
9,
|
|
29051
|
-
["+", 10, ["*", 0.4, ["coalesce", ["get", "prank"], 10]]],
|
|
29052
|
-
13,
|
|
29053
|
-
["+", 13, ["*", 0.5, ["coalesce", ["get", "prank"], 10]]]
|
|
29054
|
-
],
|
|
29055
|
-
"text-letter-spacing": ["case", ["==", ["get", "upcase"], true], 0.14, 0.02],
|
|
29056
|
-
"text-offset": anchorOffset(0.75),
|
|
29057
|
-
"text-anchor": ANCHOR,
|
|
29058
|
-
"text-padding": 10,
|
|
29059
|
-
"text-allow-overlap": false,
|
|
29060
|
-
"symbol-sort-key": ["*", -1, ["coalesce", ["get", "pop"], 0]]
|
|
29061
|
-
},
|
|
29062
|
-
paint: { "text-color": T.label, "text-halo-color": T.halo, "text-halo-width": 1.6 }
|
|
29063
|
-
}));
|
|
29064
|
-
layers.push(L({
|
|
29065
|
-
id: "chrtland-town-port",
|
|
29066
|
-
type: "symbol",
|
|
29067
|
-
source: src,
|
|
29068
|
-
"source-layer": "land_town",
|
|
29069
|
-
minzoom: 8.5,
|
|
29070
|
-
filter: [
|
|
29071
|
-
"all",
|
|
29072
|
-
["==", ["get", "enc_dup"], true],
|
|
29073
|
-
["<", ["coalesce", ["get", "prank"], 0], 10]
|
|
29074
|
-
],
|
|
29075
|
-
layout: {
|
|
29076
|
-
"text-field": ["get", "name"],
|
|
29077
|
-
"text-font": FONT,
|
|
29078
|
-
"text-size": ["interpolate", ["linear"], ["zoom"], 8.5, 11, 12, 13.5],
|
|
29079
|
-
"text-offset": anchorOffset(0.75),
|
|
29080
|
-
"text-anchor": ANCHOR,
|
|
29081
|
-
"text-padding": 8,
|
|
29082
|
-
"text-allow-overlap": false,
|
|
29083
|
-
// Within the tier, the bigger place wins the space: without this the
|
|
29084
|
-
// tie broke on data order and "West Gloucester" beat Gloucester.
|
|
29085
|
-
"symbol-sort-key": ["*", -1, ["coalesce", ["get", "pop"], 0]]
|
|
29086
|
-
},
|
|
29087
|
-
paint: { "text-color": T.label, "text-halo-color": T.halo, "text-halo-width": 1.4 }
|
|
29088
|
-
}));
|
|
29089
|
-
layers.push(L({
|
|
29090
|
-
id: "chrtland-town",
|
|
29091
|
-
type: "symbol",
|
|
29092
|
-
source: src,
|
|
29093
|
-
"source-layer": "land_town",
|
|
29094
|
-
minzoom: 9,
|
|
29095
|
-
filter: [
|
|
29096
|
-
"all",
|
|
29097
|
-
FITS,
|
|
29098
|
-
["<", ["coalesce", ["get", "prank"], 0], 10],
|
|
29099
|
-
["!=", ["get", "enc_dup"], true]
|
|
29100
|
-
],
|
|
29101
|
-
layout: {
|
|
29102
|
-
"text-field": [
|
|
29103
|
-
"case",
|
|
29104
|
-
["==", ["get", "upcase"], true],
|
|
29105
|
-
["upcase", ["get", "name"]],
|
|
29106
|
-
["get", "name"]
|
|
29107
|
-
],
|
|
29108
|
-
"text-font": FONT,
|
|
29109
|
-
"text-size": ["interpolate", ["linear"], ["zoom"], 9, 10, 14, 13.5],
|
|
29110
|
-
"text-letter-spacing": ["case", ["==", ["get", "upcase"], true], 0.14, 0],
|
|
29111
|
-
"text-offset": anchorOffset(0.75),
|
|
29112
|
-
"text-anchor": ANCHOR,
|
|
29113
|
-
"text-padding": 6,
|
|
29114
|
-
"text-allow-overlap": false,
|
|
29115
|
-
"symbol-sort-key": 2
|
|
29116
|
-
},
|
|
29117
|
-
paint: { "text-color": T.label, "text-halo-color": T.halo, "text-halo-width": 1.2 }
|
|
29118
|
-
}));
|
|
29119
|
-
layers.push(L({
|
|
29120
|
-
id: "chrtland-summit",
|
|
29121
|
-
type: "symbol",
|
|
29122
|
-
source: src,
|
|
29123
|
-
"source-layer": "land_summit",
|
|
29124
|
-
minzoom: 11.5,
|
|
29125
|
-
filter: ["all", FITS, [">=", ["get", "peak_m"], 40]],
|
|
29126
|
-
layout: {
|
|
29127
|
-
"text-field": ["concat", ["get", "name"], "\n", ["to-string", ["get", "peak_m"]], " m"],
|
|
29128
|
-
"text-font": FONT,
|
|
29129
|
-
"text-size": ["interpolate", ["linear"], ["zoom"], 11.5, 8.5, 14, 11],
|
|
29130
|
-
"text-offset": anchorOffset(0.8),
|
|
29131
|
-
"text-anchor": ANCHOR,
|
|
29132
|
-
"text-padding": 5,
|
|
29133
|
-
"text-allow-overlap": false,
|
|
29134
|
-
"symbol-sort-key": 3
|
|
29135
|
-
},
|
|
29136
|
-
paint: { "text-color": T.label, "text-halo-color": T.halo, "text-halo-width": 1.2 }
|
|
29137
|
-
}));
|
|
29138
|
-
layers.push(L({
|
|
29139
|
-
id: "chrtland-poi",
|
|
29140
|
-
type: "symbol",
|
|
29141
|
-
source: src,
|
|
29142
|
-
"source-layer": "land_poi",
|
|
29143
|
-
minzoom: 13,
|
|
29144
|
-
filter: FITS,
|
|
29145
|
-
layout: {
|
|
29146
|
-
"text-field": ["get", "name"],
|
|
29147
|
-
"text-font": FONT_ITALIC,
|
|
29148
|
-
"text-size": ["interpolate", ["linear"], ["zoom"], 13, 8, 14, 9.5],
|
|
29149
|
-
"text-offset": anchorOffset(0.7),
|
|
29150
|
-
"text-anchor": ANCHOR,
|
|
29151
|
-
"text-padding": 5,
|
|
29152
|
-
"text-allow-overlap": false,
|
|
29153
|
-
"symbol-sort-key": 5
|
|
29154
|
-
},
|
|
29155
|
-
paint: { "text-color": T.label, "text-halo-color": T.halo, "text-halo-width": 1.2 }
|
|
29156
|
-
}));
|
|
29157
|
-
for (const layer of layers) {
|
|
29158
|
-
const l = layer;
|
|
29159
|
-
if (!LAND_SURFACE_LAYERS(l.id)) continue;
|
|
29160
|
-
l.minzoom = Math.max(l.minzoom ?? 0, LAND_SURFACE_MINZOOM);
|
|
29161
|
-
}
|
|
29162
|
-
return layers;
|
|
29163
|
-
}
|
|
29164
|
-
|
|
29165
|
-
// src/atlas/base-layers.ts
|
|
29166
|
-
var NOCOVERAGE_PATTERN = "chrt:hatch-nocoverage";
|
|
29167
|
-
var UNCHARTED_PATTERN = "chrt:hatch-uncharted";
|
|
29168
|
-
var BASE_THEMES = {
|
|
29169
|
-
DAY: {
|
|
29170
|
-
// ── `earth` is the jurisdiction tan DIMMED (~0.55), not a blue-grey ──
|
|
29171
|
-
// Outside the jurisdiction the map still owes the reader "what is land".
|
|
29172
|
-
// State 3 in the header is "the geography, under a crosshatch", and until
|
|
29173
|
-
// 2026-08-31 that geography was unreadable: earth #2A3439 against sea
|
|
29174
|
-
// #1B2328 measured 1.25:1, so Hispaniola showed charted boxes with tan
|
|
29175
|
-
// land inside and nothing recognisable around them (owner report: "no
|
|
29176
|
-
// land painting down near the DR at some zooms"). Land is warm and sea is
|
|
29177
|
-
// cool because that is what land and sea are; dimming the JURISDICTION
|
|
29178
|
-
// tan rather than inventing a colour says the true thing — this is the
|
|
29179
|
-
// same land, we simply do not carry charts for it. Held against BOTH
|
|
29180
|
-
// neighbours: legible over sea, and never mistakable for the full tan of
|
|
29181
|
-
// a country we do carry. DAY 3.59:1 vs sea, 3.17:1 vs tan.
|
|
29182
|
-
earth: "#807761",
|
|
29183
|
-
water: "#1B2328",
|
|
29184
|
-
river: "#24313A",
|
|
29185
|
-
boundary: "#4A575E",
|
|
29186
|
-
jurisdiction: "#E8D9B0",
|
|
29187
|
-
// CHRTland's own tan — one land colour
|
|
29188
|
-
inlandWater: "#B9CFDD",
|
|
29189
|
-
// muted, unmistakably not a charted blue
|
|
29190
|
-
// State furniture. These three were referenced by the layers but missing
|
|
29191
|
-
// from this table (and its type — the long-standing TS2339 trio), so the
|
|
29192
|
-
// lines shipped on MapLibre's DEFAULT black. Now deliberate: a hairline
|
|
29193
|
-
// a shade deeper than the tan, quiet caps, tan halo.
|
|
29194
|
-
stateLine: "#C4B389",
|
|
29195
|
-
stateLabel: "#8E8468",
|
|
29196
|
-
stateHalo: "#E8D9B0",
|
|
29197
|
-
// Rough-lake furniture (owner ask 2026-08-28: "the lakes need labels,
|
|
29198
|
-
// and shorelines drawn"): a shoreline a shade deeper than the rough
|
|
29199
|
-
// water, and a name in the water's own voice, haloed by the water.
|
|
29200
|
-
inlandShore: "#8FA9BA",
|
|
29201
|
-
inlandLabel: "#54707F",
|
|
29202
|
-
inlandHalo: "#B9CFDD"
|
|
29203
|
-
},
|
|
29204
|
-
DUSK: {
|
|
29205
|
-
// ── Re-derived 2026-09-01: the basemap sits UNDER the chart ──────────
|
|
29206
|
-
// These were the DAY tones scaled by a constant, never measured against
|
|
29207
|
-
// the DUSK chart — so `jurisdiction` came out at L=0.506 against a chart
|
|
29208
|
-
// whose own land (LANDA #8a7d5e) is L=0.209, i.e. the context layer was
|
|
29209
|
-
// 2.4x brighter than the data layer. Now capped at the chart's own land.
|
|
29210
|
-
// The rest of the block rides the same 0.666 channel factor so every
|
|
29211
|
-
// relationship the palette already chose is preserved, only moved down.
|
|
29212
|
-
// `water` is deliberately NOT scaled: it is the reference the land/sea
|
|
29213
|
-
// floor is measured against.
|
|
29214
|
-
earth: "#544E3E",
|
|
29215
|
-
water: "#161D21",
|
|
29216
|
-
river: "#141B20",
|
|
29217
|
-
boundary: "#293135",
|
|
29218
|
-
jurisdiction: "#867D64",
|
|
29219
|
-
inlandWater: "#62717A",
|
|
29220
|
-
// Label stays DARK here — the halo is still mid-toned, so 3:1 is reachable
|
|
29221
|
-
// downward and a bright label would be a new light source at dusk.
|
|
29222
|
-
stateLine: "#B5A987",
|
|
29223
|
-
stateLabel: "#38342A",
|
|
29224
|
-
stateHalo: "#867D64",
|
|
29225
|
-
inlandShore: "#4D5B67",
|
|
29226
|
-
inlandLabel: "#212629",
|
|
29227
|
-
inlandHalo: "#62717A"
|
|
29228
|
-
},
|
|
29229
|
-
NIGHT: {
|
|
29230
|
-
// ── Re-derived 2026-09-01 — the owner-reported night defect ──────────
|
|
29231
|
-
// `jurisdiction` was L=0.240 against a chart whose own land (LANDA
|
|
29232
|
-
// #3a3020) is L=0.031: the world basemap was 7.7x BRIGHTER than the chart
|
|
29233
|
-
// it sits under, so at z<11 the uncharted interior read as a pale
|
|
29234
|
-
// continent-sized slab on a night chart. Capped at the chart's own land.
|
|
29235
|
-
//
|
|
29236
|
-
// ⚠ `earth` AND `jurisdiction` CONVERGE HERE, and that is forced, not
|
|
29237
|
-
// sloppy. Holding earth 2:1 above the ocean AND 2:1 below the jurisdiction
|
|
29238
|
-
// tan requires jurisdiction >= L 0.174 — 5.6x the chart's own land. At
|
|
29239
|
-
// night the range between the ocean (L 0.006) and the cap (L 0.031) is too
|
|
29240
|
-
// compressed to carry two land tones. COVERAGE IS STILL SAID, by the
|
|
29241
|
-
// `chrt:hatch-nocoverage` crosshatch, which is a stronger signal than tone
|
|
29242
|
-
// and is the one thing that cannot be lost to palette compression.
|
|
29243
|
-
//
|
|
29244
|
-
// Labels invert to light-on-dark: 3:1 downward is unreachable off a halo
|
|
29245
|
-
// this close to black, and CHRTland's own night town labels already sit at
|
|
29246
|
-
// L=0.177 for exactly this reason.
|
|
29247
|
-
earth: "#333026",
|
|
29248
|
-
water: "#10161A",
|
|
29249
|
-
river: "#090D0F",
|
|
29250
|
-
boundary: "#131719",
|
|
29251
|
-
jurisdiction: "#353128",
|
|
29252
|
-
inlandWater: "#232A30",
|
|
29253
|
-
stateLine: "#484236",
|
|
29254
|
-
stateLabel: "#837963",
|
|
29255
|
-
stateHalo: "#353128",
|
|
29256
|
-
inlandShore: "#1C2227",
|
|
29257
|
-
inlandLabel: "#617484",
|
|
29258
|
-
inlandHalo: "#232A30"
|
|
29259
|
-
}
|
|
29260
|
-
};
|
|
29261
|
-
function baseLayers(opts = {}) {
|
|
29262
|
-
const palette = opts.palette ?? "DAY";
|
|
29263
|
-
const T = BASE_THEMES[palette] ?? BASE_THEMES.DAY;
|
|
29264
|
-
const src = opts.sourceId ?? BASE_REGION;
|
|
29265
|
-
const L = (o) => o;
|
|
29266
|
-
return [
|
|
29267
|
-
// 1. Geography — the world as it is, in the quiet dark voice. The OCEAN
|
|
29268
|
-
// is a background, not a polygon: the archive ships land and lakes,
|
|
29269
|
-
// and "everything else is sea" is exactly what a background expresses
|
|
29270
|
-
// — geometry-free, gap-free at every antimeridian and pole. Without
|
|
29271
|
-
// it the sea outside coverage was bare S-52 NODTA, a light grey that
|
|
29272
|
-
// read as "charted ground" with a hatch on it.
|
|
29273
|
-
L({
|
|
29274
|
-
id: "chrtbase-ocean",
|
|
29275
|
-
type: "background",
|
|
29276
|
-
paint: { "background-color": T.water }
|
|
29277
|
-
}),
|
|
29278
|
-
L({
|
|
29279
|
-
id: "chrtbase-earth",
|
|
29280
|
-
type: "fill",
|
|
29281
|
-
source: src,
|
|
29282
|
-
"source-layer": "base_earth",
|
|
29283
|
-
paint: { "fill-color": T.earth }
|
|
29284
|
-
}),
|
|
29285
|
-
L({
|
|
29286
|
-
id: "chrtbase-water",
|
|
29287
|
-
type: "fill",
|
|
29288
|
-
source: src,
|
|
29289
|
-
"source-layer": "base_water",
|
|
29290
|
-
paint: { "fill-color": T.water }
|
|
29291
|
-
}),
|
|
29292
|
-
L({
|
|
29293
|
-
id: "chrtbase-river",
|
|
29294
|
-
type: "line",
|
|
29295
|
-
source: src,
|
|
29296
|
-
"source-layer": "base_river",
|
|
29297
|
-
minzoom: 9,
|
|
29298
|
-
paint: {
|
|
29299
|
-
"line-color": T.river,
|
|
29300
|
-
"line-width": ["interpolate", ["linear"], ["zoom"], 9, 0.6, 14, 1.6]
|
|
29301
|
-
}
|
|
29302
|
-
}),
|
|
29303
|
-
L({
|
|
29304
|
-
id: "chrtbase-boundary",
|
|
28985
|
+
}),
|
|
28986
|
+
L({
|
|
28987
|
+
id: "chrtbase-boundary",
|
|
29305
28988
|
type: "line",
|
|
29306
28989
|
source: src,
|
|
29307
28990
|
"source-layer": "base_boundary",
|
|
@@ -29568,32 +29251,360 @@ function baseInlandWaterLayers(opts = {}) {
|
|
|
29568
29251
|
}
|
|
29569
29252
|
}),
|
|
29570
29253
|
L({
|
|
29571
|
-
id: "chrtbase-inland-label",
|
|
29572
|
-
type: "symbol",
|
|
29254
|
+
id: "chrtbase-inland-label",
|
|
29255
|
+
type: "symbol",
|
|
29256
|
+
source: src,
|
|
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 isLandOverlay = (id) => id.startsWith("chrtland-") && id !== "chrtland-base";
|
|
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",
|
|
29573
29374
|
source: src,
|
|
29574
|
-
"source-layer": "
|
|
29575
|
-
|
|
29576
|
-
|
|
29577
|
-
|
|
29578
|
-
|
|
29579
|
-
|
|
29580
|
-
|
|
29581
|
-
|
|
29582
|
-
|
|
29583
|
-
|
|
29584
|
-
|
|
29585
|
-
|
|
29586
|
-
|
|
29587
|
-
|
|
29588
|
-
"
|
|
29589
|
-
|
|
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,
|
|
29590
29409
|
paint: {
|
|
29591
|
-
"
|
|
29592
|
-
"
|
|
29593
|
-
"
|
|
29410
|
+
"hillshade-exaggeration": T.exaggeration,
|
|
29411
|
+
"hillshade-shadow-color": T.shadow,
|
|
29412
|
+
"hillshade-highlight-color": T.highlight,
|
|
29413
|
+
"hillshade-accent-color": T.shadow
|
|
29594
29414
|
}
|
|
29595
|
-
})
|
|
29415
|
+
}));
|
|
29416
|
+
}
|
|
29417
|
+
const isIndexContour = [
|
|
29418
|
+
"any",
|
|
29419
|
+
["<=", ["coalesce", ["get", "index_z"], 99], ["zoom"]],
|
|
29420
|
+
["==", ["get", "is_index"], 1]
|
|
29596
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;
|
|
29597
29608
|
}
|
|
29598
29609
|
|
|
29599
29610
|
// src/atlas/band-collapse.ts
|
|
@@ -30313,7 +30324,7 @@ function generateStyle(palette = "DAY", opts = {}) {
|
|
|
30313
30324
|
const surface = [];
|
|
30314
30325
|
const kept = [];
|
|
30315
30326
|
assembled.forEach((l, i) => {
|
|
30316
|
-
if (i < lastRepaint &&
|
|
30327
|
+
if (i < lastRepaint && isLandOverlay(idOf(l))) surface.push(l);
|
|
30317
30328
|
else kept.push(l);
|
|
30318
30329
|
});
|
|
30319
30330
|
if (surface.length === 0) return assembled;
|