@tileflow/dev 0.1.0-alpha.38 → 0.1.0-alpha.39
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/README.md +9 -21
- package/dist/artifacts.js +4 -4
- package/dist/{chunk-MRFNAWWR.js → chunk-AVJMTXW5.js} +57 -22
- package/dist/{chunk-54VM4SNV.js → chunk-C4VPHZ3F.js} +1 -1
- package/dist/{chunk-UTRO4IBQ.js → chunk-FOMTSCOP.js} +1 -1
- package/dist/{chunk-7C4F6GAX.js → chunk-RTU7TD4M.js} +4 -2
- package/dist/fonts.js +2 -2
- package/dist/icons.js +2 -2
- package/dist/preview.js +4 -2
- package/dist/server.js +4 -4
- package/package.json +4 -5
- package/docs/artifact-lifecycle.md +0 -152
- package/docs/beacon-map-audits.md +0 -145
- package/docs/bounded-pmtiles-resource-inspection.md +0 -21
- package/docs/bounded-vector-feature-inspection.md +0 -99
- package/docs/building-models.md +0 -218
- package/docs/layers-inspection.md +0 -92
- package/docs/local-comparison-workbench-and-compiler-inspection.md +0 -130
- package/docs/map-design-diagnostics.md +0 -76
- package/docs/native-artifacts.md +0 -287
- package/docs/native-icons.md +0 -129
- package/docs/structured-config-inspection-and-diagnostics.md +0 -39
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
# Inspector and compiler inspection
|
|
2
|
-
|
|
3
|
-
Start with the [@tileflow/dev guide](https://github.com/tileflow/tileflow-sdk/blob/main/packages/dev/README.md) for installation and a complete first example.
|
|
4
|
-
|
|
5
|
-
The CLI opens Inspector through `tileflow preview`. It uses one map and one watched artifact
|
|
6
|
-
session by default. The panel groups Map, Layers, Tiles, Assets, Debug and Diagnostics. Camera controls
|
|
7
|
-
occupy a separate row below the navigation. Use the three-dot menu to dock left, right or below
|
|
8
|
-
the map and choose System, Light or Dark appearance. Drag the divider to resize it; focused dividers
|
|
9
|
-
also support arrow keys. Dock position and dimensions persist locally. Layer observations and highlights stay local to the preview. The map fills the remaining
|
|
10
|
-
workspace without brand headers or map-status badges. Closing the panel leaves a small **Inspector**
|
|
11
|
-
button to reopen it; capture and comparison controls are absent from the interface.
|
|
12
|
-
|
|
13
|
-
Add `--against-map ...` or `--against-config ...` for synchronized comparison. Custom local servers
|
|
14
|
-
can compose the same shell around existing dev handlers; omit `right` for a single-map session:
|
|
15
|
-
|
|
16
|
-
```ts
|
|
17
|
-
import {createTileflowComparisonRequestHandler} from '@tileflow/dev/server';
|
|
18
|
-
|
|
19
|
-
const fetch = createTileflowComparisonRequestHandler({
|
|
20
|
-
left: {
|
|
21
|
-
basePath: '/left',
|
|
22
|
-
handler: leftHandler,
|
|
23
|
-
label: 'candidate / light',
|
|
24
|
-
previewUrl: '/left/',
|
|
25
|
-
sidecarUrl: '/left/__inspection/candidate/light.json',
|
|
26
|
-
},
|
|
27
|
-
right: {
|
|
28
|
-
basePath: '/right',
|
|
29
|
-
handler: rightHandler,
|
|
30
|
-
label: 'reference / light',
|
|
31
|
-
previewUrl: '/right/',
|
|
32
|
-
sidecarUrl: '/right/__inspection/reference/light.json',
|
|
33
|
-
},
|
|
34
|
-
});
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
Set `fitViewport: true` on each dev handler embedded in a resizable Inspector pane. Scene previews
|
|
38
|
-
then fit their pane while captures retain the scene's declared frame. Standalone dev handlers keep
|
|
39
|
-
the fixed scene viewport by default.
|
|
40
|
-
|
|
41
|
-
Each side handler retains ownership of its styles, fonts, sprites, events, diagnostics, and
|
|
42
|
-
last-known-good artifact generation. The comparison router owns the shell, its bundled UI fonts and
|
|
43
|
-
strict dispatch to disjoint same-origin route prefixes. An optional `workbench: {url, handle}`
|
|
44
|
-
adapter enables theme selection and browser context. Existing CLI capture-record and comparison
|
|
45
|
-
APIs remain separate from this interface. Custom servers that omit the adapter retain inspection,
|
|
46
|
-
zoom-curve sampling and the sprite atlas. Explicit two-map server configurations retain synchronized
|
|
47
|
-
cameras and URL-driven side-by-side/split/overlay/blink layouts without comparison controls.
|
|
48
|
-
|
|
49
|
-
See the [human/agent workflow](https://github.com/tileflow/tileflow-sdk/blob/main/packages/cli/docs/map-authoring.md#work-with-a-person-and-an-agent)
|
|
50
|
-
for retained evidence, context bounds and `inspect session`. Browser context reports the observed
|
|
51
|
-
camera and viewport; capture commands render compiled source without temporary preview edits. The rendered feature summary shows available semantic paths and
|
|
52
|
-
keeps raw feature data in a disclosure. It does not infer exact source lines or token ownership.
|
|
53
|
-
|
|
54
|
-
Set `inspection: true` on `createTileflowBuildArtifacts` or
|
|
55
|
-
`createTileflowArtifactSession` to compute `artifacts.styleInspections[map][theme]`. A dev handler
|
|
56
|
-
serves an available sidecar at `/__inspection/<map>/<theme>.json`; otherwise that route is 404. The
|
|
57
|
-
option is deliberately off by default. Sidecars remain in memory, do not alter Style bytes or
|
|
58
|
-
manifest hashes, and are excluded from `getTileflowArtifactFiles()` and every stable build output.
|
|
59
|
-
|
|
60
|
-
When a resolved map declares `fonts`, preparation reads its ordered directories and uses OpenType
|
|
61
|
-
full names as the canonical IDs referenced by `text-font`. TTF, OTF, and WOFF2 inputs are supported;
|
|
62
|
-
every contributing directory must contain `LICENSE.txt`. Later directories replace earlier faces
|
|
63
|
-
with the same exact ID, case-only collisions fail, and every primary font in the final style must be
|
|
64
|
-
present. `font` is an exact face ID; local `fallbacks` entries are exact face names or explicit CSS
|
|
65
|
-
generic families such as `sans-serif`. Preparation never synthesizes a face name from a family and
|
|
66
|
-
weight. Only selected primary faces and licenses are emitted as
|
|
67
|
-
content-addressed managed artifacts.
|
|
68
|
-
|
|
69
|
-
`fonts` and `glyphs` are mutually exclusive map fields. Omission inherits the parent's current text
|
|
70
|
-
provider; declaring either one replaces an inherited provider of either kind atomically. The font
|
|
71
|
-
pipeline is driven only by directory metadata and final style usage—there are no hard-coded map or
|
|
72
|
-
family names, and a URL provider comes only from the resolved map instead of being invented by the
|
|
73
|
-
pipeline. After inheritance resolves, a map with any text layer must have exactly one provider. A
|
|
74
|
-
`glyphs: {kind: 'url', ...}` provider enumerates the exact comma-joined MapLibre request keys
|
|
75
|
-
produced by the style's `text-font` arrays.
|
|
76
|
-
|
|
77
|
-
The resulting style records strict `tileflow:fontFaces` metadata. Preview, capture, and browser
|
|
78
|
-
framework adapters load those definitions before constructing MapLibre. Hosted deploy rejects a
|
|
79
|
-
prepared local-font bundle before authentication until managed font storage is available. A derived
|
|
80
|
-
map that declares `glyphs` replaces the inherited local provider atomically; the URL-backed map is
|
|
81
|
-
complete as declared and independent of its World selection.
|
|
82
|
-
|
|
83
|
-
### Pick an element in Layers
|
|
84
|
-
|
|
85
|
-
Press **I** or the element-picker icon, hover for a layer/type/ID hint, then click the map.
|
|
86
|
-
The clicked element selects its physical layer in **Layers** and opens **Rules**, the first detail tab.
|
|
87
|
-
Expression values use that picked feature, rather than an arbitrary viewport sample. **Data** shows
|
|
88
|
-
its properties and additional viewport samples; **Use for rules** chooses a different sample.
|
|
89
|
-
There is no separate Inspect tab. Legacy `tab=inspect` links open Layers.
|
|
90
|
-
|
|
91
|
-
Selecting another layer clears the picked-feature context. Compiler and scene revisions invalidate
|
|
92
|
-
old feature snapshots. The renderer's layer ID remains selected across reloads through the `layer`
|
|
93
|
-
URL parameter; missing IDs are reported explicitly. Rules expose inline temporary paint/layout
|
|
94
|
-
editors for the entire physical layer, with per-rule reset and shared undo history. Preview edits do
|
|
95
|
-
not write config, source data or build artifacts. See [Layers inspection](./layers-inspection.md) for diagnostic limits,
|
|
96
|
-
map highlighting, provenance and agent context.
|
|
97
|
-
|
|
98
|
-
### Tiles
|
|
99
|
-
|
|
100
|
-
**Tiles** shows in-view resident tiles in a spatial grid and source-grouped list, with canonical
|
|
101
|
-
`z/x/y`, display zoom, state and raw tile bytes where available. Filter by source or coordinates.
|
|
102
|
-
Select a tile to outline its bounds and inspect **Source layers**, **Features** and **Info**.
|
|
103
|
-
Source-layer rows link to consuming style layers. Features are paginated in groups of 50 and can
|
|
104
|
-
be copied as real GeoJSON. Counts describe tile fragments, including buffer geometry, rather than
|
|
105
|
-
unique objects across tiles. **Show on map** fits the selected bounds.
|
|
106
|
-
|
|
107
|
-
Raster DEM tiles show decoded grid dimensions and elevation statistics. Raster imagery has no
|
|
108
|
-
vector features. Eviction, unavailable internals and unsupported MLT decoding are reported explicitly.
|
|
109
|
-
Inspection decodes resident MVT buffers on demand without requesting tiles.
|
|
110
|
-
|
|
111
|
-
The view reads the pinned MapLibre renderer's tile managers through an isolated adapter. A resident
|
|
112
|
-
tile can come from cache and need not have a new HTTP request. Unsupported renderer internals
|
|
113
|
-
produce an unavailable state. Network does not list application scripts, development-server
|
|
114
|
-
traffic or other HTTP resources. Sprite and font sources remain in **Assets**.
|
|
115
|
-
|
|
116
|
-
### Assets and debug overlays
|
|
117
|
-
|
|
118
|
-
**Assets** separates Icons, 3D models and Fonts. Icons lists registered images, including runtime
|
|
119
|
-
additions, with lazy thumbnails and searchable IDs. Theme and time-of-day filters load the actual
|
|
120
|
-
registered theme atlases; the selected icon's sidebar compares its day/night variants and links to
|
|
121
|
-
consuming layers. Missing variants are marked, never synthesized from a naming convention.
|
|
122
|
-
|
|
123
|
-
3D models previews bounded samples of the actual loaded building and vegetation meshes. Counts,
|
|
124
|
-
bytes, LODs and available instance counts describe controller data. The wire geometry preview is
|
|
125
|
-
not the map's lighting renderer. Fonts renders editable specimens from the actual font or glyph
|
|
126
|
-
provider and shows observed glyph ranges and consuming layers. Pending requests are cancelled
|
|
127
|
-
when leaving the panel; unavailable sources do not silently use a fallback font.
|
|
128
|
-
|
|
129
|
-
**Debug** offers collision boxes, overdraw with a color legend, tile boundaries and real pixel-ratio
|
|
130
|
-
controls. **Diagnostics** lists design findings and optional drawing-cost observations; see [Map design diagnostics](./map-design-diagnostics.md).
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
# Map design diagnostics
|
|
2
|
-
|
|
3
|
-
Open **Diagnostics** in Inspector to investigate a map's rules, visual resources and current-view
|
|
4
|
-
composition. The list groups findings under **Readability**, **Style**, **Assets** and **Performance**.
|
|
5
|
-
**Problem** means a confirmed configuration or resource failure. **Review** means an observed
|
|
6
|
-
situation may be intentional. Counts refer to grouped findings, not quality scores.
|
|
7
|
-
|
|
8
|
-
## Check the map
|
|
9
|
-
|
|
10
|
-
Style observations refresh after changes settle. **Check view** explicitly collects samples from
|
|
11
|
-
the current map and briefly profiles drawing work. It does not navigate to other cities, change the
|
|
12
|
-
camera, compile themes or save edits. Changing the map or leaving the panel cancels pending work.
|
|
13
|
-
Expensive renderer observations are not repeated continuously while editing colors or dragging.
|
|
14
|
-
|
|
15
|
-
The initial detectors cover invalid style rules, broken references and zoom ranges, unresolved
|
|
16
|
-
icons, verifiable text contrast, large layer stacks, potentially repeated rules and drawing work.
|
|
17
|
-
Findings group affected layers and keep bounded examples. A missing image must remain unresolved
|
|
18
|
-
after loading; images with a working fallback are not missing resources. An empty viewport or a
|
|
19
|
-
layer outside its zoom range does not by itself create a global problem.
|
|
20
|
-
|
|
21
|
-
Text contrast is checked only where the evaluated text and opaque halo make the color pair
|
|
22
|
-
verifiable. This is not a measurement of all pixels behind a label or certification that a map is
|
|
23
|
-
readable. Unavailable evaluation context does not become a passing observation. Size thresholds,
|
|
24
|
-
absence of halos and ordinary collision rejection do not establish design defects.
|
|
25
|
-
|
|
26
|
-
Performance findings are review indications. A style layer, a queried feature, a draw call and an
|
|
27
|
-
overdraw pass measure different things. Layer stacks are grouped by compiler provenance when it is
|
|
28
|
-
available; unknown ownership is not inferred from names. Equivalent drawing rules may be deliberate
|
|
29
|
-
casings, shadows or blending, so they are never automatically removed. Counts and short CPU samples
|
|
30
|
-
do not attribute GPU cost to an individual layer or establish a universal performance grade.
|
|
31
|
-
|
|
32
|
-
Native overdraw is observed only when the renderer and scene permit a meaningful measurement.
|
|
33
|
-
Custom rendering, terrain, sky, globe projection or active debug modes can make it unavailable. The native sample saturates
|
|
34
|
-
at eight passes, so an eight-pass observation is a lower bound. Sampling temporarily enables the
|
|
35
|
-
native debug rendering and restores it; open **Debug** explicitly to keep an overlay visible.
|
|
36
|
-
|
|
37
|
-
Drawing-work sampling requests repaints for approximately 650 ms and requires at least ten complete
|
|
38
|
-
frames. Compatible native overdraw sampling has a separate two-second limit. A median of at least
|
|
39
|
-
1,000 draw submissions, or at least 25% of sampled pixels reaching eight passes, creates a review
|
|
40
|
-
finding. These are disclosed review triggers, not universal limits. Label evaluation and retained
|
|
41
|
-
examples are capped; reading the style and querying rendered features still depend on map size.
|
|
42
|
-
Detailed rule checks inspect at most 2,000 non-internal layers, while stack counts include the
|
|
43
|
-
whole style. Contrast sampling retains up to 5,000 symbol candidates, evaluates at most 200 of
|
|
44
|
-
them and keeps up to 40 eligible examples. Coverage limits remain available in the copied report.
|
|
45
|
-
|
|
46
|
-
## Investigate a finding
|
|
47
|
-
|
|
48
|
-
Expand a row to read its evidence and limitations. **Open rule** selects the layer and focuses the
|
|
49
|
-
related paint, layout or filter declaration. **Show on map** uses the finding's observed context;
|
|
50
|
-
asset and overdraw actions open the corresponding inspection tools. Available actions depend on
|
|
51
|
-
the evidence. Preview changes remain temporary and share Undo/Redo and Reset all changes.
|
|
52
|
-
|
|
53
|
-
Findings retain the map revision and camera in which they were observed. Moving away is not proof
|
|
54
|
-
that a problem was fixed. Old view evidence is marked stale until checked again. Local dismissals
|
|
55
|
-
apply to a case fingerprint; changing the relevant evidence makes it reviewable again. Incomplete
|
|
56
|
-
checks and missing renderer capabilities are included in the copied report.
|
|
57
|
-
|
|
58
|
-
**Copy findings** and each finding's copy action include structured evidence, conditions and
|
|
59
|
-
temporary edits. Context is sanitized, bounded and reports omissions. Nothing is sent to an agent
|
|
60
|
-
automatically. The output is diagnostic evidence, not a benchmark or release certification.
|
|
61
|
-
|
|
62
|
-
## Explain a layer's visibility
|
|
63
|
-
|
|
64
|
-
Select a layer in **Layers**, then open **Diagnosis**. It shows declared visibility,
|
|
65
|
-
zoom eligibility, source state and viewport-query observations. With an actual selected feature it
|
|
66
|
-
also evaluates its filter and relevant zero-size or zero-opacity rules. A zero component does not
|
|
67
|
-
prove the whole layer is invisible: a circle stroke or another symbol component may still draw.
|
|
68
|
-
Unknown expression context and geometry-dependent filters remain unavailable. Query matches do
|
|
69
|
-
not establish final pixel visibility, depth or occlusion.
|
|
70
|
-
|
|
71
|
-
## Compatibility
|
|
72
|
-
|
|
73
|
-
The tab persists as `tab=diagnostics`. Previous `tab=beacon` links open the new panel. The former
|
|
74
|
-
Beacon scoring and tour interface is retired; its historical report scores are not comparable to
|
|
75
|
-
Diagnostics findings. Network infrastructure, platform regressions and broad map quality remain
|
|
76
|
-
separate concerns from these author-facing checks.
|
package/docs/native-artifacts.md
DELETED
|
@@ -1,287 +0,0 @@
|
|
|
1
|
-
# Prepare native map artifacts
|
|
2
|
-
|
|
3
|
-
Use the existing artifact pipeline with `renderer: 'native'` to prepare the `native-v1` static
|
|
4
|
-
profile. The same config loader, inheritance resolver, semantic compiler, icon composition and
|
|
5
|
-
font pipeline are used. There is no separate native map language.
|
|
6
|
-
|
|
7
|
-
Install the packages and create a trusted `tileflow.config.ts` as described in the
|
|
8
|
-
[package README](../README.md). The source version containing this option must be installed;
|
|
9
|
-
a source branch or a successful build does not establish npm availability.
|
|
10
|
-
|
|
11
|
-
## Prepare in memory
|
|
12
|
-
|
|
13
|
-
<!-- docs:check -->
|
|
14
|
-
|
|
15
|
-
```ts
|
|
16
|
-
import {createTileflowBuildArtifacts} from '@tileflow/dev/artifacts';
|
|
17
|
-
|
|
18
|
-
const artifacts = await createTileflowBuildArtifacts({
|
|
19
|
-
config: 'tileflow.config.ts',
|
|
20
|
-
renderer: 'native',
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
try {
|
|
24
|
-
console.log(artifacts.manifest);
|
|
25
|
-
console.log(artifacts.nativeBuild);
|
|
26
|
-
} finally {
|
|
27
|
-
await artifacts.dispose?.();
|
|
28
|
-
}
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
The pipeline checks every concrete theme. A rejected theme fails the complete generation before
|
|
32
|
-
production output is written. Native preparation applies the versioned transformations below;
|
|
33
|
-
other unsupported layers, fonts or protocols are not silently removed.
|
|
34
|
-
Local PMTiles are rejected before creating archive snapshots. URL checks do not fetch remote
|
|
35
|
-
TileJSON, glyphs or tiles and do not prove their content or availability.
|
|
36
|
-
|
|
37
|
-
Font preparation verifies the same licensed source bytes as web preparation, then maps exact full
|
|
38
|
-
names into Native's `font-faces` root property. It does not retain browser `tileflow:fontFaces`
|
|
39
|
-
metadata or claim a system font is equivalent. Sprites keep the original independently generated
|
|
40
|
-
1x and 2x bytes; the native check verifies their pair, dimensions, IDs and existing size limits.
|
|
41
|
-
|
|
42
|
-
## Versioned native lowering
|
|
43
|
-
|
|
44
|
-
Selecting `renderer: 'native'` applies `native-lowering-v1` after shared semantic compilation and
|
|
45
|
-
before final native validation. It never edits the authored map, the official map definitions or
|
|
46
|
-
the shared compiler. Web output is not lowered.
|
|
47
|
-
|
|
48
|
-
A browser `sky` is removed, because Native draws no sky, and the entry records `sky: 'removed'`.
|
|
49
|
-
A fixed `projection: {type: 'globe'}` is explicitly normalized to Native's implicit Mercator. This
|
|
50
|
-
is a renderer-specific projection change, not equivalent globe rendering. An explicit fixed
|
|
51
|
-
Mercator declaration is also omitted. Adaptive/expression projections and unknown projection
|
|
52
|
-
options remain errors. Every style receipt states which normalization, if any, occurred.
|
|
53
|
-
|
|
54
|
-
For line layers, finite `line-cap` and `line-dasharray` decisions become contiguous physical layers
|
|
55
|
-
with constant values. Supported trees use constant leaves, `literal`, first-match `case`, disjoint
|
|
56
|
-
`match` labels and `step`. Predicates may combine boolean operations, scalar equality, membership,
|
|
57
|
-
`has`, geometry type and typed numeric comparisons/steps. Unchecked feature values are restricted
|
|
58
|
-
to vector sources, whose properties are scalar. Numeric coercion requires an explicit finite
|
|
59
|
-
fallback. Arbitrary feature-valued leaves, continuous interpolation, feature state, unsupported
|
|
60
|
-
operators and any unprovable decision fail with the original property pointer.
|
|
61
|
-
|
|
62
|
-
The partition preserves first-match priority. Each feature accepted by the original filter is
|
|
63
|
-
accepted by exactly one active replacement with the same cap and dash values; all other features
|
|
64
|
-
remain excluded. Existing legacy filters are converted with the pinned Style Spec converter before
|
|
65
|
-
intersection. Source, source-layer, metadata and other layout/paint values are preserved. Existing
|
|
66
|
-
`minzoom`/`maxzoom` are intersected with the decision intervals. Both target properties use integer
|
|
67
|
-
camera-zoom evaluation, so a step at 8.5 changes its value at zoom 9, while an original fractional
|
|
68
|
-
layer visibility bound remains fractional. New branch filters contain no camera-zoom expression.
|
|
69
|
-
|
|
70
|
-
Grouped outcomes use compact boolean decision trees rather than repeated lists of every earlier
|
|
71
|
-
arm's negated guard. Multi-arm cases remain flat to avoid trading size for excessive depth.
|
|
72
|
-
Identical outcomes and adjacent identical intervals are coalesced. IDs derive from the original
|
|
73
|
-
layer ID, the lowering version and deterministic branch order, with collision checks against the
|
|
74
|
-
whole input style. The original layer's replacements stay together; surrounding layers are not
|
|
75
|
-
reordered. Existing sort-key expressions are retained, not simplified or replaced.
|
|
76
|
-
|
|
77
|
-
Replacements shift the physical index of every later layer, so lowering rebinds the style's layer
|
|
78
|
-
references from the recorded spans. Each `tileflow:interaction-manifest` POI `priority` becomes its
|
|
79
|
-
layer's final index. An overlay placement anchor naming an expanded layer moves to that layer's first
|
|
80
|
-
replacement, because anchors mark insertion-before boundaries. Metadata that the spans cannot prove,
|
|
81
|
-
such as a POI priority that differs from its compiled layer index, a POI entry whose source does not
|
|
82
|
-
match its layer or an anchor naming a missing layer, fails with `NATIVE_UNSUPPORTED_STYLE` at the
|
|
83
|
-
style's `/metadata` pointer rather than being guessed. Local builds, watched sessions and native
|
|
84
|
-
preview share this step with Hosted publication.
|
|
85
|
-
|
|
86
|
-
MapLibre Native has no symbol overlap modes and reads only `icon-allow-overlap` and
|
|
87
|
-
`text-allow-overlap`. Lowering replaces each constant `icon-overlap` or `text-overlap` value with
|
|
88
|
-
the matching `*-allow-overlap`: `false` for `never` and `true` for `always` and `cooperative`. A
|
|
89
|
-
cooperative symbol therefore no longer gives way to symbols placed with `never` and can cover labels
|
|
90
|
-
it avoids on the web. The layer keeps its ID and position, so the build record lists it under
|
|
91
|
-
`symbolOverlap` rather than as a layer span. An overlap mode given as an expression fails with its
|
|
92
|
-
property pointer.
|
|
93
|
-
|
|
94
|
-
Work is bounded per property by depth 16, 512 decision visits, 64 decision paths, 16 distinct
|
|
95
|
-
outcomes and 64 dash elements; the product is limited to 32 physical layers and 32 zoom intervals
|
|
96
|
-
per logical layer. Raw compiler input must fit 160,000 JSON nodes before any lowering. Its expanded
|
|
97
|
-
native representation has a separate fixed 540,000-node ceiling, checked after lowering, after
|
|
98
|
-
font preparation and after generation URL retargeting. Both stages retain 4,096 layers, depth 64
|
|
99
|
-
and 8 MiB. No caller option raises either budget and no rejected input is retried under the output
|
|
100
|
-
allowance. A failure occurs before output writes and leaves the previous valid generation intact.
|
|
101
|
-
|
|
102
|
-
This is one shared authored map, not a second mobile catalog: the native-v1 representation adapts
|
|
103
|
-
only finite `line-cap`/`line-dasharray` decisions and constant symbol overlap modes, together with
|
|
104
|
-
its explicit fixed-projection policy. Unsupported advanced expressions or other properties fail
|
|
105
|
-
with their native diagnostic and JSON Pointer; their web behavior is unchanged. The raw and
|
|
106
|
-
prepared validators share their semantic checks and bounded traversal. See the
|
|
107
|
-
[Core budget contract](https://github.com/tileflow/tileflow-sdk/blob/main/packages/core/docs/native-artifact-profile.md#input-and-prepared-style-budgets)
|
|
108
|
-
for the measured Streets sizes and the approximately 5.2% output margin.
|
|
109
|
-
|
|
110
|
-
The equivalence checks cover per-feature selection, cap/dash values and zoom ranges, **not draw
|
|
111
|
-
order across features**. Copying `line-sort-key` preserves ordering only inside each physical
|
|
112
|
-
layer. If a feature with sort key 1 enters the first branch and a feature with sort key 0 enters
|
|
113
|
-
the second, the physical layers draw them as 1 then 0 instead of 0 then 1. Both features can satisfy
|
|
114
|
-
mutually exclusive filters yet have overlapping geometry. The resulting composition can differ,
|
|
115
|
-
not merely its antialiasing. Even without a sort key, partitioning can change source feature order.
|
|
116
|
-
|
|
117
|
-
The native-lowering-v1 policy permits these bounded partitions without promising identical global
|
|
118
|
-
feature order. Applications requiring exact overlapping-feature order must not treat such an
|
|
119
|
-
artifact as order-equivalent to its web style. Automated checks establish feature selection,
|
|
120
|
-
cap/dash values, zoom ranges, determinism and resource bounds, not pixel equivalence.
|
|
121
|
-
|
|
122
|
-
A small directed iOS/Android rendering check of cap/dash/overlap is required for each accepted
|
|
123
|
-
candidate using the recipe below. Full visual qualification belongs to the general mobile release
|
|
124
|
-
gate; it is not claimed by artifact preparation. Browser capture cannot replace either native
|
|
125
|
-
check, and a few visual samples cannot prove preservation of arbitrary feature order.
|
|
126
|
-
|
|
127
|
-
## Write a separate output
|
|
128
|
-
|
|
129
|
-
<!-- docs:check -->
|
|
130
|
-
|
|
131
|
-
```ts
|
|
132
|
-
import {writeTileflowBuildArtifacts} from '@tileflow/dev/artifacts';
|
|
133
|
-
|
|
134
|
-
await writeTileflowBuildArtifacts({
|
|
135
|
-
config: 'tileflow.config.ts',
|
|
136
|
-
renderer: 'native',
|
|
137
|
-
outDir: 'public/tileflow',
|
|
138
|
-
});
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
This writes `public/tileflow/native/manifest.json`, `build-manifest.json`, `native-build.json` and
|
|
142
|
-
the complete style/asset generation beneath `public/tileflow/native`. The writer adds `native` once
|
|
143
|
-
beneath `outDir`; pass the output parent, not an already renderer-qualified directory. The native
|
|
144
|
-
subdirectory owns a separate inventory. A web build at the parent neither replaces its manifest nor
|
|
145
|
-
collects the native generation, and vice versa.
|
|
146
|
-
|
|
147
|
-
The runtime manifest remains strict version 1 with the same map/theme shape. No renderer/profile
|
|
148
|
-
field is added to it. Native font declarations live in the native styles, not a web font loader.
|
|
149
|
-
`native-build.json` is a separate strict build record that identifies the renderer, profile, selected
|
|
150
|
-
engines, `validation: 'static-artifacts'` and the canonical `build-manifest.json` SHA-256. Its
|
|
151
|
-
schema version is 2 and its `preparationVersion` is `native-lowering-v1`.
|
|
152
|
-
|
|
153
|
-
The `transformations` array is sorted uniquely by map/theme. Each entry records input and lowered
|
|
154
|
-
style SHA-256 values, input/output layer counts, projection normalization and, when present, sky
|
|
155
|
-
removal. `layers` lists the
|
|
156
|
-
input ordinal, output start/count and affected properties of each partitioned line layer;
|
|
157
|
-
`symbolOverlap` lists the input ordinal and replaced properties of each symbol layer whose overlap
|
|
158
|
-
modes became `*-allow-overlap` values. Ordinals refer to the complete style layer arrays, including
|
|
159
|
-
unchanged layers. These spans make the deterministic
|
|
160
|
-
physical IDs traceable without duplicating layer definitions in the receipt. The input hash binds shared
|
|
161
|
-
compiler output; the lowered hash includes the rebound layer references and precedes native font
|
|
162
|
-
preparation and generation URL retargeting.
|
|
163
|
-
The build-manifest hash separately binds the final prepared styles and assets. All styles receive
|
|
164
|
-
an entry, including styles for which no lowering was needed. Schema v1 build records do not imply
|
|
165
|
-
this preparation policy and are not parsed as v2.
|
|
166
|
-
|
|
167
|
-
The existing logical map revision remains based on resolved cartography and source asset identity.
|
|
168
|
-
Representation changes, such as native font mapping, change the style hash rather than inventing
|
|
169
|
-
a second logical map. Transport credentials and device state never enter these artifacts.
|
|
170
|
-
|
|
171
|
-
File names in an in-memory plan remain relative to the renderer output root. Relative style/font
|
|
172
|
-
URLs remain relative to their owning documents. An explicit absolute or host-relative
|
|
173
|
-
`styleBaseUrl`/`assetBaseUrl`, such as `/tileflow`, receives the `/native` suffix. The pipeline uses
|
|
174
|
-
an inert `.invalid` document base only to check relative URL syntax; it does not publish that base
|
|
175
|
-
or infer the application's real delivery origin.
|
|
176
|
-
|
|
177
|
-
A served local preview can use an absolute HTTP base, such as `http://127.0.0.1:3333`, only when it
|
|
178
|
-
also passes that exact origin as `developmentOrigin`. Native checks then accept HTTP resource URLs,
|
|
179
|
-
such as the sprite and fonts, with that scheme, host and port. Every other origin still requires
|
|
180
|
-
HTTPS, and browser protocols remain rejected. The option is never inferred from a base URL.
|
|
181
|
-
Web preparation, `target: 'production'` and `writeTileflowBuildArtifacts()` reject it with
|
|
182
|
-
`NATIVE_RENDERER_UNSUPPORTED` at `/developmentOrigin`, so written artifacts never depend on it.
|
|
183
|
-
|
|
184
|
-
Omitting `renderer`, or specifying `renderer: 'web'`, preserves the existing web artifact bytes and
|
|
185
|
-
output layout. The native record is absent from web plans.
|
|
186
|
-
|
|
187
|
-
## Retain the last valid generation
|
|
188
|
-
|
|
189
|
-
`createTileflowArtifactSession({renderer: 'native', watch: true})` uses the existing session lifecycle.
|
|
190
|
-
An incompatible edit publishes an `invalid` state with native diagnostic context. It retains the
|
|
191
|
-
previous valid artifacts but does not publish them again as a new successful generation. Acquiring,
|
|
192
|
-
releasing and disposing a generation follow the existing [artifact lifecycle](artifact-lifecycle.md).
|
|
193
|
-
|
|
194
|
-
This is artifact watching, not a native preview server. Do not pass these artifacts to browser
|
|
195
|
-
preview/capture as evidence of a native render. Native inspection sidecars, React Native components,
|
|
196
|
-
Hermes execution, iOS/Android qualification, Hosted authorization and deployment are not supplied.
|
|
197
|
-
|
|
198
|
-
## Audit lowering size and feature order
|
|
199
|
-
|
|
200
|
-
From the SDK source root after installing and building the pinned workspace:
|
|
201
|
-
|
|
202
|
-
```sh
|
|
203
|
-
pnpm exec tsx scripts/native-lowering-audit.ts > native-lowering-audit.json
|
|
204
|
-
```
|
|
205
|
-
|
|
206
|
-
This diagnostic report compiles the unchanged full Streets family through the web preparation
|
|
207
|
-
path, then measures the native representation for **all twelve** themes before applying output
|
|
208
|
-
budget assertions. It writes no native artifact generation and is not a compatibility verdict.
|
|
209
|
-
Each theme includes layer counts, visited JSON nodes, UTF-8 bytes and maximum depth before/after;
|
|
210
|
-
every transformed layer is listed with its ID, physical span, branch count and zoom intervals,
|
|
211
|
-
sort-key expression and paint indicators. Simultaneously active branches are marked as an
|
|
212
|
-
unproven feature-order boundary, not as a claim that their geometry is disjoint.
|
|
213
|
-
|
|
214
|
-
Subtree accounts separate copied unchanged layer payload from generated filters and input
|
|
215
|
-
cap/dash decisions. They identify whether predicate expansion or repetition of other properties
|
|
216
|
-
dominates; they are not an additive byte decomposition. The counters include array keys, matching
|
|
217
|
-
the profile's existing node convention. Retain the report with the checkout SHA. An over-budget
|
|
218
|
-
result must not be treated as a successful native build or fixed by dropping layers or weakening
|
|
219
|
-
validation. The test suite prints the full theme size summary even when a budget assertion fails.
|
|
220
|
-
|
|
221
|
-
## Prepare Streets for a directed native check
|
|
222
|
-
|
|
223
|
-
From a source checkout, install and build the pinned workspace first. The test-only
|
|
224
|
-
`test/fixtures/native-streets.config.ts` exports the unchanged official Streets definition. It
|
|
225
|
-
exists to make artifact generation repeatable without a second compiler, custom map or native
|
|
226
|
-
harness. From the SDK root:
|
|
227
|
-
|
|
228
|
-
```sh
|
|
229
|
-
pnpm --filter @tileflow/dev exec node ../cli/dist/index.js validate \
|
|
230
|
-
--config test/fixtures/native-streets.config.ts --renderer native --target local --json
|
|
231
|
-
pnpm --filter @tileflow/dev exec node ../cli/dist/index.js build \
|
|
232
|
-
--config test/fixtures/native-streets.config.ts --renderer native --target local \
|
|
233
|
-
--out output/native-streets --json
|
|
234
|
-
pnpm exec tsx scripts/native-lowering-audit.ts > /tmp/native-lowering-audit.json
|
|
235
|
-
```
|
|
236
|
-
|
|
237
|
-
The output root is `packages/dev/output/native-streets/native`. It contains
|
|
238
|
-
`styles/streets/dark.json`, `styles/streets/light.json`, their shared sprite/font assets, a version-1
|
|
239
|
-
`manifest.json` and the version-2 `native-build.json` receipt. Keep the complete directory together.
|
|
240
|
-
The manifest points to the content-addressed generation; use those URLs for an actual render.
|
|
241
|
-
Do not copy only the two style files and leave their relative assets behind. Record the checkout
|
|
242
|
-
SHA, both prepared style hashes, engine versions and the resource origin used for the check.
|
|
243
|
-
The fixture and output are source-checkout tools, not a published mobile component or a baseline.
|
|
244
|
-
|
|
245
|
-
Use an existing native test application with the pinned engines and a reachable artifact origin;
|
|
246
|
-
artifact generation starts no server and requests no deployment. Load the same generated manifest
|
|
247
|
-
family independently on iOS and Android. Resolve its style URL against the manifest URL, then each
|
|
248
|
-
relative style resource against that style's URL before passing the style to MapLibre Native. A raw
|
|
249
|
-
style URL does not transfer this ownership to the renderer. The directed artifact check may use a
|
|
250
|
-
test-owned resolver, but that does not qualify a future runtime resolver. A useful starting viewport
|
|
251
|
-
is a dense road/rail junction with visible paths and bridges; select one where the loaded vector data
|
|
252
|
-
actually contains features for the transformed layers listed in
|
|
253
|
-
`/tmp/native-lowering-audit.json`. Use the audit's exact physical IDs, source layers, branch counts
|
|
254
|
-
and zoom intervals rather than assuming that a map location exercises every branch.
|
|
255
|
-
|
|
256
|
-
Check all themes at the same center, viewport, pitch 0 and bearing 0. Exercise at least one cap
|
|
257
|
-
partition, one dashed/solid partition and an overlap between simultaneously active branches. Pan
|
|
258
|
-
slightly and inspect just below/at/above the relevant audit zoom cuts (for example 15.99/16/16.01
|
|
259
|
-
when a selected interval changes at 16). Check that caps and dash patterns are visible, layers do
|
|
260
|
-
not disappear or double-select a feature, theme replacement preserves the scene, and no resource
|
|
261
|
-
or style errors are reported. Inspect overlapping strokes for the documented composition
|
|
262
|
-
trade-off, not for equality with web drawing order. Keep brief per-platform observations and
|
|
263
|
-
explicitly distinguish an unexercised branch from a passed one.
|
|
264
|
-
|
|
265
|
-
This check has not been run by the artifact tests. It neither establishes full iOS/Android visual
|
|
266
|
-
qualification nor creates a screenshot baseline. Renderers, native view lifecycle, network
|
|
267
|
-
transport and mobile distribution remain outside these build tools.
|
|
268
|
-
|
|
269
|
-
## Reproduce the official-map report
|
|
270
|
-
|
|
271
|
-
From an SDK source checkout after installing and building its pinned workspace:
|
|
272
|
-
|
|
273
|
-
```sh
|
|
274
|
-
pnpm exec tsx scripts/native-catalog-report.ts > native-catalog-report.json
|
|
275
|
-
```
|
|
276
|
-
|
|
277
|
-
The report evaluates all ten official maps and each of their themes through the shared pipeline.
|
|
278
|
-
Rows contain either a static-compatible style hash or exact incompatibility diagnostics, sorted by
|
|
279
|
-
map/theme with no timestamp or local path. Each row checks an individual theme; it is not a revision
|
|
280
|
-
receipt for a rewritten single-theme map. Unexpected compilation/tool failures stop report generation
|
|
281
|
-
rather than being relabeled as known incompatibilities. Retain the output together with the checkout
|
|
282
|
-
SHA and lockfile used to produce it. The test suite compares two independent evaluations and requires
|
|
283
|
-
Streets to pass. No unchecked catalog-wide compatibility assertion is implied by the presence of
|
|
284
|
-
this command, and this report is not a device-qualification result.
|
|
285
|
-
|
|
286
|
-
See the [Core profile contract](https://github.com/tileflow/tileflow-sdk/blob/main/packages/core/docs/native-artifact-profile.md)
|
|
287
|
-
for the version intersection, diagnostic codes and unsupported representations.
|
package/docs/native-icons.md
DELETED
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
# Author recolorable and adaptable icons
|
|
2
|
-
|
|
3
|
-
Use SDF for a monochrome silhouette whose fill and halo vary by map. Keep multicolor artwork as
|
|
4
|
-
fixed-color RGBA. Ordinary filenames and icon IDs stay unchanged.
|
|
5
|
-
|
|
6
|
-
In an icon directory already selected by your map, place `tileflow.icons.json` beside `health.svg`:
|
|
7
|
-
|
|
8
|
-
```json
|
|
9
|
-
{
|
|
10
|
-
"schemaVersion": 1,
|
|
11
|
-
"icons": {
|
|
12
|
-
"health": {
|
|
13
|
-
"representation": "sdf",
|
|
14
|
-
"defaults": {"color": "#c43d35", "haloColor": "#ffffff", "haloWidth": 1, "haloBlur": 0}
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
Only explicitly declared SDF assets are converted. Omitted entries, or `representation: "rgba"`,
|
|
21
|
-
preserve fixed-color rendering. SDF uses the source alpha silhouette; source RGB does not define its
|
|
22
|
-
default color. `defaults.color` is required. Omitted halo fields become transparent, zero width and
|
|
23
|
-
zero blur. Unknown IDs, duplicate JSON keys, unknown fields and invalid colors fail preparation.
|
|
24
|
-
|
|
25
|
-
The generated cell remains 24 × 24 logical pixels at both densities. Within that cell, the source
|
|
26
|
-
silhouette needs six fully transparent pixels on every side. Tileflow rejects edge-touching,
|
|
27
|
-
empty, or insufficiently defined silhouettes instead of adding padding or shrinking artwork.
|
|
28
|
-
Author opaque silhouettes with antialiased edges; gradients and translucent artwork should remain
|
|
29
|
-
RGBA. Thin shapes without a resolved interior fail verification. Generation rasterizes 1x and 2x
|
|
30
|
-
independently and encodes distance in white-RGB alpha. SDF is for symbol icons, not patterns.
|
|
31
|
-
|
|
32
|
-
For existing artwork, expand the source canvas explicitly before declaring SDF. A drawing bounded
|
|
33
|
-
by `viewBox="0 0 15 15"` fits the profile when its outer SVG uses `width="24" height="24"`
|
|
34
|
-
and `viewBox="-7.5 -7.5 30 30"`: the drawing occupies at most the central 12px. Review fine details
|
|
35
|
-
at the intended map size; use `icon.size` to choose the displayed size. Keep the original source for
|
|
36
|
-
fixed-color use. A transparent margin does not make an excessively thin silhouette suitable.
|
|
37
|
-
|
|
38
|
-
## Keep each symbol layer homogeneous
|
|
39
|
-
|
|
40
|
-
One package may contain RGBA and SDF icons. Every icon selectable by one symbol layer, including
|
|
41
|
-
fallbacks, must use the same representation. Tileflow checks the effective composition after all
|
|
42
|
-
local overrides. It does not split layers or alter collision priority, coupled labels or IDs.
|
|
43
|
-
|
|
44
|
-
An unbounded selection such as a POI icon read from feature data can select any effective icon ID.
|
|
45
|
-
It therefore requires a homogeneous inventory. To use a mixed package, select one fixed icon or
|
|
46
|
-
an explicit `expr.match`/`expr.case` expression whose possible outputs and fallback are homogeneous.
|
|
47
|
-
Sampling the current feature data does not prove this condition.
|
|
48
|
-
|
|
49
|
-
`tileflow validate`, `tileflow preview`, `tileflow build`, framework preparation and Capture use the
|
|
50
|
-
same check. `TF_ICON_REPRESENTATION_MIXED` identifies the layer and image-selection path. Replace
|
|
51
|
-
the conflicting override, align all selectable representations, or bound the selection explicitly.
|
|
52
|
-
Compiled SDF admission rejects legacy token templates and function objects with
|
|
53
|
-
`TF_ICON_SELECTION_UNPROVEN`; rebuild using expression-based image selection.
|
|
54
|
-
Development reports an invalid generation and retains its last valid artifact until recovery.
|
|
55
|
-
|
|
56
|
-
## Style each map independently
|
|
57
|
-
|
|
58
|
-
Use the existing `styles.<category>.icon` fields: `color`, `haloColor`, `haloWidth`, and `haloBlur`.
|
|
59
|
-
Theme tokens, explicit `fixed(...)` values and supported data, zoom and feature-state expressions
|
|
60
|
-
compile to native MapLibre paint. Feature state is supported in paint, not image selection.
|
|
61
|
-
Keep halo width within 0–2 logical pixels and blur within 0–1. Dynamic halo expressions must prove
|
|
62
|
-
these bounds; use `expr.min`/`expr.max` around unconstrained feature values. Otherwise compilation
|
|
63
|
-
reports `TF_ICON_HALO_BOUNDS`.
|
|
64
|
-
|
|
65
|
-
An omitted paint property uses that selected icon's declared default, including missing-ID
|
|
66
|
-
fallbacks. An override replaces only its property. It does not edit the shared revision or another
|
|
67
|
-
map. Image IDs remain stable; recoloring does not generate image variants. Existing size, opacity,
|
|
68
|
-
rotation and anchor controls retain their native semantics.
|
|
69
|
-
|
|
70
|
-
## Fit a background around text
|
|
71
|
-
|
|
72
|
-
Declare optional `layout` beside the representation. It applies to RGBA and SDF independently.
|
|
73
|
-
For a 24px background whose central region can stretch, use this sidecar entry:
|
|
74
|
-
|
|
75
|
-
```json
|
|
76
|
-
{
|
|
77
|
-
"schemaVersion": 1,
|
|
78
|
-
"icons": {
|
|
79
|
-
"price": {
|
|
80
|
-
"representation": "rgba",
|
|
81
|
-
"layout": {
|
|
82
|
-
"stretchX": [[9, 15]],
|
|
83
|
-
"stretchY": [[9, 15]],
|
|
84
|
-
"content": [7, 7, 17, 17]
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
Coordinates use the generated logical cell, not the original SVG viewBox. Each stretch interval
|
|
92
|
-
is `[start, end]`; `content` is `[left, top, right, bottom]`. Use positive, ordered, non-overlapping
|
|
93
|
-
integer ranges inside the cell. Each configured axis must overlap its content area. Put corners,
|
|
94
|
-
borders and pointers outside stretch regions. Tileflow scales metadata for the 2x index, verifies
|
|
95
|
-
both densities and rejects layout on patterns. SDF backgrounds still need the six-pixel guard.
|
|
96
|
-
|
|
97
|
-
Enable the existing map `icon.textFit` control (`width`, `height` or `both`) and set
|
|
98
|
-
`icon.textFitPadding` in top/right/bottom/left order. For centered price labels, also set
|
|
99
|
-
`text.anchor: 'center'` and `text.offset: [0, 0]`; the POI defaults place labels beside icons.
|
|
100
|
-
This style fragment belongs inside the selected category's `styles` entry:
|
|
101
|
-
|
|
102
|
-
```ts
|
|
103
|
-
{
|
|
104
|
-
icon: {image: fixed('price', {reason: 'Price background'}), textFit: 'both', textFitPadding: [4, 6, 4, 6]},
|
|
105
|
-
text: {anchor: 'center', offset: [0, 0]},
|
|
106
|
-
}
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
Import `fixed` from `@tileflow/core`. The same layer retains label coupling, collision priority and
|
|
110
|
-
interaction identity. Text fitting does not happen merely because an asset has metadata. Explicit
|
|
111
|
-
new local artwork replaces the shared asset's layout; omitted metadata never inherits stale bounds.
|
|
112
|
-
|
|
113
|
-
## Inspect and distribute the result
|
|
114
|
-
|
|
115
|
-
Packages with SDF appearance or layout use `tileflow-icon-package-v2`; composition receipts use
|
|
116
|
-
`tileflow-icon-composition-v2` when an effective winner has either capability. Paired sprite JSON entries contain
|
|
117
|
-
`sdf: true` and verified `tileflow` appearance metadata. Defaults and layout participate in revision identity
|
|
118
|
-
and diffs even when pixel hashes match. Metadata-free RGBA packages and receipts keep their v1 identity.
|
|
119
|
-
Old readers reject v2; upgrade every producing and consuming package together.
|
|
120
|
-
|
|
121
|
-
`tileflow icons list --json` includes `appearances` and `layouts` for effective icons. Diff reports show default appearance;
|
|
122
|
-
downloadable PNGs remain the original distance fields. Bare MapLibre consumes the standard sprite
|
|
123
|
-
and compiled paint without a recoloring adapter. Capture uses the same prepared assets.
|
|
124
|
-
|
|
125
|
-
Hosted admission, Dashboard and Static Maps require coordinated Platform adoption. Additional
|
|
126
|
-
Static Maps symbols use asset defaults and retain adjacent icon/label layout; base-map symbols use
|
|
127
|
-
compiled map paint and text fitting. Device support
|
|
128
|
-
requires separate Native qualification. This contract does not provide independently parameterized
|
|
129
|
-
multicolor SVG, COLRv1, `textFitWidth`/`textFitHeight` metadata or an icon editor.
|