stipple-maplibre 0.1.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/LICENSE +21 -0
- package/README.md +289 -0
- package/dist/index.d.ts +605 -0
- package/dist/index.global.js +1787 -0
- package/dist/index.js +1762 -0
- package/package.json +66 -0
- package/schema/pattern-metadata-v1.schema.json +173 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,605 @@
|
|
|
1
|
+
import { Map } from 'maplibre-gl';
|
|
2
|
+
|
|
3
|
+
type PatternType = "solid" | "stipple" | "hachures" | "cross" | "grid" | "dots";
|
|
4
|
+
/** Tile edge length in px. MapLibre does not require power-of-two fill-pattern images. Larger tiles read as a lower-density pattern. */
|
|
5
|
+
type TileSize = number;
|
|
6
|
+
type HachureAngle = 0 | 45 | 90 | -45;
|
|
7
|
+
/** Raw RGBA pixel buffer ready for `map.addImage` / `map.updateImage`. */
|
|
8
|
+
interface TileImage {
|
|
9
|
+
width: number;
|
|
10
|
+
height: number;
|
|
11
|
+
data: Uint8Array;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* The subset of the Canvas 2D API `makeTile` needs. A real
|
|
15
|
+
* `CanvasRenderingContext2D` satisfies this directly in the browser; in Node
|
|
16
|
+
* (or anywhere `document` is unavailable) {@link createMiniContext} provides
|
|
17
|
+
* a small pure-JS implementation so the pattern engine has no DOM dependency.
|
|
18
|
+
*/
|
|
19
|
+
interface TileContext {
|
|
20
|
+
strokeStyle: string;
|
|
21
|
+
fillStyle: string;
|
|
22
|
+
lineWidth: number;
|
|
23
|
+
lineCap: string;
|
|
24
|
+
clearRect(x: number, y: number, w: number, h: number): void;
|
|
25
|
+
beginPath(): void;
|
|
26
|
+
moveTo(x: number, y: number): void;
|
|
27
|
+
lineTo(x: number, y: number): void;
|
|
28
|
+
stroke(): void;
|
|
29
|
+
arc(x: number, y: number, radius: number, startAngle: number, endAngle: number): void;
|
|
30
|
+
fill(): void;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
interface MakeTileOptions {
|
|
34
|
+
/** Override how the drawing context is created. Mainly useful for tests. */
|
|
35
|
+
contextFactory?: (size: number) => {
|
|
36
|
+
ctx: TileContext;
|
|
37
|
+
toTileImage: () => TileImage;
|
|
38
|
+
};
|
|
39
|
+
/** Raster pixels per MapLibre layout pixel. Use 2 for high-density displays. Default 1. */
|
|
40
|
+
pixelRatio?: number;
|
|
41
|
+
/** Fixed dot count for a stipple tile, useful when the tile itself scales with zoom. */
|
|
42
|
+
stippleCount?: number;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Renders one seamless pattern tile (any pixel size; MapLibre's
|
|
46
|
+
* `fill-pattern` doesn't require power-of-two images) as a raw RGBA buffer
|
|
47
|
+
* ready for `map.addImage` / `map.updateImage`. Runs unchanged in the browser
|
|
48
|
+
* (native canvas) or in Node (pure-JS {@link createMiniContext} rasterizer).
|
|
49
|
+
* same output shape either way. Larger tiles read as a lower-density pattern
|
|
50
|
+
* (fewer repeats per unit area); use `size` as the density control.
|
|
51
|
+
*
|
|
52
|
+
* The pattern's visual parameters (angle, density, weight) only ever live in
|
|
53
|
+
* this generated image, never in the style.json. Regenerate with the exact
|
|
54
|
+
* same arguments wherever the tile is consumed to get an identical result.
|
|
55
|
+
*/
|
|
56
|
+
declare function makeTile(pattern: PatternType, size: number, color: string, weight: number, angle: number, options?: MakeTileOptions): TileImage;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Minimal software rasterizer implementing just the {@link TileContext}
|
|
60
|
+
* surface `makeTile` relies on (straight strokes with round caps, filled
|
|
61
|
+
* circles). Lets the pattern engine run in Node without a DOM or a native
|
|
62
|
+
* canvas dependency. The browser path uses the real Canvas 2D API instead,
|
|
63
|
+
* this is only exercised server-side (tests, tooling, SSR previews).
|
|
64
|
+
*/
|
|
65
|
+
declare function createMiniContext(size: number): {
|
|
66
|
+
ctx: TileContext;
|
|
67
|
+
toTileImage: () => TileImage;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
/** Deterministic PRNG (mulberry32). The same seed always produces the same sequence. */
|
|
71
|
+
declare function mulberry32(seed: number): () => number;
|
|
72
|
+
/** Turns an arbitrary string (e.g. a layer id) into a stable 32-bit seed. */
|
|
73
|
+
declare function hashStringToSeed(str: string): number;
|
|
74
|
+
|
|
75
|
+
type SvgDistributionMode = "regular" | "offset" | "natural";
|
|
76
|
+
interface SvgScatterLayoutOptions {
|
|
77
|
+
tileSize: number;
|
|
78
|
+
stampSize: number;
|
|
79
|
+
density: number;
|
|
80
|
+
seed: number | string;
|
|
81
|
+
rotationJitterDeg: number;
|
|
82
|
+
scaleJitter: number;
|
|
83
|
+
positionJitter: number;
|
|
84
|
+
stagger: boolean;
|
|
85
|
+
/** Placement logic. Defaults to offset when stagger is true, regular otherwise. */
|
|
86
|
+
distribution?: SvgDistributionMode;
|
|
87
|
+
/** Minimum visible gap between stamps in natural mode, in layout px. Default 0. */
|
|
88
|
+
minSpacing?: number;
|
|
89
|
+
}
|
|
90
|
+
interface SvgStampPlacement {
|
|
91
|
+
/** Stable index shared by a logical stamp and all of its wrapped copies. */
|
|
92
|
+
stampIndex: number;
|
|
93
|
+
x: number;
|
|
94
|
+
y: number;
|
|
95
|
+
rotationRad: number;
|
|
96
|
+
scale: number;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Builds the pure geometry for a seamless SVG scatter tile.
|
|
100
|
+
*
|
|
101
|
+
* Every placement sharing a `stampIndex` has the exact same rotation and
|
|
102
|
+
* scale. Wrapped copies therefore reproduce the same logical stamp on the
|
|
103
|
+
* opposite edge instead of consuming new random transforms.
|
|
104
|
+
*/
|
|
105
|
+
declare function createSvgScatterLayout(options: SvgScatterLayoutOptions): SvgStampPlacement[];
|
|
106
|
+
|
|
107
|
+
/** A closed ring of [x, y] planar coordinates in any consistent unit. */
|
|
108
|
+
type Ring = Array<[number, number]>;
|
|
109
|
+
interface ScatteredPoint {
|
|
110
|
+
x: number;
|
|
111
|
+
y: number;
|
|
112
|
+
/** Seeded rotation in degrees for icon-rotate variety. 0 unless `rotationJitterDeg` is set. */
|
|
113
|
+
rotation: number;
|
|
114
|
+
/** Seeded scale multiplier for icon-size variety. 1 unless `scaleJitter` is set. */
|
|
115
|
+
scale: number;
|
|
116
|
+
}
|
|
117
|
+
interface ScatterPointsOptions {
|
|
118
|
+
/** Required clearance from any edge (including holes) for a point to qualify, at scale 1. */
|
|
119
|
+
radius: number;
|
|
120
|
+
/** Approx. points per 100x100 unit area. Default 1. */
|
|
121
|
+
density?: number;
|
|
122
|
+
/** Deterministic variation seed. Default 1. */
|
|
123
|
+
seed?: number | string;
|
|
124
|
+
/** +/- rotation jitter applied to each point, in degrees. Default 0. */
|
|
125
|
+
rotationJitterDeg?: number;
|
|
126
|
+
/** +/- scale jitter applied to each point (as a fraction of `radius`). Default 0. The erosion test uses each point's actual scaled radius, so a bigger icon still never pokes outside the polygon. */
|
|
127
|
+
scaleJitter?: number;
|
|
128
|
+
/** +/- position jitter within each grid cell, as a fraction of the cell. Default 0.15 gives a light irregularity, not a full organic scatter. 0 = exact grid. */
|
|
129
|
+
positionJitter?: number;
|
|
130
|
+
/** Offset alternate rows by half a cell (quincunx), the classic regular cartographic symbol layout. Default true. */
|
|
131
|
+
stagger?: boolean;
|
|
132
|
+
/** Point layout. Defaults to offset for backward compatibility. */
|
|
133
|
+
distribution?: SvgDistributionMode;
|
|
134
|
+
/** Extra minimum gap between natural-layout icon envelopes. Default 0. */
|
|
135
|
+
minSpacing?: number;
|
|
136
|
+
/** Optional planar bounds limiting generated point centres. Polygon containment and edge clearance still use every ring. */
|
|
137
|
+
clipBounds?: {
|
|
138
|
+
minX: number;
|
|
139
|
+
minY: number;
|
|
140
|
+
maxX: number;
|
|
141
|
+
maxY: number;
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Scatters points inside a (possibly holed) polygon whose complete clearance
|
|
146
|
+
* circle remains inside it. Uses exact point-to-segment distances for every
|
|
147
|
+
* exterior and interior boundary. Deterministic for a given seed.
|
|
148
|
+
*
|
|
149
|
+
* `rings` should include the exterior ring first, followed by any hole
|
|
150
|
+
* rings; coordinates are unit-agnostic (pass pixels for on-screen icon
|
|
151
|
+
* placement (see {@link scatterIconPoints}) or any planar unit
|
|
152
|
+
* consistent with `radius`).
|
|
153
|
+
*/
|
|
154
|
+
declare function scatterPointsInPolygon(rings: Ring[], options: ScatterPointsOptions): ScatteredPoint[];
|
|
155
|
+
|
|
156
|
+
type PatternScaleMode = "screen" | "map";
|
|
157
|
+
interface PatternScaleOptions {
|
|
158
|
+
mode: PatternScaleMode;
|
|
159
|
+
zoom: number;
|
|
160
|
+
referenceZoom: number;
|
|
161
|
+
visualSize: number;
|
|
162
|
+
spacing: number;
|
|
163
|
+
opticalScale?: number;
|
|
164
|
+
minReadableSize?: number;
|
|
165
|
+
maxVisualSize?: number;
|
|
166
|
+
/**
|
|
167
|
+
* When a map-scaled motif reaches its readable-size floor, cap the spacing
|
|
168
|
+
* to this multiple of the visible motif size. This keeps small polygons
|
|
169
|
+
* from becoming empty while preserving the configured spacing at normal
|
|
170
|
+
* and close zooms.
|
|
171
|
+
*/
|
|
172
|
+
maxSpacingAtReadableFloorRatio?: number;
|
|
173
|
+
}
|
|
174
|
+
interface PatternScaleResult {
|
|
175
|
+
scale: number;
|
|
176
|
+
rawVisualSize: number;
|
|
177
|
+
visualSize: number;
|
|
178
|
+
stampSize: number;
|
|
179
|
+
spacing: number;
|
|
180
|
+
density: number;
|
|
181
|
+
opacity: number;
|
|
182
|
+
floored: boolean;
|
|
183
|
+
capped: boolean;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Resolves a pattern at a given zoom without using feature dimensions.
|
|
187
|
+
*
|
|
188
|
+
* Screen mode keeps visual size and spacing in pixels. Map mode treats the
|
|
189
|
+
* configured values as the appearance at referenceZoom, then doubles them for
|
|
190
|
+
* every zoom level in. Map-scaled motifs stop shrinking at their minimum
|
|
191
|
+
* readable size and stop growing at maxVisualSize.
|
|
192
|
+
*/
|
|
193
|
+
declare function scalePatternForZoom(options: PatternScaleOptions): PatternScaleResult;
|
|
194
|
+
|
|
195
|
+
interface ScreenPatternPhase {
|
|
196
|
+
index: number;
|
|
197
|
+
pixelRatioScale: number;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Chooses a preloaded image scale that counters MapLibre's fractional-zoom
|
|
201
|
+
* scaling of fill patterns. The image changes only a few times per zoom level,
|
|
202
|
+
* while the SVG tile itself stays cached.
|
|
203
|
+
*/
|
|
204
|
+
declare function screenPatternPhase(zoom: number, steps?: number): ScreenPatternPhase;
|
|
205
|
+
|
|
206
|
+
interface ImportedPolygonFeature {
|
|
207
|
+
type: "Feature";
|
|
208
|
+
id?: string | number;
|
|
209
|
+
properties: Record<string, unknown>;
|
|
210
|
+
geometry: {
|
|
211
|
+
type: "Polygon";
|
|
212
|
+
coordinates: number[][][];
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
interface GeoJsonPolygonImport {
|
|
216
|
+
features: ImportedPolygonFeature[];
|
|
217
|
+
ignoredFeatures: number;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Extracts editable Polygon features from GeoJSON. MultiPolygons are split
|
|
221
|
+
* into one feature per polygon so every part can receive its own fill.
|
|
222
|
+
*/
|
|
223
|
+
declare function importGeoJsonPolygons(input: unknown, maximumFeatures?: number): GeoJsonPolygonImport;
|
|
224
|
+
|
|
225
|
+
interface PatternFillConfig {
|
|
226
|
+
pattern: PatternType;
|
|
227
|
+
tile: TileSize;
|
|
228
|
+
color: string;
|
|
229
|
+
opacity: number;
|
|
230
|
+
weight: number;
|
|
231
|
+
angle: number;
|
|
232
|
+
/** Raster pixels per MapLibre layout pixel. Omit for the display ratio. */
|
|
233
|
+
pixelRatio?: number;
|
|
234
|
+
/** Optional fixed dot count for stipple zoom variants. */
|
|
235
|
+
stippleCount?: number;
|
|
236
|
+
}
|
|
237
|
+
interface BackgroundFillConfig {
|
|
238
|
+
enabled: boolean;
|
|
239
|
+
color: string;
|
|
240
|
+
opacity: number;
|
|
241
|
+
}
|
|
242
|
+
interface OutlineConfig {
|
|
243
|
+
enabled: boolean;
|
|
244
|
+
color: string;
|
|
245
|
+
width: number;
|
|
246
|
+
dash: number[];
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
declare const PATTERN_METADATA_KEY: "maplibre-pattern-fills:v1";
|
|
250
|
+
type GeometricPatternType = Exclude<PatternType, "solid">;
|
|
251
|
+
interface GeometricPatternDefinition {
|
|
252
|
+
kind: "geometric";
|
|
253
|
+
pattern: GeometricPatternType;
|
|
254
|
+
size: number;
|
|
255
|
+
color: string;
|
|
256
|
+
weight: number;
|
|
257
|
+
angle: number;
|
|
258
|
+
/** Raster pixels per MapLibre layout pixel. Omit for the display ratio. */
|
|
259
|
+
pixelRatio?: number;
|
|
260
|
+
/** Fixed dot count used by ground-scaled stipple variants. */
|
|
261
|
+
stippleCount?: number;
|
|
262
|
+
}
|
|
263
|
+
interface SvgPatternDefinition {
|
|
264
|
+
kind: "svg";
|
|
265
|
+
svg: string;
|
|
266
|
+
tileSize: number;
|
|
267
|
+
stampSize: number;
|
|
268
|
+
density: number;
|
|
269
|
+
seed: number | string;
|
|
270
|
+
rotationJitterDeg: number;
|
|
271
|
+
scaleJitter: number;
|
|
272
|
+
positionJitter: number;
|
|
273
|
+
stagger: boolean;
|
|
274
|
+
distribution: SvgDistributionMode;
|
|
275
|
+
minSpacing: number;
|
|
276
|
+
}
|
|
277
|
+
interface FontPatternDefinition {
|
|
278
|
+
kind: "font";
|
|
279
|
+
text: string;
|
|
280
|
+
fontFamily: string;
|
|
281
|
+
fontSize: number;
|
|
282
|
+
fontWeight: string;
|
|
283
|
+
fontStyle: "normal" | "italic";
|
|
284
|
+
letterSpacing: number;
|
|
285
|
+
horizontalSpacing: number;
|
|
286
|
+
verticalSpacing: number;
|
|
287
|
+
rotationDeg: number;
|
|
288
|
+
stagger: boolean;
|
|
289
|
+
color: string;
|
|
290
|
+
}
|
|
291
|
+
type PatternDefinition = GeometricPatternDefinition | SvgPatternDefinition | FontPatternDefinition;
|
|
292
|
+
interface PatternVariant {
|
|
293
|
+
zoom: number;
|
|
294
|
+
imageId: string;
|
|
295
|
+
definition: PatternDefinition;
|
|
296
|
+
}
|
|
297
|
+
interface PatternMetadataV1 {
|
|
298
|
+
imageId: string;
|
|
299
|
+
definition: PatternDefinition;
|
|
300
|
+
variants?: PatternVariant[];
|
|
301
|
+
}
|
|
302
|
+
/** Validates untrusted JSON metadata and returns a normalized definition. */
|
|
303
|
+
declare function parsePatternDefinition(value: unknown): PatternDefinition;
|
|
304
|
+
/** Parses a complete v1 metadata payload from a style layer. */
|
|
305
|
+
declare function parsePatternMetadata(value: unknown): PatternMetadataV1;
|
|
306
|
+
/** Stable JSON representation used for image IDs and cache keys. */
|
|
307
|
+
declare function serializePatternDefinition(definition: PatternDefinition): string;
|
|
308
|
+
/** Small deterministic FNV-1a identifier suitable for MapLibre image names. */
|
|
309
|
+
declare function patternDefinitionId(definition: PatternDefinition, prefix?: string): string;
|
|
310
|
+
declare function createSvgPatternDefinition(options: {
|
|
311
|
+
svg: string;
|
|
312
|
+
tileSize?: number;
|
|
313
|
+
stampSize?: number;
|
|
314
|
+
density?: number;
|
|
315
|
+
seed?: number | string;
|
|
316
|
+
rotationJitterDeg?: number;
|
|
317
|
+
scaleJitter?: number;
|
|
318
|
+
positionJitter?: number;
|
|
319
|
+
stagger?: boolean;
|
|
320
|
+
distribution?: SvgDistributionMode;
|
|
321
|
+
minSpacing?: number;
|
|
322
|
+
}): SvgPatternDefinition;
|
|
323
|
+
declare function createFontPatternDefinition(options: {
|
|
324
|
+
text: string;
|
|
325
|
+
fontFamily?: string;
|
|
326
|
+
fontSize?: number;
|
|
327
|
+
fontWeight?: string;
|
|
328
|
+
fontStyle?: "normal" | "italic";
|
|
329
|
+
letterSpacing?: number;
|
|
330
|
+
horizontalSpacing?: number;
|
|
331
|
+
verticalSpacing?: number;
|
|
332
|
+
rotationDeg?: number;
|
|
333
|
+
stagger?: boolean;
|
|
334
|
+
color?: string;
|
|
335
|
+
}): FontPatternDefinition;
|
|
336
|
+
|
|
337
|
+
interface SyncPatternTextureOptions {
|
|
338
|
+
imageId: string;
|
|
339
|
+
pattern: PatternType;
|
|
340
|
+
size: TileSize;
|
|
341
|
+
color: string;
|
|
342
|
+
weight: number;
|
|
343
|
+
angle: number;
|
|
344
|
+
/** Raster pixels per MapLibre layout pixel. Defaults to the display ratio, capped at 2. */
|
|
345
|
+
pixelRatio?: number;
|
|
346
|
+
/** Fixed dot count for stipple tiles that change size across zoom levels. */
|
|
347
|
+
stippleCount?: number;
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* (Re)generates a fill-pattern texture with {@link makeTile} and pushes it to
|
|
351
|
+
* the map. Uses `updateImage` when the tile dimensions are unchanged (no flash),
|
|
352
|
+
* or `removeImage` + `addImage` when the pattern type or tile size changed.
|
|
353
|
+
* Safe to call on every UI change (colour picker, slider drag, etc).
|
|
354
|
+
*/
|
|
355
|
+
declare function syncPatternTexture(map: Map, options: SyncPatternTextureOptions): void;
|
|
356
|
+
|
|
357
|
+
interface BuildStyleFragmentOptions {
|
|
358
|
+
/** Vector source id, e.g. `"urbanisme.plan_de_secteur"`. */
|
|
359
|
+
source: string;
|
|
360
|
+
/** Source-layer name (the table/layer inside the vector source). */
|
|
361
|
+
sourceLayer: string;
|
|
362
|
+
/** Vector tile URL. Defaults to a `<url>/<source>` placeholder to fill in. */
|
|
363
|
+
sourceUrl?: string;
|
|
364
|
+
bg?: BackgroundFillConfig;
|
|
365
|
+
pattern: PatternFillConfig;
|
|
366
|
+
line?: OutlineConfig;
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Builds the sources+layers fragment for the three-layer stack
|
|
370
|
+
* (tinted background / pattern fill / outline). The pattern's visual
|
|
371
|
+
* parameters are not baked into the paint properties. They are carried in
|
|
372
|
+
* versioned `layer.metadata["maplibre-pattern-fills:v1"]` so
|
|
373
|
+
* {@link installPatternFills} can
|
|
374
|
+
* regenerate the exact same texture at runtime via `makeTile`.
|
|
375
|
+
*/
|
|
376
|
+
declare function buildStyleFragment(options: BuildStyleFragmentOptions): {
|
|
377
|
+
sources: {
|
|
378
|
+
[x: string]: {
|
|
379
|
+
type: string;
|
|
380
|
+
url: string;
|
|
381
|
+
};
|
|
382
|
+
};
|
|
383
|
+
layers: Record<string, unknown>[];
|
|
384
|
+
};
|
|
385
|
+
|
|
386
|
+
interface StyleLike {
|
|
387
|
+
layers: Array<{
|
|
388
|
+
metadata?: Record<string, unknown>;
|
|
389
|
+
}>;
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Scans a style (or `map.getStyle()`) for layers carrying the
|
|
393
|
+
* versioned metadata produced by {@link buildStyleFragment}, validates it,
|
|
394
|
+
* and installs each distinct geometric or SVG texture. Custom metadata is
|
|
395
|
+
* not interpreted by MapLibre itself.
|
|
396
|
+
*/
|
|
397
|
+
declare function installPatternFills(map: Map, style: StyleLike): Promise<void>;
|
|
398
|
+
|
|
399
|
+
interface ObservePatternFillsOptions {
|
|
400
|
+
/** Defaults to `map.getStyle()`. Useful when metadata is stored separately. */
|
|
401
|
+
getStyle?: () => StyleLike;
|
|
402
|
+
/** Receives asynchronous restoration failures triggered by style reloads. */
|
|
403
|
+
onError?: (error: unknown) => void;
|
|
404
|
+
}
|
|
405
|
+
interface PatternFillObserver {
|
|
406
|
+
/** Installs or restores every registered image in the current style. */
|
|
407
|
+
refresh(): Promise<void>;
|
|
408
|
+
/** Removes the `style.load` listener. Safe to call repeatedly. */
|
|
409
|
+
dispose(): void;
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Restores generated pattern images after every MapLibre style load.
|
|
413
|
+
*
|
|
414
|
+
* The returned observer owns one listener and must be disposed with the map or
|
|
415
|
+
* component that created it. Installation is idempotent, so `refresh` is also
|
|
416
|
+
* safe to call explicitly after changing metadata.
|
|
417
|
+
*/
|
|
418
|
+
declare function observePatternFills(map: Map, options?: ObservePatternFillsOptions): PatternFillObserver;
|
|
419
|
+
|
|
420
|
+
interface SvgPatternOptions {
|
|
421
|
+
imageId: string;
|
|
422
|
+
/** Raw `<svg>...</svg>` markup, used as the repeatable stamp. */
|
|
423
|
+
svg: string;
|
|
424
|
+
/** Size of the generated meta-tile in layout px. Default 288. */
|
|
425
|
+
tileSize?: number;
|
|
426
|
+
/** Rendered size of each SVG stamp in px. Default 28. */
|
|
427
|
+
stampSize?: number;
|
|
428
|
+
/** Approximate stamps per 100x100px area. Default 1.4. */
|
|
429
|
+
density?: number;
|
|
430
|
+
/** Deterministic variation seed. The same seed always gives the same tile. */
|
|
431
|
+
seed?: number | string;
|
|
432
|
+
/** +/- rotation jitter per stamp, in degrees. Default 0 (regular grid). */
|
|
433
|
+
rotationJitterDeg?: number;
|
|
434
|
+
/** +/- scale jitter per stamp, as a fraction of stampSize. Default 0 (regular grid). */
|
|
435
|
+
scaleJitter?: number;
|
|
436
|
+
/** +/- position jitter per stamp, as a fraction of the grid cell. Default 0.15 gives a light irregularity, not a full organic scatter. 0 = exact grid. */
|
|
437
|
+
positionJitter?: number;
|
|
438
|
+
/** Offset alternate rows by half a cell (quincunx), the classic regular cartographic symbol layout (orchard/marsh map fills). Default true. */
|
|
439
|
+
stagger?: boolean;
|
|
440
|
+
/** Regular grid, offset rows, or seamless blue-noise placement. */
|
|
441
|
+
distribution?: SvgDistributionMode;
|
|
442
|
+
/** Minimum gap between symbols in natural mode, in layout px. Default 0. */
|
|
443
|
+
minSpacing?: number;
|
|
444
|
+
/** Raster pixels per MapLibre layout pixel. Defaults to the display ratio, capped at 2 when installed. */
|
|
445
|
+
pixelRatio?: number;
|
|
446
|
+
}
|
|
447
|
+
/**
|
|
448
|
+
* Rasterizes an SVG into a large seamless "meta-tile" repeated on a grid
|
|
449
|
+
* (seeded jitter, so deterministic). Defaults to a regular, lightly
|
|
450
|
+
* staggered cartographic grid, the classic look of official map symbology
|
|
451
|
+
* used for orchard and marsh fills, rather than a fully organic scatter. Raise
|
|
452
|
+
* `rotationJitterDeg`/`scaleJitter`/`positionJitter` for a more natural,
|
|
453
|
+
* irregular look (grass, foliage...). Stamps near an edge are additionally
|
|
454
|
+
* drawn wrapped on the opposite side so the tile still repeats seamlessly.
|
|
455
|
+
*
|
|
456
|
+
* Uses the browser's native SVG rasterizer (`Image` + canvas). No SVG
|
|
457
|
+
* parsing of our own, per MapLibre's own `addImage` pipeline.
|
|
458
|
+
*/
|
|
459
|
+
declare function createSvgScatterTile(options: SvgPatternOptions): Promise<TileImage>;
|
|
460
|
+
/**
|
|
461
|
+
* Rasterizes an SVG scatter tile and installs it as a `fill-pattern` image.
|
|
462
|
+
* Repeated equivalent calls are no-ops, same-sized changes use `updateImage`,
|
|
463
|
+
* and a stale asynchronous render cannot overwrite a newer call.
|
|
464
|
+
*/
|
|
465
|
+
declare function installSvgPatternFill(map: Map, options: SvgPatternOptions): Promise<void>;
|
|
466
|
+
|
|
467
|
+
interface FontPatternOptions {
|
|
468
|
+
imageId: string;
|
|
469
|
+
/** Text repeated through the fill. A single letter or short abbreviation works best. */
|
|
470
|
+
text: string;
|
|
471
|
+
/** CSS font-family value. Default `sans-serif`. */
|
|
472
|
+
fontFamily?: string;
|
|
473
|
+
/** Font size in layout pixels. Default 18. */
|
|
474
|
+
fontSize?: number;
|
|
475
|
+
/** CSS font-weight value. Default `500`. */
|
|
476
|
+
fontWeight?: string;
|
|
477
|
+
/** Upright or italic letterforms. Default `normal`. */
|
|
478
|
+
fontStyle?: "normal" | "italic";
|
|
479
|
+
/** Extra spacing between characters in layout pixels. Default 0. */
|
|
480
|
+
letterSpacing?: number;
|
|
481
|
+
/** Horizontal gap between repeated labels in layout pixels. Default 26. */
|
|
482
|
+
horizontalSpacing?: number;
|
|
483
|
+
/** Vertical gap between repeated rows in layout pixels. Default 22. */
|
|
484
|
+
verticalSpacing?: number;
|
|
485
|
+
/** Clockwise text rotation in degrees. Default 0. */
|
|
486
|
+
rotationDeg?: number;
|
|
487
|
+
/** Offset alternate rows by half a cell. Default true. */
|
|
488
|
+
stagger?: boolean;
|
|
489
|
+
/** Text colour. Default black. */
|
|
490
|
+
color?: string;
|
|
491
|
+
/** Raster pixels per MapLibre layout pixel. Defaults to the display ratio, capped at 2 when installed. */
|
|
492
|
+
pixelRatio?: number;
|
|
493
|
+
}
|
|
494
|
+
/** Rasterizes a seamless, optionally staggered text pattern in the browser. */
|
|
495
|
+
declare function createFontPatternTile(options: FontPatternOptions): Promise<TileImage>;
|
|
496
|
+
/** Installs or updates a browser-rasterized text texture as a MapLibre fill pattern. */
|
|
497
|
+
declare function installFontPatternFill(map: Map, options: FontPatternOptions): Promise<void>;
|
|
498
|
+
|
|
499
|
+
type PolygonGeometry = {
|
|
500
|
+
type: "Polygon";
|
|
501
|
+
coordinates: number[][][];
|
|
502
|
+
} | {
|
|
503
|
+
type: "MultiPolygon";
|
|
504
|
+
coordinates: number[][][][];
|
|
505
|
+
};
|
|
506
|
+
interface PointFeature {
|
|
507
|
+
type: "Feature";
|
|
508
|
+
id: number;
|
|
509
|
+
geometry: {
|
|
510
|
+
type: "Point";
|
|
511
|
+
coordinates: [number, number];
|
|
512
|
+
};
|
|
513
|
+
properties: {
|
|
514
|
+
rotation: number;
|
|
515
|
+
scale: number;
|
|
516
|
+
};
|
|
517
|
+
}
|
|
518
|
+
interface PointFeatureCollection {
|
|
519
|
+
type: "FeatureCollection";
|
|
520
|
+
features: PointFeature[];
|
|
521
|
+
}
|
|
522
|
+
interface ScatterIconPointsOptions {
|
|
523
|
+
map: Map;
|
|
524
|
+
/** Polygon in [lng, lat] coordinates (the same geometry the fill is drawn from). */
|
|
525
|
+
polygon: PolygonGeometry;
|
|
526
|
+
/** On-screen icon radius in px. No point whose disc of this radius pokes outside the polygon. */
|
|
527
|
+
iconRadiusPx: number;
|
|
528
|
+
/** Approx. points per 100x100 screen px area. Default 1. */
|
|
529
|
+
density?: number;
|
|
530
|
+
/** Deterministic variation seed. Default 1. */
|
|
531
|
+
seed?: number | string;
|
|
532
|
+
/** +/- rotation jitter per point, in degrees. Default 0. */
|
|
533
|
+
rotationJitterDeg?: number;
|
|
534
|
+
/** +/- scale jitter per point (fraction of `iconRadiusPx`). Default 0. */
|
|
535
|
+
scaleJitter?: number;
|
|
536
|
+
/** +/- position jitter within each grid cell, as a fraction of the cell. Default 0.15. 0 = exact grid. */
|
|
537
|
+
positionJitter?: number;
|
|
538
|
+
/** Offset alternate rows by half a cell (quincunx), the classic regular cartographic symbol layout. Default true. */
|
|
539
|
+
stagger?: boolean;
|
|
540
|
+
/** Regular grid, offset rows, or natural non-overlapping scatter. */
|
|
541
|
+
distribution?: SvgDistributionMode;
|
|
542
|
+
/** Extra minimum gap in screen pixels for natural distribution. */
|
|
543
|
+
minSpacing?: number;
|
|
544
|
+
/** Only generate points inside the visible canvas plus this pixel margin. Omit to process the complete polygon. */
|
|
545
|
+
viewportPaddingPx?: number;
|
|
546
|
+
}
|
|
547
|
+
/**
|
|
548
|
+
* Computes scatter points inside a polygon, in the map's current screen
|
|
549
|
+
* projection, using exact distance to every polygon boundary around each
|
|
550
|
+
* point. Bound to the current scale: recompute after zoom if the layout
|
|
551
|
+
* should keep a fixed screen size.
|
|
552
|
+
*/
|
|
553
|
+
declare function scatterIconPoints(options: ScatterIconPointsOptions): PointFeatureCollection;
|
|
554
|
+
|
|
555
|
+
type IconScaleMode = "screen" | "map";
|
|
556
|
+
interface InstallSvgIconScatterOptions {
|
|
557
|
+
/** GeoJSON source id to (re)create with the computed scatter points. */
|
|
558
|
+
sourceId: string;
|
|
559
|
+
/** Symbol layer id. */
|
|
560
|
+
layerId: string;
|
|
561
|
+
/** MapLibre image id used for the rasterized SVG. */
|
|
562
|
+
iconId: string;
|
|
563
|
+
polygon: PolygonGeometry;
|
|
564
|
+
svg: string;
|
|
565
|
+
/** Rendered square icon size in px. Default 32; its circumscribed radius is used for clearance. */
|
|
566
|
+
size?: number;
|
|
567
|
+
density?: number;
|
|
568
|
+
seed?: number | string;
|
|
569
|
+
rotationJitterDeg?: number;
|
|
570
|
+
/** +/- scale jitter per icon (fraction of `size`). Default 0. Driven by the symbol layer's native `icon-size`, not by re-rasterizing. */
|
|
571
|
+
scaleJitter?: number;
|
|
572
|
+
/** +/- position jitter within each grid cell, as a fraction of the cell. Default 0.15. 0 = exact grid. */
|
|
573
|
+
positionJitter?: number;
|
|
574
|
+
/** Offset alternate rows by half a cell (quincunx), the classic regular cartographic symbol layout. Default true. */
|
|
575
|
+
stagger?: boolean;
|
|
576
|
+
/** Regular grid, offset rows, or natural non-overlapping scatter. */
|
|
577
|
+
distribution?: SvgDistributionMode;
|
|
578
|
+
/** Extra minimum gap in screen pixels for natural distribution. */
|
|
579
|
+
minSpacing?: number;
|
|
580
|
+
/** Symbol opacity. Default 1. */
|
|
581
|
+
opacity?: number;
|
|
582
|
+
/** Keep a fixed screen size, or scale with the map from the installation zoom. Default screen. */
|
|
583
|
+
scaleMode?: IconScaleMode;
|
|
584
|
+
/** Keep the complete icon inside the polygon. Default true. */
|
|
585
|
+
edgeClearance?: boolean;
|
|
586
|
+
/** Extra off-screen area retained for fixed-pixel symbols. Computed from icon size and spacing by default. */
|
|
587
|
+
viewportPaddingPx?: number;
|
|
588
|
+
}
|
|
589
|
+
/**
|
|
590
|
+
* @experimental
|
|
591
|
+
*
|
|
592
|
+
* The no-cut alternative to {@link installSvgPatternFill}: instead of a
|
|
593
|
+
* repeating texture (which always clips hard at the polygon edge),
|
|
594
|
+
* places SVG icons where exact point-to-segment distances prove that their
|
|
595
|
+
* circular safety envelope fits inside the polygon. The envelope is
|
|
596
|
+
* conservative because it covers the complete rotated square icon canvas.
|
|
597
|
+
*
|
|
598
|
+
* Points are computed in screen pixels at call time, then frozen as
|
|
599
|
+
* lng/lat, so density (icon count per screen area) drifts out of sync
|
|
600
|
+
* with the current zoom unless you recompute after each completed movement,
|
|
601
|
+
* e.g. `map.on('moveend', () => installSvgIconScatter(map, options))`.
|
|
602
|
+
*/
|
|
603
|
+
declare function installSvgIconScatter(map: Map, options: InstallSvgIconScatterOptions): Promise<void>;
|
|
604
|
+
|
|
605
|
+
export { type BackgroundFillConfig, type BuildStyleFragmentOptions, type FontPatternDefinition, type FontPatternOptions, type GeoJsonPolygonImport, type GeometricPatternDefinition, type GeometricPatternType, type HachureAngle, type IconScaleMode, type ImportedPolygonFeature, type InstallSvgIconScatterOptions, type MakeTileOptions, type ObservePatternFillsOptions, type OutlineConfig, PATTERN_METADATA_KEY, type PatternDefinition, type PatternFillConfig, type PatternFillObserver, type PatternMetadataV1, type PatternScaleMode, type PatternScaleOptions, type PatternScaleResult, type PatternType, type PatternVariant, type PointFeature, type PointFeatureCollection, type PolygonGeometry, type Ring, type ScatterIconPointsOptions, type ScatterPointsOptions, type ScatteredPoint, type ScreenPatternPhase, type StyleLike, type SvgDistributionMode, type SvgPatternDefinition, type SvgPatternOptions, type SvgScatterLayoutOptions, type SvgStampPlacement, type SyncPatternTextureOptions, type TileContext, type TileImage, type TileSize, buildStyleFragment, createFontPatternDefinition, createFontPatternTile, createMiniContext, createSvgPatternDefinition, createSvgScatterLayout, createSvgScatterTile, hashStringToSeed, importGeoJsonPolygons, installFontPatternFill, installPatternFills, installSvgIconScatter, installSvgPatternFill, makeTile, mulberry32, observePatternFills, parsePatternDefinition, parsePatternMetadata, patternDefinitionId, scalePatternForZoom, scatterIconPoints, scatterPointsInPolygon, screenPatternPhase, serializePatternDefinition, syncPatternTexture };
|