@chrtco/sdk 0.10.11 → 0.10.12

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 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,
@@ -24032,6 +24043,102 @@ function computePolygonCentroid(geom) {
24032
24043
  }
24033
24044
  return [sumX / coords.length, sumY / coords.length];
24034
24045
  }
24046
+ var PLACENAME_SOURCE_LAYER = "PLACENAME";
24047
+ var PLACENAME_WATER_CLASSES = [
24048
+ "SEAARE",
24049
+ "LAKARE",
24050
+ "RIVERS",
24051
+ "CANALS",
24052
+ "PRDARE"
24053
+ ];
24054
+ var PLACENAME_LAND_CLASSES = [
24055
+ "LNDRGN",
24056
+ "LNDARE",
24057
+ "BUAARE",
24058
+ "AIRARE"
24059
+ ];
24060
+ var PLACENAME_FITS = ["<=", ["coalesce", ["get", "min_z"], 0], ["zoom"]];
24061
+ var PLACENAME_RETIRES = [">=", ["coalesce", ["get", "max_z"], 14], ["zoom"]];
24062
+ var PLACENAME_TIER = [
24063
+ "to-number",
24064
+ ["coalesce", ["get", "tier"], 9]
24065
+ ];
24066
+ var PLACENAME_TEXT_OPACITY = [
24067
+ "interpolate",
24068
+ ["linear"],
24069
+ ["zoom"],
24070
+ 3,
24071
+ 0.55,
24072
+ 9,
24073
+ 0.5,
24074
+ 12,
24075
+ 0.4,
24076
+ 16,
24077
+ 0.3
24078
+ ];
24079
+ var PLACENAME_WATER_SIZE_STOPS = [
24080
+ [3, [14, 9, 0, 0, 0, 0, 0, 0, 0, 0]],
24081
+ [5, [16, 13, 9, 0, 0, 0, 0, 0, 0, 0]],
24082
+ [7, [14, 14, 12, 9, 0, 0, 0, 0, 0, 0]],
24083
+ [9, [12, 13, 14, 11, 10, 9, 0, 9, 9, 9]],
24084
+ [11, [10, 12, 13, 12, 10, 9, 9, 11, 11, 9]],
24085
+ [13, [9, 11, 12, 11, 10, 10, 10, 11, 11, 10]],
24086
+ [16, [9, 10, 11, 10, 9, 9, 9, 10, 10, 9]]
24087
+ ];
24088
+ var PLACENAME_LAND_SIZE_STOPS = [
24089
+ [3, [0, 0, 11, 0, 0, 0, 0, 0, 0, 0]],
24090
+ [5, [0, 0, 13, 0, 0, 0, 0, 0, 0, 0]],
24091
+ [7, [0, 0, 13, 9, 9, 0, 0, 0, 0, 0]],
24092
+ [9, [0, 0, 12, 12, 11, 0, 0, 0, 0, 0]],
24093
+ [11, [0, 0, 11, 12, 11, 9, 9, 0, 0, 9]],
24094
+ [13, [0, 0, 10, 11, 10, 11, 10, 10, 10, 10]],
24095
+ [16, [0, 0, 10, 10, 9, 10, 9, 9, 9, 9]]
24096
+ ];
24097
+ function buildPlaceNameLayers(sourceId) {
24098
+ const sortKey = ["to-number", ["coalesce", ["get", "rank"], 9999999]];
24099
+ const make = (idSuffix, classes, font, haloColor, letterSpacing, stops) => ({
24100
+ id: `chrt-placename-${idSuffix}`,
24101
+ type: "symbol",
24102
+ source: sourceId,
24103
+ "source-layer": PLACENAME_SOURCE_LAYER,
24104
+ minzoom: 3,
24105
+ filter: [
24106
+ "all",
24107
+ ["match", ["get", "cls"], [...classes], true, false],
24108
+ PLACENAME_FITS,
24109
+ PLACENAME_RETIRES
24110
+ ],
24111
+ layout: {
24112
+ "text-field": ["get", "name"],
24113
+ "text-font": font,
24114
+ "text-size": tieredSizeCurve(PLACENAME_TIER, stops),
24115
+ "text-letter-spacing": letterSpacing,
24116
+ "text-max-width": 9,
24117
+ "text-padding": 4,
24118
+ "text-allow-overlap": false,
24119
+ "text-ignore-placement": false,
24120
+ "text-optional": true,
24121
+ "text-variable-anchor": ["center", "top", "bottom", "left", "right"],
24122
+ "text-radial-offset": 0.3,
24123
+ "text-justify": "auto",
24124
+ "symbol-sort-key": sortKey
24125
+ },
24126
+ paint: {
24127
+ "text-color": DARK_BG,
24128
+ "text-halo-color": haloColor,
24129
+ "text-halo-width": ORIENTATION_HALO_WIDTH,
24130
+ "text-opacity": PLACENAME_TEXT_OPACITY
24131
+ },
24132
+ metadata: {
24133
+ "chrt:placename": true,
24134
+ "chrt:labelPriority": ORIENTATION_LABEL_PRIORITY
24135
+ }
24136
+ });
24137
+ return [
24138
+ make("water", PLACENAME_WATER_CLASSES, ["Open Sans Italic"], COLOR.WATER_DEEP, 0.05, PLACENAME_WATER_SIZE_STOPS),
24139
+ make("land", PLACENAME_LAND_CLASSES, ["Open Sans Regular"], COLOR.LAND_REGION, 0.02, PLACENAME_LAND_SIZE_STOPS)
24140
+ ];
24141
+ }
24035
24142
 
24036
24143
  // src/atlas/feature-decimation.ts
24037
24144
  function getGridSizeForZoom(zoom) {
@@ -28812,9 +28919,12 @@ function generateStyle(palette = "DAY", opts = {}) {
28812
28919
  emitChartFeatureVariants(topLightBundles);
28813
28920
  const chartLabelBundles = byLabelPriorityBottomUp(
28814
28921
  bundles.filter(
28815
- (b) => b.label !== null
28922
+ (b) => b.label !== null && (opts.labels !== "placename" || getLabelBehavior(b.objectClass) !== "orientation-cross-band")
28816
28923
  )
28817
28924
  );
28925
+ if (opts.labels === "placename") {
28926
+ labelLayers.push(...buildPlaceNameLayers(sourceId));
28927
+ }
28818
28928
  for (const { label } of chartLabelBundles) {
28819
28929
  if (bandFan === "collapsed") {
28820
28930
  labelLayers.push(
@@ -28859,10 +28969,14 @@ function generateStyle(palette = "DAY", opts = {}) {
28859
28969
  }
28860
28970
  }
28861
28971
  }
28862
- for (const { objectClass, label } of bundles) {
28863
- if (!label) continue;
28864
- if (getLabelBehavior(objectClass) === "orientation-cross-band") {
28865
- labelLayers.push(...fanOrientationLabelByCellBand(label, bandFan));
28972
+ if (opts.labels === "placename") {
28973
+ labelLayers.push(...buildPlaceNameLayers(sourceId));
28974
+ } else {
28975
+ for (const { objectClass, label } of bundles) {
28976
+ if (!label) continue;
28977
+ if (getLabelBehavior(objectClass) === "orientation-cross-band") {
28978
+ labelLayers.push(...fanOrientationLabelByCellBand(label, bandFan));
28979
+ }
28866
28980
  }
28867
28981
  }
28868
28982
  const featureLabelBundles = byLabelPriorityBottomUp(
@@ -29743,6 +29857,9 @@ var Chrt = class {
29743
29857
  NON_SOLAS_DISCLAIMER_SHORT,
29744
29858
  OfflineError,
29745
29859
  OfflineStyleError,
29860
+ PLACENAME_LAND_CLASSES,
29861
+ PLACENAME_SOURCE_LAYER,
29862
+ PLACENAME_WATER_CLASSES,
29746
29863
  RASTER_ATON_CLASSES,
29747
29864
  RASTER_GLYPH_NAMES,
29748
29865
  RASTER_ICON_PREFIX,
@@ -29782,10 +29899,18 @@ var Chrt = class {
29782
29899
  applyS101SymbolSet,
29783
29900
  atonIconExpression,
29784
29901
  bandFilterExpression,
29902
+ buildAirportTierExpression,
29903
+ buildBuiltUpAreaTierExpression,
29785
29904
  buildFlashPattern,
29786
29905
  buildLabelLayer,
29906
+ buildLakeTierExpression,
29907
+ buildLandAreaTierExpression,
29908
+ buildLandRegionTierExpression,
29787
29909
  buildLayersForClass,
29788
29910
  buildOfflineStyle,
29911
+ buildPlaceNameLayers,
29912
+ buildRiverTierExpression,
29913
+ buildSeaAreaTierExpression,
29789
29914
  buildSectorArcGeoJSON,
29790
29915
  buildSectorArcsFC,
29791
29916
  buildSectorsFromFeatures,