flutter_map_vector_tiles 1.2.0
flutter_map_vector_tiles: ^1.2.0 copied to clipboard
Vector tiles for flutter_map: a clean, self-contained MapLibre-style vector tile layer with isolate-based decoding, raster tile caching and screen-space label collision.
Changelog #
1.2.0 #
Two style features that used to be skipped now render.
- ๐จ
line-pattern: the sprite is stamped along the line, rotated to the local direction and scaled so its height matches the line width (MapLibre semantics, data-driven patterns included). Per spec the pattern replacesline-colorandline-dasharray;line-opacitystill applies. A missing sprite falls back to the color stroke. - ๐ฐ๏ธ Raster sources inside vector styles (satellite/hybrid imagery,
pre-rendered hillshade tiles):
rasterlayers draw their tiles at the correct position in the layer order.raster-opacity,raster-brightness-min/-max,raster-contrast,raster-saturationandraster-hue-rotatereplicate MapLibre's fragment-shader math (including its factor curves and spin weights). Raster tiles share the tile disk cache, are decoded once and cached process-wide (released byVectorTileLayer.clearMemoryCache()), overzoom past the source maximum, respect the sourcetileSize(512/256) underTileOffset, and render in-memory ancestors as provisional imagery during zoom โ the same lifecycle vector tiles get.StyleReaderpicks raster sources up automatically (inlinetilesor TileJSONurl); passstyle.rasterSourcesto the newVectorTileLayer.rasterSourcesparameter.
1.1.0 #
Reopening a map is now nearly instant. Both caches used to die with the layer, so every time a map screen was pushed it started from nothing.
- โก The disk cache is awaited rather than raced. It initializes asynchronously โ its directory comes from a platform channel โ but tiles are requested on the very first frame, and the load path read it as a plain field that was still null. Every map open therefore fetched its opening screenful over the network, with the tiles already on disk. The stores now hold the pending cache and await it.
- โก Decoded tiles are cached process-wide instead of per layer, so a
reopened map paints without decoding anything again. Entries are keyed by
source and by the properties the theme reads โ two styles over one
source do not share trimmed tiles โ and are capped by
VectorTileLayer.memoryCacheMaxBytesper key. They outlive the layer by design;VectorTileLayer.clearMemoryCache()releases them, e.g. from a memory-pressure handler. - โก
DiskCacheinstances are shared per directory, so a second layer over the same folder reuses an initialized cache instead of setting up its own. - ๐
VectorTileProvider.cacheKeynow also identifies the in-memory cache. Providers serving different bytes must not share one.
1.0.0 #
First stable release: the public API is now considered settled and will follow semantic versioning from here.
- โจ
icon-color,icon-halo-colorandicon-halo-widthare supported for SDF sprite sheets (see the rendering fix below). - ๐ The map no longer shakes while zooming and no longer slides out from under its labels while dragging. Tile rectangles are now made camera-relative in Dart before they reach the canvas: world pixel coordinates pass 2^24 around zoom 16, and the canvas transform is float32, so absolute coordinates were snapping the imagery onto a grid โ 0.25 px at zoom 14, but 4 px at zoom 18 and 16 px at zoom 20. The label pass does its own float64 arithmetic, so the two drifted apart. This is why the artifacts only appeared when heavily zoomed in.
- ๐ SDF sprites are rendered correctly instead of as dark blobs.
Sheets flagged
"sdf": truestore a distance field in the alpha channel over flat RGB; they were being blitted directly, which painted the raw field. They are now thresholded and tinted, adding support foricon-color,icon-halo-colorandicon-halo-width. Ordinary sprites are unaffected. Dark MapLibre styles are typically entirely SDF, which is why icons looked correct in light styles and wrong in dark ones. - ๐
text-opacityis now applied. Labels the style fades out are also no longer laid out at all, so they stop reserving collision space and suppressing the visible labels around them.
0.4.1 #
- ๐ The map no longer blanks and reloads moments after first paint: the async disk-cache initialization now attaches to the running tile stores instead of rebuilding them (which disposed every rendered tile).
- ๐ No more flash on zoom level changes: the previous level's imagery is kept until the new tiles are rasterized and fully faded in โ it used to be dropped mid-fade, dipping to the background color.
- ๐ Labels no longer blink out on zoom level changes: the previous level's labels keep drawing wherever the new level has no label data yet (current-level labels win collisions as they arrive).
- โก Smoother zooming: tiles are rasterized through a priority queue with a per-frame time budget (viewport centre first) instead of all in one frame. With warm caches, a zoom change used to rasterize the entire grid synchronously in a single frame, dropping frames.
0.4.0 #
- โ๏ธ Offline support for recently visited places:
StyleReadernow caches the style bundle (style.json, TileJSON, sprites) on disk with stale-while-revalidate: the cached copy is served instantly โ including fully offline โ and refreshed in the background once older thanrefreshAfter(12 h default). Opt out withcache: false.- Tiles: when a network fetch fails, an expired disk-cache entry is
served instead of a blank tile.
diskCacheTtlis now a freshness window โ stale tiles are kept (up to the size cap, evicted oldest first) as the offline fallback instead of being deleted by age. - The default cache folder moved from the system temp directory to the application support directory, which the OS doesn't purge. Existing temp-dir caches are simply abandoned and refetched once.
0.3.0 #
- โจ Curved line text: road labels now follow their line glyph by glyph,
with MapLibre semantics โ
text-max-angle(labels on too-sharp bends are not placed),text-keep-upright(reading direction flips so text is never upside-down) andtext-rotation-alignment: viewport(horizontal shield text). Glyph spacing/kerning comes from the full string layout; per-glyph collision boxes; nearly straight labels are drawn as a single rotated string for speed. - Scripts with contextual shaping (Arabic, Indic, Thai, โฆ) fall back to straight placement so glyphs are never mis-joined; labels longer than their line are dropped instead of sticking out (matches MapLibre).
- Along-line labels no longer wrap to multiple lines.
- โฌ๏ธ
latlong2constraint widened to>=0.9.1 <0.11.0, so 0.10.x resolves. Still compatible with flutter_map 8.2.0+, which pins^0.9.1until 8.3.1. - ๐งน Source reformatted with the Dart formatter (no behaviour change).
0.2.0 #
- โจ
text-variable-anchor+text-radial-offset: labels try alternate anchors before being dropped on collision โ dense areas keep far more POI and place labels visible (matches MapLibre behaviour). - โจ
fill-pattern(andfill-extrusion-pattern): polygon fills render repeating sprite patterns (wetlands, glaciers, pedestrian zones), world-grid aligned across tile seams; missing sprites fall back to the color fill. - ๐ Bare literal arrays in style JSON (
text-offset: [0, 0.6],text-font: [...],line-dasharray: [2, 1], anchor lists) were mis-parsed as expressions and silently fell back to defaults โ affected font stacks and label offsets in most real styles. LabelPainter.paintnow returns the symbols that were actually drawn.
0.1.0 #
Initial release. ๐
VectorTileLayerfor flutter_map โฅ 8 rendering MapLibre/Mapbox GL styles from MVT vector tile sources.- Self-contained: built-in MVT decoder, style/expression engine (modern expressions + legacy filters/functions/tokens), sprite support.
- GPU-resident per-tile rasterization (
Picture.toImageSync) with fade-in, ancestor-tile retention and provisional rendering from cached parent tiles (no white flashes on zoom). - Screen-space label pass with global cross-tile collision, upright text under rotation, halo and sprite icon support.
- Worker-isolate decode pipeline with priority ordering and silent cancellation.
- Deterministic LRU memory caches (byte budgets) and TTL + size-capped disk cache.
StyleReaderfor style.json / TileJSON / sprites with{key}substitution, tolerant of real-world provider quirks (MapTiler, OpenFreeMap, Stadia, ArcGIS, Protomaps).TileOffset.maplibredefault for correct 512px-convention rendering.