@massif-maps/style-tools 6.1.0-rc.1

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.
Files changed (55) hide show
  1. package/README.md +58 -0
  2. package/dist/cli.js +436 -0
  3. package/dist/cli.js.map +1 -0
  4. package/dist/generated/properties.json +2488 -0
  5. package/dist/legend-svg.js +142 -0
  6. package/dist/legend-svg.js.map +1 -0
  7. package/dist/mapbox2css/browser-host.js +27 -0
  8. package/dist/mapbox2css/browser-host.js.map +1 -0
  9. package/dist/mapbox2css/casing.js +84 -0
  10. package/dist/mapbox2css/casing.js.map +1 -0
  11. package/dist/mapbox2css/config.js +212 -0
  12. package/dist/mapbox2css/config.js.map +1 -0
  13. package/dist/mapbox2css/contour.js +61 -0
  14. package/dist/mapbox2css/contour.js.map +1 -0
  15. package/dist/mapbox2css/coverage.js +56 -0
  16. package/dist/mapbox2css/coverage.js.map +1 -0
  17. package/dist/mapbox2css/emissive.js +192 -0
  18. package/dist/mapbox2css/emissive.js.map +1 -0
  19. package/dist/mapbox2css/expression.js +606 -0
  20. package/dist/mapbox2css/expression.js.map +1 -0
  21. package/dist/mapbox2css/filter.js +285 -0
  22. package/dist/mapbox2css/filter.js.map +1 -0
  23. package/dist/mapbox2css/fold.js +588 -0
  24. package/dist/mapbox2css/fold.js.map +1 -0
  25. package/dist/mapbox2css/host.js +13 -0
  26. package/dist/mapbox2css/host.js.map +1 -0
  27. package/dist/mapbox2css/index.js +3599 -0
  28. package/dist/mapbox2css/index.js.map +1 -0
  29. package/dist/mapbox2css/narrow.js +284 -0
  30. package/dist/mapbox2css/narrow.js.map +1 -0
  31. package/dist/mapbox2css/node-host.js +36 -0
  32. package/dist/mapbox2css/node-host.js.map +1 -0
  33. package/dist/mapbox2css/placement.js +62 -0
  34. package/dist/mapbox2css/placement.js.map +1 -0
  35. package/dist/mapbox2css/png.js +264 -0
  36. package/dist/mapbox2css/png.js.map +1 -0
  37. package/dist/mapbox2css/properties.js +155 -0
  38. package/dist/mapbox2css/properties.js.map +1 -0
  39. package/dist/mapbox2css/schema.js +865 -0
  40. package/dist/mapbox2css/schema.js.map +1 -0
  41. package/dist/mapbox2css/shield.js +118 -0
  42. package/dist/mapbox2css/shield.js.map +1 -0
  43. package/dist/mapbox2css/split.js +380 -0
  44. package/dist/mapbox2css/split.js.map +1 -0
  45. package/dist/mapbox2css/sprite.js +882 -0
  46. package/dist/mapbox2css/sprite.js.map +1 -0
  47. package/dist/mapbox2css/types.js +2 -0
  48. package/dist/mapbox2css/types.js.map +1 -0
  49. package/dist/mapbox2css/variables.js +273 -0
  50. package/dist/mapbox2css/variables.js.map +1 -0
  51. package/dist/wasm.js +43 -0
  52. package/dist/wasm.js.map +1 -0
  53. package/package.json +48 -0
  54. package/wasm/massif-style.mjs +2 -0
  55. package/wasm/massif-style.wasm +0 -0
package/README.md ADDED
@@ -0,0 +1,58 @@
1
+ # @massif-maps/style-tools
2
+
3
+ Style conversion for [Massif Maps](https://github.com/massif-maps/MassifMaps). One command,
4
+ `massif-style`, with no toolchain to install.
5
+
6
+ ```sh
7
+ npx @massif-maps/style-tools css2xml style/project.json style.xml
8
+ ```
9
+
10
+ ## Subcommands
11
+
12
+ | | |
13
+ |---|---|
14
+ | `css2xml <project.json> <out.xml>` | compile a CartoCSS style project to the mapnik XML the decoder reads |
15
+ | `mapbox2css <style.json> <outdir>` | translate a MapBox/MapLibre style to a CartoCSS project |
16
+ | `legend <project.json> [--spec legend.json] [--params k=v]... [--svg out.svg]` | resolve a [legend spec](../../docs/features/legends.md) against the style, as JSON, and optionally draw it |
17
+
18
+ `css2xml` runs the SDK's own C++ compiled to WebAssembly — the same compiler the map uses at
19
+ runtime, so what compiles here renders there. `mapbox2css` is TypeScript.
20
+
21
+ ```sh
22
+ massif-style css2xml --roundtrip project.json out.xml # also parse the XML back and diff
23
+ massif-style legend project.json --params variant=eink --svg legend.svg # the legend as a parameter paints it
24
+ massif-style mapbox2css style.json out/ --validate # compile the result before writing it
25
+ massif-style mapbox2css topo.json out/ --contour-schema div # nth_line -> div contour attributes
26
+ massif-style mapbox2css standard.json out/ --schema openmaptiles # read OpenMapTiles tiles instead
27
+ ```
28
+
29
+ `--schema openmaptiles` retargets the style at an OpenMapTiles tileset. Both **MapBox Streets v8**
30
+ and **MapTiler `planet_v4`** are understood as the source, detected from the style's own source-layer
31
+ names (`--source-schema mapbox|maptiler` says it outright). Layer names, field names and field values
32
+ are all rewritten, one source layer can feed several target ones, and anything without an equivalent
33
+ is dropped and named in the coverage report rather than guessed at. See
34
+ [the docs](https://massif-maps.github.io/MassifMaps/docs/contributing/style-tools#retargeting-at-another-tile-schema---schema).
35
+
36
+ `--contour-schema div` rewrites contour-layer `nth_line` tests onto a `div` (interval in metres)
37
+ attribute, for tiles built with the gdal ladder rather than MapTiler's schema. Only the major/minor
38
+ split survives — the base interval is not in the style — and `--contour-major-div` (default 100)
39
+ sets the threshold. Colours and widths are untouched.
40
+
41
+ `mapbox2css` skips MapBox properties CartoCSS has no equivalent for and prints a coverage report
42
+ naming each one and how often it appeared. `--strict` turns any skipped property into a non-zero
43
+ exit.
44
+
45
+ ## Requirements
46
+
47
+ Node 20 or newer. The wasm build uses `NODERAWFS`, so it runs under Node only — not in a browser.
48
+
49
+ ## Development
50
+
51
+ The wasm is built from `libs-massif/cartocss` and is **not** in the repository. Either build it
52
+ (see [the docs](https://massif-maps.github.io/MassifMaps/docs/contributing/style-tools)) or download
53
+ `massif-style.wasm` and `massif-style.mjs` from an SDK
54
+ [release](https://github.com/massif-maps/MassifMaps/releases) into `wasm/`.
55
+
56
+ ```sh
57
+ npm ci && npm run build && npm test
58
+ ```
package/dist/cli.js ADDED
@@ -0,0 +1,436 @@
1
+ #!/usr/bin/env node
2
+ import { copyFileSync, existsSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, writeFileSync } from 'node:fs';
3
+ import { tmpdir } from 'node:os';
4
+ import { dirname, extname, join } from 'node:path';
5
+ import { fileURLToPath } from 'node:url';
6
+ import { VARIABLES_FILE, convert } from './mapbox2css/index.js';
7
+ import { nodeSpriteHost } from './mapbox2css/node-host.js';
8
+ import { loadSprites, setSpriteHost } from './mapbox2css/sprite.js';
9
+ import { renderLegendSvg } from './legend-svg.js';
10
+ import { WasmMissing, runWasm, wasmAvailable } from './wasm.js';
11
+ const HERE = dirname(fileURLToPath(import.meta.url));
12
+ /**
13
+ * Sides a POI name may take when --shield-anchors is passed with no list of its own. MapBox's own
14
+ * styles that DO use text-variable-anchor state exactly this order, and the horizontal sides come
15
+ * first because a name beside an icon reads better than one under it.
16
+ */
17
+ const DEFAULT_SHIELD_ANCHORS = 'right,left,top,bottom';
18
+ /** What ShieldSymbolizer::parseAnchors accepts - the corners spelled without the hyphen. */
19
+ const SHIELD_ANCHORS = new Set([
20
+ 'center', 'top', 'bottom', 'left', 'right', 'topleft', 'topright', 'bottomleft', 'bottomright',
21
+ ]);
22
+ const USAGE = `Usage: massif-style <command> [options] [args]
23
+
24
+ mapbox2css <style.json> <out-dir> [--validate] [--strict] [--no-sprite]
25
+ [--sprite-key '?key=...']
26
+ [--contour-schema div] [--contour-major-div N]
27
+ [--label-spacing N] [--schema openmaptiles]
28
+ [--source-schema mapbox|maptiler]
29
+ translate a MapBox/MapLibre style to a CartoCSS project
30
+
31
+ --sprite-key query string appended to the style's sprite URLs, for a
32
+ provider that needs a key
33
+ --label-spacing N multiply the collision gap between labels; 1 is what the
34
+ style asks for, higher thins the map out
35
+ --shield-anchors [sides]
36
+ let a POI name take the first FREE side of its icon instead of
37
+ the one fixed place the style states, and draw the icon alone
38
+ when no side fits (shield-anchors + shield-text-optional).
39
+ Sides in preference order, comma separated; the default is
40
+ '${DEFAULT_SHIELD_ANCHORS}'. A layer that already states
41
+ text-variable-anchor keeps its own list
42
+ --icon-font FACE draw every SHIELD icon as a glyph of the FACE icon font instead of a
43
+ sprite (shield-icon-name + shield-icon-face-name), so the style ships
44
+ one font rather than a sheet of PNGs. Needs --icon-font-map. A marker
45
+ (a oneway arrow, a crossing) keeps its sprite - it has no glyph run
46
+ --icon-font-map FILE JSON mapping the style's icon-image names onto that face's characters:
47
+ {"mountain": "\\ue90a"} or {"mountain": "U+E90A"} or {"mountain": 59658}.
48
+ A name absent from it draws no icon, so country artwork (an RER
49
+ roundel, a national motorway plate) is lost - that is the trade
50
+ --icon-font-size PX the height in sprite pixels a glyph fills at icon-size 1, so icon-size
51
+ scales a glyph as it scales the sprite; unset, a multiple of text-size
52
+ --schema NAME retarget the style's source layers at another tile schema.
53
+ 'openmaptiles' is the only target. A MapTiler planet_v4 style
54
+ becomes the OpenMapTiles layer plus the class filter that
55
+ stands in for its per-feature-type split (forest, grass,
56
+ city_label, peak, ...); a MapBox Streets v8 style is further
57
+ away and also gets its field names (height ->
58
+ render_height), its field values (class 'street' -> 'minor')
59
+ and its one-layer-two-targets splits (road is both
60
+ transportation and transportation_name) rewritten. A layer
61
+ with no equivalent is dropped and named in the coverage report
62
+ --source-schema NAME which vocabulary the style itself is written in, 'mapbox' or
63
+ 'maptiler'. Detected from the source layer names when unset,
64
+ and conversion stops rather than guess when they are ambiguous
65
+ --no-sprite skip the sprite; every icon-image is then dropped
66
+ --no-variables keep the colours, fonts and sizes inline in style.mss instead of
67
+ hoisting them into a variables.mss a variant can override
68
+ --no-presets do not emit the extra lightPreset palettes (Mapbox Standard)
69
+ --config k=v set one of the style's own config values, for a style that declares a
70
+ schema (Mapbox Standard). Repeatable, and k=v,k2=v2 also works. Every
71
+ config read is resolved to a constant, so this is a build-time choice:
72
+ --config lightPreset=night is how the dark version is produced
73
+ --live-light leave the 2D colours as the style authored them and carry its
74
+ emissive strengths instead, for an SDK that lights them at draw
75
+ time. One palette then covers every light preset and the hour can
76
+ be changed at runtime. Off, the light is folded into the colours
77
+ and a palette is emitted per preset
78
+ --label-emissive N a CAP on every text and icon emissive, and the default where the
79
+ style states none. MapBox's own default is 1 - a label drawn as
80
+ authored at any hour - and Standard states 1 on its shields
81
+ deliberately, so a cap is what makes them follow the light too.
82
+ Needs --live-light
83
+ --halo-emissive N the same for a label's HALO, which the SDK grades separately: the
84
+ ink keeps its emissive and stays bright while the outline takes
85
+ this one and goes dark with the scene, so a name stays readable
86
+ over a map that darkens. Needs --live-light
87
+ --geometry-emissive N a FLOOR on what a fill, line or background emissive defaults to
88
+ where the style states none. MapBox's own default is 0 -
89
+ entirely at the mercy of the light - which collapses a style
90
+ with no light model of its own as soon as the sun is down.
91
+ Needs --live-light
92
+ --building-height-ramp grow the extrusions in over a third of a zoom level where the
93
+ style states no fill-extrusion-vertical-scale of its own
94
+ --ao-follows-height fade the ground AO on the same ramp that lays the buildings down as
95
+ the camera tilts over, so a flattened city does not keep a dark ring
96
+ around every footprint. Off by default: whether the contact shadow
97
+ outlives the walls is the style's call, not the renderer's
98
+ --sdf-flatten resolve SDF icons to plain bitmaps, for an SDK without
99
+ marker-sdf; loses the zoom-driven size and the halo
100
+ --fold-casings fold a casing layer into the fill it runs under, as one
101
+ line-border-* rule. Halves those rules and their geometry,
102
+ and MOVES the casing: it then draws per class instead of
103
+ under every fill
104
+ --fonts DIR copy the .ttf/.otf faces in DIR into the project's fonts/ and list
105
+ them in project.json. The decoder registers a style's own fonts ahead
106
+ of the system ones, which is how a face reaches a build that has none
107
+ --tile-draw-size N the Options::TileDrawSize the style will be drawn at, in dp.
108
+ Shifts every zoom stop by log2(512 / N); the default 256 is
109
+ the SDK's own, 512 an app on maplibre's convention
110
+ --contour-schema div rewrite contour-layer nth_line tests onto a div (interval in
111
+ metres) attribute; --contour-major-div is the major threshold,
112
+ and --contour-elevation is what the target tiles call the
113
+ elevation (default ele; MapTiler's own say height),
114
+ default 100
115
+
116
+ css2xml [--roundtrip] <project.json> <out.xml>
117
+ compile a CartoCSS style project to mapnik XML
118
+
119
+ legend <project.json> [--spec legend.json] [--params k=v]... [--out out.json]
120
+ [--svg out.svg] [--lang en]
121
+ resolve a legend spec against the style: every item is a synthetic feature, and comes
122
+ back as the swatch the style draws it with - lines, fill, icon, road plate, text - as
123
+ the SDK's MBVectorTileDecoder.getLegend returns it
124
+
125
+ --spec FILE the spec; legend.json beside the project by default
126
+ --params k=v a style parameter value, as setStyleParameter takes it. Repeatable
127
+ --out FILE write the JSON there instead of stdout
128
+ --svg FILE also draw the legend as an SVG sheet, images inlined
129
+ --lang CODE which label to draw when a label is a {lang: text} object
130
+ `;
131
+ function loadPropertyTable() {
132
+ // dist/cli.js -> dist/generated; src/cli.ts -> src/generated.
133
+ return JSON.parse(readFileSync(join(HERE, 'generated', 'properties.json'), 'utf8'));
134
+ }
135
+ /** `--flag`, `--key value` and `--key=value`, which is as much as this CLI needs. */
136
+ function parseFlags(args) {
137
+ const flags = new Map();
138
+ const positional = [];
139
+ for (let i = 0; i < args.length; i++) {
140
+ const arg = args[i];
141
+ if (!arg.startsWith('--')) {
142
+ positional.push(arg);
143
+ continue;
144
+ }
145
+ const eq = arg.indexOf('=');
146
+ if (eq !== -1) {
147
+ flags.set(arg.slice(2, eq), arg.slice(eq + 1));
148
+ }
149
+ else if (i + 1 < args.length && !args[i + 1].startsWith('--') && VALUE_FLAGS.has(arg.slice(2))) {
150
+ flags.set(arg.slice(2), args[++i]);
151
+ }
152
+ else {
153
+ flags.set(arg.slice(2), '');
154
+ }
155
+ }
156
+ return { flags, positional };
157
+ }
158
+ const VALUE_FLAGS = new Set(['shield-anchors', 'icon-font', 'icon-font-map', 'icon-font-size', 'contour-schema', 'contour-major-div', 'sprite-key', 'label-spacing', 'tile-draw-size', 'fonts', 'label-emissive', 'halo-emissive', 'geometry-emissive', 'contour-elevation', 'schema', 'source-schema', 'config', 'spec', 'params', 'out', 'svg', 'lang']);
159
+ /**
160
+ * `--config key=value`, repeatable, for a style with a `schema` (Mapbox Standard). Values are read
161
+ * as JSON when they parse - so `show3dObjects=false` and `densityPointOfInterestLabels=2` arrive as
162
+ * a boolean and a number - and as a plain string otherwise, which is what a colour or a preset is.
163
+ */
164
+ function parseConfig(args) {
165
+ const config = {};
166
+ for (let i = 0; i < args.length; i++) {
167
+ const arg = args[i];
168
+ const pair = arg === '--config' ? args[++i] : arg.startsWith('--config=') ? arg.slice('--config='.length) : null;
169
+ if (!pair)
170
+ continue;
171
+ for (const entry of pair.split(',')) {
172
+ const eq = entry.indexOf('=');
173
+ if (eq === -1)
174
+ continue;
175
+ const [key, raw] = [entry.slice(0, eq).trim(), entry.slice(eq + 1).trim()];
176
+ try {
177
+ config[key] = JSON.parse(raw);
178
+ }
179
+ catch {
180
+ config[key] = raw;
181
+ }
182
+ }
183
+ }
184
+ return config;
185
+ }
186
+ /**
187
+ * The icon face's own character per icon name. An icon-font builder emits the codepoint in any of
188
+ * three ways - the character itself, a `U+E90A`/`0xE90A`/`e90a` codepoint, or a number - and all
189
+ * three are the same thing, so all three are read rather than making the caller convert.
190
+ */
191
+ function readGlyphMap(file) {
192
+ let raw;
193
+ try {
194
+ raw = JSON.parse(readFileSync(file, 'utf8'));
195
+ }
196
+ catch (error) {
197
+ process.stderr.write(`--icon-font-map ${file}: ${error instanceof Error ? error.message : String(error)}\n`);
198
+ return null;
199
+ }
200
+ if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {
201
+ process.stderr.write(`--icon-font-map ${file}: expected an object of name -> character.\n`);
202
+ return null;
203
+ }
204
+ const glyphs = new Map();
205
+ for (const [name, value] of Object.entries(raw)) {
206
+ if (typeof value === 'number') {
207
+ glyphs.set(name, String.fromCodePoint(value));
208
+ continue;
209
+ }
210
+ if (typeof value !== 'string' || value.length === 0) {
211
+ process.stderr.write(`--icon-font-map ${file}: "${name}" is not a character or a codepoint.\n`);
212
+ return null;
213
+ }
214
+ const codepoint = /^(?:U\+|0x|\\u)?([0-9a-f]{4,6})$/i.exec(value);
215
+ // A bare 4-6 hex-digit string is a codepoint, never a name: no icon face carries a glyph
216
+ // whose CHARACTER is "e90a".
217
+ glyphs.set(name, codepoint ? String.fromCodePoint(parseInt(codepoint[1], 16)) : value);
218
+ }
219
+ if (glyphs.size === 0) {
220
+ process.stderr.write(`--icon-font-map ${file}: no glyphs in it.\n`);
221
+ return null;
222
+ }
223
+ return glyphs;
224
+ }
225
+ async function mapbox2css(args) {
226
+ const { flags, positional } = parseFlags(args);
227
+ const [input, outDir] = positional;
228
+ if (!input || !outDir) {
229
+ process.stderr.write(USAGE);
230
+ return 2;
231
+ }
232
+ const contourSchema = flags.get('contour-schema');
233
+ if (contourSchema !== undefined && contourSchema !== 'div') {
234
+ process.stderr.write(`Unknown --contour-schema "${contourSchema}"; only "div" is supported.\n`);
235
+ return 2;
236
+ }
237
+ const schema = flags.get('schema');
238
+ if (schema !== undefined && schema !== 'openmaptiles') {
239
+ process.stderr.write(`Unknown --schema "${schema}"; only "openmaptiles" is supported.\n`);
240
+ return 2;
241
+ }
242
+ const sourceSchema = flags.get('source-schema');
243
+ if (sourceSchema !== undefined && sourceSchema !== 'mapbox' && sourceSchema !== 'maptiler') {
244
+ process.stderr.write(`Unknown --source-schema "${sourceSchema}"; "mapbox" or "maptiler".\n`);
245
+ return 2;
246
+ }
247
+ let shieldAnchors;
248
+ if (flags.has('shield-anchors')) {
249
+ shieldAnchors = (flags.get('shield-anchors') || DEFAULT_SHIELD_ANCHORS)
250
+ .split(',').map((a) => a.trim().replace('-', '')).filter(Boolean);
251
+ const unknown = shieldAnchors.filter((a) => !SHIELD_ANCHORS.has(a));
252
+ if (unknown.length > 0) {
253
+ process.stderr.write(`Unknown --shield-anchors side(s): ${unknown.join(', ')}; `
254
+ + `one of ${[...SHIELD_ANCHORS].join(', ')}.\n`);
255
+ return 2;
256
+ }
257
+ }
258
+ const face = flags.get('icon-font');
259
+ const mapFile = flags.get('icon-font-map');
260
+ if ((face === undefined) !== (mapFile === undefined)) {
261
+ process.stderr.write('--icon-font and --icon-font-map go together: the face names the font, '
262
+ + "the map says which character it carries each of the style's icons at.\n");
263
+ return 2;
264
+ }
265
+ let iconFont;
266
+ if (face && mapFile) {
267
+ const glyphs = readGlyphMap(mapFile);
268
+ if (glyphs === null)
269
+ return 2;
270
+ const size = flags.get('icon-font-size');
271
+ iconFont = { face, glyphs, ...(size !== undefined ? { size: Number(size) } : {}) };
272
+ process.stdout.write(`Icon font "${face}": ${glyphs.size} glyph(s).\n`);
273
+ }
274
+ const style = JSON.parse(readFileSync(input, 'utf8'));
275
+ // Icons need the sprite sheet, which the style only points at - so this is opt-in and says
276
+ // what it fetches rather than reaching out silently.
277
+ let sprites;
278
+ if (!flags.has('no-sprite')) {
279
+ try {
280
+ const sheets = await loadSprites(style, flags.get('sprite-key') ?? '');
281
+ if (sheets.size > 0) {
282
+ process.stdout.write(`Loaded ${sheets.size} sprite sheet(s).\n`);
283
+ sprites = { sheets, outDir };
284
+ }
285
+ }
286
+ catch (error) {
287
+ process.stderr.write(`Sprite not loaded (${error instanceof Error ? error.message : String(error)}); icons will be dropped.\n`);
288
+ }
289
+ }
290
+ // A style CARRIES its fonts: the decoder registers everything under <style>/fonts/ ahead of the
291
+ // system ones, which is the only way a face reaches a build with no system fonts at all - the
292
+ // web one. Only the faces a style actually names are worth carrying; they are preloaded nowhere.
293
+ const fontDir = flags.get('fonts');
294
+ const fontFiles = fontDir
295
+ ? readdirSync(fontDir).filter((name) => /\.(?:ttf|otf|ttc)$/i.test(name)).sort()
296
+ : [];
297
+ const { mss, project, coverage, variables, presets, defaultPreset, presetOverrides } = convert(style, loadPropertyTable(), {
298
+ sprites,
299
+ variables: !flags.has('no-variables'),
300
+ liveLight: flags.has('live-light'),
301
+ labelEmissive: flags.has('label-emissive') ? Number(flags.get('label-emissive')) : undefined,
302
+ haloEmissive: flags.has('halo-emissive') ? Number(flags.get('halo-emissive')) : undefined,
303
+ geometryEmissive: flags.has('geometry-emissive') ? Number(flags.get('geometry-emissive')) : undefined,
304
+ buildingHeightRamp: flags.has('building-height-ramp'),
305
+ aoFollowsHeight: flags.has('ao-follows-height'),
306
+ config: parseConfig(args),
307
+ presets: flags.has('no-presets') ? [] : undefined,
308
+ flattenSdf: flags.has('sdf-flatten'),
309
+ foldCasings: flags.has('fold-casings'),
310
+ labelSpacing: Number(flags.get('label-spacing') ?? 1),
311
+ tileDrawSize: Number(flags.get('tile-draw-size') ?? 256),
312
+ fonts: fontFiles,
313
+ shieldAnchors: shieldAnchors?.join(','),
314
+ iconFont,
315
+ schema: schema === 'openmaptiles' ? 'openmaptiles' : undefined,
316
+ sourceSchema,
317
+ contour: contourSchema === 'div'
318
+ ? {
319
+ schema: 'div',
320
+ majorDiv: Number(flags.get('contour-major-div') ?? 100),
321
+ elevationField: flags.get('contour-elevation') ?? undefined,
322
+ }
323
+ : undefined,
324
+ });
325
+ mkdirSync(outDir, { recursive: true });
326
+ writeFileSync(join(outDir, 'style.mss'), mss);
327
+ writeFileSync(join(outDir, 'project.json'), project);
328
+ if (fontDir && fontFiles.length > 0) {
329
+ mkdirSync(join(outDir, 'fonts'), { recursive: true });
330
+ for (const name of fontFiles)
331
+ copyFileSync(join(fontDir, name), join(outDir, 'fonts', name));
332
+ }
333
+ if (variables)
334
+ writeFileSync(join(outDir, VARIABLES_FILE), variables);
335
+ // One palette per other light preset, plus the project that picks it. Same style.mss.
336
+ const overrides = presetOverrides ?? new Map();
337
+ for (const [preset, palette] of presets) {
338
+ writeFileSync(join(outDir, `${preset}.mss`), palette);
339
+ const params = overrides.get(preset);
340
+ writeFileSync(join(outDir, `${preset}.json`), `${JSON.stringify({
341
+ extends: './project.json', styles: [`${preset}.mss`, 'style.mss'],
342
+ ...(params ? { styleparameters: params } : {}),
343
+ }, null, 2)}\n`);
344
+ }
345
+ if (defaultPreset) {
346
+ writeFileSync(join(outDir, `${defaultPreset}.json`), `${JSON.stringify({
347
+ extends: './project.json', styles: [VARIABLES_FILE, 'style.mss'],
348
+ }, null, 2)}\n`);
349
+ }
350
+ if (presets.size > 0) {
351
+ process.stdout.write(`Light presets: ${[defaultPreset, ...presets.keys()].filter(Boolean).join(', ')}`
352
+ + ' (one palette each, over the same style.mss).\n');
353
+ }
354
+ process.stdout.write(`${coverage.report()}\n`);
355
+ if (flags.has('validate')) {
356
+ if (!wasmAvailable()) {
357
+ process.stderr.write('--validate needs massif-style.mjs; skipping validation.\n');
358
+ return 1;
359
+ }
360
+ const status = await runWasm(['css2xml', join(outDir, 'project.json'), join(outDir, 'style.xml')]);
361
+ if (status !== 0) {
362
+ process.stderr.write('Validation failed: the generated CartoCSS did not compile.\n');
363
+ return status;
364
+ }
365
+ process.stdout.write('Validated: the generated CartoCSS compiles.\n');
366
+ }
367
+ if (flags.has('strict') && coverage.droppedCount > 0) {
368
+ process.stderr.write(`--strict: ${coverage.droppedCount} properties dropped.\n`);
369
+ return 1;
370
+ }
371
+ return 0;
372
+ }
373
+ const IMAGE_TYPES = { '.png': 'image/png', '.svg': 'image/svg+xml', '.jpg': 'image/jpeg', '.jpeg': 'image/jpeg' };
374
+ async function legend(args) {
375
+ const { flags, positional } = parseFlags(args);
376
+ const [project] = positional;
377
+ if (!project) {
378
+ process.stderr.write(USAGE);
379
+ return 2;
380
+ }
381
+ const svg = flags.get('svg');
382
+ // --svg and --lang are drawn here; every other option is the C++ command's own.
383
+ const local = ['--svg', '--lang'];
384
+ const wasmArgs = args.filter((arg, i) => !local.includes(arg) && !local.includes(args[i - 1]));
385
+ const out = flags.get('out') || (svg ? join(mkdtempSync(join(tmpdir(), 'massif-legend-')), 'legend.json') : undefined);
386
+ if (svg && !flags.get('out')) {
387
+ wasmArgs.push('--out', out);
388
+ }
389
+ const status = await runWasm(['legend', ...wasmArgs]);
390
+ if (status !== 0 || !svg || !out) {
391
+ return status;
392
+ }
393
+ if (!flags.get('out')) {
394
+ process.stdout.write(`${readFileSync(out, 'utf8')}\n`);
395
+ }
396
+ // Inlined, so the sheet still shows its icons once it is moved away from the project.
397
+ const folder = dirname(project);
398
+ const imageHref = (file) => {
399
+ const path = join(folder, file);
400
+ const type = IMAGE_TYPES[extname(file).toLowerCase()];
401
+ return type && existsSync(path) ? `data:${type};base64,${readFileSync(path).toString('base64')}` : file;
402
+ };
403
+ writeFileSync(svg, renderLegendSvg(JSON.parse(readFileSync(out, 'utf8')), { lang: flags.get('lang'), imageHref }));
404
+ return 0;
405
+ }
406
+ async function main(argv) {
407
+ // The slicer reads and writes through a host so it can also run in a browser; here it is node.
408
+ setSpriteHost(nodeSpriteHost);
409
+ const [command, ...args] = argv;
410
+ if (!command || command === '--help' || command === '-h' || command === 'help') {
411
+ process.stdout.write(USAGE);
412
+ return command ? 0 : 2;
413
+ }
414
+ try {
415
+ if (command === 'mapbox2css')
416
+ return await mapbox2css(args);
417
+ if (command === 'css2xml')
418
+ return await runWasm([command, ...args]);
419
+ if (command === 'legend')
420
+ return await legend(args);
421
+ }
422
+ catch (error) {
423
+ if (error instanceof WasmMissing) {
424
+ process.stderr.write(`${error.message}\n`);
425
+ return 1;
426
+ }
427
+ throw error;
428
+ }
429
+ process.stderr.write(`Unknown command: ${command}\n\n${USAGE}`);
430
+ return 2;
431
+ }
432
+ main(process.argv.slice(2)).then((code) => { process.exitCode = code; }, (error) => {
433
+ process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
434
+ process.exitCode = 1;
435
+ });
436
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}