@chrtco/sdk 0.10.12 → 0.10.13
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 +87 -40
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -10
- package/dist/index.d.ts +9 -10
- package/dist/index.js +87 -40
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -5488,16 +5488,23 @@ function patternSpriteId(patternName) {
|
|
|
5488
5488
|
// src/atlas/s52-conditional.ts
|
|
5489
5489
|
var DEFAULT_SAFETY_CONTOUR_M = 10;
|
|
5490
5490
|
var DEPARE_DEEP_CUT_M = 18.2;
|
|
5491
|
-
|
|
5491
|
+
var DEPARE_SHALLOW_CUT_M = 2;
|
|
5492
|
+
function effectiveSafetyContour(safetyContourM) {
|
|
5493
|
+
if (!Number.isFinite(safetyContourM)) return DEFAULT_SAFETY_CONTOUR_M;
|
|
5494
|
+
return Math.min(Math.max(safetyContourM, DEPARE_SHALLOW_CUT_M), DEPARE_DEEP_CUT_M);
|
|
5495
|
+
}
|
|
5496
|
+
function depareColor(props, ct = "DAY", safetyContourM = DEFAULT_SAFETY_CONTOUR_M) {
|
|
5492
5497
|
const drval1 = Number(props.DRVAL1 ?? props.drval1 ?? -1);
|
|
5493
5498
|
const drval2 = Number(props.DRVAL2 ?? props.drval2 ?? drval1);
|
|
5499
|
+
const safety = effectiveSafetyContour(safetyContourM);
|
|
5494
5500
|
if (drval1 < 0 && drval2 <= 0) return resolveColor("DEPIT", ct);
|
|
5495
|
-
if (drval1 <
|
|
5496
|
-
if (drval1 <
|
|
5501
|
+
if (drval1 < DEPARE_SHALLOW_CUT_M) return resolveColor("DEPVS", ct);
|
|
5502
|
+
if (drval1 < safety) return resolveColor("DEPMS", ct);
|
|
5497
5503
|
if (drval1 < DEPARE_DEEP_CUT_M) return resolveColor("DEPMD", ct);
|
|
5498
5504
|
return resolveColor("DEPDW", ct);
|
|
5499
5505
|
}
|
|
5500
|
-
function depareFillExpression(ct = "DAY") {
|
|
5506
|
+
function depareFillExpression(ct = "DAY", safetyContourM = DEFAULT_SAFETY_CONTOUR_M) {
|
|
5507
|
+
const safety = effectiveSafetyContour(safetyContourM);
|
|
5501
5508
|
return [
|
|
5502
5509
|
"case",
|
|
5503
5510
|
[
|
|
@@ -5506,9 +5513,9 @@ function depareFillExpression(ct = "DAY") {
|
|
|
5506
5513
|
["<=", ["coalesce", ["get", "DRVAL2"], ["get", "drval2"], 0], 0]
|
|
5507
5514
|
],
|
|
5508
5515
|
resolveColor("DEPIT", ct),
|
|
5509
|
-
["<", ["coalesce", ["get", "DRVAL1"], ["get", "drval1"], -1],
|
|
5516
|
+
["<", ["coalesce", ["get", "DRVAL1"], ["get", "drval1"], -1], DEPARE_SHALLOW_CUT_M],
|
|
5510
5517
|
resolveColor("DEPVS", ct),
|
|
5511
|
-
["<", ["coalesce", ["get", "DRVAL1"], ["get", "drval1"], -1],
|
|
5518
|
+
["<", ["coalesce", ["get", "DRVAL1"], ["get", "drval1"], -1], safety],
|
|
5512
5519
|
resolveColor("DEPMS", ct),
|
|
5513
5520
|
["<", ["coalesce", ["get", "DRVAL1"], ["get", "drval1"], -1], DEPARE_DEEP_CUT_M],
|
|
5514
5521
|
resolveColor("DEPMD", ct),
|
|
@@ -22287,15 +22294,32 @@ function isVisibleInMode(displayCategory, mode) {
|
|
|
22287
22294
|
if (mode === "STANDARD") return displayCategory === "BASE" || displayCategory === "STANDARD";
|
|
22288
22295
|
return displayCategory === "BASE";
|
|
22289
22296
|
}
|
|
22297
|
+
var SCAMIN_ZOOM_BUCKETS = [
|
|
22298
|
+
[12e3, 14],
|
|
22299
|
+
[22e3, 12],
|
|
22300
|
+
[45e3, 11],
|
|
22301
|
+
[9e4, 10],
|
|
22302
|
+
[35e4, 8],
|
|
22303
|
+
[15e5, 6]
|
|
22304
|
+
];
|
|
22290
22305
|
function scaminToMinZoom(scamin) {
|
|
22291
22306
|
if (scamin === void 0 || scamin === null || scamin === 0) return void 0;
|
|
22292
|
-
|
|
22293
|
-
|
|
22294
|
-
|
|
22295
|
-
|
|
22296
|
-
|
|
22297
|
-
|
|
22298
|
-
|
|
22307
|
+
let zoom;
|
|
22308
|
+
for (const [denom, z] of SCAMIN_ZOOM_BUCKETS) {
|
|
22309
|
+
if (scamin >= denom) zoom = z;
|
|
22310
|
+
}
|
|
22311
|
+
return zoom;
|
|
22312
|
+
}
|
|
22313
|
+
function scaminZoomGateFilter() {
|
|
22314
|
+
const step = [
|
|
22315
|
+
"step",
|
|
22316
|
+
["to-number", ["coalesce", ["get", "SCAMIN"], ["get", "scamin"], 0]],
|
|
22317
|
+
0
|
|
22318
|
+
];
|
|
22319
|
+
for (const [denom, z] of SCAMIN_ZOOM_BUCKETS) {
|
|
22320
|
+
step.push(denom, z);
|
|
22321
|
+
}
|
|
22322
|
+
return [">=", ["zoom"], step];
|
|
22299
22323
|
}
|
|
22300
22324
|
var SAFETY_CRITICAL_GROUPS = /* @__PURE__ */ new Set([24020, 27010, 27070, 27080]);
|
|
22301
22325
|
var OPAQUE_FILL_LAYERS = /* @__PURE__ */ new Set(["DEPARE", "LNDARE", "UNSARE", "LAKARE", "DRGARE", "SEAARE"]);
|
|
@@ -22329,7 +22353,7 @@ var ZOOM_SCALED_LINES = {
|
|
|
22329
22353
|
BRIDGE: [8, 1, 14, 2],
|
|
22330
22354
|
DAMCON: [8, 1, 14, 2]
|
|
22331
22355
|
};
|
|
22332
|
-
function resolvePaint(layerName, paint, geomType, ct = "DAY") {
|
|
22356
|
+
function resolvePaint(layerName, paint, geomType, ct = "DAY", opts = {}) {
|
|
22333
22357
|
const resolved = {};
|
|
22334
22358
|
for (const [key, value] of Object.entries(paint)) {
|
|
22335
22359
|
if (typeof value === "string" && /^[A-Z]{4,5}[0-9]?$/.test(value)) {
|
|
@@ -22339,7 +22363,7 @@ function resolvePaint(layerName, paint, geomType, ct = "DAY") {
|
|
|
22339
22363
|
}
|
|
22340
22364
|
}
|
|
22341
22365
|
if (layerName === "DEPARE" && geomType === "fill") {
|
|
22342
|
-
resolved["fill-color"] = depareFillExpression(ct);
|
|
22366
|
+
resolved["fill-color"] = depareFillExpression(ct, opts.safetyContour);
|
|
22343
22367
|
} else if (layerName === "LIGHTS" && geomType === "circle") {
|
|
22344
22368
|
resolved["circle-color"] = lightFillExpression(ct);
|
|
22345
22369
|
} else if ((layerName === "BOYLAT" || layerName === "BCNLAT") && geomType === "circle") {
|
|
@@ -22351,7 +22375,7 @@ function resolvePaint(layerName, paint, geomType, ct = "DAY") {
|
|
|
22351
22375
|
}
|
|
22352
22376
|
return resolved;
|
|
22353
22377
|
}
|
|
22354
|
-
function resolveStyle(layerName, geomKind, ct = "DAY") {
|
|
22378
|
+
function resolveStyle(layerName, geomKind, ct = "DAY", opts = {}) {
|
|
22355
22379
|
const entry = S52_LOOKUP[layerName];
|
|
22356
22380
|
if (!entry) {
|
|
22357
22381
|
const type = geomKind ?? "circle";
|
|
@@ -22387,7 +22411,7 @@ function resolveStyle(layerName, geomKind, ct = "DAY") {
|
|
|
22387
22411
|
const paint2 = effectiveType === "fill" ? { "fill-color": hexColor, "fill-opacity": 0.3 } : effectiveType === "line" ? { "line-color": hexColor, "line-width": 1 } : { "circle-color": hexColor, "circle-radius": 3, "circle-stroke-width": 0 };
|
|
22388
22412
|
return { type: effectiveType, paint: paint2 };
|
|
22389
22413
|
}
|
|
22390
|
-
const paint = resolvePaint(layerName, { ...entry.style.paint }, effectiveType, ct);
|
|
22414
|
+
const paint = resolvePaint(layerName, { ...entry.style.paint }, effectiveType, ct, opts);
|
|
22391
22415
|
if (effectiveType === "fill" && OPAQUE_FILL_LAYERS.has(layerName)) {
|
|
22392
22416
|
paint["fill-opacity"] = 1;
|
|
22393
22417
|
}
|
|
@@ -23336,21 +23360,19 @@ function getLabelConfig(layerName, opts = {}) {
|
|
|
23336
23360
|
layout: orientationLabelLayout({
|
|
23337
23361
|
"text-letter-spacing": 0.15,
|
|
23338
23362
|
"text-max-width": 9,
|
|
23339
|
-
// SEAARE
|
|
23340
|
-
//
|
|
23341
|
-
//
|
|
23342
|
-
//
|
|
23343
|
-
//
|
|
23344
|
-
//
|
|
23345
|
-
//
|
|
23346
|
-
//
|
|
23347
|
-
//
|
|
23348
|
-
//
|
|
23349
|
-
//
|
|
23350
|
-
//
|
|
23351
|
-
|
|
23352
|
-
"text-ignore-placement": true,
|
|
23353
|
-
"text-optional": false,
|
|
23363
|
+
// SEAARE was always-paint (allow-overlap + ignore-placement)
|
|
23364
|
+
// because collision starved big-water names at z8. That trade
|
|
23365
|
+
// inverted in the field on 2026-08-21: the always-paint copies —
|
|
23366
|
+
// per band, per adjacent cell, and one per TILE-CLIPPED piece of
|
|
23367
|
+
// a big polygon — stack into unreadable black smears (dozens of
|
|
23368
|
+
// "Chesapeake Bay" at z9, owner screenshot). With collision ON
|
|
23369
|
+
// the duplicates collide with EACH OTHER, so MapLibre keeps one
|
|
23370
|
+
// and drops the rest: a possibly-starved name beats an illegible
|
|
23371
|
+
// smear categorically. This is the interim state until the
|
|
23372
|
+
// PLACENAME layer (one anchor per named place, PR #1308) reaches
|
|
23373
|
+
// the tiles and replaces this fan outright — do not restore
|
|
23374
|
+
// always-paint on a starvation report; flip `labels: "placename"`
|
|
23375
|
+
// instead once the build carries the layer.
|
|
23354
23376
|
"text-padding": 2
|
|
23355
23377
|
})
|
|
23356
23378
|
};
|
|
@@ -26957,6 +26979,13 @@ function buildSources(opts = {}) {
|
|
|
26957
26979
|
}
|
|
26958
26980
|
|
|
26959
26981
|
// src/atlas/layer-builder.ts
|
|
26982
|
+
var SCAMIN_DECLUTTER_CLASSES = /* @__PURE__ */ new Set([
|
|
26983
|
+
"OFSPLF",
|
|
26984
|
+
"PIPSOL",
|
|
26985
|
+
"PIPARE",
|
|
26986
|
+
"CBLSUB",
|
|
26987
|
+
"CBLARE"
|
|
26988
|
+
]);
|
|
26960
26989
|
var GEOM_FILTERS = {
|
|
26961
26990
|
fill: ["any", ["==", ["geometry-type"], "Polygon"], ["==", ["geometry-type"], "MultiPolygon"]],
|
|
26962
26991
|
line: ["any", ["==", ["geometry-type"], "LineString"], ["==", ["geometry-type"], "MultiLineString"]],
|
|
@@ -27115,7 +27144,7 @@ function buildLayersForClass(objectClass, ct, sourceId = DEFAULT_REGION, opts =
|
|
|
27115
27144
|
const layers = [];
|
|
27116
27145
|
const geomTypes = getGeomTypesForClass(objectClass, entry?.style.type);
|
|
27117
27146
|
for (const geomType of geomTypes) {
|
|
27118
|
-
const resolved = resolveStyle(objectClass, geomType, ct);
|
|
27147
|
+
const resolved = resolveStyle(objectClass, geomType, ct, { safetyContour: opts.safetyContour });
|
|
27119
27148
|
const layerId = `s52-${objectClass}-${resolved.type}`;
|
|
27120
27149
|
const layer = {
|
|
27121
27150
|
id: layerId,
|
|
@@ -27134,6 +27163,9 @@ function buildLayersForClass(objectClass, ct, sourceId = DEFAULT_REGION, opts =
|
|
|
27134
27163
|
} else if (GEOM_FILTERS[resolved.type]) {
|
|
27135
27164
|
layer.filter = GEOM_FILTERS[resolved.type];
|
|
27136
27165
|
}
|
|
27166
|
+
if (SCAMIN_DECLUTTER_CLASSES.has(objectClass)) {
|
|
27167
|
+
layer.filter = layer.filter ? ["all", layer.filter, scaminZoomGateFilter()] : ["all", scaminZoomGateFilter()];
|
|
27168
|
+
}
|
|
27137
27169
|
if (resolved.minzoom) {
|
|
27138
27170
|
layer.minzoom = resolved.minzoom;
|
|
27139
27171
|
}
|
|
@@ -28429,6 +28461,18 @@ function isExemptOpaqueFill(layer) {
|
|
|
28429
28461
|
}
|
|
28430
28462
|
return false;
|
|
28431
28463
|
}
|
|
28464
|
+
var FILL_FLOOR_FREE_BANDS = /* @__PURE__ */ new Set([
|
|
28465
|
+
"1",
|
|
28466
|
+
"2",
|
|
28467
|
+
"3"
|
|
28468
|
+
]);
|
|
28469
|
+
function bandVariantMinzoom(layer, B) {
|
|
28470
|
+
const classMinzoom = layer.minzoom ?? 0;
|
|
28471
|
+
if (isExemptOpaqueFill(layer) && FILL_FLOOR_FREE_BANDS.has(B)) {
|
|
28472
|
+
return classMinzoom;
|
|
28473
|
+
}
|
|
28474
|
+
return Math.max(classMinzoom, BAND_PRIORITY_RANGES[B].minzoom);
|
|
28475
|
+
}
|
|
28432
28476
|
var BAND_DRAW_ORDER = ["1", "2", "3", "4", "5", "6"];
|
|
28433
28477
|
var CHART_BAND_CODES = {
|
|
28434
28478
|
Overview: ["1"],
|
|
@@ -28547,9 +28591,7 @@ function collapsedDominanceGate(B, minzoom) {
|
|
|
28547
28591
|
return ["any", ...clauses];
|
|
28548
28592
|
}
|
|
28549
28593
|
function makeCollapsedBandVariant(layer, B, isExempt) {
|
|
28550
|
-
const
|
|
28551
|
-
const classMinzoom = layer.minzoom ?? 0;
|
|
28552
|
-
const minzoom = isExemptOpaqueFill(layer) ? classMinzoom : Math.max(classMinzoom, range.minzoom);
|
|
28594
|
+
const minzoom = bandVariantMinzoom(layer, B);
|
|
28553
28595
|
if (isExempt) {
|
|
28554
28596
|
const exempt = {
|
|
28555
28597
|
...layer,
|
|
@@ -28688,8 +28730,7 @@ function isDominanceExempt(layer) {
|
|
|
28688
28730
|
var TOP_STACK_LIGHT_CLASSES = /* @__PURE__ */ new Set(["LIGHTS"]);
|
|
28689
28731
|
function makeBandVariants(layer, B) {
|
|
28690
28732
|
const range = BAND_PRIORITY_RANGES[B];
|
|
28691
|
-
const
|
|
28692
|
-
const minzoom = isExemptOpaqueFill(layer) ? classMinzoom : Math.max(classMinzoom, range.minzoom);
|
|
28733
|
+
const minzoom = bandVariantMinzoom(layer, B);
|
|
28693
28734
|
const variants = [];
|
|
28694
28735
|
if (isDominanceExempt(layer)) {
|
|
28695
28736
|
const exempt = {
|
|
@@ -28997,6 +29038,12 @@ function generateStyle(palette = "DAY", opts = {}) {
|
|
|
28997
29038
|
}
|
|
28998
29039
|
const symbolSet = opts.symbolSet ?? "s52";
|
|
28999
29040
|
const spriteBase = `${opts.tileBaseUrl ?? "https://tiles.chrt.co"}/v1/sprites`;
|
|
29041
|
+
const isLndareFill = (l) => /^s52-LNDARE-fill-band\d+$/.test(l.id);
|
|
29042
|
+
const emitted = opts.land ? (() => {
|
|
29043
|
+
const fills = layers.filter(isLndareFill);
|
|
29044
|
+
const rest = layers.filter((l) => !isLndareFill(l));
|
|
29045
|
+
return [rest[0], ...fills, ...rest.slice(1)];
|
|
29046
|
+
})() : layers;
|
|
29000
29047
|
const style = {
|
|
29001
29048
|
version: 8,
|
|
29002
29049
|
name: `CHRT ${SYMBOL_SET_LABELS[symbolSet]} ${PALETTE_NAMES[palette]}${opts.chartMode ? ` \u2014 chart:${opts.chartMode.band}` : ""}`,
|
|
@@ -29005,7 +29052,7 @@ function generateStyle(palette = "DAY", opts = {}) {
|
|
|
29005
29052
|
"chrt:symbol-set": symbolSet,
|
|
29006
29053
|
"chrt:color-table": palette,
|
|
29007
29054
|
"chrt:generated-at": (/* @__PURE__ */ new Date()).toISOString(),
|
|
29008
|
-
"chrt:layer-count":
|
|
29055
|
+
"chrt:layer-count": emitted.length,
|
|
29009
29056
|
"chrt:land": Boolean(opts.land),
|
|
29010
29057
|
"chrt:relief": Boolean(opts.relief),
|
|
29011
29058
|
"chrt:render-mode": opts.chartMode ? `chart:${opts.chartMode.band}` : "continuous",
|
|
@@ -29028,7 +29075,7 @@ function generateStyle(palette = "DAY", opts = {}) {
|
|
|
29028
29075
|
sprite: `${spriteBase}/${symbolSet}-${palette.toLowerCase()}`
|
|
29029
29076
|
},
|
|
29030
29077
|
glyphs: "https://fonts.openmaptiles.org/{fontstack}/{range}.pbf",
|
|
29031
|
-
layers
|
|
29078
|
+
layers: emitted
|
|
29032
29079
|
};
|
|
29033
29080
|
if (symbolSet === "s101") return applyS101SymbolSet(style);
|
|
29034
29081
|
if (symbolSet === "chrt") return applyChrtSymbolSet(style, palette);
|