@chrtco/sdk 0.10.11 → 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/CHANGELOG.md +12 -0
- package/dist/index.cjs +217 -45
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +120 -11
- package/dist/index.d.ts +120 -11
- package/dist/index.js +206 -45
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,18 @@ All notable changes to `@chrtco/sdk` will be documented in this file.
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
7
|
### Added
|
|
8
|
+
- **`StyleGeneratorOptions.labels`** — `"legacy"` (default) or `"placename"`.
|
|
9
|
+
`"placename"` swaps the 9 orientation classes' 54-layer per-band label fan
|
|
10
|
+
for 2 collision-managed `PLACENAME` symbol layers over the tile pipeline's
|
|
11
|
+
place-name index: one label per named place, per-feature zoom windows
|
|
12
|
+
(`min_z`/`max_z` from place extent, S-57 SCAMIN and class floors), and a
|
|
13
|
+
build-side `rank` driving `symbol-sort-key` so the most important names
|
|
14
|
+
survive density. Requires tiles carrying the `PLACENAME` layer; the default
|
|
15
|
+
stays `"legacy"` until the deconfliction rollout flips it
|
|
16
|
+
(docs/design/chart-label-deconfliction.md §2.3). New exports:
|
|
17
|
+
`buildPlaceNameLayers()`, `PLACENAME_SOURCE_LAYER`,
|
|
18
|
+
`PLACENAME_WATER_CLASSES`, `PLACENAME_LAND_CLASSES`, and the per-class
|
|
19
|
+
tier expression builders (`buildSeaAreaTierExpression()` et al.).
|
|
8
20
|
- **CHRTland on the Style API** — `StyleUrlOptions.land` / `.relief` thread
|
|
9
21
|
`?land=` / `?relief=` to `GET /v1/styles/{region}/style.json`. `generateStyle`
|
|
10
22
|
learned to emit CHRTland and the first-party app learned to ask for it, but
|
package/dist/index.cjs
CHANGED
|
@@ -70,6 +70,9 @@ __export(index_exports, {
|
|
|
70
70
|
NON_SOLAS_DISCLAIMER_SHORT: () => NON_SOLAS_DISCLAIMER_SHORT,
|
|
71
71
|
OfflineError: () => OfflineError,
|
|
72
72
|
OfflineStyleError: () => OfflineStyleError,
|
|
73
|
+
PLACENAME_LAND_CLASSES: () => PLACENAME_LAND_CLASSES,
|
|
74
|
+
PLACENAME_SOURCE_LAYER: () => PLACENAME_SOURCE_LAYER,
|
|
75
|
+
PLACENAME_WATER_CLASSES: () => PLACENAME_WATER_CLASSES,
|
|
73
76
|
RASTER_ATON_CLASSES: () => RASTER_ATON_CLASSES,
|
|
74
77
|
RASTER_GLYPH_NAMES: () => RASTER_GLYPH_NAMES,
|
|
75
78
|
RASTER_ICON_PREFIX: () => RASTER_ICON_PREFIX,
|
|
@@ -109,10 +112,18 @@ __export(index_exports, {
|
|
|
109
112
|
applyS101SymbolSet: () => applyS101SymbolSet,
|
|
110
113
|
atonIconExpression: () => atonIconExpression,
|
|
111
114
|
bandFilterExpression: () => bandFilterExpression,
|
|
115
|
+
buildAirportTierExpression: () => buildAirportTierExpression,
|
|
116
|
+
buildBuiltUpAreaTierExpression: () => buildBuiltUpAreaTierExpression,
|
|
112
117
|
buildFlashPattern: () => buildFlashPattern,
|
|
113
118
|
buildLabelLayer: () => buildLabelLayer,
|
|
119
|
+
buildLakeTierExpression: () => buildLakeTierExpression,
|
|
120
|
+
buildLandAreaTierExpression: () => buildLandAreaTierExpression,
|
|
121
|
+
buildLandRegionTierExpression: () => buildLandRegionTierExpression,
|
|
114
122
|
buildLayersForClass: () => buildLayersForClass,
|
|
115
123
|
buildOfflineStyle: () => buildOfflineStyle,
|
|
124
|
+
buildPlaceNameLayers: () => buildPlaceNameLayers,
|
|
125
|
+
buildRiverTierExpression: () => buildRiverTierExpression,
|
|
126
|
+
buildSeaAreaTierExpression: () => buildSeaAreaTierExpression,
|
|
116
127
|
buildSectorArcGeoJSON: () => buildSectorArcGeoJSON,
|
|
117
128
|
buildSectorArcsFC: () => buildSectorArcsFC,
|
|
118
129
|
buildSectorsFromFeatures: () => buildSectorsFromFeatures,
|
|
@@ -5477,16 +5488,23 @@ function patternSpriteId(patternName) {
|
|
|
5477
5488
|
// src/atlas/s52-conditional.ts
|
|
5478
5489
|
var DEFAULT_SAFETY_CONTOUR_M = 10;
|
|
5479
5490
|
var DEPARE_DEEP_CUT_M = 18.2;
|
|
5480
|
-
|
|
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) {
|
|
5481
5497
|
const drval1 = Number(props.DRVAL1 ?? props.drval1 ?? -1);
|
|
5482
5498
|
const drval2 = Number(props.DRVAL2 ?? props.drval2 ?? drval1);
|
|
5499
|
+
const safety = effectiveSafetyContour(safetyContourM);
|
|
5483
5500
|
if (drval1 < 0 && drval2 <= 0) return resolveColor("DEPIT", ct);
|
|
5484
|
-
if (drval1 <
|
|
5485
|
-
if (drval1 <
|
|
5501
|
+
if (drval1 < DEPARE_SHALLOW_CUT_M) return resolveColor("DEPVS", ct);
|
|
5502
|
+
if (drval1 < safety) return resolveColor("DEPMS", ct);
|
|
5486
5503
|
if (drval1 < DEPARE_DEEP_CUT_M) return resolveColor("DEPMD", ct);
|
|
5487
5504
|
return resolveColor("DEPDW", ct);
|
|
5488
5505
|
}
|
|
5489
|
-
function depareFillExpression(ct = "DAY") {
|
|
5506
|
+
function depareFillExpression(ct = "DAY", safetyContourM = DEFAULT_SAFETY_CONTOUR_M) {
|
|
5507
|
+
const safety = effectiveSafetyContour(safetyContourM);
|
|
5490
5508
|
return [
|
|
5491
5509
|
"case",
|
|
5492
5510
|
[
|
|
@@ -5495,9 +5513,9 @@ function depareFillExpression(ct = "DAY") {
|
|
|
5495
5513
|
["<=", ["coalesce", ["get", "DRVAL2"], ["get", "drval2"], 0], 0]
|
|
5496
5514
|
],
|
|
5497
5515
|
resolveColor("DEPIT", ct),
|
|
5498
|
-
["<", ["coalesce", ["get", "DRVAL1"], ["get", "drval1"], -1],
|
|
5516
|
+
["<", ["coalesce", ["get", "DRVAL1"], ["get", "drval1"], -1], DEPARE_SHALLOW_CUT_M],
|
|
5499
5517
|
resolveColor("DEPVS", ct),
|
|
5500
|
-
["<", ["coalesce", ["get", "DRVAL1"], ["get", "drval1"], -1],
|
|
5518
|
+
["<", ["coalesce", ["get", "DRVAL1"], ["get", "drval1"], -1], safety],
|
|
5501
5519
|
resolveColor("DEPMS", ct),
|
|
5502
5520
|
["<", ["coalesce", ["get", "DRVAL1"], ["get", "drval1"], -1], DEPARE_DEEP_CUT_M],
|
|
5503
5521
|
resolveColor("DEPMD", ct),
|
|
@@ -22276,15 +22294,32 @@ function isVisibleInMode(displayCategory, mode) {
|
|
|
22276
22294
|
if (mode === "STANDARD") return displayCategory === "BASE" || displayCategory === "STANDARD";
|
|
22277
22295
|
return displayCategory === "BASE";
|
|
22278
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
|
+
];
|
|
22279
22305
|
function scaminToMinZoom(scamin) {
|
|
22280
22306
|
if (scamin === void 0 || scamin === null || scamin === 0) return void 0;
|
|
22281
|
-
|
|
22282
|
-
|
|
22283
|
-
|
|
22284
|
-
|
|
22285
|
-
|
|
22286
|
-
|
|
22287
|
-
|
|
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];
|
|
22288
22323
|
}
|
|
22289
22324
|
var SAFETY_CRITICAL_GROUPS = /* @__PURE__ */ new Set([24020, 27010, 27070, 27080]);
|
|
22290
22325
|
var OPAQUE_FILL_LAYERS = /* @__PURE__ */ new Set(["DEPARE", "LNDARE", "UNSARE", "LAKARE", "DRGARE", "SEAARE"]);
|
|
@@ -22318,7 +22353,7 @@ var ZOOM_SCALED_LINES = {
|
|
|
22318
22353
|
BRIDGE: [8, 1, 14, 2],
|
|
22319
22354
|
DAMCON: [8, 1, 14, 2]
|
|
22320
22355
|
};
|
|
22321
|
-
function resolvePaint(layerName, paint, geomType, ct = "DAY") {
|
|
22356
|
+
function resolvePaint(layerName, paint, geomType, ct = "DAY", opts = {}) {
|
|
22322
22357
|
const resolved = {};
|
|
22323
22358
|
for (const [key, value] of Object.entries(paint)) {
|
|
22324
22359
|
if (typeof value === "string" && /^[A-Z]{4,5}[0-9]?$/.test(value)) {
|
|
@@ -22328,7 +22363,7 @@ function resolvePaint(layerName, paint, geomType, ct = "DAY") {
|
|
|
22328
22363
|
}
|
|
22329
22364
|
}
|
|
22330
22365
|
if (layerName === "DEPARE" && geomType === "fill") {
|
|
22331
|
-
resolved["fill-color"] = depareFillExpression(ct);
|
|
22366
|
+
resolved["fill-color"] = depareFillExpression(ct, opts.safetyContour);
|
|
22332
22367
|
} else if (layerName === "LIGHTS" && geomType === "circle") {
|
|
22333
22368
|
resolved["circle-color"] = lightFillExpression(ct);
|
|
22334
22369
|
} else if ((layerName === "BOYLAT" || layerName === "BCNLAT") && geomType === "circle") {
|
|
@@ -22340,7 +22375,7 @@ function resolvePaint(layerName, paint, geomType, ct = "DAY") {
|
|
|
22340
22375
|
}
|
|
22341
22376
|
return resolved;
|
|
22342
22377
|
}
|
|
22343
|
-
function resolveStyle(layerName, geomKind, ct = "DAY") {
|
|
22378
|
+
function resolveStyle(layerName, geomKind, ct = "DAY", opts = {}) {
|
|
22344
22379
|
const entry = S52_LOOKUP[layerName];
|
|
22345
22380
|
if (!entry) {
|
|
22346
22381
|
const type = geomKind ?? "circle";
|
|
@@ -22376,7 +22411,7 @@ function resolveStyle(layerName, geomKind, ct = "DAY") {
|
|
|
22376
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 };
|
|
22377
22412
|
return { type: effectiveType, paint: paint2 };
|
|
22378
22413
|
}
|
|
22379
|
-
const paint = resolvePaint(layerName, { ...entry.style.paint }, effectiveType, ct);
|
|
22414
|
+
const paint = resolvePaint(layerName, { ...entry.style.paint }, effectiveType, ct, opts);
|
|
22380
22415
|
if (effectiveType === "fill" && OPAQUE_FILL_LAYERS.has(layerName)) {
|
|
22381
22416
|
paint["fill-opacity"] = 1;
|
|
22382
22417
|
}
|
|
@@ -23325,21 +23360,19 @@ function getLabelConfig(layerName, opts = {}) {
|
|
|
23325
23360
|
layout: orientationLabelLayout({
|
|
23326
23361
|
"text-letter-spacing": 0.15,
|
|
23327
23362
|
"text-max-width": 9,
|
|
23328
|
-
// SEAARE
|
|
23329
|
-
//
|
|
23330
|
-
//
|
|
23331
|
-
//
|
|
23332
|
-
//
|
|
23333
|
-
//
|
|
23334
|
-
//
|
|
23335
|
-
//
|
|
23336
|
-
//
|
|
23337
|
-
//
|
|
23338
|
-
//
|
|
23339
|
-
//
|
|
23340
|
-
|
|
23341
|
-
"text-ignore-placement": true,
|
|
23342
|
-
"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.
|
|
23343
23376
|
"text-padding": 2
|
|
23344
23377
|
})
|
|
23345
23378
|
};
|
|
@@ -24032,6 +24065,102 @@ function computePolygonCentroid(geom) {
|
|
|
24032
24065
|
}
|
|
24033
24066
|
return [sumX / coords.length, sumY / coords.length];
|
|
24034
24067
|
}
|
|
24068
|
+
var PLACENAME_SOURCE_LAYER = "PLACENAME";
|
|
24069
|
+
var PLACENAME_WATER_CLASSES = [
|
|
24070
|
+
"SEAARE",
|
|
24071
|
+
"LAKARE",
|
|
24072
|
+
"RIVERS",
|
|
24073
|
+
"CANALS",
|
|
24074
|
+
"PRDARE"
|
|
24075
|
+
];
|
|
24076
|
+
var PLACENAME_LAND_CLASSES = [
|
|
24077
|
+
"LNDRGN",
|
|
24078
|
+
"LNDARE",
|
|
24079
|
+
"BUAARE",
|
|
24080
|
+
"AIRARE"
|
|
24081
|
+
];
|
|
24082
|
+
var PLACENAME_FITS = ["<=", ["coalesce", ["get", "min_z"], 0], ["zoom"]];
|
|
24083
|
+
var PLACENAME_RETIRES = [">=", ["coalesce", ["get", "max_z"], 14], ["zoom"]];
|
|
24084
|
+
var PLACENAME_TIER = [
|
|
24085
|
+
"to-number",
|
|
24086
|
+
["coalesce", ["get", "tier"], 9]
|
|
24087
|
+
];
|
|
24088
|
+
var PLACENAME_TEXT_OPACITY = [
|
|
24089
|
+
"interpolate",
|
|
24090
|
+
["linear"],
|
|
24091
|
+
["zoom"],
|
|
24092
|
+
3,
|
|
24093
|
+
0.55,
|
|
24094
|
+
9,
|
|
24095
|
+
0.5,
|
|
24096
|
+
12,
|
|
24097
|
+
0.4,
|
|
24098
|
+
16,
|
|
24099
|
+
0.3
|
|
24100
|
+
];
|
|
24101
|
+
var PLACENAME_WATER_SIZE_STOPS = [
|
|
24102
|
+
[3, [14, 9, 0, 0, 0, 0, 0, 0, 0, 0]],
|
|
24103
|
+
[5, [16, 13, 9, 0, 0, 0, 0, 0, 0, 0]],
|
|
24104
|
+
[7, [14, 14, 12, 9, 0, 0, 0, 0, 0, 0]],
|
|
24105
|
+
[9, [12, 13, 14, 11, 10, 9, 0, 9, 9, 9]],
|
|
24106
|
+
[11, [10, 12, 13, 12, 10, 9, 9, 11, 11, 9]],
|
|
24107
|
+
[13, [9, 11, 12, 11, 10, 10, 10, 11, 11, 10]],
|
|
24108
|
+
[16, [9, 10, 11, 10, 9, 9, 9, 10, 10, 9]]
|
|
24109
|
+
];
|
|
24110
|
+
var PLACENAME_LAND_SIZE_STOPS = [
|
|
24111
|
+
[3, [0, 0, 11, 0, 0, 0, 0, 0, 0, 0]],
|
|
24112
|
+
[5, [0, 0, 13, 0, 0, 0, 0, 0, 0, 0]],
|
|
24113
|
+
[7, [0, 0, 13, 9, 9, 0, 0, 0, 0, 0]],
|
|
24114
|
+
[9, [0, 0, 12, 12, 11, 0, 0, 0, 0, 0]],
|
|
24115
|
+
[11, [0, 0, 11, 12, 11, 9, 9, 0, 0, 9]],
|
|
24116
|
+
[13, [0, 0, 10, 11, 10, 11, 10, 10, 10, 10]],
|
|
24117
|
+
[16, [0, 0, 10, 10, 9, 10, 9, 9, 9, 9]]
|
|
24118
|
+
];
|
|
24119
|
+
function buildPlaceNameLayers(sourceId) {
|
|
24120
|
+
const sortKey = ["to-number", ["coalesce", ["get", "rank"], 9999999]];
|
|
24121
|
+
const make = (idSuffix, classes, font, haloColor, letterSpacing, stops) => ({
|
|
24122
|
+
id: `chrt-placename-${idSuffix}`,
|
|
24123
|
+
type: "symbol",
|
|
24124
|
+
source: sourceId,
|
|
24125
|
+
"source-layer": PLACENAME_SOURCE_LAYER,
|
|
24126
|
+
minzoom: 3,
|
|
24127
|
+
filter: [
|
|
24128
|
+
"all",
|
|
24129
|
+
["match", ["get", "cls"], [...classes], true, false],
|
|
24130
|
+
PLACENAME_FITS,
|
|
24131
|
+
PLACENAME_RETIRES
|
|
24132
|
+
],
|
|
24133
|
+
layout: {
|
|
24134
|
+
"text-field": ["get", "name"],
|
|
24135
|
+
"text-font": font,
|
|
24136
|
+
"text-size": tieredSizeCurve(PLACENAME_TIER, stops),
|
|
24137
|
+
"text-letter-spacing": letterSpacing,
|
|
24138
|
+
"text-max-width": 9,
|
|
24139
|
+
"text-padding": 4,
|
|
24140
|
+
"text-allow-overlap": false,
|
|
24141
|
+
"text-ignore-placement": false,
|
|
24142
|
+
"text-optional": true,
|
|
24143
|
+
"text-variable-anchor": ["center", "top", "bottom", "left", "right"],
|
|
24144
|
+
"text-radial-offset": 0.3,
|
|
24145
|
+
"text-justify": "auto",
|
|
24146
|
+
"symbol-sort-key": sortKey
|
|
24147
|
+
},
|
|
24148
|
+
paint: {
|
|
24149
|
+
"text-color": DARK_BG,
|
|
24150
|
+
"text-halo-color": haloColor,
|
|
24151
|
+
"text-halo-width": ORIENTATION_HALO_WIDTH,
|
|
24152
|
+
"text-opacity": PLACENAME_TEXT_OPACITY
|
|
24153
|
+
},
|
|
24154
|
+
metadata: {
|
|
24155
|
+
"chrt:placename": true,
|
|
24156
|
+
"chrt:labelPriority": ORIENTATION_LABEL_PRIORITY
|
|
24157
|
+
}
|
|
24158
|
+
});
|
|
24159
|
+
return [
|
|
24160
|
+
make("water", PLACENAME_WATER_CLASSES, ["Open Sans Italic"], COLOR.WATER_DEEP, 0.05, PLACENAME_WATER_SIZE_STOPS),
|
|
24161
|
+
make("land", PLACENAME_LAND_CLASSES, ["Open Sans Regular"], COLOR.LAND_REGION, 0.02, PLACENAME_LAND_SIZE_STOPS)
|
|
24162
|
+
];
|
|
24163
|
+
}
|
|
24035
24164
|
|
|
24036
24165
|
// src/atlas/feature-decimation.ts
|
|
24037
24166
|
function getGridSizeForZoom(zoom) {
|
|
@@ -26850,6 +26979,13 @@ function buildSources(opts = {}) {
|
|
|
26850
26979
|
}
|
|
26851
26980
|
|
|
26852
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
|
+
]);
|
|
26853
26989
|
var GEOM_FILTERS = {
|
|
26854
26990
|
fill: ["any", ["==", ["geometry-type"], "Polygon"], ["==", ["geometry-type"], "MultiPolygon"]],
|
|
26855
26991
|
line: ["any", ["==", ["geometry-type"], "LineString"], ["==", ["geometry-type"], "MultiLineString"]],
|
|
@@ -27008,7 +27144,7 @@ function buildLayersForClass(objectClass, ct, sourceId = DEFAULT_REGION, opts =
|
|
|
27008
27144
|
const layers = [];
|
|
27009
27145
|
const geomTypes = getGeomTypesForClass(objectClass, entry?.style.type);
|
|
27010
27146
|
for (const geomType of geomTypes) {
|
|
27011
|
-
const resolved = resolveStyle(objectClass, geomType, ct);
|
|
27147
|
+
const resolved = resolveStyle(objectClass, geomType, ct, { safetyContour: opts.safetyContour });
|
|
27012
27148
|
const layerId = `s52-${objectClass}-${resolved.type}`;
|
|
27013
27149
|
const layer = {
|
|
27014
27150
|
id: layerId,
|
|
@@ -27027,6 +27163,9 @@ function buildLayersForClass(objectClass, ct, sourceId = DEFAULT_REGION, opts =
|
|
|
27027
27163
|
} else if (GEOM_FILTERS[resolved.type]) {
|
|
27028
27164
|
layer.filter = GEOM_FILTERS[resolved.type];
|
|
27029
27165
|
}
|
|
27166
|
+
if (SCAMIN_DECLUTTER_CLASSES.has(objectClass)) {
|
|
27167
|
+
layer.filter = layer.filter ? ["all", layer.filter, scaminZoomGateFilter()] : ["all", scaminZoomGateFilter()];
|
|
27168
|
+
}
|
|
27030
27169
|
if (resolved.minzoom) {
|
|
27031
27170
|
layer.minzoom = resolved.minzoom;
|
|
27032
27171
|
}
|
|
@@ -28322,6 +28461,18 @@ function isExemptOpaqueFill(layer) {
|
|
|
28322
28461
|
}
|
|
28323
28462
|
return false;
|
|
28324
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
|
+
}
|
|
28325
28476
|
var BAND_DRAW_ORDER = ["1", "2", "3", "4", "5", "6"];
|
|
28326
28477
|
var CHART_BAND_CODES = {
|
|
28327
28478
|
Overview: ["1"],
|
|
@@ -28440,9 +28591,7 @@ function collapsedDominanceGate(B, minzoom) {
|
|
|
28440
28591
|
return ["any", ...clauses];
|
|
28441
28592
|
}
|
|
28442
28593
|
function makeCollapsedBandVariant(layer, B, isExempt) {
|
|
28443
|
-
const
|
|
28444
|
-
const classMinzoom = layer.minzoom ?? 0;
|
|
28445
|
-
const minzoom = isExemptOpaqueFill(layer) ? classMinzoom : Math.max(classMinzoom, range.minzoom);
|
|
28594
|
+
const minzoom = bandVariantMinzoom(layer, B);
|
|
28446
28595
|
if (isExempt) {
|
|
28447
28596
|
const exempt = {
|
|
28448
28597
|
...layer,
|
|
@@ -28581,8 +28730,7 @@ function isDominanceExempt(layer) {
|
|
|
28581
28730
|
var TOP_STACK_LIGHT_CLASSES = /* @__PURE__ */ new Set(["LIGHTS"]);
|
|
28582
28731
|
function makeBandVariants(layer, B) {
|
|
28583
28732
|
const range = BAND_PRIORITY_RANGES[B];
|
|
28584
|
-
const
|
|
28585
|
-
const minzoom = isExemptOpaqueFill(layer) ? classMinzoom : Math.max(classMinzoom, range.minzoom);
|
|
28733
|
+
const minzoom = bandVariantMinzoom(layer, B);
|
|
28586
28734
|
const variants = [];
|
|
28587
28735
|
if (isDominanceExempt(layer)) {
|
|
28588
28736
|
const exempt = {
|
|
@@ -28812,9 +28960,12 @@ function generateStyle(palette = "DAY", opts = {}) {
|
|
|
28812
28960
|
emitChartFeatureVariants(topLightBundles);
|
|
28813
28961
|
const chartLabelBundles = byLabelPriorityBottomUp(
|
|
28814
28962
|
bundles.filter(
|
|
28815
|
-
(b) => b.label !== null
|
|
28963
|
+
(b) => b.label !== null && (opts.labels !== "placename" || getLabelBehavior(b.objectClass) !== "orientation-cross-band")
|
|
28816
28964
|
)
|
|
28817
28965
|
);
|
|
28966
|
+
if (opts.labels === "placename") {
|
|
28967
|
+
labelLayers.push(...buildPlaceNameLayers(sourceId));
|
|
28968
|
+
}
|
|
28818
28969
|
for (const { label } of chartLabelBundles) {
|
|
28819
28970
|
if (bandFan === "collapsed") {
|
|
28820
28971
|
labelLayers.push(
|
|
@@ -28859,10 +29010,14 @@ function generateStyle(palette = "DAY", opts = {}) {
|
|
|
28859
29010
|
}
|
|
28860
29011
|
}
|
|
28861
29012
|
}
|
|
28862
|
-
|
|
28863
|
-
|
|
28864
|
-
|
|
28865
|
-
|
|
29013
|
+
if (opts.labels === "placename") {
|
|
29014
|
+
labelLayers.push(...buildPlaceNameLayers(sourceId));
|
|
29015
|
+
} else {
|
|
29016
|
+
for (const { objectClass, label } of bundles) {
|
|
29017
|
+
if (!label) continue;
|
|
29018
|
+
if (getLabelBehavior(objectClass) === "orientation-cross-band") {
|
|
29019
|
+
labelLayers.push(...fanOrientationLabelByCellBand(label, bandFan));
|
|
29020
|
+
}
|
|
28866
29021
|
}
|
|
28867
29022
|
}
|
|
28868
29023
|
const featureLabelBundles = byLabelPriorityBottomUp(
|
|
@@ -28883,6 +29038,12 @@ function generateStyle(palette = "DAY", opts = {}) {
|
|
|
28883
29038
|
}
|
|
28884
29039
|
const symbolSet = opts.symbolSet ?? "s52";
|
|
28885
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;
|
|
28886
29047
|
const style = {
|
|
28887
29048
|
version: 8,
|
|
28888
29049
|
name: `CHRT ${SYMBOL_SET_LABELS[symbolSet]} ${PALETTE_NAMES[palette]}${opts.chartMode ? ` \u2014 chart:${opts.chartMode.band}` : ""}`,
|
|
@@ -28891,7 +29052,7 @@ function generateStyle(palette = "DAY", opts = {}) {
|
|
|
28891
29052
|
"chrt:symbol-set": symbolSet,
|
|
28892
29053
|
"chrt:color-table": palette,
|
|
28893
29054
|
"chrt:generated-at": (/* @__PURE__ */ new Date()).toISOString(),
|
|
28894
|
-
"chrt:layer-count":
|
|
29055
|
+
"chrt:layer-count": emitted.length,
|
|
28895
29056
|
"chrt:land": Boolean(opts.land),
|
|
28896
29057
|
"chrt:relief": Boolean(opts.relief),
|
|
28897
29058
|
"chrt:render-mode": opts.chartMode ? `chart:${opts.chartMode.band}` : "continuous",
|
|
@@ -28914,7 +29075,7 @@ function generateStyle(palette = "DAY", opts = {}) {
|
|
|
28914
29075
|
sprite: `${spriteBase}/${symbolSet}-${palette.toLowerCase()}`
|
|
28915
29076
|
},
|
|
28916
29077
|
glyphs: "https://fonts.openmaptiles.org/{fontstack}/{range}.pbf",
|
|
28917
|
-
layers
|
|
29078
|
+
layers: emitted
|
|
28918
29079
|
};
|
|
28919
29080
|
if (symbolSet === "s101") return applyS101SymbolSet(style);
|
|
28920
29081
|
if (symbolSet === "chrt") return applyChrtSymbolSet(style, palette);
|
|
@@ -29743,6 +29904,9 @@ var Chrt = class {
|
|
|
29743
29904
|
NON_SOLAS_DISCLAIMER_SHORT,
|
|
29744
29905
|
OfflineError,
|
|
29745
29906
|
OfflineStyleError,
|
|
29907
|
+
PLACENAME_LAND_CLASSES,
|
|
29908
|
+
PLACENAME_SOURCE_LAYER,
|
|
29909
|
+
PLACENAME_WATER_CLASSES,
|
|
29746
29910
|
RASTER_ATON_CLASSES,
|
|
29747
29911
|
RASTER_GLYPH_NAMES,
|
|
29748
29912
|
RASTER_ICON_PREFIX,
|
|
@@ -29782,10 +29946,18 @@ var Chrt = class {
|
|
|
29782
29946
|
applyS101SymbolSet,
|
|
29783
29947
|
atonIconExpression,
|
|
29784
29948
|
bandFilterExpression,
|
|
29949
|
+
buildAirportTierExpression,
|
|
29950
|
+
buildBuiltUpAreaTierExpression,
|
|
29785
29951
|
buildFlashPattern,
|
|
29786
29952
|
buildLabelLayer,
|
|
29953
|
+
buildLakeTierExpression,
|
|
29954
|
+
buildLandAreaTierExpression,
|
|
29955
|
+
buildLandRegionTierExpression,
|
|
29787
29956
|
buildLayersForClass,
|
|
29788
29957
|
buildOfflineStyle,
|
|
29958
|
+
buildPlaceNameLayers,
|
|
29959
|
+
buildRiverTierExpression,
|
|
29960
|
+
buildSeaAreaTierExpression,
|
|
29789
29961
|
buildSectorArcGeoJSON,
|
|
29790
29962
|
buildSectorArcsFC,
|
|
29791
29963
|
buildSectorsFromFeatures,
|