@chrtco/sdk 0.10.55 → 0.10.57

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.js CHANGED
@@ -465,7 +465,9 @@ var TilesEndpoint = class {
465
465
  const params = new URLSearchParams();
466
466
  if (opts.theme) params.set("theme", opts.theme);
467
467
  if (opts.symbols) params.set("symbols", opts.symbols);
468
+ if (opts.look) params.set("look", opts.look);
468
469
  if (opts.mode) params.set("mode", opts.mode);
470
+ if (opts.lock) params.set("lock", opts.lock);
469
471
  if (opts.land) params.set("land", "1");
470
472
  if (opts.relief) params.set("relief", "1");
471
473
  if (opts.units === "imperial") params.set("units", "imperial");
@@ -31936,8 +31938,11 @@ function washTint(cls, id, tints) {
31936
31938
  if (cls === "LAKARE" || id === "chrtland-water" || id === "paper-base-lakes") return tints.lake;
31937
31939
  return null;
31938
31940
  }
31941
+ function lookSprite(style, look) {
31942
+ return typeof style.sprite === "string" ? { sprite: style.sprite.replace(/-day$/, `-look_${look}`) } : {};
31943
+ }
31939
31944
  function withLook(style, look, opts = {}) {
31940
- if (look === "paper") return withClassic(style);
31945
+ if (look === "paper") return { ...withClassic(style), ...lookSprite(style, look) };
31941
31946
  const tone = LOOK_TONES[look];
31942
31947
  const ink = tone.ink;
31943
31948
  const tints = look === "handcolored" && opts.tints !== false ? WASH_TINTS : null;
@@ -32037,10 +32042,7 @@ function withLook(style, look, opts = {}) {
32037
32042
  });
32038
32043
  return {
32039
32044
  ...style,
32040
- // The black & white sheet's symbols, the same INT-1 shapes in black, on
32041
- // both looks: the day sheet's magenta anchors and light flares read as a
32042
- // modern chart under the wash.
32043
- ...typeof style.sprite === "string" ? { sprite: style.sprite.replace(/-day$/, "-eink_mono") } : {},
32045
+ ...lookSprite(style, look),
32044
32046
  sources: {
32045
32047
  ...style.sources,
32046
32048
  [LOOK_WATERLINES_SOURCE]: { type: "geojson", data: { type: "FeatureCollection", features: [] } }
@@ -33645,8 +33647,8 @@ var SYMBOL_SET_LABELS = {
33645
33647
  var SPRITE_SHEET_FAMILY = {
33646
33648
  s52: "s52",
33647
33649
  chrt: "chrt",
33648
- int1: "raster",
33649
- uschart1: "raster"
33650
+ int1: "int1",
33651
+ uschart1: "uschart1"
33650
33652
  };
33651
33653
  function applySymbolFamily(style, family, palette) {
33652
33654
  switch (family) {
@@ -34869,7 +34871,7 @@ function applyCustomStyleSettings(style, config) {
34869
34871
  }
34870
34872
  function generateCustomStyle(config, opts = {}) {
34871
34873
  const { theme, ...generatorOpts } = opts;
34872
- const { palette, themeFellBack } = resolveCustomTheme(config, theme ?? null);
34874
+ const { palette, themeFellBack } = generatorOpts.look !== void 0 ? { palette: "DAY", themeFellBack: theme != null && theme !== "DAY" } : resolveCustomTheme(config, theme ?? null);
34873
34875
  const style = generateStyle(palette, {
34874
34876
  ...generatorOpts,
34875
34877
  safetyContour: config.sounding_settings.safetyContour,
@@ -34943,6 +34945,301 @@ function splitOpaqueDepthAreas(layers) {
34943
34945
  return out;
34944
34946
  }
34945
34947
 
34948
+ // src/atlas/chart-reduction.ts
34949
+ var CHART_LOCK_BANDS = [
34950
+ { band: 1, name: "Overview", floor: 5 },
34951
+ { band: 2, name: "General", floor: 7 },
34952
+ { band: 3, name: "Coastal", floor: 9 },
34953
+ { band: 4, name: "Approach", floor: 11 },
34954
+ { band: 5, name: "Harbor", floor: 13 },
34955
+ { band: 6, name: "Berthing", floor: 14 }
34956
+ ];
34957
+ var DEFAULT_CHART_LOCK_BAND = 5;
34958
+ var MAX_REDUCTION_LEVELS = 2;
34959
+ var CHART_ARCHIVE_MAXZOOM = 14;
34960
+ function isChartLockBand(v) {
34961
+ return v === 1 || v === 2 || v === 3 || v === 4 || v === 5 || v === 6;
34962
+ }
34963
+ function chartLockBandInfo(band) {
34964
+ return CHART_LOCK_BANDS[band - 1];
34965
+ }
34966
+ function chartLockFloor(band) {
34967
+ return chartLockBandInfo(band).floor;
34968
+ }
34969
+ function chartLockMinZoom(band) {
34970
+ return chartLockFloor(band) - MAX_REDUCTION_LEVELS;
34971
+ }
34972
+ function chartLockStyleMode(band) {
34973
+ const name = chartLockBandInfo(band).name;
34974
+ return { band: name === "Berthing" ? "Harbor" : name, finestBand: String(band) };
34975
+ }
34976
+ var FINER_DATA_DECISION_OFFSET = 1e-3;
34977
+ function chartLockDecisionZoom(band, bandOnly) {
34978
+ const floor = chartLockFloor(band);
34979
+ return bandOnly ? floor : floor - FINER_DATA_DECISION_OFFSET;
34980
+ }
34981
+ function chartLockSourceMaxzoom(band, archiveMax = CHART_ARCHIVE_MAXZOOM) {
34982
+ return Math.min(archiveMax, chartLockFloor(band));
34983
+ }
34984
+ var REDUCED_SIZE_PROPERTIES = /* @__PURE__ */ new Set([
34985
+ "text-size",
34986
+ "icon-size",
34987
+ "text-padding",
34988
+ "icon-padding",
34989
+ "icon-text-fit-padding",
34990
+ "symbol-spacing",
34991
+ "line-width",
34992
+ "line-gap-width",
34993
+ "line-offset",
34994
+ "line-blur",
34995
+ "circle-radius",
34996
+ "circle-stroke-width",
34997
+ "text-halo-width",
34998
+ "text-halo-blur",
34999
+ "icon-halo-width",
35000
+ "icon-halo-blur",
35001
+ "text-translate",
35002
+ "icon-translate",
35003
+ "line-translate",
35004
+ "fill-translate",
35005
+ "circle-translate"
35006
+ ]);
35007
+ var REDUCTION_STOPS_PER_LEVEL = 4;
35008
+ var STEP_RAMP = 1e-3;
35009
+ var isZoom = (e) => Array.isArray(e) && e.length === 1 && e[0] === "zoom";
35010
+ function round2(n) {
35011
+ return Math.round(n * 1e4) / 1e4;
35012
+ }
35013
+ function mentionsZoom2(v) {
35014
+ if (Array.isArray(v)) {
35015
+ if (v[0] === "literal") return false;
35016
+ if (isZoom(v)) return true;
35017
+ return v.some(mentionsZoom2);
35018
+ }
35019
+ if (v !== null && typeof v === "object") return Object.values(v).some(mentionsZoom2);
35020
+ return false;
35021
+ }
35022
+ function isNumArray(v) {
35023
+ return Array.isArray(v) && v.length > 0 && v.every((n) => typeof n === "number");
35024
+ }
35025
+ function numArrayOf(v) {
35026
+ if (isNumArray(v)) return v;
35027
+ if (Array.isArray(v) && v.length === 2 && v[0] === "literal" && isNumArray(v[1])) return v[1];
35028
+ return null;
35029
+ }
35030
+ function asOutput(v) {
35031
+ return isNumArray(v) ? ["literal", v] : v;
35032
+ }
35033
+ function zoomCurveOf(v) {
35034
+ if (Array.isArray(v)) {
35035
+ if (v[0] === "interpolate" && isZoom(v[2])) {
35036
+ const stops = [];
35037
+ for (let i = 3; i + 1 < v.length; i += 2) {
35038
+ if (typeof v[i] !== "number") return null;
35039
+ stops.push([v[i], v[i + 1]]);
35040
+ }
35041
+ return stops.length > 0 ? { kind: "interpolate", type: v[1], first: void 0, stops } : null;
35042
+ }
35043
+ if (v[0] === "step" && isZoom(v[1])) {
35044
+ const stops = [];
35045
+ for (let i = 3; i + 1 < v.length; i += 2) {
35046
+ if (typeof v[i] !== "number") return null;
35047
+ stops.push([v[i], v[i + 1]]);
35048
+ }
35049
+ return { kind: "step", type: null, first: v[2], stops };
35050
+ }
35051
+ return null;
35052
+ }
35053
+ if (v !== null && typeof v === "object") {
35054
+ const f = v;
35055
+ if (f.property !== void 0 || !Array.isArray(f.stops) || f.stops.length === 0) return null;
35056
+ const stops = [];
35057
+ for (const s of f.stops) {
35058
+ if (!Array.isArray(s) || s.length !== 2 || typeof s[0] !== "number") return null;
35059
+ stops.push([s[0], s[1]]);
35060
+ }
35061
+ if (f.type === "interval") return { kind: "step", type: null, first: stops[0][1], stops: stops.slice(1) };
35062
+ if (f.type !== void 0 && f.type !== "exponential") return null;
35063
+ const base = typeof f.base === "number" ? f.base : 1;
35064
+ return { kind: "interpolate", type: base === 1 ? ["linear"] : ["exponential", base], first: void 0, stops };
35065
+ }
35066
+ return null;
35067
+ }
35068
+ function interpolationT(type, z, z0, z1) {
35069
+ if (Array.isArray(type) && type[0] === "exponential" && typeof type[1] === "number" && type[1] !== 1) {
35070
+ const b = type[1];
35071
+ return (b ** (z - z0) - 1) / (b ** (z1 - z0) - 1);
35072
+ }
35073
+ return (z - z0) / (z1 - z0);
35074
+ }
35075
+ function blend(a, b, t, numeric) {
35076
+ if (t <= 0) return a;
35077
+ if (t >= 1) return b;
35078
+ if (typeof a === "number" && typeof b === "number") return round2(a + (b - a) * t);
35079
+ const aa = numArrayOf(a);
35080
+ const bb = numArrayOf(b);
35081
+ if (aa && bb) return aa.length === bb.length ? aa.map((x, i) => round2(x + (bb[i] - x) * t)) : void 0;
35082
+ if (numeric && !aa && !bb && (typeof a === "number" || Array.isArray(a)) && (typeof b === "number" || Array.isArray(b))) {
35083
+ return ["+", ["*", a, round2(1 - t)], ["*", b, round2(t)]];
35084
+ }
35085
+ return void 0;
35086
+ }
35087
+ function valueAt(c, z, numeric) {
35088
+ if (c.kind === "step") {
35089
+ let out = c.first;
35090
+ for (const [sz, o] of c.stops) if (sz <= z) out = o;
35091
+ return out;
35092
+ }
35093
+ const s = c.stops;
35094
+ if (z <= s[0][0]) return s[0][1];
35095
+ if (z >= s[s.length - 1][0]) return s[s.length - 1][1];
35096
+ for (let j = 0; j + 1 < s.length; j++) {
35097
+ const [z0, o0] = s[j];
35098
+ const [z1, o1] = s[j + 1];
35099
+ if (z === z0) return o0;
35100
+ if (z0 < z && z < z1) return blend(o0, o1, interpolationT(c.type, z, z0, z1), numeric);
35101
+ }
35102
+ return void 0;
35103
+ }
35104
+ function scaled3(v, f) {
35105
+ if (typeof v === "number") return round2(v * f);
35106
+ const arr = numArrayOf(v);
35107
+ if (arr) return arr.map((n) => round2(n * f));
35108
+ if (Array.isArray(v) && typeof v[0] === "string") return ["*", v, round2(f)];
35109
+ return void 0;
35110
+ }
35111
+ function reducedSize(value, floor, levels) {
35112
+ const curve = zoomCurveOf(value);
35113
+ if (curve === null && mentionsZoom2(value)) return void 0;
35114
+ const atFloor = curve ? valueAt(curve, floor, true) : value;
35115
+ if (atFloor === void 0) return void 0;
35116
+ const out = [];
35117
+ for (let i = levels * REDUCTION_STOPS_PER_LEVEL; i >= 1; i--) {
35118
+ const dz = i / REDUCTION_STOPS_PER_LEVEL;
35119
+ const v = scaled3(atFloor, 2 ** -dz);
35120
+ if (v === void 0) return void 0;
35121
+ out.push(round2(floor - dz), asOutput(v));
35122
+ }
35123
+ out.push(floor, asOutput(atFloor));
35124
+ if (curve === null) return ["interpolate", ["linear"], ["zoom"], ...out];
35125
+ if (curve.kind === "interpolate") {
35126
+ for (const [z, o] of curve.stops) if (z > floor) out.push(z, o);
35127
+ return ["interpolate", curve.type, ["zoom"], ...out];
35128
+ }
35129
+ let prev = atFloor;
35130
+ for (const [z, o] of curve.stops) {
35131
+ if (z <= floor) continue;
35132
+ if (z - STEP_RAMP > floor) out.push(z - STEP_RAMP, asOutput(prev));
35133
+ out.push(z, asOutput(o));
35134
+ prev = o;
35135
+ }
35136
+ return ["interpolate", ["linear"], ["zoom"], ...out];
35137
+ }
35138
+ function heldAtFloor(value, floor) {
35139
+ const curve = zoomCurveOf(value);
35140
+ if (curve === null) return void 0;
35141
+ const atFloor = valueAt(curve, floor, false);
35142
+ if (atFloor === void 0) return void 0;
35143
+ const above = curve.stops.filter(([z]) => z > floor).flatMap(([z, o]) => [z, o]);
35144
+ if (above.length === 0) return atFloor;
35145
+ return curve.kind === "step" ? ["step", ["zoom"], atFloor, ...above] : ["interpolate", curve.type, ["zoom"], floor, asOutput(atFloor), ...above];
35146
+ }
35147
+ function filterAtFloor(filter, floor) {
35148
+ if (!Array.isArray(filter)) return filter;
35149
+ if (filter[0] === "literal") return filter;
35150
+ if (isZoom(filter)) return ["max", ["zoom"], floor];
35151
+ return filter.map((e) => filterAtFloor(e, floor));
35152
+ }
35153
+ function propsReduced(props, floor, decideAt, levels) {
35154
+ if (!props) return props;
35155
+ let next = null;
35156
+ for (const [name, value] of Object.entries(props)) {
35157
+ if (name === "visibility") continue;
35158
+ const moved = REDUCED_SIZE_PROPERTIES.has(name) ? reducedSize(value, floor, levels) : heldAtFloor(value, decideAt);
35159
+ if (moved === void 0) continue;
35160
+ next ??= { ...props };
35161
+ next[name] = moved;
35162
+ }
35163
+ return next ?? props;
35164
+ }
35165
+ function withChartReduction(layers, floor, options = {}) {
35166
+ const levels = options.levels ?? MAX_REDUCTION_LEVELS;
35167
+ const at = Math.min(floor, options.decideAt ?? floor);
35168
+ const lo = floor - levels;
35169
+ return layers.map((layer) => {
35170
+ const next = { ...layer };
35171
+ const min = layer.minzoom ?? 0;
35172
+ const max = layer.maxzoom ?? 24;
35173
+ if (min <= at && at < max) {
35174
+ if (min > lo) next.minzoom = lo;
35175
+ } else if (max <= at) {
35176
+ next.maxzoom = Math.max(min, Math.min(max, lo));
35177
+ }
35178
+ if (layer.filter !== void 0) next.filter = filterAtFloor(layer.filter, at);
35179
+ const paint = propsReduced(layer.paint, floor, at, levels);
35180
+ if (paint !== void 0) next.paint = paint;
35181
+ const layout = propsReduced(layer.layout, floor, at, levels);
35182
+ if (layout !== void 0) next.layout = layout;
35183
+ return next;
35184
+ });
35185
+ }
35186
+
35187
+ // src/atlas/served-chart-lock.ts
35188
+ var ONLY_SUFFIX = ":only";
35189
+ var CHART_LOCK_PARAMS = CHART_LOCK_BANDS.flatMap(({ name }) => {
35190
+ const band = name.toLowerCase();
35191
+ return [band, `${band}${ONLY_SUFFIX}`];
35192
+ });
35193
+ function chartLockParam(lock) {
35194
+ const band = chartLockBandInfo(lock.band).name.toLowerCase();
35195
+ return lock.bandOnly ? `${band}${ONLY_SUFFIX}` : band;
35196
+ }
35197
+ function parseChartLock(raw) {
35198
+ const lower = raw.toLowerCase();
35199
+ const bandOnly = lower.endsWith(ONLY_SUFFIX);
35200
+ const name = bandOnly ? lower.slice(0, -ONLY_SUFFIX.length) : lower;
35201
+ const info = CHART_LOCK_BANDS.find((b) => b.name.toLowerCase() === name);
35202
+ return info ? { band: info.band, bandOnly } : null;
35203
+ }
35204
+ function chartLockGeneratorOptions(lock) {
35205
+ return lock?.bandOnly ? { chartMode: chartLockStyleMode(lock.band) } : {};
35206
+ }
35207
+ function servedChartLockMetadata(lock) {
35208
+ const info = chartLockBandInfo(lock.band);
35209
+ return {
35210
+ "chrt:lock": chartLockParam(lock),
35211
+ "chrt:lock-band": info.name,
35212
+ "chrt:lock-floor": info.floor,
35213
+ "chrt:lock-min-zoom": chartLockMinZoom(lock.band),
35214
+ "chrt:lock-band-only": lock.bandOnly
35215
+ };
35216
+ }
35217
+ function withServedChartLock(style, lock, chartSource) {
35218
+ const info = chartLockBandInfo(lock.band);
35219
+ const param = chartLockParam(lock);
35220
+ const layers = withChartReduction(style.layers, info.floor, {
35221
+ decideAt: chartLockDecisionZoom(lock.band, lock.bandOnly)
35222
+ });
35223
+ let sources = style.sources;
35224
+ const chart = style.sources[chartSource];
35225
+ if (lock.bandOnly && chart !== null && typeof chart === "object") {
35226
+ const current = chart.maxzoom;
35227
+ const maxzoom = chartLockSourceMaxzoom(lock.band, typeof current === "number" ? current : CHART_ARCHIVE_MAXZOOM);
35228
+ sources = { ...style.sources, [chartSource]: { ...chart, maxzoom } };
35229
+ }
35230
+ return {
35231
+ ...style,
35232
+ name: `${style.name.replace(/ — chart:[A-Za-z]+$/, "")} \u2014 lock:${param}`,
35233
+ metadata: {
35234
+ ...style.metadata,
35235
+ "chrt:render-mode": "continuous",
35236
+ ...servedChartLockMetadata(lock)
35237
+ },
35238
+ sources,
35239
+ layers
35240
+ };
35241
+ }
35242
+
34946
35243
  // src/pagination.ts
34947
35244
  async function* paginate(fetchPage, getItems, getTotalCount, options) {
34948
35245
  const pageSize = options?.pageSize ?? 100;
@@ -35388,8 +35685,11 @@ export {
35388
35685
  BUILD_MAXZOOM,
35389
35686
  BUILD_MINZOOM,
35390
35687
  BUILD_PARAM,
35688
+ CHART_ARCHIVE_MAXZOOM,
35391
35689
  CHART_BAND_CODES,
35392
35690
  CHART_CASCADE_CODES,
35691
+ CHART_LOCK_BANDS,
35692
+ CHART_LOCK_PARAMS,
35393
35693
  CHART_LOOKS,
35394
35694
  CHART_SECTIONS,
35395
35695
  CHART_SOUNDINGS_RULE,
@@ -35418,6 +35718,7 @@ export {
35418
35718
  DANGER_DEPTH_PLACER_ID,
35419
35719
  DANGER_DEPTH_PLACER_LAYOUT,
35420
35720
  DANGER_DEPTH_VISIBLE_LAYOUT,
35721
+ DEFAULT_CHART_LOCK_BAND,
35421
35722
  DEFAULT_CLICK_TOLERANCE,
35422
35723
  DEFAULT_CUSTOM_STYLE_CONFIG,
35423
35724
  DEFAULT_INSPECT_CLASS_RANK,
@@ -35439,6 +35740,7 @@ export {
35439
35740
  EINK_HATCH_PATTERN,
35440
35741
  EINK_MONO_GREYS,
35441
35742
  ENGRAVED_LOOKS,
35743
+ FINER_DATA_DECISION_OFFSET,
35442
35744
  HAZARD_LABEL_PRIORITY,
35443
35745
  INSPECT_CLASS_RANK,
35444
35746
  INSPECT_RANK_DEVIATIONS,
@@ -35466,6 +35768,7 @@ export {
35466
35768
  LOOK_TONES,
35467
35769
  LOOK_WATERLINES_SOURCE,
35468
35770
  MAPLIBRE_DEFAULT_TEXT_PADDING_PX,
35771
+ MAX_REDUCTION_LEVELS,
35469
35772
  NAUTICAL_SYMBOLS,
35470
35773
  NAV_AID_LAYER_GROUPS,
35471
35774
  NAV_AID_QUERY_LAYERS,
@@ -35483,6 +35786,7 @@ export {
35483
35786
  RASTER_ATON_CLASSES,
35484
35787
  RASTER_GLYPH_NAMES,
35485
35788
  RASTER_ICON_PREFIX,
35789
+ REDUCED_SIZE_PROPERTIES,
35486
35790
  RELIEF_ATTRIBUTION,
35487
35791
  RELIEF_ENCODING,
35488
35792
  RELIEF_REGION,
@@ -35578,6 +35882,14 @@ export {
35578
35882
  capLuminance,
35579
35883
  cellBandCharacters,
35580
35884
  cellBandMatch,
35885
+ chartLockBandInfo,
35886
+ chartLockDecisionZoom,
35887
+ chartLockFloor,
35888
+ chartLockGeneratorOptions,
35889
+ chartLockMinZoom,
35890
+ chartLockParam,
35891
+ chartLockSourceMaxzoom,
35892
+ chartLockStyleMode,
35581
35893
  chartSymbolSizingCensus,
35582
35894
  chrtAtonTintExpression,
35583
35895
  chrtHouseColor,
@@ -35617,6 +35929,7 @@ export {
35617
35929
  extinguishedLightExpression,
35618
35930
  extractNavAidDesignation,
35619
35931
  featureIdentity,
35932
+ filterAtFloor,
35620
35933
  formatDayboard,
35621
35934
  formatLightDescription,
35622
35935
  formatLightRhythm,
@@ -35653,6 +35966,7 @@ export {
35653
35966
  hazardFillExpression,
35654
35967
  iconExpressionForFamily,
35655
35968
  iconSliderFor,
35969
+ isChartLockBand,
35656
35970
  isDangerDepthPlacer,
35657
35971
  isDepthAreaClassLayerId,
35658
35972
  isDrapeable,
@@ -35691,6 +36005,7 @@ export {
35691
36005
  normalizeTheme,
35692
36006
  opaqueSplitBaseOf,
35693
36007
  paginate,
36008
+ parseChartLock,
35694
36009
  parseChartLook,
35695
36010
  parseListCodes,
35696
36011
  parseSigseqTerms,
@@ -35720,6 +36035,7 @@ export {
35720
36035
  seafloorLayers,
35721
36036
  sectorLimitToArcBearing,
35722
36037
  semiboldFontStack,
36038
+ servedChartLockMetadata,
35723
36039
  snapChartSymbolScale,
35724
36040
  soundingPadding,
35725
36041
  soundingPaddingValue,
@@ -35732,8 +36048,10 @@ export {
35732
36048
  themeChrtGlyph,
35733
36049
  tileTemplate,
35734
36050
  uncoveredSectorArcs,
36051
+ withChartReduction,
35735
36052
  withClassicMarks,
35736
36053
  withLook,
36054
+ withServedChartLock,
35737
36055
  withWaterLines,
35738
36056
  withinBboxFilter,
35739
36057
  worldMinusBboxPolygon