@chrtco/sdk 0.10.47 → 0.10.49
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 +465 -76
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +316 -113
- package/dist/index.d.ts +316 -113
- package/dist/index.js +430 -70
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -25386,15 +25386,46 @@ function getLabelConfig(layerName, opts = {}) {
|
|
|
25386
25386
|
// UWTROC/OBSTRN/WRECKS are dominance-PARTICIPATING classes —
|
|
25387
25387
|
// exactly one band's copy renders at any zoom, so anchor-shifting
|
|
25388
25388
|
// can't split a cross-band duplicate pair into two visible labels.
|
|
25389
|
-
// Shallowest (most dangerous) hazard wins within-class contests;
|
|
25390
|
-
// VALSOU-less hazards (awash / unsounded) rank first of all.
|
|
25391
25389
|
layout: {
|
|
25392
25390
|
"text-variable-anchor": ["top-left", "bottom-left", "top-right", "bottom-right"],
|
|
25393
25391
|
"text-radial-offset": 0.9,
|
|
25394
25392
|
"text-justify": "auto",
|
|
25395
|
-
|
|
25393
|
+
// ⚠ A DANGER DEPTH IS NEVER DROPPED (owner, 2026-10-06). Before,
|
|
25394
|
+
// a callout with no free corner was culled and the rock, wreck or
|
|
25395
|
+
// obstruction drew with no depth beside it: 15 of 136 at Boston
|
|
25396
|
+
// z12.3. ALLOW-OVERLAP ONLY, and that is the whole point:
|
|
25397
|
+
// - the variable anchors still fan out first — MapLibre 5.24
|
|
25398
|
+
// tries every corner without overlap and overlaps, at the
|
|
25399
|
+
// first corner, only when none is free (`placement.ts`,
|
|
25400
|
+
// `placementPasses`), so only the callouts that used to vanish
|
|
25401
|
+
// draw over something;
|
|
25402
|
+
// - `text-ignore-placement` stays false, so a callout keeps its
|
|
25403
|
+
// collision space and blocks what it blocked before. Ignoring
|
|
25404
|
+
// placement as well freed that space for buoy and place names,
|
|
25405
|
+
// which then pushed shallow soundings off: 11 shoals uncovered
|
|
25406
|
+
// at z12.3 on the bench. This form: 0.
|
|
25407
|
+
// The census and its numbers: `scripts/chart-bench/
|
|
25408
|
+
// danger-depth-census.ts` and `.chrt/standards/s-52.md` §8a.
|
|
25409
|
+
"text-allow-overlap": true,
|
|
25396
25410
|
"text-optional": true,
|
|
25397
25411
|
"text-padding": 2,
|
|
25412
|
+
// ⚠ THE DEPTH SORT KEY IS LOAD-BEARING — do not "optimise" it to a
|
|
25413
|
+
// constant. It costs draw calls: MapLibre 5.24 draws an overlapping
|
|
25414
|
+
// layer with a data-driven key one segment per distinct key, twice
|
|
25415
|
+
// with a halo over 1 px (`drawLayerSymbols`, `hasSortKey &&
|
|
25416
|
+
// bucket.canOverlap`), so at 100 % the chart issues +14 % draw calls
|
|
25417
|
+
// at z12.3 against 0.10.3 (R6's 0.10.4 gate). But the key is also
|
|
25418
|
+
// the PLACEMENT order, and a callout keeps its collision box, so the
|
|
25419
|
+
// order decides which corner each callout takes and therefore which
|
|
25420
|
+
// soundings and buoy names survive beneath it. Measured with each
|
|
25421
|
+
// form booted fresh (2026-10-06, Boston and Salem Sound, z11.5–16,
|
|
25422
|
+
// at 1280×800 and the Pi's 1920×1185): a constant key, 3/4/5 depth
|
|
25423
|
+
// bands and whole metres ALL uncover shoals that 0.10.3 drew (a
|
|
25424
|
+
// constant key: 5 at z12.3 on the Pi's canvas, a 0.6 m one at
|
|
25425
|
+
// 1280×800) and change buoy names; only this key matches 0.10.4's
|
|
25426
|
+
// census. `danger-depth-census.ts --form <json>` re-runs that gate
|
|
25427
|
+
// for any candidate. A 1 px halo (one pass, not two) halves the
|
|
25428
|
+
// cost with placement byte-identical — a portrayal call, not taken.
|
|
25398
25429
|
"symbol-sort-key": labelSortKey(100, ["*", 10, valsou])
|
|
25399
25430
|
}
|
|
25400
25431
|
};
|
|
@@ -28678,65 +28709,364 @@ function iconExpressionForFamily(objectClass2, family) {
|
|
|
28678
28709
|
}
|
|
28679
28710
|
}
|
|
28680
28711
|
|
|
28681
|
-
// src/atlas/
|
|
28682
|
-
var
|
|
28683
|
-
var
|
|
28684
|
-
|
|
28685
|
-
|
|
28686
|
-
|
|
28687
|
-
|
|
28688
|
-
|
|
28689
|
-
|
|
28690
|
-
"SOUNDG",
|
|
28691
|
-
"DEPCNT",
|
|
28692
|
-
"UWTROC",
|
|
28693
|
-
"OBSTRN",
|
|
28694
|
-
"WRECKS"
|
|
28695
|
-
]);
|
|
28696
|
-
var SEMIBOLD = ["Open Sans Semibold"];
|
|
28697
|
-
var HAZARD_DEPTH = {
|
|
28698
|
-
textSize: ["interpolate", ["linear"], ["zoom"], 12, 12, 16, 15],
|
|
28699
|
-
haloWidth: 1.4,
|
|
28700
|
-
font: SEMIBOLD
|
|
28712
|
+
// src/atlas/chart-symbol-sizing.ts
|
|
28713
|
+
var CHART_SYMBOL_SIZES = ["landLabels", "waterLabels", "depthNumbers", "waypoints", "chartIcons"];
|
|
28714
|
+
var CHART_SYMBOL_SIZE_WIRE = {
|
|
28715
|
+
landLabels: "chart.landLabelScale",
|
|
28716
|
+
waterLabels: "chart.waterLabelScale",
|
|
28717
|
+
/** Proposed for CHRTKit; aligned with sail's ChartSymbolSizing before release. */
|
|
28718
|
+
depthNumbers: "chart.depthNumberScale",
|
|
28719
|
+
waypoints: "chart.waypointScale",
|
|
28720
|
+
chartIcons: "chart.chartIconScale"
|
|
28701
28721
|
};
|
|
28702
|
-
var
|
|
28703
|
-
|
|
28704
|
-
|
|
28705
|
-
|
|
28706
|
-
|
|
28707
|
-
|
|
28708
|
-
},
|
|
28709
|
-
// Standard: 8 / 10 at z10 / 14, halo 1.2, Regular.
|
|
28710
|
-
//
|
|
28711
|
-
// ⚠ ~1.2x, NOT 1.4x, AND SEMIBOLD CARRIES THE REST. A contour value rides
|
|
28712
|
-
// its line (`symbol-placement: line`) and needs a straight-enough run to fit;
|
|
28713
|
-
// it also shares rank 300 with the soundings, which place first. At 1.4x the
|
|
28714
|
-
// Boston harbour view kept 15 of Standard's 20 contour labels; at 1.2x, 18.
|
|
28715
|
-
DEPCNT: {
|
|
28716
|
-
textSize: ["interpolate", ["linear"], ["zoom"], 10, 10, 14, 12],
|
|
28717
|
-
haloWidth: 1.2,
|
|
28718
|
-
font: SEMIBOLD
|
|
28719
|
-
},
|
|
28720
|
-
UWTROC: HAZARD_DEPTH,
|
|
28721
|
-
OBSTRN: HAZARD_DEPTH,
|
|
28722
|
-
WRECKS: HAZARD_DEPTH
|
|
28722
|
+
var CHART_SYMBOL_SIZE_LABELS = {
|
|
28723
|
+
landLabels: "Land labels",
|
|
28724
|
+
waterLabels: "Water labels",
|
|
28725
|
+
depthNumbers: "Depth numbers",
|
|
28726
|
+
waypoints: "Waypoints",
|
|
28727
|
+
chartIcons: "Chart icons"
|
|
28723
28728
|
};
|
|
28724
|
-
var
|
|
28725
|
-
|
|
28726
|
-
|
|
28727
|
-
|
|
28728
|
-
|
|
28729
|
-
|
|
28730
|
-
|
|
28731
|
-
|
|
28732
|
-
|
|
28733
|
-
|
|
28734
|
-
|
|
28735
|
-
|
|
28736
|
-
|
|
28737
|
-
|
|
28738
|
-
|
|
28739
|
-
|
|
28729
|
+
var CHART_SYMBOL_SIZE_REACH = {
|
|
28730
|
+
landLabels: "Towns, landmarks, buildings and land areas.",
|
|
28731
|
+
waterLabels: "Sea, channel, lake and river names, and clearances.",
|
|
28732
|
+
depthNumbers: "Soundings, contour values, and the depths beside rocks, wrecks and obstructions.",
|
|
28733
|
+
waypoints: "Your waypoints and route marks, and how far a tap reaches them.",
|
|
28734
|
+
chartIcons: "Buoys, beacons, lights, wrecks, rocks and their names."
|
|
28735
|
+
};
|
|
28736
|
+
var CHART_SYMBOL_SCALE = {
|
|
28737
|
+
min: 50,
|
|
28738
|
+
max: 200,
|
|
28739
|
+
standard: 100,
|
|
28740
|
+
/** The − / + step. */
|
|
28741
|
+
buttonStep: 10,
|
|
28742
|
+
/** The slider's snap. */
|
|
28743
|
+
sliderStep: 5
|
|
28744
|
+
};
|
|
28745
|
+
var STANDARD_CHART_SYMBOL_SCALES = {
|
|
28746
|
+
landLabels: 100,
|
|
28747
|
+
waterLabels: 100,
|
|
28748
|
+
depthNumbers: 100,
|
|
28749
|
+
waypoints: 100,
|
|
28750
|
+
chartIcons: 100
|
|
28751
|
+
};
|
|
28752
|
+
function clampChartSymbolScale(percent) {
|
|
28753
|
+
if (!Number.isFinite(percent)) return CHART_SYMBOL_SCALE.standard;
|
|
28754
|
+
return Math.min(Math.max(Math.round(percent), CHART_SYMBOL_SCALE.min), CHART_SYMBOL_SCALE.max);
|
|
28755
|
+
}
|
|
28756
|
+
function snapChartSymbolScale(value) {
|
|
28757
|
+
if (!Number.isFinite(value)) return CHART_SYMBOL_SCALE.standard;
|
|
28758
|
+
const step = CHART_SYMBOL_SCALE.sliderStep;
|
|
28759
|
+
return clampChartSymbolScale(Math.round(value / step) * step);
|
|
28760
|
+
}
|
|
28761
|
+
function stepChartSymbolScale(percent, presses) {
|
|
28762
|
+
return clampChartSymbolScale(percent + presses * CHART_SYMBOL_SCALE.buttonStep);
|
|
28763
|
+
}
|
|
28764
|
+
function decodeChartSymbolScale(raw) {
|
|
28765
|
+
if (typeof raw === "number") return Number.isFinite(raw) ? clampChartSymbolScale(raw) : null;
|
|
28766
|
+
if (typeof raw === "string" && /^\s*-?\d+(\.\d+)?\s*$/.test(raw)) return clampChartSymbolScale(Number(raw));
|
|
28767
|
+
return null;
|
|
28768
|
+
}
|
|
28769
|
+
var LAND_TEXT_CLASSES = /* @__PURE__ */ new Set([
|
|
28770
|
+
"BUAARE",
|
|
28771
|
+
"LNDARE",
|
|
28772
|
+
"LNDRGN",
|
|
28773
|
+
"AIRARE",
|
|
28774
|
+
"PRDARE",
|
|
28775
|
+
"LNDMRK",
|
|
28776
|
+
"BUISGL",
|
|
28777
|
+
"SLCONS",
|
|
28778
|
+
"HRBFAC",
|
|
28779
|
+
"BRIDGE"
|
|
28780
|
+
]);
|
|
28781
|
+
var WATER_TEXT_CLASSES = /* @__PURE__ */ new Set([
|
|
28782
|
+
"SEAARE",
|
|
28783
|
+
"DRGNOTE",
|
|
28784
|
+
"SBDARE",
|
|
28785
|
+
"WEDKLP",
|
|
28786
|
+
"ACHARE",
|
|
28787
|
+
"LAKARE",
|
|
28788
|
+
"RIVERS",
|
|
28789
|
+
"CANALS",
|
|
28790
|
+
"CBLOHD",
|
|
28791
|
+
"PIPOHD"
|
|
28792
|
+
]);
|
|
28793
|
+
var SYMBOL_ANNOTATION_TEXT_CLASSES = /* @__PURE__ */ new Set([
|
|
28794
|
+
"LIGHTS",
|
|
28795
|
+
"FOGSIG",
|
|
28796
|
+
"BOYCAR",
|
|
28797
|
+
"BOYINB",
|
|
28798
|
+
"BOYISD",
|
|
28799
|
+
"BOYLAT",
|
|
28800
|
+
"BOYSAW",
|
|
28801
|
+
"BOYSPP",
|
|
28802
|
+
"BCNCAR",
|
|
28803
|
+
"BCNISD",
|
|
28804
|
+
"BCNLAT",
|
|
28805
|
+
"BCNSAW",
|
|
28806
|
+
"BCNSPP",
|
|
28807
|
+
"MORFAC",
|
|
28808
|
+
"PILPNT"
|
|
28809
|
+
]);
|
|
28810
|
+
var BASEMAP_LAND_TEXT = /* @__PURE__ */ new Set([
|
|
28811
|
+
"CHRT_LAND/land_town",
|
|
28812
|
+
"CHRT_LAND/land_summit",
|
|
28813
|
+
"CHRT_LAND/land_poi",
|
|
28814
|
+
"CHRT_BASE/state_label"
|
|
28815
|
+
]);
|
|
28816
|
+
var BASEMAP_WATER_TEXT = /* @__PURE__ */ new Set([
|
|
28817
|
+
"CHRT_BASE/inland_water_label",
|
|
28818
|
+
"CHRT_BASE/inland_water_label_detail"
|
|
28819
|
+
]);
|
|
28820
|
+
var BASEMAP_SOURCES = /* @__PURE__ */ new Set(["CHRT_LAND", "CHRT_BASE"]);
|
|
28821
|
+
var HAZARD_LABEL_PRIORITY = 100;
|
|
28822
|
+
var DEPTH_FIGURE_CLASSES = /* @__PURE__ */ new Set(["SOUNDG", "DEPCNT", "UWTROC", "OBSTRN", "WRECKS"]);
|
|
28823
|
+
function contourValueFactor(depthNumbersFactor) {
|
|
28824
|
+
return 1 + (depthNumbersFactor - 1) / 2;
|
|
28825
|
+
}
|
|
28826
|
+
var SERVED_FONT_STACKS = ["Open Sans Regular", "Open Sans Italic", "Open Sans Semibold"];
|
|
28827
|
+
function semiboldFontStack(font) {
|
|
28828
|
+
if (!Array.isArray(font) || !font.every((face) => typeof face === "string")) return font;
|
|
28829
|
+
return font.map((face) => {
|
|
28830
|
+
const semibold = face.replace(/ Regular$/, " Semibold");
|
|
28831
|
+
return SERVED_FONT_STACKS.includes(semibold) ? semibold : face;
|
|
28832
|
+
});
|
|
28833
|
+
}
|
|
28834
|
+
function factsOf(layer) {
|
|
28835
|
+
const l = layer;
|
|
28836
|
+
const source = typeof l.source === "string" ? l.source : void 0;
|
|
28837
|
+
const sourceLayer = typeof l["source-layer"] === "string" ? l["source-layer"] : void 0;
|
|
28838
|
+
const meta = l.metadata ?? {};
|
|
28839
|
+
const isBasemap = source !== void 0 && BASEMAP_SOURCES.has(source);
|
|
28840
|
+
const cls = meta["s52:objectClass"];
|
|
28841
|
+
const objectClass2 = isBasemap ? void 0 : (typeof cls === "string" ? cls : sourceLayer)?.toUpperCase();
|
|
28842
|
+
const p = meta["chrt:labelPriority"];
|
|
28843
|
+
return { source, sourceLayer, objectClass: objectClass2, labelPriority: typeof p === "number" ? p : void 0 };
|
|
28844
|
+
}
|
|
28845
|
+
function textSliderFor(layer) {
|
|
28846
|
+
const f = factsOf(layer);
|
|
28847
|
+
if (f.source !== void 0 && BASEMAP_SOURCES.has(f.source)) {
|
|
28848
|
+
const key = `${f.source}/${f.sourceLayer ?? ""}`;
|
|
28849
|
+
if (BASEMAP_LAND_TEXT.has(key)) return "landLabels";
|
|
28850
|
+
if (BASEMAP_WATER_TEXT.has(key)) return "waterLabels";
|
|
28851
|
+
return null;
|
|
28852
|
+
}
|
|
28853
|
+
const cls = f.objectClass;
|
|
28854
|
+
if (cls === void 0) return null;
|
|
28855
|
+
if (DEPTH_FIGURE_CLASSES.has(cls)) return "depthNumbers";
|
|
28856
|
+
if (LAND_TEXT_CLASSES.has(cls)) return "landLabels";
|
|
28857
|
+
if (WATER_TEXT_CLASSES.has(cls)) return "waterLabels";
|
|
28858
|
+
if (SYMBOL_ANNOTATION_TEXT_CLASSES.has(cls)) return "chartIcons";
|
|
28859
|
+
return null;
|
|
28860
|
+
}
|
|
28861
|
+
function iconSliderFor(layer) {
|
|
28862
|
+
const f = factsOf(layer);
|
|
28863
|
+
if (f.source !== void 0 && BASEMAP_SOURCES.has(f.source)) return null;
|
|
28864
|
+
return f.objectClass === void 0 ? null : "chartIcons";
|
|
28865
|
+
}
|
|
28866
|
+
function mentionsZoom(v) {
|
|
28867
|
+
if (Array.isArray(v)) {
|
|
28868
|
+
if (v.length === 1 && v[0] === "zoom") return true;
|
|
28869
|
+
return v.some(mentionsZoom);
|
|
28870
|
+
}
|
|
28871
|
+
if (v !== null && typeof v === "object") return Object.values(v).some(mentionsZoom);
|
|
28872
|
+
return false;
|
|
28873
|
+
}
|
|
28874
|
+
function scaledOutput(v, factor) {
|
|
28875
|
+
return typeof v === "number" ? round(v * factor) : ["*", v, factor];
|
|
28876
|
+
}
|
|
28877
|
+
function round(n) {
|
|
28878
|
+
return Math.round(n * 1e3) / 1e3;
|
|
28879
|
+
}
|
|
28880
|
+
function scaleSizeExpression(value, factor, fallback) {
|
|
28881
|
+
if (!Number.isFinite(factor) || factor <= 0) return null;
|
|
28882
|
+
if (value === void 0) return round(fallback * factor);
|
|
28883
|
+
if (factor === 1) return value;
|
|
28884
|
+
if (typeof value === "number") return round(value * factor);
|
|
28885
|
+
if (Array.isArray(value)) {
|
|
28886
|
+
const op = value[0];
|
|
28887
|
+
if (typeof op !== "string") return null;
|
|
28888
|
+
if (op === "interpolate" || op === "interpolate-hcl" || op === "interpolate-lab") {
|
|
28889
|
+
if (value.length < 5 || value.length % 2 !== 1) return null;
|
|
28890
|
+
const out = [...value];
|
|
28891
|
+
for (let i = 4; i < out.length; i += 2) out[i] = scaledOutput(out[i], factor);
|
|
28892
|
+
return out;
|
|
28893
|
+
}
|
|
28894
|
+
if (op === "step") {
|
|
28895
|
+
if (value.length < 3 || value.length % 2 !== 1) return null;
|
|
28896
|
+
const out = [...value];
|
|
28897
|
+
for (let i = 2; i < out.length; i += 2) out[i] = scaledOutput(out[i], factor);
|
|
28898
|
+
return out;
|
|
28899
|
+
}
|
|
28900
|
+
return mentionsZoom(value) ? null : ["*", value, factor];
|
|
28901
|
+
}
|
|
28902
|
+
if (value !== null && typeof value === "object") {
|
|
28903
|
+
const stops = value.stops;
|
|
28904
|
+
if (!Array.isArray(stops)) return null;
|
|
28905
|
+
const outStops = [];
|
|
28906
|
+
for (const stop of stops) {
|
|
28907
|
+
if (!Array.isArray(stop) || stop.length !== 2 || typeof stop[1] !== "number") return null;
|
|
28908
|
+
outStops.push([stop[0], round(stop[1] * factor)]);
|
|
28909
|
+
}
|
|
28910
|
+
return { ...value, stops: outStops };
|
|
28911
|
+
}
|
|
28912
|
+
return null;
|
|
28913
|
+
}
|
|
28914
|
+
function haloFactor(factor) {
|
|
28915
|
+
return factor > 1 ? 1 + (factor - 1) / 2 : 1;
|
|
28916
|
+
}
|
|
28917
|
+
var SERVED_SOUNDING_PADDING_PX = 6;
|
|
28918
|
+
var SOUNDING_PADDING_PER_FACTOR = 6.25;
|
|
28919
|
+
function soundingPadding(factor, served = SERVED_SOUNDING_PADDING_PX) {
|
|
28920
|
+
if (factor <= 1) return served;
|
|
28921
|
+
return round(Math.max(0, served - SOUNDING_PADDING_PER_FACTOR * (factor - 1)));
|
|
28922
|
+
}
|
|
28923
|
+
var MAPLIBRE_DEFAULT_TEXT_PADDING_PX = 2;
|
|
28924
|
+
function soundingPaddingValue(served, factor) {
|
|
28925
|
+
if (factor <= 1) return served;
|
|
28926
|
+
if (served === void 0) return soundingPadding(factor, MAPLIBRE_DEFAULT_TEXT_PADDING_PX);
|
|
28927
|
+
if (typeof served === "number") return soundingPadding(factor, served);
|
|
28928
|
+
if (!Array.isArray(served) || typeof served[0] !== "string") return served;
|
|
28929
|
+
const first = served[0] === "interpolate" ? 4 : served[0] === "step" ? 2 : null;
|
|
28930
|
+
if (first === null) return served;
|
|
28931
|
+
const out = [...served];
|
|
28932
|
+
for (let i = first; i < out.length; i += 2) {
|
|
28933
|
+
if (typeof out[i] !== "number") return served;
|
|
28934
|
+
out[i] = soundingPadding(factor, out[i]);
|
|
28935
|
+
}
|
|
28936
|
+
return out;
|
|
28937
|
+
}
|
|
28938
|
+
function factorOf(scales, size) {
|
|
28939
|
+
return clampChartSymbolScale(scales[size]) / 100;
|
|
28940
|
+
}
|
|
28941
|
+
var OUTRANK_LABELS = { kind: "outrankLabels" };
|
|
28942
|
+
var CHART_SOUNDINGS_RULE = { kind: "zoomSplit", harbourFrom: 14 };
|
|
28943
|
+
var KEPT_ABOVE_SOUNDINGS_CLASSES = /* @__PURE__ */ new Set(["SEAARE", "LNDARE", "LNDRGN"]);
|
|
28944
|
+
function keptAboveSoundings(layer, splittingLights = false) {
|
|
28945
|
+
const facts = factsOf(layer);
|
|
28946
|
+
if (splittingLights && facts.objectClass === "LIGHTS") return false;
|
|
28947
|
+
if (facts.labelPriority === HAZARD_LABEL_PRIORITY) return true;
|
|
28948
|
+
if (facts.source !== void 0 && BASEMAP_SOURCES.has(facts.source)) return true;
|
|
28949
|
+
return KEPT_ABOVE_SOUNDINGS_CLASSES.has(facts.objectClass ?? "");
|
|
28950
|
+
}
|
|
28951
|
+
function fromZoom(z, value) {
|
|
28952
|
+
return ["step", ["zoom"], value ?? false, z, true];
|
|
28953
|
+
}
|
|
28954
|
+
function labelSlidersOffStandard(scales) {
|
|
28955
|
+
return ["landLabels", "waterLabels", "depthNumbers", "chartIcons"].some((s) => clampChartSymbolScale(scales[s]) !== 100);
|
|
28956
|
+
}
|
|
28957
|
+
function applyChartSymbolScalesToLayer(layer, scales, yieldText = false) {
|
|
28958
|
+
if (layer.type !== "symbol") return layer;
|
|
28959
|
+
const layout = layer.layout ?? {};
|
|
28960
|
+
const hasText = layout["text-field"] !== void 0;
|
|
28961
|
+
const hasIcon = layout["icon-image"] !== void 0;
|
|
28962
|
+
if (!hasText && !hasIcon) return layer;
|
|
28963
|
+
const facts = factsOf(layer);
|
|
28964
|
+
const nextLayout = { ...layout };
|
|
28965
|
+
let nextPaint = null;
|
|
28966
|
+
let touched = false;
|
|
28967
|
+
if (hasText) {
|
|
28968
|
+
const slider = textSliderFor(layer);
|
|
28969
|
+
const isDepthFigure = slider === "depthNumbers";
|
|
28970
|
+
const sliderFactor = slider === null ? 1 : factorOf(scales, slider);
|
|
28971
|
+
const f = isDepthFigure && facts.objectClass === "DEPCNT" ? contourValueFactor(sliderFactor) : sliderFactor;
|
|
28972
|
+
const size = f === 1 ? null : scaleSizeExpression(layout["text-size"], f, 16);
|
|
28973
|
+
if (size !== null) {
|
|
28974
|
+
touched = true;
|
|
28975
|
+
nextLayout["text-size"] = size;
|
|
28976
|
+
if (f > 1) {
|
|
28977
|
+
if (isDepthFigure) {
|
|
28978
|
+
const semibold = semiboldFontStack(layout["text-font"]);
|
|
28979
|
+
if (JSON.stringify(semibold) !== JSON.stringify(layout["text-font"])) nextLayout["text-font"] = semibold;
|
|
28980
|
+
if (facts.objectClass === "SOUNDG") {
|
|
28981
|
+
const padding = soundingPaddingValue(layout["text-padding"], f);
|
|
28982
|
+
if (padding !== void 0) nextLayout["text-padding"] = padding;
|
|
28983
|
+
} else if (facts.labelPriority === HAZARD_LABEL_PRIORITY) {
|
|
28984
|
+
nextLayout["text-ignore-placement"] = true;
|
|
28985
|
+
nextLayout["text-allow-overlap"] = true;
|
|
28986
|
+
}
|
|
28987
|
+
} else {
|
|
28988
|
+
nextLayout["text-ignore-placement"] = true;
|
|
28989
|
+
if (facts.labelPriority === HAZARD_LABEL_PRIORITY) nextLayout["text-allow-overlap"] = true;
|
|
28990
|
+
}
|
|
28991
|
+
const halo = layer.paint?.["text-halo-width"];
|
|
28992
|
+
if (isDepthFigure && halo !== void 0) {
|
|
28993
|
+
const wider = scaleSizeExpression(halo, haloFactor(sliderFactor), 0);
|
|
28994
|
+
if (wider !== null) nextPaint = { ...layer.paint ?? {}, "text-halo-width": wider };
|
|
28995
|
+
}
|
|
28996
|
+
}
|
|
28997
|
+
}
|
|
28998
|
+
if (yieldText && facts.objectClass !== "SOUNDG") {
|
|
28999
|
+
touched = true;
|
|
29000
|
+
nextLayout["text-ignore-placement"] = true;
|
|
29001
|
+
}
|
|
29002
|
+
}
|
|
29003
|
+
if (hasIcon) {
|
|
29004
|
+
const slider = iconSliderFor(layer);
|
|
29005
|
+
const f = slider === null ? 1 : factorOf(scales, slider);
|
|
29006
|
+
const size = f === 1 ? null : scaleSizeExpression(layout["icon-size"], f, 1);
|
|
29007
|
+
if (size !== null) {
|
|
29008
|
+
touched = true;
|
|
29009
|
+
nextLayout["icon-size"] = size;
|
|
29010
|
+
if (f > 1) nextLayout["icon-ignore-placement"] = true;
|
|
29011
|
+
}
|
|
29012
|
+
}
|
|
29013
|
+
if (!touched) return layer;
|
|
29014
|
+
return { ...layer, layout: nextLayout, ...nextPaint ? { paint: nextPaint } : {} };
|
|
29015
|
+
}
|
|
29016
|
+
var isSoundingText = (l) => l.type === "symbol" && l.layout?.["text-field"] !== void 0 && factsOf(l).objectClass === "SOUNDG";
|
|
29017
|
+
function applyChartSymbolScales(layers, scales, rule = CHART_SOUNDINGS_RULE) {
|
|
29018
|
+
if (scales === void 0 || ["landLabels", "waterLabels", "depthNumbers", "chartIcons"].every((s) => clampChartSymbolScale(scales[s]) === 100)) {
|
|
29019
|
+
return layers;
|
|
29020
|
+
}
|
|
29021
|
+
const outrank = labelSlidersOffStandard(scales);
|
|
29022
|
+
const soundingsAt = layers.findIndex(isSoundingText);
|
|
29023
|
+
const split = rule.kind === "zoomSplit" ? rule : null;
|
|
29024
|
+
const demoted = [];
|
|
29025
|
+
const kept = [];
|
|
29026
|
+
layers.forEach((l, i) => {
|
|
29027
|
+
const above = outrank && soundingsAt !== -1 && i > soundingsAt;
|
|
29028
|
+
const hasText = l.type === "symbol" && l.layout?.["text-field"] !== void 0;
|
|
29029
|
+
if (split !== null && above && hasText && !isSoundingText(l) && !keptAboveSoundings(l, split.splitLights === true)) {
|
|
29030
|
+
const own = applyChartSymbolScalesToLayer(l, scales, false);
|
|
29031
|
+
const layout = own.layout ?? {};
|
|
29032
|
+
demoted.push({
|
|
29033
|
+
...own,
|
|
29034
|
+
layout: {
|
|
29035
|
+
...layout,
|
|
29036
|
+
"text-allow-overlap": fromZoom(split.harbourFrom, layout["text-allow-overlap"]),
|
|
29037
|
+
"text-ignore-placement": fromZoom(split.harbourFrom, layout["text-ignore-placement"])
|
|
29038
|
+
}
|
|
29039
|
+
});
|
|
29040
|
+
return;
|
|
29041
|
+
}
|
|
29042
|
+
kept.push(applyChartSymbolScalesToLayer(l, scales, above));
|
|
29043
|
+
});
|
|
29044
|
+
if (demoted.length === 0) return kept;
|
|
29045
|
+
const at = kept.findIndex(isSoundingText);
|
|
29046
|
+
return [...kept.slice(0, at), ...demoted, ...kept.slice(at)];
|
|
29047
|
+
}
|
|
29048
|
+
function demotedBelowSoundings(layers, scales, rule = CHART_SOUNDINGS_RULE) {
|
|
29049
|
+
if (scales === void 0 || rule.kind !== "zoomSplit" || !labelSlidersOffStandard(scales)) return [];
|
|
29050
|
+
const soundingsAt = layers.findIndex(isSoundingText);
|
|
29051
|
+
if (soundingsAt === -1) return [];
|
|
29052
|
+
return layers.filter((l, i) => i > soundingsAt && l.type === "symbol" && l.layout?.["text-field"] !== void 0 && !isSoundingText(l) && !keptAboveSoundings(l, rule.splitLights === true)).map((l) => l.id);
|
|
29053
|
+
}
|
|
29054
|
+
function chartSymbolSizingCensus(layers) {
|
|
29055
|
+
const unclassified = [];
|
|
29056
|
+
const unscalable = [];
|
|
29057
|
+
for (const l of layers) {
|
|
29058
|
+
if (l.type !== "symbol") continue;
|
|
29059
|
+
const layout = l.layout ?? {};
|
|
29060
|
+
if (layout["text-field"] !== void 0) {
|
|
29061
|
+
if (textSliderFor(l) === null) unclassified.push(`${l.id} text`);
|
|
29062
|
+
else if (scaleSizeExpression(layout["text-size"], 2, 16) === null) unscalable.push(`${l.id} text`);
|
|
29063
|
+
}
|
|
29064
|
+
if (layout["icon-image"] !== void 0) {
|
|
29065
|
+
if (iconSliderFor(l) === null) unclassified.push(`${l.id} icon`);
|
|
29066
|
+
else if (scaleSizeExpression(layout["icon-size"], 2, 1) === null) unscalable.push(`${l.id} icon`);
|
|
29067
|
+
}
|
|
29068
|
+
}
|
|
29069
|
+
return { unclassified, unscalable };
|
|
28740
29070
|
}
|
|
28741
29071
|
|
|
28742
29072
|
// src/atlas/base-bundle.ts
|
|
@@ -30079,7 +30409,7 @@ function buildLabelLayer2(objectClass2, ct, sourceId = DEFAULT_REGION, depthUnit
|
|
|
30079
30409
|
if (getLabelBehavior(objectClass2) === "orientation-cross-band") {
|
|
30080
30410
|
layer.filter = LABEL_ANCHOR_FILTER;
|
|
30081
30411
|
}
|
|
30082
|
-
return
|
|
30412
|
+
return layer;
|
|
30083
30413
|
}
|
|
30084
30414
|
function getGeomTypesForClass(objectClass2, defaultType) {
|
|
30085
30415
|
if (SYMBOL_MAP[objectClass2] && defaultType === "symbol") {
|
|
@@ -31234,8 +31564,7 @@ function generateStyle(palette = "DAY", opts = {}) {
|
|
|
31234
31564
|
label: buildLabelLayer2(objectClass2, palette, sourceId, opts.depthUnits ?? "meters", {
|
|
31235
31565
|
safetyContour: opts.safetyContour,
|
|
31236
31566
|
twoShadeSoundings: opts.twoShadeSoundings,
|
|
31237
|
-
soundingFontWeight: opts.soundingFontWeight
|
|
31238
|
-
depthLabelSize: opts.depthLabelSize
|
|
31567
|
+
soundingFontWeight: opts.soundingFontWeight
|
|
31239
31568
|
})
|
|
31240
31569
|
});
|
|
31241
31570
|
}
|
|
@@ -31660,7 +31989,9 @@ function generateStyle(palette = "DAY", opts = {}) {
|
|
|
31660
31989
|
layers: finalLayers
|
|
31661
31990
|
};
|
|
31662
31991
|
const familyStyle = symbolSet === "s101" ? applyS101SymbolSet(style) : symbolSet === "chrt" ? applyChrtSymbolSet(style, palette) : symbolSet === "raster" ? applyRasterSymbolSet(style) : style;
|
|
31663
|
-
|
|
31992
|
+
const portrayed = applyEinkPortrayal(familyStyle, palette, { safetyContour: opts.safetyContour });
|
|
31993
|
+
const sized = applyChartSymbolScales(portrayed.layers, opts.symbolScales, opts.soundingsRule);
|
|
31994
|
+
return sized === portrayed.layers ? portrayed : { ...portrayed, layers: sized };
|
|
31664
31995
|
}
|
|
31665
31996
|
function generateStyleJSON(palette = "DAY", opts = {}) {
|
|
31666
31997
|
return JSON.stringify(generateStyle(palette, opts), null, 2);
|
|
@@ -32566,6 +32897,12 @@ export {
|
|
|
32566
32897
|
CHART_BAND_CODES,
|
|
32567
32898
|
CHART_CASCADE_CODES,
|
|
32568
32899
|
CHART_SECTIONS,
|
|
32900
|
+
CHART_SOUNDINGS_RULE,
|
|
32901
|
+
CHART_SYMBOL_SCALE,
|
|
32902
|
+
CHART_SYMBOL_SIZES,
|
|
32903
|
+
CHART_SYMBOL_SIZE_LABELS,
|
|
32904
|
+
CHART_SYMBOL_SIZE_REACH,
|
|
32905
|
+
CHART_SYMBOL_SIZE_WIRE,
|
|
32569
32906
|
CHRTRASTER_REF_CROPS,
|
|
32570
32907
|
CHRTRASTER_SVGS,
|
|
32571
32908
|
CHRT_ATON_COLORS,
|
|
@@ -32579,7 +32916,6 @@ export {
|
|
|
32579
32916
|
ChrtError,
|
|
32580
32917
|
DEFAULT_CLICK_TOLERANCE,
|
|
32581
32918
|
DEFAULT_CUSTOM_STYLE_CONFIG,
|
|
32582
|
-
DEFAULT_DEPTH_LABEL_SIZE,
|
|
32583
32919
|
DEFAULT_INSPECT_CLASS_RANK,
|
|
32584
32920
|
DEFAULT_LABEL_SETTINGS,
|
|
32585
32921
|
DEFAULT_NAV_AID_SETTINGS,
|
|
@@ -32591,14 +32927,14 @@ export {
|
|
|
32591
32927
|
DEFAULT_WATER_BODY_SETTINGS,
|
|
32592
32928
|
DEPARE_FILL_BRANCH_TOKENS,
|
|
32593
32929
|
DEPARE_FILL_FALLBACK_TOKEN,
|
|
32594
|
-
|
|
32595
|
-
DEPTH_LABEL_SIZES,
|
|
32930
|
+
DEPTH_FIGURE_CLASSES,
|
|
32596
32931
|
DRAPEABLE_LAYER_TYPES,
|
|
32597
32932
|
EINK_COLOR_TABLES,
|
|
32598
32933
|
EINK_DANGER_PATTERN,
|
|
32599
32934
|
EINK_DOTS_PATTERN,
|
|
32600
32935
|
EINK_HATCH_PATTERN,
|
|
32601
32936
|
EINK_MONO_GREYS,
|
|
32937
|
+
HAZARD_LABEL_PRIORITY,
|
|
32602
32938
|
INSPECT_CLASS_RANK,
|
|
32603
32939
|
INSPECT_RANK_DEVIATIONS,
|
|
32604
32940
|
InteractClient,
|
|
@@ -32614,7 +32950,8 @@ export {
|
|
|
32614
32950
|
LAND_ATTRIBUTION,
|
|
32615
32951
|
LAND_BUILD_MAXZOOM,
|
|
32616
32952
|
LAND_REGION,
|
|
32617
|
-
|
|
32953
|
+
LAND_TEXT_CLASSES,
|
|
32954
|
+
MAPLIBRE_DEFAULT_TEXT_PADDING_PX,
|
|
32618
32955
|
NAUTICAL_SYMBOLS,
|
|
32619
32956
|
NAV_AID_LAYER_GROUPS,
|
|
32620
32957
|
NAV_AID_QUERY_LAYERS,
|
|
@@ -32623,6 +32960,7 @@ export {
|
|
|
32623
32960
|
NON_SOLAS_DISCLAIMER,
|
|
32624
32961
|
NON_SOLAS_DISCLAIMER_SHORT,
|
|
32625
32962
|
OPAQUE_SPLIT_OF,
|
|
32963
|
+
OUTRANK_LABELS,
|
|
32626
32964
|
OfflineError,
|
|
32627
32965
|
OfflineStyleError,
|
|
32628
32966
|
PLACENAME_LAND_CLASSES,
|
|
@@ -32657,9 +32995,14 @@ export {
|
|
|
32657
32995
|
S52_LOOKUP,
|
|
32658
32996
|
S52_NIGHT,
|
|
32659
32997
|
S52_PATTERN_SPRITE_PREFIX,
|
|
32998
|
+
SERVED_FONT_STACKS,
|
|
32999
|
+
SERVED_SOUNDING_PADDING_PX,
|
|
32660
33000
|
SIGPER_TOLERANCE_SECONDS,
|
|
32661
33001
|
SIGSEQ_MAX_TERMS,
|
|
32662
33002
|
SOUNDING_LAYERS,
|
|
33003
|
+
SOUNDING_PADDING_PER_FACTOR,
|
|
33004
|
+
STANDARD_CHART_SYMBOL_SCALES,
|
|
33005
|
+
SYMBOL_ANNOTATION_TEXT_CLASSES,
|
|
32663
33006
|
SYMBOL_FAMILIES,
|
|
32664
33007
|
SYMBOL_FAMILY_META,
|
|
32665
33008
|
SYMBOL_GROUPS,
|
|
@@ -32667,12 +33010,14 @@ export {
|
|
|
32667
33010
|
TileAuth,
|
|
32668
33011
|
TileTokenError,
|
|
32669
33012
|
WATER_BODY_LAYER_GROUPS,
|
|
33013
|
+
WATER_TEXT_CLASSES,
|
|
32670
33014
|
WeatherEndpoint,
|
|
32671
33015
|
applyBaseBundle,
|
|
33016
|
+
applyChartSymbolScales,
|
|
33017
|
+
applyChartSymbolScalesToLayer,
|
|
32672
33018
|
applyChrtSymbolSet,
|
|
32673
33019
|
applyColorTheme,
|
|
32674
33020
|
applyCustomStyleSettings,
|
|
32675
|
-
applyDepthLabelSize,
|
|
32676
33021
|
applyEinkPortrayal,
|
|
32677
33022
|
applyRasterSymbolSet,
|
|
32678
33023
|
applyS101SymbolSet,
|
|
@@ -32699,19 +33044,24 @@ export {
|
|
|
32699
33044
|
capLuminance,
|
|
32700
33045
|
cellBandCharacters,
|
|
32701
33046
|
cellBandMatch,
|
|
33047
|
+
chartSymbolSizingCensus,
|
|
32702
33048
|
chrtAtonTintExpression,
|
|
32703
33049
|
chrtHouseColor,
|
|
32704
33050
|
chrtLightTintExpression,
|
|
33051
|
+
clampChartSymbolScale,
|
|
32705
33052
|
collectCandidates,
|
|
32706
33053
|
collectClickCandidates,
|
|
32707
33054
|
combineWithBandFilter,
|
|
33055
|
+
contourValueFactor,
|
|
32708
33056
|
contrastRatio,
|
|
32709
33057
|
daymarkColor,
|
|
32710
33058
|
decimateFeatures,
|
|
32711
33059
|
decodeAreaFeatureProps,
|
|
32712
33060
|
decodeBridgeProps,
|
|
32713
33061
|
decodeCandidate,
|
|
33062
|
+
decodeChartSymbolScale,
|
|
32714
33063
|
decodeNavAidProps,
|
|
33064
|
+
demotedBelowSoundings,
|
|
32715
33065
|
depareColor,
|
|
32716
33066
|
depareFillExpression,
|
|
32717
33067
|
depthAreaClassLayerId,
|
|
@@ -32721,6 +33071,7 @@ export {
|
|
|
32721
33071
|
drapedFirst,
|
|
32722
33072
|
extractNavAidDesignation,
|
|
32723
33073
|
featureIdentity,
|
|
33074
|
+
fromZoom,
|
|
32724
33075
|
generateCustomStyle,
|
|
32725
33076
|
generateSpriteManifest,
|
|
32726
33077
|
generateSpriteSheet,
|
|
@@ -32748,9 +33099,11 @@ export {
|
|
|
32748
33099
|
getThemedS101Svg,
|
|
32749
33100
|
getThemedS52Svg,
|
|
32750
33101
|
getTopmarkMeaning,
|
|
33102
|
+
haloFactor,
|
|
32751
33103
|
hazardColor,
|
|
32752
33104
|
hazardFillExpression,
|
|
32753
33105
|
iconExpressionForFamily,
|
|
33106
|
+
iconSliderFor,
|
|
32754
33107
|
isDepthAreaClassLayerId,
|
|
32755
33108
|
isDrapeable,
|
|
32756
33109
|
isEinkColorTable,
|
|
@@ -32762,6 +33115,7 @@ export {
|
|
|
32762
33115
|
isSoundingLayerVisible,
|
|
32763
33116
|
isVisibleInMode,
|
|
32764
33117
|
isWaterBodyLayerVisible,
|
|
33118
|
+
keptAboveSoundings,
|
|
32765
33119
|
labelSortKey,
|
|
32766
33120
|
lampRhythmColour,
|
|
32767
33121
|
lampRhythmOpacity,
|
|
@@ -32774,7 +33128,6 @@ export {
|
|
|
32774
33128
|
normalizeTheme,
|
|
32775
33129
|
opaqueSplitBaseOf,
|
|
32776
33130
|
paginate,
|
|
32777
|
-
parseDepthLabelSize,
|
|
32778
33131
|
parseListCodes,
|
|
32779
33132
|
parseSigseqTerms,
|
|
32780
33133
|
parseSymbolFamily,
|
|
@@ -32797,12 +33150,19 @@ export {
|
|
|
32797
33150
|
safetyContourValues,
|
|
32798
33151
|
sanitizeCustomStyleConfig,
|
|
32799
33152
|
scaleLinearLight,
|
|
33153
|
+
scaleSizeExpression,
|
|
32800
33154
|
scaleSizeValue,
|
|
32801
33155
|
scaminToMinZoom,
|
|
32802
33156
|
sectorLimitToArcBearing,
|
|
33157
|
+
semiboldFontStack,
|
|
33158
|
+
snapChartSymbolScale,
|
|
33159
|
+
soundingPadding,
|
|
33160
|
+
soundingPaddingValue,
|
|
32803
33161
|
splitOpaqueDepthAreas,
|
|
33162
|
+
stepChartSymbolScale,
|
|
32804
33163
|
styleModeBand,
|
|
32805
33164
|
terrainStackCount,
|
|
33165
|
+
textSliderFor,
|
|
32806
33166
|
themeChrtGlyph,
|
|
32807
33167
|
tileTemplate,
|
|
32808
33168
|
uncoveredSectorArcs,
|