isard 0.3.0 → 0.4.0

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/symbols.js CHANGED
@@ -1,11 +1,13 @@
1
1
  /**
2
- * Text labels from GeoJSON: at points, at the middle of lines, at the center of polygons. Shaped on the page, placed by
3
- * the engine every frame with collisions shared by all symbol layers (the top layer first, each layer in data order),
4
- * drawn with a halo, standing on the relief.
2
+ * Text labels and icons from GeoJSON: at points, at the middle of lines, at the center of polygons. Shaped on the page,
3
+ * placed by the engine every frame with collisions shared by all symbol layers (the top layer first, each layer in
4
+ * data order), drawn with a halo, standing on the relief. The icons are the map's images (`map.addImage`, a vector
5
+ * basemap's sprite), beside their text or stretched around it.
5
6
  */
6
7
  import { evaluate, featuresOf, parseColor, stops, } from "./features.js";
7
8
  import { toMercator } from "./geo.js";
8
9
  import { codes, DEFAULT_FONT, shape } from "./glyphs.js";
10
+ import { layoutIcon } from "./icons.js";
9
11
  import { Layer } from "./layers.js";
10
12
  /** Where a geometry is labelled: its points, the middle of its longest line (with the direction of the line there),
11
13
  * the centroid of its largest polygon */
@@ -66,8 +68,33 @@ function points(geometry) {
66
68
  return geometry.geometries.flatMap(points);
67
69
  }
68
70
  }
69
- /** Numbers per glyph quad: its label's index, its place, its atlas coordinates, its scale */
70
- const QUAD = 10;
71
+ /** Flags of a label for the engine (`flag` in symbols.rs) */
72
+ const FLAG = {
73
+ textOverlap: 1,
74
+ textIgnore: 2,
75
+ iconOverlap: 4,
76
+ iconIgnore: 8,
77
+ textOptional: 16,
78
+ iconOptional: 32,
79
+ text: 64,
80
+ icon: 128,
81
+ textAlong: 256,
82
+ iconAlong: 512,
83
+ iconUpright: 1024,
84
+ };
85
+ /** Flags of an overlap: allowed to overlap, ignored by the placement */
86
+ function overlapFlags(overlap, allow, ignore) {
87
+ if (overlap === true)
88
+ return allow | ignore;
89
+ if (overlap === 'allow')
90
+ return allow;
91
+ return overlap === 'ignore' ? ignore : 0;
92
+ }
93
+ /** Room around an icon's box, CSS pixels (MapLibre's default `icon-padding`) */
94
+ const ICON_PADDING = 2;
95
+ /** Numbers per quad: its label's index, its place, its atlas coordinates, its scale (a glyph's; -1 or -2: an icon),
96
+ * its turn */
97
+ const QUAD = 11;
71
98
  /** Every character of a run has its glyph */
72
99
  function present(part, loaded) {
73
100
  const glyphs = loaded.get(part.font ?? DEFAULT_FONT);
@@ -190,7 +217,7 @@ export class SymbolLayer extends Layer {
190
217
  const valid = c !== undefined &&
191
218
  c.style === this.styleGeneration &&
192
219
  (c.base === base || this.indexFree) &&
193
- (c.complete || c.glyphs === glyphs.version);
220
+ (c.complete || (c.glyphs === glyphs.version && c.icons === this.host.icons.version));
194
221
  if (!valid)
195
222
  todo.push({ group, base, parts: this.parts(group, base) });
196
223
  base += group.length;
@@ -219,70 +246,155 @@ export class SymbolLayer extends Layer {
219
246
  this.chunks.set(group, chunk);
220
247
  }
221
248
  this.labels = concat(groups.map((g) => built.get(g) ?? this.chunks.get(g)));
249
+ // The icons packed for them
250
+ this.host.icons.flush();
222
251
  this.send(this.map.engine, this.id);
223
252
  this.map.requestRender();
224
253
  }
225
254
  /** The labels of a group of features, `base` the index of its first feature */
226
255
  build(group, base, parts, loaded) {
227
256
  const { font, size, anchor, offset, maxWidth, lineHeight, color, haloColor, haloWidth, overlap, placement } = this.style;
257
+ const st = this.style;
258
+ const icons = this.host.icons;
228
259
  const anchorList = [];
229
260
  const boxes = [];
230
261
  const styles = [];
231
- const quads = [];
262
+ const iconQuads = [];
263
+ const textQuads = [];
232
264
  let count = 0;
233
265
  let complete = true;
234
266
  group.forEach((f, k) => {
235
267
  const i = base + k;
268
+ const p = f.properties;
236
269
  const text = parts[k];
237
- if (!text?.length || text.every((p) => !p.text))
270
+ const filtered = st.filter !== undefined && !st.filter(p, i);
271
+ const hasText = !!text?.length && text.some((t) => t.text);
272
+ const iconName = filtered ? '' : evaluate(st.icon, p, i);
273
+ const icon = iconName ? icons.get(iconName) : undefined;
274
+ // An image not added yet: laid out again once more are
275
+ if (iconName && !icon)
276
+ complete = false;
277
+ if (!hasText && !icon)
238
278
  return;
239
279
  // Glyphs still missing: shaped again once more glyphs are loaded
240
- if (complete && !text.every((p) => present(p, loaded)))
280
+ if (complete && text && !text.every((t) => present(t, loaded)))
241
281
  complete = false;
242
282
  // Shaped at its largest size; the engine scales by the zoom stops
243
- const s0 = evaluate(size, f.properties, i);
244
- const shaped = typeof s0 === 'number' ? s0 : Math.max(...s0.map(([, v]) => v), 1);
245
- const scale = typeof s0 === 'number' ? 1 : s0.map(([z, v]) => [z, v / shaped]);
246
- const s = shape(text, (name) => loaded.get(name), {
247
- font: evaluate(font, f.properties, i),
248
- size: shaped,
249
- maxWidth: evaluate(maxWidth, f.properties, i),
250
- lineHeight: evaluate(lineHeight, f.properties, i),
251
- anchor: evaluate(anchor, f.properties, i),
252
- offset: evaluate(offset, f.properties, i),
253
- });
254
- if (!s.quads.length)
283
+ const shapedAt = (v) => (typeof v === 'number' ? v : Math.max(...v.map(([, x]) => x), 1e-6));
284
+ const scaleOf = (v, at) => typeof v === 'number' ? 1 : v.map(([z, x]) => [z, x / at]);
285
+ const s0 = evaluate(size, p, i);
286
+ const shaped = shapedAt(s0);
287
+ const scale = scaleOf(s0, shaped);
288
+ let s;
289
+ if (hasText && text) {
290
+ s = shape(text, (name) => loaded.get(name), {
291
+ font: evaluate(font, p, i),
292
+ size: shaped,
293
+ maxWidth: evaluate(maxWidth, p, i),
294
+ lineHeight: evaluate(lineHeight, p, i),
295
+ anchor: evaluate(anchor, p, i),
296
+ offset: evaluate(offset, p, i),
297
+ });
298
+ if (!s.quads.length)
299
+ s = undefined;
300
+ }
301
+ if (!s && !icon)
255
302
  return;
256
- const halo = evaluate(haloWidth, f.properties, i);
257
- const fill = parseColor(evaluate(color, f.properties, i));
258
- const haloRgba = parseColor(evaluate(haloColor, f.properties, i));
259
- for (const { at, along } of anchors(f.geometry)) {
303
+ const along = evaluate(placement, p, i) === 'line';
304
+ let flags = overlapFlags(evaluate(overlap, p, i), FLAG.textOverlap, FLAG.textIgnore);
305
+ if (evaluate(st.textOptional, p, i))
306
+ flags |= FLAG.textOptional;
307
+ if (s)
308
+ flags |= FLAG.text;
309
+ // The icon: beside its text, or stretched around it (then scaled and turned with it)
310
+ let iconScale = 1;
311
+ let iconBox = [0, 0, 0, 0];
312
+ let iconColor = [0, 0, 0, 0];
313
+ let quads = [];
314
+ let iconTurns = false;
315
+ let fitted = false;
316
+ if (icon) {
317
+ const fit = evaluate(st.iconTextFit, p, i);
318
+ fitted = fit !== 'none' && s !== undefined;
319
+ const i0 = evaluate(st.iconSize, p, i);
320
+ const iconShaped = fitted ? 1 : shapedAt(i0);
321
+ iconScale = fitted ? scale : scaleOf(i0, iconShaped);
322
+ const laid = layoutIcon(icon, {
323
+ size: iconShaped,
324
+ anchor: evaluate(st.iconAnchor, p, i),
325
+ offset: evaluate(st.iconOffset, p, i),
326
+ rotate: evaluate(st.iconRotate, p, i),
327
+ fit,
328
+ padding: evaluate(st.iconTextFitPadding, p, i),
329
+ text: s?.layout,
330
+ });
331
+ quads = laid.quads;
332
+ if (quads.length) {
333
+ flags |= FLAG.icon | overlapFlags(evaluate(st.iconOverlap, p, i), FLAG.iconOverlap, FLAG.iconIgnore);
334
+ if (evaluate(st.iconOptional, p, i))
335
+ flags |= FLAG.iconOptional;
336
+ const alignment = evaluate(st.iconRotationAlignment, p, i);
337
+ if (fitted)
338
+ flags |= FLAG.iconUpright;
339
+ iconTurns = alignment === 'map' || (alignment === 'auto' && along);
340
+ iconBox = [
341
+ laid.box[0] - ICON_PADDING,
342
+ laid.box[1] - ICON_PADDING,
343
+ laid.box[2] + ICON_PADDING,
344
+ laid.box[3] + ICON_PADDING,
345
+ ];
346
+ const [r, g, b, a] = parseColor(evaluate(st.iconColor, p, i));
347
+ iconColor = [r, g, b, a * Math.max(0, Math.min(1, evaluate(st.iconOpacity, p, i)))];
348
+ }
349
+ }
350
+ if (!(flags & (FLAG.text | FLAG.icon)))
351
+ return;
352
+ const halo = s ? evaluate(haloWidth, p, i) : 0;
353
+ const fill = parseColor(evaluate(color, p, i));
354
+ const haloRgba = parseColor(evaluate(haloColor, p, i));
355
+ // The collision box: the ink, with the halo and a little room
356
+ const pad = halo + 1;
357
+ const textBox = s ? [s.box[0] - pad, s.box[1] - pad, s.box[2] + pad, s.box[3] + pad] : [0, 0, 0, 0];
358
+ for (const { at, along: line } of anchors(f.geometry)) {
260
359
  const label = count++;
261
360
  const [x, y] = toMercator(at);
262
361
  anchorList.push(x, y);
263
- // Along the line: its direction in Mercator (y towards the south)
362
+ // The text along its line, kept upright; the icon turning with the map (along its line, or with the east at a
363
+ // point), or with its text when fitted to it
364
+ const textAlong = along && line !== undefined && s !== undefined;
365
+ const iconAlong = (flags & FLAG.icon) !== 0 && (fitted ? textAlong : iconTurns);
366
+ let labelFlags = flags | (textAlong ? FLAG.textAlong : 0) | (iconAlong ? FLAG.iconAlong : 0);
367
+ // The direction of its line in Mercator (y towards the south)
264
368
  let direction = [0, 0];
265
- if (placement === 'line' && along) {
266
- const [x1, y1] = toMercator([at[0] + along[0], at[1] + along[1]]);
369
+ if (line && (textAlong || iconAlong)) {
370
+ const [x1, y1] = toMercator([at[0] + line[0], at[1] + line[1]]);
267
371
  direction = [x1 - x, y1 - y];
268
372
  }
269
- // The collision box: the ink, with the halo and a little room
270
- const pad = halo + 1;
271
- boxes.push(s.box[0] - pad, s.box[1] - pad, s.box[2] + pad, s.box[3] + pad);
272
- styles.push(...fill, ...haloRgba, halo, evaluate(overlap, f.properties, i) ? 1 : 0, ...direction, ...stops(scale));
273
- for (const q of s.quads)
274
- quads.push(label, ...q);
373
+ else if (iconAlong) {
374
+ direction = [1, 0];
375
+ }
376
+ if (direction[0] === 0 && direction[1] === 0)
377
+ labelFlags &= ~(FLAG.textAlong | FLAG.iconAlong);
378
+ boxes.push(...textBox);
379
+ styles.push(...fill, ...haloRgba, halo, labelFlags, ...direction, ...stops(scale), ...iconBox, ...iconColor, ...stops(iconScale));
380
+ for (const q of quads)
381
+ iconQuads.push(label, ...q);
382
+ if (s)
383
+ for (const q of s.quads)
384
+ textQuads.push(label, ...q, 0);
275
385
  }
276
386
  });
277
387
  return {
278
388
  anchors: Float64Array.from(anchorList),
279
389
  boxes: Float32Array.from(boxes),
280
390
  styles: Float32Array.from(styles),
281
- quads: Float32Array.from(quads),
391
+ // The icons under the texts
392
+ quads: Float32Array.from([...iconQuads, ...textQuads]),
282
393
  count,
283
394
  style: this.styleGeneration,
284
395
  base,
285
396
  glyphs: this.host.glyphs.version,
397
+ icons: icons.version,
286
398
  complete,
287
399
  };
288
400
  }
@@ -330,6 +442,19 @@ export function symbolStyle(options) {
330
442
  maxWidth: 10,
331
443
  lineHeight: 1.2,
332
444
  overlap: false,
445
+ textOptional: false,
446
+ icon: '',
447
+ iconSize: 1,
448
+ iconAnchor: 'center',
449
+ iconOffset: [0, 0],
450
+ iconRotate: 0,
451
+ iconRotationAlignment: 'auto',
452
+ iconOverlap: false,
453
+ iconOptional: false,
454
+ iconTextFit: 'none',
455
+ iconTextFitPadding: [0, 0, 0, 0],
456
+ iconColor: '#000',
457
+ iconOpacity: 1,
333
458
  ...rest,
334
459
  };
335
460
  }
@@ -1 +1 @@
1
- {"version":3,"file":"symbols.js","sourceRoot":"","sources":["../src/symbols.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Text labels from GeoJSON: at points, at the middle of lines, at the center of polygons. Shaped on the page, placed by\n * the engine every frame with collisions shared by all symbol layers (the top layer first, each layer in data order),\n * drawn with a halo, standing on the relief.\n */\nimport {\n evaluate,\n type Feature,\n type FeatureData,\n type FeatureLayerStyle,\n featuresOf,\n type Geometry,\n type Placement,\n type Position,\n type Properties,\n parseColor,\n type Size,\n type Styled,\n stops,\n} from './features.ts';\nimport { toMercator } from './geo.ts';\nimport { codes, DEFAULT_FONT, type Glyph, type Glyphs, shape, type TextPart } from './glyphs.ts';\nimport { Layer } from './layers.ts';\nimport type { Anchor } from './overlay.ts';\nimport type { LayerHost } from './types.ts';\nimport type { Engine } from './wasm/isard.js';\n\nexport interface SymbolStyle<P = Properties> extends Omit<FeatureLayerStyle<P>, 'ramp'> {\n /** The text: a string (`\\n` breaks lines) or runs with their own scale and font; empty: no label */\n text: Styled<string | TextPart[], P>;\n /** A font of the map's glyphs (default `Noto Sans Regular`; also Bold and Italic with the default glyphs) */\n font: Styled<string, P>;\n /** CSS pixels, or zoom stops (default 12) */\n size: Styled<Size, P>;\n /** `'point'` (default): horizontal text; `'line'`: along the line at its middle, kept upright */\n placement: 'point' | 'line';\n color: Styled<string, P>;\n haloColor: Styled<string, P>;\n /** CSS pixels (default 0) */\n haloWidth: Styled<number, P>;\n /** Side of the text at the anchor (default `'center'`) */\n anchor: Styled<Anchor, P>;\n /** Shift, ems (default [0, 0]) */\n offset: Styled<[x: number, y: number], P>;\n /** Wrapping width, ems (default 10) */\n maxWidth: Styled<number, P>;\n /** Ems (default 1.2) */\n lineHeight: Styled<number, P>;\n /** Shown even where it overlaps other labels, and hiding none (MapLibre's allow-overlap and ignore-placement)\n * (default false) */\n overlap: Styled<boolean, P>;\n}\n\nexport interface SymbolOptions<P = Properties> extends Partial<SymbolStyle<P>>, Placement {\n data: FeatureData<P>;\n}\n\n/** Where a geometry is labelled: its points, the middle of its longest line (with the direction of the line there),\n * the centroid of its largest polygon */\nfunction anchors(geometry: Geometry | null): { at: Position; along?: [number, number] }[] {\n return points(geometry).map((p) => (p.length > 2 ? { at: [p[0], p[1]], along: [p[2] ?? 0, p[3] ?? 0] } : { at: p }));\n}\n\n/** Anchors as positions, a line's carrying the direction (lon, lat, dlon, dlat) */\nfunction points(geometry: Geometry | null): Position[] {\n if (!geometry) return [];\n switch (geometry.type) {\n case 'Point':\n return [geometry.coordinates];\n case 'MultiPoint':\n return geometry.coordinates;\n case 'LineString':\n case 'MultiLineString': {\n const lines = geometry.type === 'LineString' ? [geometry.coordinates] : geometry.coordinates;\n const length = (l: Position[]) =>\n l.slice(1).reduce((s, p, i) => s + Math.hypot(p[0] - (l[i]?.[0] ?? 0), p[1] - (l[i]?.[1] ?? 0)), 0);\n const line = lines.reduce((a, b) => (length(b) > length(a) ? b : a), lines[0] ?? []);\n let rest = length(line) / 2;\n for (let i = 1; i < line.length; i += 1) {\n const [a, b] = [line[i - 1], line[i]];\n if (!a || !b) continue;\n const d = Math.hypot(b[0] - a[0], b[1] - a[1]);\n if (d >= rest && d > 0) {\n return [[a[0] + ((b[0] - a[0]) * rest) / d, a[1] + ((b[1] - a[1]) * rest) / d, b[0] - a[0], b[1] - a[1]]];\n }\n rest -= d;\n }\n return line[0] ? [line[0]] : [];\n }\n case 'Polygon':\n case 'MultiPolygon': {\n const polygons = geometry.type === 'Polygon' ? [geometry.coordinates] : geometry.coordinates;\n let best: Position | undefined;\n let bestArea = 0;\n for (const p of polygons) {\n const ring = p[0] ?? [];\n let [a, cx, cy] = [0, 0, 0];\n for (let i = 0; i + 1 < ring.length; i += 1) {\n const [x0, y0] = ring[i] ?? [0, 0];\n const [x1, y1] = ring[i + 1] ?? [0, 0];\n const cross = x0 * y1 - x1 * y0;\n a += cross;\n cx += (x0 + x1) * cross;\n cy += (y0 + y1) * cross;\n }\n if (Math.abs(a) > bestArea) {\n bestArea = Math.abs(a);\n best = [cx / (3 * a), cy / (3 * a)];\n }\n }\n return best ? [best] : [];\n }\n case 'GeometryCollection':\n return geometry.geometries.flatMap(points);\n }\n}\n\n/** The map's glyphs, for a layer */\nexport interface GlyphHost extends LayerHost {\n readonly glyphs: Glyphs;\n}\n\n/** Labels built for the engine: an anchor (Mercator x, y), a collision box, a style per label; glyph quads whose first\n * number is their label's index */\ninterface Labels {\n anchors: Float64Array;\n boxes: Float32Array;\n styles: Float32Array;\n quads: Float32Array;\n}\n\n/** Numbers per glyph quad: its label's index, its place, its atlas coordinates, its scale */\nconst QUAD = 10;\n\n/** The labels of a group of features, kept while they stay valid: same style, the same index of the group's first\n * feature (unless the style reads no index), and their glyphs complete or none loaded since */\ninterface Chunk extends Labels {\n count: number;\n style: number;\n base: number;\n glyphs: number;\n complete: boolean;\n}\n\n/** Every character of a run has its glyph */\nfunction present(part: TextPart, loaded: Map<string, Map<number, Glyph>>): boolean {\n const glyphs = loaded.get(part.font ?? DEFAULT_FONT);\n if (!glyphs) return false;\n for (const ch of part.text) if (ch !== '\\n' && !glyphs.has(ch.codePointAt(0) ?? 32)) return false;\n return true;\n}\n\n/** The labels of chunks one after the other, the quads' label indices moved past those of the chunks before */\nfunction concat(chunks: readonly Chunk[]): Labels {\n if (chunks.length === 1 && chunks[0]) return chunks[0];\n const length = (key: keyof Labels) => chunks.reduce((n, c) => n + c[key].length, 0);\n const out: Labels = {\n anchors: new Float64Array(length('anchors')),\n boxes: new Float32Array(length('boxes')),\n styles: new Float32Array(length('styles')),\n quads: new Float32Array(length('quads')),\n };\n const at = { anchors: 0, boxes: 0, styles: 0, quads: 0 };\n let labels = 0;\n for (const c of chunks) {\n out.anchors.set(c.anchors, at.anchors);\n out.boxes.set(c.boxes, at.boxes);\n out.styles.set(c.styles, at.styles);\n out.quads.set(c.quads, at.quads);\n if (labels > 0)\n for (let q = at.quads; q < at.quads + c.quads.length; q += QUAD) out.quads[q] = (out.quads[q] ?? 0) + labels;\n at.anchors += c.anchors.length;\n at.boxes += c.boxes.length;\n at.styles += c.styles.length;\n at.quads += c.quads.length;\n labels += c.count;\n }\n return out;\n}\n\nexport class SymbolLayer<P = Properties> extends Layer {\n private list: Feature<P>[];\n /** The features in groups that do not change (`setGroups`): each group's labels kept between updates */\n private groups: readonly (readonly Feature<P>[])[] | undefined;\n private readonly chunks = new WeakMap<readonly Feature<P>[], Chunk>();\n /** Bumped by each change: a shaping that finished after a newer one began is dropped */\n private generation = 0;\n /** Bumped by each change of style: the labels kept are shaped again */\n private styleGeneration = 0;\n /** No style function takes the index of a feature: a group's labels do not depend on its place */\n private indexFree = true;\n private labels: Labels | undefined;\n\n /** @internal */\n constructor(\n private readonly host: GlyphHost,\n data: FeatureData<P>,\n private style: SymbolStyle<P>,\n ) {\n super(host);\n this.list = featuresOf(data);\n this.styled();\n }\n\n get features(): readonly Feature<P>[] {\n return this.list;\n }\n\n setData(data: FeatureData<P>): void {\n this.list = featuresOf(data);\n this.groups = undefined;\n void this.update();\n }\n\n /**\n * @internal The features as groups that are never changed once given (the labels of a vector tile and style layer),\n * in order: the labels of a group seen before are not shaped again\n */\n setGroups(groups: readonly (readonly Feature<P>[])[]): void {\n this.groups = groups;\n this.list = groups.flat();\n void this.update();\n }\n\n setStyle(style: Partial<SymbolStyle<P>>): void {\n this.style = { ...this.style, ...style };\n this.styled();\n void this.update();\n }\n\n setFilter(filter: ((properties: P, index: number) => boolean) | undefined): void {\n this.setStyle({ filter } as Partial<SymbolStyle<P>>);\n }\n\n setVisible(visible: boolean): void {\n this.style = { ...this.style, visible };\n this.sendLayer(this.map.engine, this.id);\n this.map.requestRender();\n }\n\n private styled(): void {\n this.styleGeneration += 1;\n // A function of one parameter reads the properties only\n this.indexFree = Object.values(this.style).every((v) => typeof v !== 'function' || v.length < 2);\n }\n\n /** The runs of text of each feature of a group (none for a feature filtered out) */\n private parts(group: readonly Feature<P>[], base: number): TextPart[][] {\n const { text, font, filter } = this.style;\n return group.map((f, k): TextPart[] => {\n const i = base + k;\n if (filter && !filter(f.properties, i)) return [];\n const t = evaluate(text, f.properties, i);\n const own = evaluate(font, f.properties, i);\n // Each run in its font, the feature's by default\n return (typeof t === 'string' ? [{ text: t }] : t).map((p) => ({ ...p, font: p.font ?? own }));\n });\n }\n\n /** Shapes the labels (loading their glyphs first) and sends them; the groups' labels still valid are kept */\n private async update(): Promise<void> {\n const generation = ++this.generation;\n const groups = this.groups ?? [this.list];\n const keep = this.groups !== undefined;\n const glyphs = this.host.glyphs;\n const todo: { group: readonly Feature<P>[]; base: number; parts: TextPart[][] }[] = [];\n let base = 0;\n for (const group of groups) {\n const c = keep ? this.chunks.get(group) : undefined;\n const valid =\n c !== undefined &&\n c.style === this.styleGeneration &&\n (c.base === base || this.indexFree) &&\n (c.complete || c.glyphs === glyphs.version);\n if (!valid) todo.push({ group, base, parts: this.parts(group, base) });\n base += group.length;\n }\n const byFont = new Map<string, Set<number>>();\n for (const { parts } of todo) {\n for (const p of parts.flat()) {\n const key = p.font ?? DEFAULT_FONT;\n const set = byFont.get(key) ?? new Set<number>();\n for (const code of codes([p])) set.add(code);\n byFont.set(key, set);\n }\n }\n const loaded = new Map<string, Map<number, Glyph>>();\n await Promise.all(\n [...byFont].map(async ([f, set]) => {\n loaded.set(f, await glyphs.load(f, set));\n }),\n );\n if (generation !== this.generation) return;\n const built = new Map<readonly Feature<P>[], Chunk>();\n for (const { group, base: b, parts } of todo) {\n const chunk = this.build(group, b, parts, loaded);\n built.set(group, chunk);\n if (keep) this.chunks.set(group, chunk);\n }\n this.labels = concat(groups.map((g) => built.get(g) ?? (this.chunks.get(g) as Chunk)));\n this.send(this.map.engine, this.id);\n this.map.requestRender();\n }\n\n /** The labels of a group of features, `base` the index of its first feature */\n private build(\n group: readonly Feature<P>[],\n base: number,\n parts: TextPart[][],\n loaded: Map<string, Map<number, Glyph>>,\n ): Chunk {\n const { font, size, anchor, offset, maxWidth, lineHeight, color, haloColor, haloWidth, overlap, placement } =\n this.style;\n const anchorList: number[] = [];\n const boxes: number[] = [];\n const styles: number[] = [];\n const quads: number[] = [];\n let count = 0;\n let complete = true;\n group.forEach((f, k) => {\n const i = base + k;\n const text = parts[k];\n if (!text?.length || text.every((p) => !p.text)) return;\n // Glyphs still missing: shaped again once more glyphs are loaded\n if (complete && !text.every((p) => present(p, loaded))) complete = false;\n // Shaped at its largest size; the engine scales by the zoom stops\n const s0 = evaluate(size, f.properties, i);\n const shaped = typeof s0 === 'number' ? s0 : Math.max(...s0.map(([, v]) => v), 1);\n const scale: Size = typeof s0 === 'number' ? 1 : s0.map(([z, v]): [number, number] => [z, v / shaped]);\n const s = shape(text, (name) => loaded.get(name), {\n font: evaluate(font, f.properties, i),\n size: shaped,\n maxWidth: evaluate(maxWidth, f.properties, i),\n lineHeight: evaluate(lineHeight, f.properties, i),\n anchor: evaluate(anchor, f.properties, i),\n offset: evaluate(offset, f.properties, i),\n });\n if (!s.quads.length) return;\n const halo = evaluate(haloWidth, f.properties, i);\n const fill = parseColor(evaluate(color, f.properties, i));\n const haloRgba = parseColor(evaluate(haloColor, f.properties, i));\n for (const { at, along } of anchors(f.geometry)) {\n const label = count++;\n const [x, y] = toMercator(at);\n anchorList.push(x, y);\n // Along the line: its direction in Mercator (y towards the south)\n let direction: [number, number] = [0, 0];\n if (placement === 'line' && along) {\n const [x1, y1] = toMercator([at[0] + along[0], at[1] + along[1]]);\n direction = [x1 - x, y1 - y];\n }\n // The collision box: the ink, with the halo and a little room\n const pad = halo + 1;\n boxes.push(s.box[0] - pad, s.box[1] - pad, s.box[2] + pad, s.box[3] + pad);\n styles.push(\n ...fill,\n ...haloRgba,\n halo,\n evaluate(overlap, f.properties, i) ? 1 : 0,\n ...direction,\n ...stops(scale),\n );\n for (const q of s.quads) quads.push(label, ...q);\n }\n });\n return {\n anchors: Float64Array.from(anchorList),\n boxes: Float32Array.from(boxes),\n styles: Float32Array.from(styles),\n quads: Float32Array.from(quads),\n count,\n style: this.styleGeneration,\n base,\n glyphs: this.host.glyphs.version,\n complete,\n };\n }\n\n private send(engine: Engine, id: number): void {\n const l = this.labels;\n if (l) engine.setSymbols(id, l.anchors, l.boxes, l.styles, l.quads);\n this.sendLayer(engine, id);\n }\n\n private sendLayer(engine: Engine, id: number): void {\n const { opacity, minZoom, maxZoom, visible } = this.style;\n // The sizes are per label; the layer's own scale stays 1\n engine.setSymbolLayer(\n id,\n Float32Array.from(stops(1)),\n Float32Array.from(stops(opacity)),\n minZoom,\n maxZoom,\n visible,\n );\n }\n\n /** @internal */\n protected create(engine: Engine): number {\n const id = engine.addSymbols();\n if (this.labels) this.send(engine, id);\n else {\n this.sendLayer(engine, id);\n // The first shaping, once the id is known\n queueMicrotask(() => void this.update());\n }\n return id;\n }\n}\n\nexport function symbolStyle<P>(options: SymbolOptions<P>): SymbolStyle<P> {\n const { data: _, before: __, ...rest } = options;\n return {\n opacity: 1,\n minZoom: 0,\n maxZoom: 24,\n visible: true,\n filter: undefined,\n text: '',\n font: DEFAULT_FONT,\n size: 12,\n color: '#000',\n haloColor: '#fff',\n haloWidth: 0,\n anchor: 'center',\n placement: 'point',\n offset: [0, 0],\n maxWidth: 10,\n lineHeight: 1.2,\n overlap: false,\n ...rest,\n };\n}\n"]}
1
+ {"version":3,"file":"symbols.js","sourceRoot":"","sources":["../src/symbols.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Text labels and icons from GeoJSON: at points, at the middle of lines, at the center of polygons. Shaped on the page,\n * placed by the engine every frame with collisions shared by all symbol layers (the top layer first, each layer in\n * data order), drawn with a halo, standing on the relief. The icons are the map's images (`map.addImage`, a vector\n * basemap's sprite), beside their text or stretched around it.\n */\nimport {\n evaluate,\n type Feature,\n type FeatureData,\n type FeatureLayerStyle,\n featuresOf,\n type Geometry,\n type Placement,\n type Position,\n type Properties,\n parseColor,\n type Size,\n type Styled,\n stops,\n} from './features.ts';\nimport { toMercator } from './geo.ts';\nimport { codes, DEFAULT_FONT, type Glyph, type Glyphs, type Shaping, shape, type TextPart } from './glyphs.ts';\nimport { type Icons, layoutIcon } from './icons.ts';\nimport { Layer } from './layers.ts';\nimport type { Anchor } from './overlay.ts';\nimport type { LayerHost } from './types.ts';\nimport type { Engine } from './wasm/isard.js';\n\nexport interface SymbolStyle<P = Properties> extends Omit<FeatureLayerStyle<P>, 'ramp'> {\n /** The text: a string (`\\n` breaks lines) or runs with their own scale and font; empty: no label */\n text: Styled<string | TextPart[], P>;\n /** A font of the map's glyphs (default `Noto Sans Regular`; also Bold and Italic with the default glyphs) */\n font: Styled<string, P>;\n /** CSS pixels, or zoom stops (default 12) */\n size: Styled<Size, P>;\n /** `'point'` (default): horizontal text; `'line'`: along the line at its middle, kept upright */\n placement: Styled<'point' | 'line', P>;\n color: Styled<string, P>;\n haloColor: Styled<string, P>;\n /** CSS pixels (default 0) */\n haloWidth: Styled<number, P>;\n /** Side of the text at the anchor (default `'center'`) */\n anchor: Styled<Anchor, P>;\n /** Shift, ems (default [0, 0]) */\n offset: Styled<[x: number, y: number], P>;\n /** Wrapping width, ems (default 10) */\n maxWidth: Styled<number, P>;\n /** Ems (default 1.2) */\n lineHeight: Styled<number, P>;\n /** Shown even where it overlaps other labels, and hiding none (MapLibre's allow-overlap and ignore-placement);\n * `'allow'`: shown even where it overlaps, still hiding the labels after it; `'ignore'`: shown only where it fits,\n * hiding none (default false) */\n overlap: Styled<Overlap, P>;\n /** Shown without its icon where the icon does not fit (default false) */\n textOptional: Styled<boolean, P>;\n /** An image of the map (`map.addImage`); empty: none (default) */\n icon: Styled<string, P>;\n /** Scale of the image, or zoom stops (default 1) */\n iconSize: Styled<Size, P>;\n /** Side of the icon at the anchor (default `'center'`) */\n iconAnchor: Styled<Anchor, P>;\n /** Shift, CSS pixels at size 1 (default [0, 0]) */\n iconOffset: Styled<[x: number, y: number], P>;\n /** Degrees, clockwise (default 0) */\n iconRotate: Styled<number, P>;\n /** `'viewport'`: facing the screen; `'map'`: turning with the map, along its line when placed on one; `'auto'`\n * (default): `'map'` with the `'line'` placement */\n iconRotationAlignment: Styled<'map' | 'viewport' | 'auto', P>;\n /** As `overlap`, for the icon (default false) */\n iconOverlap: Styled<Overlap, P>;\n /** Shown without its text where the text does not fit (default false) */\n iconOptional: Styled<boolean, P>;\n /** Stretched around its text: its width, its height, both (a road shield; `'none'` by default) */\n iconTextFit: Styled<'none' | 'width' | 'height' | 'both', P>;\n /** Room around the text of a fitted icon: top, right, bottom, left (CSS pixels, default 0) */\n iconTextFitPadding: Styled<[top: number, right: number, bottom: number, left: number], P>;\n /** Color of a signed distance field image (default black) */\n iconColor: Styled<string, P>;\n /** 0 to 1 (default 1) */\n iconOpacity: Styled<number, P>;\n}\n\n/** How a label's text or icon meets the others: `true` shown wherever and hiding none, `'allow'` shown wherever,\n * `'ignore'` hiding none, `false` neither (MapLibre's allow-overlap and ignore-placement) */\nexport type Overlap = boolean | 'allow' | 'ignore';\n\nexport interface SymbolOptions<P = Properties> extends Partial<SymbolStyle<P>>, Placement {\n data: FeatureData<P>;\n}\n\n/** Where a geometry is labelled: its points, the middle of its longest line (with the direction of the line there),\n * the centroid of its largest polygon */\nfunction anchors(geometry: Geometry | null): { at: Position; along?: [number, number] }[] {\n return points(geometry).map((p) => (p.length > 2 ? { at: [p[0], p[1]], along: [p[2] ?? 0, p[3] ?? 0] } : { at: p }));\n}\n\n/** Anchors as positions, a line's carrying the direction (lon, lat, dlon, dlat) */\nfunction points(geometry: Geometry | null): Position[] {\n if (!geometry) return [];\n switch (geometry.type) {\n case 'Point':\n return [geometry.coordinates];\n case 'MultiPoint':\n return geometry.coordinates;\n case 'LineString':\n case 'MultiLineString': {\n const lines = geometry.type === 'LineString' ? [geometry.coordinates] : geometry.coordinates;\n const length = (l: Position[]) =>\n l.slice(1).reduce((s, p, i) => s + Math.hypot(p[0] - (l[i]?.[0] ?? 0), p[1] - (l[i]?.[1] ?? 0)), 0);\n const line = lines.reduce((a, b) => (length(b) > length(a) ? b : a), lines[0] ?? []);\n let rest = length(line) / 2;\n for (let i = 1; i < line.length; i += 1) {\n const [a, b] = [line[i - 1], line[i]];\n if (!a || !b) continue;\n const d = Math.hypot(b[0] - a[0], b[1] - a[1]);\n if (d >= rest && d > 0) {\n return [[a[0] + ((b[0] - a[0]) * rest) / d, a[1] + ((b[1] - a[1]) * rest) / d, b[0] - a[0], b[1] - a[1]]];\n }\n rest -= d;\n }\n return line[0] ? [line[0]] : [];\n }\n case 'Polygon':\n case 'MultiPolygon': {\n const polygons = geometry.type === 'Polygon' ? [geometry.coordinates] : geometry.coordinates;\n let best: Position | undefined;\n let bestArea = 0;\n for (const p of polygons) {\n const ring = p[0] ?? [];\n let [a, cx, cy] = [0, 0, 0];\n for (let i = 0; i + 1 < ring.length; i += 1) {\n const [x0, y0] = ring[i] ?? [0, 0];\n const [x1, y1] = ring[i + 1] ?? [0, 0];\n const cross = x0 * y1 - x1 * y0;\n a += cross;\n cx += (x0 + x1) * cross;\n cy += (y0 + y1) * cross;\n }\n if (Math.abs(a) > bestArea) {\n bestArea = Math.abs(a);\n best = [cx / (3 * a), cy / (3 * a)];\n }\n }\n return best ? [best] : [];\n }\n case 'GeometryCollection':\n return geometry.geometries.flatMap(points);\n }\n}\n\n/** The map's glyphs and icons, for a layer */\nexport interface GlyphHost extends LayerHost {\n readonly glyphs: Glyphs;\n readonly icons: Icons;\n}\n\n/** Flags of a label for the engine (`flag` in symbols.rs) */\nconst FLAG = {\n textOverlap: 1,\n textIgnore: 2,\n iconOverlap: 4,\n iconIgnore: 8,\n textOptional: 16,\n iconOptional: 32,\n text: 64,\n icon: 128,\n textAlong: 256,\n iconAlong: 512,\n iconUpright: 1024,\n} as const;\n\n/** Flags of an overlap: allowed to overlap, ignored by the placement */\nfunction overlapFlags(overlap: Overlap, allow: number, ignore: number): number {\n if (overlap === true) return allow | ignore;\n if (overlap === 'allow') return allow;\n return overlap === 'ignore' ? ignore : 0;\n}\n\n/** Room around an icon's box, CSS pixels (MapLibre's default `icon-padding`) */\nconst ICON_PADDING = 2;\n\n/** Labels built for the engine: an anchor (Mercator x, y), a collision box, a style per label; glyph quads whose first\n * number is their label's index */\ninterface Labels {\n anchors: Float64Array;\n boxes: Float32Array;\n styles: Float32Array;\n quads: Float32Array;\n}\n\n/** Numbers per quad: its label's index, its place, its atlas coordinates, its scale (a glyph's; -1 or -2: an icon),\n * its turn */\nconst QUAD = 11;\n\n/** The labels of a group of features, kept while they stay valid: same style, the same index of the group's first\n * feature (unless the style reads no index), and their glyphs and icons complete or none added since */\ninterface Chunk extends Labels {\n count: number;\n style: number;\n base: number;\n glyphs: number;\n icons: number;\n complete: boolean;\n}\n\n/** Every character of a run has its glyph */\nfunction present(part: TextPart, loaded: Map<string, Map<number, Glyph>>): boolean {\n const glyphs = loaded.get(part.font ?? DEFAULT_FONT);\n if (!glyphs) return false;\n for (const ch of part.text) if (ch !== '\\n' && !glyphs.has(ch.codePointAt(0) ?? 32)) return false;\n return true;\n}\n\n/** The labels of chunks one after the other, the quads' label indices moved past those of the chunks before */\nfunction concat(chunks: readonly Chunk[]): Labels {\n if (chunks.length === 1 && chunks[0]) return chunks[0];\n const length = (key: keyof Labels) => chunks.reduce((n, c) => n + c[key].length, 0);\n const out: Labels = {\n anchors: new Float64Array(length('anchors')),\n boxes: new Float32Array(length('boxes')),\n styles: new Float32Array(length('styles')),\n quads: new Float32Array(length('quads')),\n };\n const at = { anchors: 0, boxes: 0, styles: 0, quads: 0 };\n let labels = 0;\n for (const c of chunks) {\n out.anchors.set(c.anchors, at.anchors);\n out.boxes.set(c.boxes, at.boxes);\n out.styles.set(c.styles, at.styles);\n out.quads.set(c.quads, at.quads);\n if (labels > 0)\n for (let q = at.quads; q < at.quads + c.quads.length; q += QUAD) out.quads[q] = (out.quads[q] ?? 0) + labels;\n at.anchors += c.anchors.length;\n at.boxes += c.boxes.length;\n at.styles += c.styles.length;\n at.quads += c.quads.length;\n labels += c.count;\n }\n return out;\n}\n\nexport class SymbolLayer<P = Properties> extends Layer {\n private list: Feature<P>[];\n /** The features in groups that do not change (`setGroups`): each group's labels kept between updates */\n private groups: readonly (readonly Feature<P>[])[] | undefined;\n private readonly chunks = new WeakMap<readonly Feature<P>[], Chunk>();\n /** Bumped by each change: a shaping that finished after a newer one began is dropped */\n private generation = 0;\n /** Bumped by each change of style: the labels kept are shaped again */\n private styleGeneration = 0;\n /** No style function takes the index of a feature: a group's labels do not depend on its place */\n private indexFree = true;\n private labels: Labels | undefined;\n\n /** @internal */\n constructor(\n private readonly host: GlyphHost,\n data: FeatureData<P>,\n private style: SymbolStyle<P>,\n ) {\n super(host);\n this.list = featuresOf(data);\n this.styled();\n }\n\n get features(): readonly Feature<P>[] {\n return this.list;\n }\n\n setData(data: FeatureData<P>): void {\n this.list = featuresOf(data);\n this.groups = undefined;\n void this.update();\n }\n\n /**\n * @internal The features as groups that are never changed once given (the labels of a vector tile and style layer),\n * in order: the labels of a group seen before are not shaped again\n */\n setGroups(groups: readonly (readonly Feature<P>[])[]): void {\n this.groups = groups;\n this.list = groups.flat();\n void this.update();\n }\n\n setStyle(style: Partial<SymbolStyle<P>>): void {\n this.style = { ...this.style, ...style };\n this.styled();\n void this.update();\n }\n\n setFilter(filter: ((properties: P, index: number) => boolean) | undefined): void {\n this.setStyle({ filter } as Partial<SymbolStyle<P>>);\n }\n\n setVisible(visible: boolean): void {\n this.style = { ...this.style, visible };\n this.sendLayer(this.map.engine, this.id);\n this.map.requestRender();\n }\n\n private styled(): void {\n this.styleGeneration += 1;\n // A function of one parameter reads the properties only\n this.indexFree = Object.values(this.style).every((v) => typeof v !== 'function' || v.length < 2);\n }\n\n /** The runs of text of each feature of a group (none for a feature filtered out) */\n private parts(group: readonly Feature<P>[], base: number): TextPart[][] {\n const { text, font, filter } = this.style;\n return group.map((f, k): TextPart[] => {\n const i = base + k;\n if (filter && !filter(f.properties, i)) return [];\n const t = evaluate(text, f.properties, i);\n const own = evaluate(font, f.properties, i);\n // Each run in its font, the feature's by default\n return (typeof t === 'string' ? [{ text: t }] : t).map((p) => ({ ...p, font: p.font ?? own }));\n });\n }\n\n /** Shapes the labels (loading their glyphs first) and sends them; the groups' labels still valid are kept */\n private async update(): Promise<void> {\n const generation = ++this.generation;\n const groups = this.groups ?? [this.list];\n const keep = this.groups !== undefined;\n const glyphs = this.host.glyphs;\n const todo: { group: readonly Feature<P>[]; base: number; parts: TextPart[][] }[] = [];\n let base = 0;\n for (const group of groups) {\n const c = keep ? this.chunks.get(group) : undefined;\n const valid =\n c !== undefined &&\n c.style === this.styleGeneration &&\n (c.base === base || this.indexFree) &&\n (c.complete || (c.glyphs === glyphs.version && c.icons === this.host.icons.version));\n if (!valid) todo.push({ group, base, parts: this.parts(group, base) });\n base += group.length;\n }\n const byFont = new Map<string, Set<number>>();\n for (const { parts } of todo) {\n for (const p of parts.flat()) {\n const key = p.font ?? DEFAULT_FONT;\n const set = byFont.get(key) ?? new Set<number>();\n for (const code of codes([p])) set.add(code);\n byFont.set(key, set);\n }\n }\n const loaded = new Map<string, Map<number, Glyph>>();\n await Promise.all(\n [...byFont].map(async ([f, set]) => {\n loaded.set(f, await glyphs.load(f, set));\n }),\n );\n if (generation !== this.generation) return;\n const built = new Map<readonly Feature<P>[], Chunk>();\n for (const { group, base: b, parts } of todo) {\n const chunk = this.build(group, b, parts, loaded);\n built.set(group, chunk);\n if (keep) this.chunks.set(group, chunk);\n }\n this.labels = concat(groups.map((g) => built.get(g) ?? (this.chunks.get(g) as Chunk)));\n // The icons packed for them\n this.host.icons.flush();\n this.send(this.map.engine, this.id);\n this.map.requestRender();\n }\n\n /** The labels of a group of features, `base` the index of its first feature */\n private build(\n group: readonly Feature<P>[],\n base: number,\n parts: TextPart[][],\n loaded: Map<string, Map<number, Glyph>>,\n ): Chunk {\n const { font, size, anchor, offset, maxWidth, lineHeight, color, haloColor, haloWidth, overlap, placement } =\n this.style;\n const st = this.style;\n const icons = this.host.icons;\n const anchorList: number[] = [];\n const boxes: number[] = [];\n const styles: number[] = [];\n const iconQuads: number[] = [];\n const textQuads: number[] = [];\n let count = 0;\n let complete = true;\n group.forEach((f, k) => {\n const i = base + k;\n const p = f.properties;\n const text = parts[k];\n const filtered = st.filter !== undefined && !st.filter(p, i);\n const hasText = !!text?.length && text.some((t) => t.text);\n const iconName = filtered ? '' : evaluate(st.icon, p, i);\n const icon = iconName ? icons.get(iconName) : undefined;\n // An image not added yet: laid out again once more are\n if (iconName && !icon) complete = false;\n if (!hasText && !icon) return;\n // Glyphs still missing: shaped again once more glyphs are loaded\n if (complete && text && !text.every((t) => present(t, loaded))) complete = false;\n // Shaped at its largest size; the engine scales by the zoom stops\n const shapedAt = (v: Size) => (typeof v === 'number' ? v : Math.max(...v.map(([, x]) => x), 1e-6));\n const scaleOf = (v: Size, at: number): Size =>\n typeof v === 'number' ? 1 : v.map(([z, x]): [number, number] => [z, x / at]);\n const s0 = evaluate(size, p, i);\n const shaped = shapedAt(s0);\n const scale = scaleOf(s0, shaped);\n let s: Shaping | undefined;\n if (hasText && text) {\n s = shape(text, (name) => loaded.get(name), {\n font: evaluate(font, p, i),\n size: shaped,\n maxWidth: evaluate(maxWidth, p, i),\n lineHeight: evaluate(lineHeight, p, i),\n anchor: evaluate(anchor, p, i),\n offset: evaluate(offset, p, i),\n });\n if (!s.quads.length) s = undefined;\n }\n if (!s && !icon) return;\n const along = evaluate(placement, p, i) === 'line';\n let flags = overlapFlags(evaluate(overlap, p, i), FLAG.textOverlap, FLAG.textIgnore);\n if (evaluate(st.textOptional, p, i)) flags |= FLAG.textOptional;\n if (s) flags |= FLAG.text;\n // The icon: beside its text, or stretched around it (then scaled and turned with it)\n let iconScale: Size = 1;\n let iconBox: [number, number, number, number] = [0, 0, 0, 0];\n let iconColor: [number, number, number, number] = [0, 0, 0, 0];\n let quads: number[][] = [];\n let iconTurns = false;\n let fitted = false;\n if (icon) {\n const fit = evaluate(st.iconTextFit, p, i);\n fitted = fit !== 'none' && s !== undefined;\n const i0 = evaluate(st.iconSize, p, i);\n const iconShaped = fitted ? 1 : shapedAt(i0);\n iconScale = fitted ? scale : scaleOf(i0, iconShaped);\n const laid = layoutIcon(icon, {\n size: iconShaped,\n anchor: evaluate(st.iconAnchor, p, i),\n offset: evaluate(st.iconOffset, p, i),\n rotate: evaluate(st.iconRotate, p, i),\n fit,\n padding: evaluate(st.iconTextFitPadding, p, i),\n text: s?.layout,\n });\n quads = laid.quads;\n if (quads.length) {\n flags |= FLAG.icon | overlapFlags(evaluate(st.iconOverlap, p, i), FLAG.iconOverlap, FLAG.iconIgnore);\n if (evaluate(st.iconOptional, p, i)) flags |= FLAG.iconOptional;\n const alignment = evaluate(st.iconRotationAlignment, p, i);\n if (fitted) flags |= FLAG.iconUpright;\n iconTurns = alignment === 'map' || (alignment === 'auto' && along);\n iconBox = [\n laid.box[0] - ICON_PADDING,\n laid.box[1] - ICON_PADDING,\n laid.box[2] + ICON_PADDING,\n laid.box[3] + ICON_PADDING,\n ];\n const [r, g, b, a] = parseColor(evaluate(st.iconColor, p, i));\n iconColor = [r, g, b, a * Math.max(0, Math.min(1, evaluate(st.iconOpacity, p, i)))];\n }\n }\n if (!(flags & (FLAG.text | FLAG.icon))) return;\n const halo = s ? evaluate(haloWidth, p, i) : 0;\n const fill = parseColor(evaluate(color, p, i));\n const haloRgba = parseColor(evaluate(haloColor, p, i));\n // The collision box: the ink, with the halo and a little room\n const pad = halo + 1;\n const textBox = s ? [s.box[0] - pad, s.box[1] - pad, s.box[2] + pad, s.box[3] + pad] : [0, 0, 0, 0];\n for (const { at, along: line } of anchors(f.geometry)) {\n const label = count++;\n const [x, y] = toMercator(at);\n anchorList.push(x, y);\n // The text along its line, kept upright; the icon turning with the map (along its line, or with the east at a\n // point), or with its text when fitted to it\n const textAlong = along && line !== undefined && s !== undefined;\n const iconAlong = (flags & FLAG.icon) !== 0 && (fitted ? textAlong : iconTurns);\n let labelFlags = flags | (textAlong ? FLAG.textAlong : 0) | (iconAlong ? FLAG.iconAlong : 0);\n // The direction of its line in Mercator (y towards the south)\n let direction: [number, number] = [0, 0];\n if (line && (textAlong || iconAlong)) {\n const [x1, y1] = toMercator([at[0] + line[0], at[1] + line[1]]);\n direction = [x1 - x, y1 - y];\n } else if (iconAlong) {\n direction = [1, 0];\n }\n if (direction[0] === 0 && direction[1] === 0) labelFlags &= ~(FLAG.textAlong | FLAG.iconAlong);\n boxes.push(...textBox);\n styles.push(\n ...fill,\n ...haloRgba,\n halo,\n labelFlags,\n ...direction,\n ...stops(scale),\n ...iconBox,\n ...iconColor,\n ...stops(iconScale),\n );\n for (const q of quads) iconQuads.push(label, ...q);\n if (s) for (const q of s.quads) textQuads.push(label, ...q, 0);\n }\n });\n return {\n anchors: Float64Array.from(anchorList),\n boxes: Float32Array.from(boxes),\n styles: Float32Array.from(styles),\n // The icons under the texts\n quads: Float32Array.from([...iconQuads, ...textQuads]),\n count,\n style: this.styleGeneration,\n base,\n glyphs: this.host.glyphs.version,\n icons: icons.version,\n complete,\n };\n }\n\n private send(engine: Engine, id: number): void {\n const l = this.labels;\n if (l) engine.setSymbols(id, l.anchors, l.boxes, l.styles, l.quads);\n this.sendLayer(engine, id);\n }\n\n private sendLayer(engine: Engine, id: number): void {\n const { opacity, minZoom, maxZoom, visible } = this.style;\n // The sizes are per label; the layer's own scale stays 1\n engine.setSymbolLayer(\n id,\n Float32Array.from(stops(1)),\n Float32Array.from(stops(opacity)),\n minZoom,\n maxZoom,\n visible,\n );\n }\n\n /** @internal */\n protected create(engine: Engine): number {\n const id = engine.addSymbols();\n if (this.labels) this.send(engine, id);\n else {\n this.sendLayer(engine, id);\n // The first shaping, once the id is known\n queueMicrotask(() => void this.update());\n }\n return id;\n }\n}\n\nexport function symbolStyle<P>(options: SymbolOptions<P>): SymbolStyle<P> {\n const { data: _, before: __, ...rest } = options;\n return {\n opacity: 1,\n minZoom: 0,\n maxZoom: 24,\n visible: true,\n filter: undefined,\n text: '',\n font: DEFAULT_FONT,\n size: 12,\n color: '#000',\n haloColor: '#fff',\n haloWidth: 0,\n anchor: 'center',\n placement: 'point',\n offset: [0, 0],\n maxWidth: 10,\n lineHeight: 1.2,\n overlap: false,\n textOptional: false,\n icon: '',\n iconSize: 1,\n iconAnchor: 'center',\n iconOffset: [0, 0],\n iconRotate: 0,\n iconRotationAlignment: 'auto',\n iconOverlap: false,\n iconOptional: false,\n iconTextFit: 'none',\n iconTextFitPadding: [0, 0, 0, 0],\n iconColor: '#000',\n iconOpacity: 1,\n ...rest,\n };\n}\n"]}
package/dist/types.d.ts CHANGED
@@ -104,8 +104,8 @@ export interface GeoMapOptions extends Partial<Camera> {
104
104
  * resolve the default URL. Maps load it first, and the engine with 3D Tiles (`wasmUrl`) for their first 3D Tiles
105
105
  * layer only */
106
106
  coreWasmUrl?: string | URL;
107
- /** Load the engine with 3D Tiles from the start (default false: it is loaded when the first 3D Tiles layer is added,
108
- * the map then moving its camera and layers onto it, a stall of about a frame or two). For a map that shows 3D Tiles
107
+ /** Load the engine with 3D Tiles from the start (default false: it is loaded when the first 3D Tiles layer or glTF
108
+ * model is added, the map then moving its camera and layers onto it, a stall of about a frame or two). For a map that shows 3D Tiles
109
109
  * at once: one engine downloaded instead of two. `'preload'`: the map starts on the engine without 3D Tiles and
110
110
  * downloads and compiles the other once idle, without running it: its first 3D Tiles layer does not wait for the
111
111
  * download (for a map that will show 3D Tiles later, on demand) */
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["/** Public types of the `isard` package */\nimport type { AttributionOptions } from './controls.ts';\nimport type { DecoderUrls } from './decoders.ts';\nimport type { Feature, Ramp, Size } from './features.ts';\nimport type { TileGrid } from './grid.ts';\nimport type { Layer } from './layers.ts';\nimport type { Camera, Engine } from './wasm/isard.js';\n\nexport type LonLat = [lon: number, lat: number];\nexport type Point = [x: number, y: number];\n\n/**\n * The named basemaps. OpenFreeMap's vector styles, OpenStreetMap data worldwide, their labels above the other layers:\n * `osm-positron` (light grey, quiet: data over it reads first), `osm-liberty` and `osm-bright` (in colour). The\n * Géoplateforme's (IGN, France): rasters (`ign-plan`, `ign-plan-grey`, `ign-ortho`, the aerial photographs) or vector\n * tiles with their labels (`ign-plan-vector`, `ign-plan-grey-vector`, the PLAN.IGN styles).\n */\nexport type BasemapName =\n | 'osm-positron'\n | 'osm-liberty'\n | 'osm-bright'\n | 'ign-plan'\n | 'ign-plan-grey'\n | 'ign-ortho'\n | 'ign-plan-vector'\n | 'ign-plan-grey-vector'\n | 'none';\n\n/**\n * @deprecated The former names of the Géoplateforme basemaps, still accepted (with a warning): the same names with the\n * `ign-` prefix (`'plan-grey'` is `'ign-plan-grey'`)\n */\nexport type LegacyBasemap = 'plan' | 'plan-grey' | 'plan-vector' | 'plan-grey-vector' | 'ortho';\n\n/** A basemap by name (see `BasemapName`; the former names of `LegacyBasemap` are deprecated) */\nexport type Basemap = BasemapName | LegacyBasemap;\n\n/**\n * The Earth's named terrain models. `'terrain-tiles'`: worldwide, the Terrain Tiles of AWS's open data registry\n * (SRTM, EU-DEM, GMTED… merged by Mapzen, 30 m in most places), the sea floor flattened at sea level. `'ign'`: France,\n * the IGN's RGE ALTI from the Géoplateforme (1 to 5 m), raised by the RAF20 geoid to heights above the ellipsoid.\n */\nexport type TerrainModel = 'terrain-tiles' | 'ign';\n\n/** How tiles encode their altitudes: `'float32'`, raw little-endian floats (`image/x-bil;bits=32`, an ArcGIS raw\n * grid); `'terrarium'`, the colors of a PNG, `R × 256 + G + B / 256 - 32768`; `'mapbox'`, those of Terrain-RGB,\n * `(R × 65536 + G × 256 + B) / 10 - 10000` */\nexport type TerrainEncoding = 'float32' | 'terrarium' | 'mapbox';\n\n/**\n * How tiles load and show. 'immediate' (default): everything visible loads, tiles show as soon as they arrive.\n * 'smooth': during flights the levels flown through are skipped, off-center tiles wait while the camera moves, tiles\n * fade in; fewer downloads, for slow networks or GPUs.\n */\nexport type LoadingMode = 'immediate' | 'smooth';\n\n/** 'globe': a sphere at low zoom, blending into Web Mercator between zooms 5 and 7 */\nexport type Projection = 'globe' | 'mercator';\n\n/** A body to draw the map on, other than the named ones (`CelestialBody`) */\nexport interface BodyOptions {\n /** Equatorial radius, metres */\n radius: number;\n /** Flattening of its ellipsoid, 0 for a sphere (default 0) */\n flattening?: number;\n /** An atmosphere: its halo around the globe, true for the Earth's light blue, or a CSS color (its alpha the\n * halo's strength) (default false) */\n atmosphere?: boolean | string;\n /** Color of the globe where no tile covers it (past the Web Mercator latitudes, 85°), a CSS color (default\n * `#808080`) */\n color?: string;\n /** Lowest and highest altitudes of its ground, metres around the ellipsoid: what its relief may raise into view\n * (default ±1 % of the radius) */\n relief?: [lowest: number, highest: number];\n}\n\n/**\n * The body the map is drawn on: 'earth' (WGS 84, the default), 'moon' (a sphere of 1 737 400 m, no atmosphere),\n * 'mars' (a sphere of 3 396 190 m, its equatorial radius, a thin dusty halo; planetocentric latitudes) or another\n * one. Zoom levels keep their meaning on screen (the Web Mercator tile pyramid), their metres follow the body:\n * altitudes, relief, buildings, 3D Tiles. Off the Earth, the map has none of the Earth's defaults: no basemap, no\n * credits, and space for its background; the Moon and Mars have NASA's relief for `terrain: true`.\n */\nexport type CelestialBody = 'earth' | 'moon' | 'mars' | BodyOptions;\n\nexport interface GeoMapOptions extends Partial<Camera> {\n /** The body the map is drawn on (default 'earth'); set at creation */\n body?: CelestialBody;\n /** Default 'globe' */\n projection?: Projection;\n /** Default 'immediate' */\n loading?: LoadingMode;\n /** The basemap (default 'osm-positron'; 'none' off the Earth) */\n basemap?: Basemap;\n /** Opacity of the IGN hillshade over the basemap (France, Géoplateforme), 0 for none (default 0) */\n hillshade?: number;\n /** Color behind the map (sky of tilted flat views), a CSS color (default `#f2f2f0`; black off the Earth) */\n background?: string;\n /** Space behind the globe: stars and atmosphere halo, fading out as the globe turns flat (default true) */\n sky?: boolean;\n /** Relief under the basemap: true for the body's terrain model (on the Earth the worldwide Terrain Tiles; NASA's on\n * the Moon and Mars: LOLA, MOLA), one of the Earth's models by name (`'ign'`: France, RGE ALTI), or its options\n * (default false; on another body, its `url` is required). Network layers are draped on it */\n terrain?: boolean | TerrainModel | TerrainOptions;\n minZoom?: number;\n maxZoom?: number;\n /** Highest pitch, degrees, up to 85 (default 70) */\n maxPitch?: number;\n /** Sky over the plane, seen when the camera is tilted towards the horizon, and the fog the ground fades into\n * (MapLibre's `setSky`); default none: the background color */\n atmosphere?: AtmosphereOptions;\n /** Mouse, touch and keyboard controls (default true) */\n interactive?: boolean;\n /** Keyboard controls once the map has the focus (it is reached with Tab): arrows pan, Shift + arrows rotate and\n * tilt, + and - zoom (Shift: two levels), 0 faces north and levels the view (default true; none when not\n * `interactive`) */\n keyboard?: boolean;\n /** Accessible name of the map, read by screen readers (default 'Map') */\n ariaLabel?: string;\n /** Where to load the engine with 3D Tiles from (`isard_bg.wasm`), when a bundler does not resolve the default URL.\n * Given without `coreWasmUrl`, maps load this engine from the start */\n wasmUrl?: string | URL;\n /** Where to load the engine without 3D Tiles from (`isard_core_bg.wasm`, a third smaller), when a bundler does not\n * resolve the default URL. Maps load it first, and the engine with 3D Tiles (`wasmUrl`) for their first 3D Tiles\n * layer only */\n coreWasmUrl?: string | URL;\n /** Load the engine with 3D Tiles from the start (default false: it is loaded when the first 3D Tiles layer is added,\n * the map then moving its camera and layers onto it, a stall of about a frame or two). For a map that shows 3D Tiles\n * at once: one engine downloaded instead of two. `'preload'`: the map starts on the engine without 3D Tiles and\n * downloads and compiles the other once idle, without running it: its first 3D Tiles layer does not wait for the\n * download (for a map that will show 3D Tiles later, on demand) */\n tiles3d?: boolean | 'preload';\n /** Where to load the vector basemap worker from, when a bundler does not resolve the default URL */\n basemapWorkerUrl?: string | URL;\n /** Texture size of the vector basemap's tiles, pixels (default 512: lines and edges sharp at every zoom on a screen\n * of pixel ratio 1). 256: a quarter of the drawing in the workers, of the uploads and of the GPU memory, for lines\n * and edges a little softer between two zoom levels (the tiles are shown 181 to 362 CSS pixels wide) */\n basemapTileSize?: number;\n /** Glyphs of the symbol layers: a URL with `{fontstack}` and `{range}` (MapLibre's glyph format; default\n * OpenFreeMap's fonts, Noto Sans). A vector basemap's labels take the glyphs of its style */\n glyphs?: string;\n /** Workers decoding 3D Tiles off the main thread: a count, or false to decode on the main thread (default: cores - 1,\n * 1 to 4). False (or 0) also decodes the PNG relief and reprojects the equirectangular rasters on the main thread,\n * else done by the vector basemap's workers */\n workers?: number | false;\n /** Where to load the decoding worker from, when a bundler does not resolve the default URL */\n workerUrl?: string | URL;\n /** Folders of the Draco and Basis Universal decoders, loaded by the workers on first use (default: the official\n * builds on gstatic.com and jsDelivr; self-host them for offline or locked-down networks). They run through\n * `new Function`: a Content Security Policy needs `'unsafe-eval'` (see `DecoderUrls`) */\n decoders?: Partial<DecoderUrls>;\n /** Credits at the bottom right: false for none, or its options (default true: the credits of the basemap,\n * hillshade and relief in use, compact on maps narrower than 640 px) */\n attributionControl?: boolean | AttributionOptions;\n}\n\nexport interface TerrainOptions {\n /** One of the Earth's named models (default `'terrain-tiles'` on the Earth); unused with a `url` */\n model?: TerrainModel;\n /** Altitudes of 256 × 256 tiles in `encoding`: a WMS GetMap URL with {bbox} (EPSG:3857 on the Earth, the body's\n * Mercator metres elsewhere: the sphere of its radius), a tile URL with {z}, {x} and {y}, or an ArcGIS image service\n * (a URL ending in `/ImageServer`), asked for raw altitudes in the body's Mercator (default: the `model`'s; on the\n * Moon and Mars, NASA's Trek LOLA and MOLA models) */\n url?: string;\n /** How the tiles of `url` encode their altitudes (default `'float32'`); `'terrarium'` and `'mapbox'` take a URL with\n * {z}, {x} and {y} */\n encoding?: TerrainEncoding;\n /** Vertical exaggeration, 1 for the true relief (default 1) */\n exaggeration?: number;\n /** Finest level of the relief, up to 15 (default 15; 14 for the Terrain Tiles, 8 for the Moon's and Mars's models). It\n * starts at level 6 on the Earth, coarser on bodies of a larger relief for their size (3 on the Moon and Mars) */\n maxZoom?: number;\n /** Altitudes over mainland France raised by the height of the RAF20 geoid (the French one, 0 away from France), to\n * heights above the ellipsoid (those of 3D Tiles); false keeps the altitudes as served (NGF-IGN69 for the IGN's)\n * (default true for the `'ign'` model, false otherwise) */\n geoid?: boolean;\n}\n\n/** Sky, horizon and fog over the plane, with the names and meanings of MapLibre's `setSky` */\nexport interface AtmosphereOptions {\n /** A CSS color (default `#9cc7ec`) */\n skyColor?: string;\n /** (default `#e8f1f8`) */\n horizonColor?: string;\n /** (default `#f2f5f8`) */\n fogColor?: string;\n /** Blend from the horizon to the sky color, share of the field of view above the horizon, 0-1 (default 0.6) */\n skyHorizonBlend?: number;\n /** Blend from the horizon to the fog color below the horizon, 0-1 (default 0.7) */\n horizonFogBlend?: number;\n /** Share of the distance to the far plane over which the ground fades into the fog, 0-1 (default 0.4) */\n fogGroundBlend?: number;\n}\n\n/** Animation of a camera move */\nexport interface AnimationOptions {\n /** Milliseconds */\n duration?: number;\n /** Progress over time, both 0 to 1 */\n easing?: (t: number) => number;\n}\n\nexport interface FlyToOptions extends AnimationOptions {\n /** How far the flight zooms out on its way, as MapLibre's `curve` (default 1.42) */\n curve?: number;\n /** Average speed in screens per second when `duration` is not given (default 1.2) */\n speed?: number;\n}\n\n/**\n * Tile grid of a raster's URL. 'mercator': Web Mercator (XYZ, WMTS PM), the engine's own. 'equirectangular':\n * longitudes and latitudes (Plate Carrée, EPSG:4326-like), two 256 px tiles side by side at level 0, rows from the\n * north (NASA's Trek WMTS, WorldCRS84Quad). A `TileGrid`: the tile matrices of a WMTS in any CRS (Lambert-93…), or a\n * WMS asked for each tile's box in its CRS. The last two are reprojected into Web Mercator tiles by the map's workers\n * (in the page with `workers: false`).\n */\nexport type RasterGrid = 'mercator' | 'equirectangular' | TileGrid;\n\n/** What `RasterLayer.setStyle` changes */\nexport interface RasterStyle {\n opacity: number;\n /** 0 = greyscale, 1 = original colors */\n saturation: number;\n}\n\nexport interface RasterOptions {\n /** Tile URL with {z}, {x} and {y} (256 px tiles); unused with a `loader` */\n url: string;\n /** Tile grid of `url` (default 'mercator'); with 'equirectangular', `minZoom` and `maxZoom` are levels of that\n * grid; with a `TileGrid`, they are map zooms, by default those its matrices span */\n grid?: RasterGrid;\n minZoom?: number;\n maxZoom?: number;\n opacity?: number;\n /** 0 = greyscale, 1 = original colors */\n saturation?: number;\n /** Side of the tiles' textures, pixels (default 256): more for sharper tiles drawn by a `loader` */\n size?: number;\n /** Draws each tile instead of fetching `url`: an image of `size` × `size`, null for nothing there; a rejection is\n * retried like a network error */\n loader?: (z: number, x: number, y: number, signal: AbortSignal) => Promise<ImageBitmap | null>;\n /** Credits of the tiles, HTML: shown by the attribution control while the layer is on the map */\n attribution?: string;\n}\n\nexport interface NetworkStyle {\n /** Line width, CSS pixels, or zoom stops `[[zoom, width], …]` (default 2) */\n width: Size;\n /** Values above are drawn as unreached (default 1800) */\n max: number;\n /** Darker line every `contour` value units, 0 for none (default 0) */\n contour: number;\n opacity: number;\n /** Width of the halo drawn under the lines, CSS pixels or zoom stops, 0 for none (default 0): wide and faint, the\n * reached streets add up into a heat map that fills the blocks */\n halo: Size;\n /** Opacity of the halo at the middle of a line, fading quadratically to its sides (default 0.11) */\n haloOpacity: number;\n /** Colors from 0 to `max`: `[[fraction of max, color], …]` (default green to red) */\n ramp: Ramp | undefined;\n /** Color of the parts beyond `max` or unreached (default `rgba(140, 140, 140, 0.25)`) */\n unreachedColor: string;\n /** Share of `max` over which the colors fade out before it, 0 to 1 (default 0) */\n fade: number;\n}\n\nexport interface NetworkOptions extends Partial<NetworkStyle> {\n /** Node coordinates in degrees: lon0, lat0, lon1, lat1… */\n nodes: Float64Array;\n /** Edges as node index pairs: a0, b0, a1, b1… */\n edges: Uint32Array;\n /** Line of each edge, from A to B: the points of edge e are `points[start[e] .. start[e + 1]]` (lon, lat pairs,\n * counted in points); with fewer than two points an edge is straight. Default: all straight. */\n lines?: { start: Uint32Array; points: Float64Array };\n /** Per edge, the cost of travelling it from A to B then from B to A, in value units (Infinity: closed that way;\n * closed both ways: not drawn). A point along an edge then takes the quickest way there, min(value(A) + cost from\n * A, value(B) + cost from B), as a travel time does. Without costs, values are interpolated along the edges. */\n costs?: Float32Array;\n /** Width factor of each edge (default 1): rail lines wider than streets */\n edgeWidths?: Float32Array;\n}\n\nexport interface Tiles3dStyle {\n /** Screen-space error (CSS pixels) above which a tile is refined: 16 by default, lower is finer and heavier */\n maxScreenSpaceError: number;\n opacity: number;\n}\n\nexport interface Tiles3dOptions extends Partial<Tiles3dStyle> {\n /** URL of a `tileset.json` (3D Tiles 1.0 b3dm or 1.1 glb meshes, external tilesets) */\n url: string;\n}\n\nexport interface MapPointerEvent {\n point: Point;\n /** Undefined above the horizon */\n lonLat: LonLat | undefined;\n}\n\n/** What 'hoverfeature' found under the pointer */\nexport interface MapHoverFeatureEvent extends MapPointerEvent {\n /** The feature under the pointer (see `GeoMap.pickFeature`), undefined if none */\n hit: FeatureHit | undefined;\n}\n\n/** A picked feature: its layer handle, its index there and, for line, circle and fill layers, the feature itself */\nexport interface FeatureHit {\n layer: Layer;\n index: number;\n feature: Feature | undefined;\n}\n\nexport interface MapEvents {\n /** The camera started moving (a gesture, an animation or `setCamera`) */\n movestart: Camera;\n /** The camera moved */\n move: Camera;\n /** The camera stopped: no gesture held, no animation running */\n moveend: Camera;\n /** The map changed size (CSS pixels) */\n resize: { width: number; height: number };\n /** The pointer moved over the map (at most once per frame, not while dragging) */\n hover: MapPointerEvent;\n /** What is under the pointer, picked without stalling the GPU: a frame or two after 'hover', only while listened to\n * (radius and layers in `GeoMap.hoverPicking`) */\n hoverfeature: MapHoverFeatureEvent;\n /** Click without drag */\n click: MapPointerEvent;\n /** A frame was drawn; duration of the engine call in milliseconds */\n render: { ms: number };\n /** Everything in view is loaded and drawn, nothing moves: the end of a load, once after each change (as MapLibre's\n * `idle`). Tiles requested by the first frame count, so it never fires before they arrive. */\n idle: Record<string, never>;\n /** The pointer left the canvas (a mouse going out of the map, or onto a control or marker) */\n leave: Record<string, never>;\n}\n\n/** What a layer handle needs from its map */\nexport interface LayerHost {\n readonly engine: Engine;\n requestRender(): void;\n /** Forgets a removed layer */\n detach(layer: object): void;\n /** Moves a layer under `before`, or on top */\n moveLayer(layer: object, before: object | undefined): void;\n /** A layer created again in the engine (new id): put at the place of its old id, which is removed */\n replaceLayer(layer: object, old: number): void;\n}\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["/** Public types of the `isard` package */\nimport type { AttributionOptions } from './controls.ts';\nimport type { DecoderUrls } from './decoders.ts';\nimport type { Feature, Ramp, Size } from './features.ts';\nimport type { TileGrid } from './grid.ts';\nimport type { Layer } from './layers.ts';\nimport type { Camera, Engine } from './wasm/isard.js';\n\nexport type LonLat = [lon: number, lat: number];\nexport type Point = [x: number, y: number];\n\n/**\n * The named basemaps. OpenFreeMap's vector styles, OpenStreetMap data worldwide, their labels above the other layers:\n * `osm-positron` (light grey, quiet: data over it reads first), `osm-liberty` and `osm-bright` (in colour). The\n * Géoplateforme's (IGN, France): rasters (`ign-plan`, `ign-plan-grey`, `ign-ortho`, the aerial photographs) or vector\n * tiles with their labels (`ign-plan-vector`, `ign-plan-grey-vector`, the PLAN.IGN styles).\n */\nexport type BasemapName =\n | 'osm-positron'\n | 'osm-liberty'\n | 'osm-bright'\n | 'ign-plan'\n | 'ign-plan-grey'\n | 'ign-ortho'\n | 'ign-plan-vector'\n | 'ign-plan-grey-vector'\n | 'none';\n\n/**\n * @deprecated The former names of the Géoplateforme basemaps, still accepted (with a warning): the same names with the\n * `ign-` prefix (`'plan-grey'` is `'ign-plan-grey'`)\n */\nexport type LegacyBasemap = 'plan' | 'plan-grey' | 'plan-vector' | 'plan-grey-vector' | 'ortho';\n\n/** A basemap by name (see `BasemapName`; the former names of `LegacyBasemap` are deprecated) */\nexport type Basemap = BasemapName | LegacyBasemap;\n\n/**\n * The Earth's named terrain models. `'terrain-tiles'`: worldwide, the Terrain Tiles of AWS's open data registry\n * (SRTM, EU-DEM, GMTED… merged by Mapzen, 30 m in most places), the sea floor flattened at sea level. `'ign'`: France,\n * the IGN's RGE ALTI from the Géoplateforme (1 to 5 m), raised by the RAF20 geoid to heights above the ellipsoid.\n */\nexport type TerrainModel = 'terrain-tiles' | 'ign';\n\n/** How tiles encode their altitudes: `'float32'`, raw little-endian floats (`image/x-bil;bits=32`, an ArcGIS raw\n * grid); `'terrarium'`, the colors of a PNG, `R × 256 + G + B / 256 - 32768`; `'mapbox'`, those of Terrain-RGB,\n * `(R × 65536 + G × 256 + B) / 10 - 10000` */\nexport type TerrainEncoding = 'float32' | 'terrarium' | 'mapbox';\n\n/**\n * How tiles load and show. 'immediate' (default): everything visible loads, tiles show as soon as they arrive.\n * 'smooth': during flights the levels flown through are skipped, off-center tiles wait while the camera moves, tiles\n * fade in; fewer downloads, for slow networks or GPUs.\n */\nexport type LoadingMode = 'immediate' | 'smooth';\n\n/** 'globe': a sphere at low zoom, blending into Web Mercator between zooms 5 and 7 */\nexport type Projection = 'globe' | 'mercator';\n\n/** A body to draw the map on, other than the named ones (`CelestialBody`) */\nexport interface BodyOptions {\n /** Equatorial radius, metres */\n radius: number;\n /** Flattening of its ellipsoid, 0 for a sphere (default 0) */\n flattening?: number;\n /** An atmosphere: its halo around the globe, true for the Earth's light blue, or a CSS color (its alpha the\n * halo's strength) (default false) */\n atmosphere?: boolean | string;\n /** Color of the globe where no tile covers it (past the Web Mercator latitudes, 85°), a CSS color (default\n * `#808080`) */\n color?: string;\n /** Lowest and highest altitudes of its ground, metres around the ellipsoid: what its relief may raise into view\n * (default ±1 % of the radius) */\n relief?: [lowest: number, highest: number];\n}\n\n/**\n * The body the map is drawn on: 'earth' (WGS 84, the default), 'moon' (a sphere of 1 737 400 m, no atmosphere),\n * 'mars' (a sphere of 3 396 190 m, its equatorial radius, a thin dusty halo; planetocentric latitudes) or another\n * one. Zoom levels keep their meaning on screen (the Web Mercator tile pyramid), their metres follow the body:\n * altitudes, relief, buildings, 3D Tiles. Off the Earth, the map has none of the Earth's defaults: no basemap, no\n * credits, and space for its background; the Moon and Mars have NASA's relief for `terrain: true`.\n */\nexport type CelestialBody = 'earth' | 'moon' | 'mars' | BodyOptions;\n\nexport interface GeoMapOptions extends Partial<Camera> {\n /** The body the map is drawn on (default 'earth'); set at creation */\n body?: CelestialBody;\n /** Default 'globe' */\n projection?: Projection;\n /** Default 'immediate' */\n loading?: LoadingMode;\n /** The basemap (default 'osm-positron'; 'none' off the Earth) */\n basemap?: Basemap;\n /** Opacity of the IGN hillshade over the basemap (France, Géoplateforme), 0 for none (default 0) */\n hillshade?: number;\n /** Color behind the map (sky of tilted flat views), a CSS color (default `#f2f2f0`; black off the Earth) */\n background?: string;\n /** Space behind the globe: stars and atmosphere halo, fading out as the globe turns flat (default true) */\n sky?: boolean;\n /** Relief under the basemap: true for the body's terrain model (on the Earth the worldwide Terrain Tiles; NASA's on\n * the Moon and Mars: LOLA, MOLA), one of the Earth's models by name (`'ign'`: France, RGE ALTI), or its options\n * (default false; on another body, its `url` is required). Network layers are draped on it */\n terrain?: boolean | TerrainModel | TerrainOptions;\n minZoom?: number;\n maxZoom?: number;\n /** Highest pitch, degrees, up to 85 (default 70) */\n maxPitch?: number;\n /** Sky over the plane, seen when the camera is tilted towards the horizon, and the fog the ground fades into\n * (MapLibre's `setSky`); default none: the background color */\n atmosphere?: AtmosphereOptions;\n /** Mouse, touch and keyboard controls (default true) */\n interactive?: boolean;\n /** Keyboard controls once the map has the focus (it is reached with Tab): arrows pan, Shift + arrows rotate and\n * tilt, + and - zoom (Shift: two levels), 0 faces north and levels the view (default true; none when not\n * `interactive`) */\n keyboard?: boolean;\n /** Accessible name of the map, read by screen readers (default 'Map') */\n ariaLabel?: string;\n /** Where to load the engine with 3D Tiles from (`isard_bg.wasm`), when a bundler does not resolve the default URL.\n * Given without `coreWasmUrl`, maps load this engine from the start */\n wasmUrl?: string | URL;\n /** Where to load the engine without 3D Tiles from (`isard_core_bg.wasm`, a third smaller), when a bundler does not\n * resolve the default URL. Maps load it first, and the engine with 3D Tiles (`wasmUrl`) for their first 3D Tiles\n * layer only */\n coreWasmUrl?: string | URL;\n /** Load the engine with 3D Tiles from the start (default false: it is loaded when the first 3D Tiles layer or glTF\n * model is added, the map then moving its camera and layers onto it, a stall of about a frame or two). For a map that shows 3D Tiles\n * at once: one engine downloaded instead of two. `'preload'`: the map starts on the engine without 3D Tiles and\n * downloads and compiles the other once idle, without running it: its first 3D Tiles layer does not wait for the\n * download (for a map that will show 3D Tiles later, on demand) */\n tiles3d?: boolean | 'preload';\n /** Where to load the vector basemap worker from, when a bundler does not resolve the default URL */\n basemapWorkerUrl?: string | URL;\n /** Texture size of the vector basemap's tiles, pixels (default 512: lines and edges sharp at every zoom on a screen\n * of pixel ratio 1). 256: a quarter of the drawing in the workers, of the uploads and of the GPU memory, for lines\n * and edges a little softer between two zoom levels (the tiles are shown 181 to 362 CSS pixels wide) */\n basemapTileSize?: number;\n /** Glyphs of the symbol layers: a URL with `{fontstack}` and `{range}` (MapLibre's glyph format; default\n * OpenFreeMap's fonts, Noto Sans). A vector basemap's labels take the glyphs of its style */\n glyphs?: string;\n /** Workers decoding 3D Tiles off the main thread: a count, or false to decode on the main thread (default: cores - 1,\n * 1 to 4). False (or 0) also decodes the PNG relief and reprojects the equirectangular rasters on the main thread,\n * else done by the vector basemap's workers */\n workers?: number | false;\n /** Where to load the decoding worker from, when a bundler does not resolve the default URL */\n workerUrl?: string | URL;\n /** Folders of the Draco and Basis Universal decoders, loaded by the workers on first use (default: the official\n * builds on gstatic.com and jsDelivr; self-host them for offline or locked-down networks). They run through\n * `new Function`: a Content Security Policy needs `'unsafe-eval'` (see `DecoderUrls`) */\n decoders?: Partial<DecoderUrls>;\n /** Credits at the bottom right: false for none, or its options (default true: the credits of the basemap,\n * hillshade and relief in use, compact on maps narrower than 640 px) */\n attributionControl?: boolean | AttributionOptions;\n}\n\nexport interface TerrainOptions {\n /** One of the Earth's named models (default `'terrain-tiles'` on the Earth); unused with a `url` */\n model?: TerrainModel;\n /** Altitudes of 256 × 256 tiles in `encoding`: a WMS GetMap URL with {bbox} (EPSG:3857 on the Earth, the body's\n * Mercator metres elsewhere: the sphere of its radius), a tile URL with {z}, {x} and {y}, or an ArcGIS image service\n * (a URL ending in `/ImageServer`), asked for raw altitudes in the body's Mercator (default: the `model`'s; on the\n * Moon and Mars, NASA's Trek LOLA and MOLA models) */\n url?: string;\n /** How the tiles of `url` encode their altitudes (default `'float32'`); `'terrarium'` and `'mapbox'` take a URL with\n * {z}, {x} and {y} */\n encoding?: TerrainEncoding;\n /** Vertical exaggeration, 1 for the true relief (default 1) */\n exaggeration?: number;\n /** Finest level of the relief, up to 15 (default 15; 14 for the Terrain Tiles, 8 for the Moon's and Mars's models). It\n * starts at level 6 on the Earth, coarser on bodies of a larger relief for their size (3 on the Moon and Mars) */\n maxZoom?: number;\n /** Altitudes over mainland France raised by the height of the RAF20 geoid (the French one, 0 away from France), to\n * heights above the ellipsoid (those of 3D Tiles); false keeps the altitudes as served (NGF-IGN69 for the IGN's)\n * (default true for the `'ign'` model, false otherwise) */\n geoid?: boolean;\n}\n\n/** Sky, horizon and fog over the plane, with the names and meanings of MapLibre's `setSky` */\nexport interface AtmosphereOptions {\n /** A CSS color (default `#9cc7ec`) */\n skyColor?: string;\n /** (default `#e8f1f8`) */\n horizonColor?: string;\n /** (default `#f2f5f8`) */\n fogColor?: string;\n /** Blend from the horizon to the sky color, share of the field of view above the horizon, 0-1 (default 0.6) */\n skyHorizonBlend?: number;\n /** Blend from the horizon to the fog color below the horizon, 0-1 (default 0.7) */\n horizonFogBlend?: number;\n /** Share of the distance to the far plane over which the ground fades into the fog, 0-1 (default 0.4) */\n fogGroundBlend?: number;\n}\n\n/** Animation of a camera move */\nexport interface AnimationOptions {\n /** Milliseconds */\n duration?: number;\n /** Progress over time, both 0 to 1 */\n easing?: (t: number) => number;\n}\n\nexport interface FlyToOptions extends AnimationOptions {\n /** How far the flight zooms out on its way, as MapLibre's `curve` (default 1.42) */\n curve?: number;\n /** Average speed in screens per second when `duration` is not given (default 1.2) */\n speed?: number;\n}\n\n/**\n * Tile grid of a raster's URL. 'mercator': Web Mercator (XYZ, WMTS PM), the engine's own. 'equirectangular':\n * longitudes and latitudes (Plate Carrée, EPSG:4326-like), two 256 px tiles side by side at level 0, rows from the\n * north (NASA's Trek WMTS, WorldCRS84Quad). A `TileGrid`: the tile matrices of a WMTS in any CRS (Lambert-93…), or a\n * WMS asked for each tile's box in its CRS. The last two are reprojected into Web Mercator tiles by the map's workers\n * (in the page with `workers: false`).\n */\nexport type RasterGrid = 'mercator' | 'equirectangular' | TileGrid;\n\n/** What `RasterLayer.setStyle` changes */\nexport interface RasterStyle {\n opacity: number;\n /** 0 = greyscale, 1 = original colors */\n saturation: number;\n}\n\nexport interface RasterOptions {\n /** Tile URL with {z}, {x} and {y} (256 px tiles); unused with a `loader` */\n url: string;\n /** Tile grid of `url` (default 'mercator'); with 'equirectangular', `minZoom` and `maxZoom` are levels of that\n * grid; with a `TileGrid`, they are map zooms, by default those its matrices span */\n grid?: RasterGrid;\n minZoom?: number;\n maxZoom?: number;\n opacity?: number;\n /** 0 = greyscale, 1 = original colors */\n saturation?: number;\n /** Side of the tiles' textures, pixels (default 256): more for sharper tiles drawn by a `loader` */\n size?: number;\n /** Draws each tile instead of fetching `url`: an image of `size` × `size`, null for nothing there; a rejection is\n * retried like a network error */\n loader?: (z: number, x: number, y: number, signal: AbortSignal) => Promise<ImageBitmap | null>;\n /** Credits of the tiles, HTML: shown by the attribution control while the layer is on the map */\n attribution?: string;\n}\n\nexport interface NetworkStyle {\n /** Line width, CSS pixels, or zoom stops `[[zoom, width], …]` (default 2) */\n width: Size;\n /** Values above are drawn as unreached (default 1800) */\n max: number;\n /** Darker line every `contour` value units, 0 for none (default 0) */\n contour: number;\n opacity: number;\n /** Width of the halo drawn under the lines, CSS pixels or zoom stops, 0 for none (default 0): wide and faint, the\n * reached streets add up into a heat map that fills the blocks */\n halo: Size;\n /** Opacity of the halo at the middle of a line, fading quadratically to its sides (default 0.11) */\n haloOpacity: number;\n /** Colors from 0 to `max`: `[[fraction of max, color], …]` (default green to red) */\n ramp: Ramp | undefined;\n /** Color of the parts beyond `max` or unreached (default `rgba(140, 140, 140, 0.25)`) */\n unreachedColor: string;\n /** Share of `max` over which the colors fade out before it, 0 to 1 (default 0) */\n fade: number;\n}\n\nexport interface NetworkOptions extends Partial<NetworkStyle> {\n /** Node coordinates in degrees: lon0, lat0, lon1, lat1… */\n nodes: Float64Array;\n /** Edges as node index pairs: a0, b0, a1, b1… */\n edges: Uint32Array;\n /** Line of each edge, from A to B: the points of edge e are `points[start[e] .. start[e + 1]]` (lon, lat pairs,\n * counted in points); with fewer than two points an edge is straight. Default: all straight. */\n lines?: { start: Uint32Array; points: Float64Array };\n /** Per edge, the cost of travelling it from A to B then from B to A, in value units (Infinity: closed that way;\n * closed both ways: not drawn). A point along an edge then takes the quickest way there, min(value(A) + cost from\n * A, value(B) + cost from B), as a travel time does. Without costs, values are interpolated along the edges. */\n costs?: Float32Array;\n /** Width factor of each edge (default 1): rail lines wider than streets */\n edgeWidths?: Float32Array;\n}\n\nexport interface Tiles3dStyle {\n /** Screen-space error (CSS pixels) above which a tile is refined: 16 by default, lower is finer and heavier */\n maxScreenSpaceError: number;\n opacity: number;\n}\n\nexport interface Tiles3dOptions extends Partial<Tiles3dStyle> {\n /** URL of a `tileset.json` (3D Tiles 1.0 b3dm or 1.1 glb meshes, external tilesets) */\n url: string;\n}\n\nexport interface MapPointerEvent {\n point: Point;\n /** Undefined above the horizon */\n lonLat: LonLat | undefined;\n}\n\n/** What 'hoverfeature' found under the pointer */\nexport interface MapHoverFeatureEvent extends MapPointerEvent {\n /** The feature under the pointer (see `GeoMap.pickFeature`), undefined if none */\n hit: FeatureHit | undefined;\n}\n\n/** A picked feature: its layer handle, its index there and, for line, circle and fill layers, the feature itself */\nexport interface FeatureHit {\n layer: Layer;\n index: number;\n feature: Feature | undefined;\n}\n\nexport interface MapEvents {\n /** The camera started moving (a gesture, an animation or `setCamera`) */\n movestart: Camera;\n /** The camera moved */\n move: Camera;\n /** The camera stopped: no gesture held, no animation running */\n moveend: Camera;\n /** The map changed size (CSS pixels) */\n resize: { width: number; height: number };\n /** The pointer moved over the map (at most once per frame, not while dragging) */\n hover: MapPointerEvent;\n /** What is under the pointer, picked without stalling the GPU: a frame or two after 'hover', only while listened to\n * (radius and layers in `GeoMap.hoverPicking`) */\n hoverfeature: MapHoverFeatureEvent;\n /** Click without drag */\n click: MapPointerEvent;\n /** A frame was drawn; duration of the engine call in milliseconds */\n render: { ms: number };\n /** Everything in view is loaded and drawn, nothing moves: the end of a load, once after each change (as MapLibre's\n * `idle`). Tiles requested by the first frame count, so it never fires before they arrive. */\n idle: Record<string, never>;\n /** The pointer left the canvas (a mouse going out of the map, or onto a control or marker) */\n leave: Record<string, never>;\n}\n\n/** What a layer handle needs from its map */\nexport interface LayerHost {\n readonly engine: Engine;\n requestRender(): void;\n /** Forgets a removed layer */\n detach(layer: object): void;\n /** Moves a layer under `before`, or on top */\n moveLayer(layer: object, before: object | undefined): void;\n /** A layer created again in the engine (new id): put at the place of its old id, which is removed */\n replaceLayer(layer: object, old: number): void;\n}\n"]}
@@ -25,7 +25,11 @@ export interface Style {
25
25
  }>;
26
26
  layers: StyleLayer[];
27
27
  glyphs?: string;
28
- sprite?: string;
28
+ /** One sprite's URL (without extension), or several with their ids (`id:name` names their images) */
29
+ sprite?: string | {
30
+ id: string;
31
+ url: string;
32
+ }[];
29
33
  }
30
34
  /** A raster source of a style: its tile URL, its deepest level and the CSS pixels of its tiles (MapLibre's
31
35
  * `tileSize`: 512 by default) */
@@ -34,15 +38,40 @@ export interface RasterSource {
34
38
  maxzoom: number;
35
39
  tileSize: number;
36
40
  }
41
+ /** How a label's text or icon meets the others (`*-allow-overlap` and `*-ignore-placement`, see `Overlap`) */
42
+ export type CandidateOverlap = boolean | 'allow' | 'ignore';
43
+ /** The icon of a label, in style terms evaluated at the tile's zoom */
44
+ export interface CandidateIcon {
45
+ /** Its image in the style's sprite */
46
+ image: string;
47
+ /** A number, or zoom stops */
48
+ size: Json;
49
+ anchor: string;
50
+ offset: [number, number];
51
+ rotate: number;
52
+ /** `map` or `viewport` (`auto` resolved) */
53
+ alignment: 'map' | 'viewport';
54
+ overlap: CandidateOverlap;
55
+ optional: boolean;
56
+ fit: 'none' | 'width' | 'height' | 'both';
57
+ padding: [number, number, number, number];
58
+ color: string;
59
+ opacity: number;
60
+ }
37
61
  /** A label to shape and place, in style terms evaluated at the tile's zoom */
38
62
  export interface LabelCandidate {
39
63
  /** Index of its style layer: higher ones are placed first */
40
64
  layer: number;
65
+ /** Its text, empty for an icon alone */
41
66
  text: string;
42
67
  lon: number;
43
68
  lat: number;
44
- /** Along a line: the direction there (degrees of longitude and latitude) */
69
+ /** On a line: the direction there (degrees of longitude and latitude) */
45
70
  along?: [number, number];
71
+ /** Its text runs along the line (`symbol-placement: line`, `text-rotation-alignment` not `viewport`) */
72
+ textAlong?: boolean;
73
+ textOptional?: boolean;
74
+ icon?: CandidateIcon;
46
75
  font: string;
47
76
  size: Json;
48
77
  color: string;
@@ -52,7 +81,7 @@ export interface LabelCandidate {
52
81
  offset: [number, number];
53
82
  maxWidth: number;
54
83
  lineHeight: number;
55
- overlap: boolean;
84
+ overlap: CandidateOverlap;
56
85
  }
57
86
  /** What expressions see of a feature */
58
87
  export interface Context {