0.43.1 - Republish for the QGIS plugin repository
- Version bump to publish the validated build (Qt6 scoped enums and
the lint/security gates
cleared). The generated viewer's version stamp now reflects the real
plugin version. No
behavioural change.
0.43.0 - Layer order follows the QGIS layer tree
- The exported map now stacks layers in your QGIS layer-tree order:
the top layer in the QGIS
panel renders on top in the web map (and appears at the top of the
layer list). Rearrange your
layers in QGIS and the export follows — you control the order
directly, including where imagery
and tile basemaps sit. (The added Protomaps basemap stays at the very
bottom.)
0.42.0 - Group on/off toggles + restore the 'My Layers' QGIS group
- Each collapsible section in the viewer's layer list (My Layers,
Carto, Basemap, ...) now has a
checkbox in its header that shows/hides ALL layers in the group at
once; it reflects the child
state (all / none / mixed).
- Fixed a regression where QGIS layer-tree groups (e.g. 'My Layers')
stopped appearing after the
source-aware TOC grouping change.
0.41.1 - Fix render order: basemaps below your data
- Tile/raster layers (XYZ imagery like Google Satellite, vector-tile
bases like Carto) now always
render BELOW your vector data instead of being interleaved or stacked
on top. Previously a full
vector-tile basemap could sit on top and cover everything, and an
opaque XYZ raster could hide
the data layers beneath it.
0.41.0 - Basemap layers under a collapsible 'Basemap' section; base
layers at the bottom
- The basemap's many sub-layers (roads, water, landuse, ...) now
collapse under a 'Basemap' section
in the viewer's layer list instead of sitting at the top level. The
base sections (styled vector
tiles like Carto, and the Basemap) now appear at the BOTTOM of the
list, below your own data
layers — matching the map's base-at-bottom rendering order.
0.40.0 - Group a vector tile layer's sub-layers under their own TOC
section
- A styled vector tile layer (e.g. Carto) adds many sub-layers (water,
roads, labels, ...). They
now appear under their own collapsible section in the viewer's layer
list, named after the
layer, instead of cluttering the top level. The TOC also groups
source-aware now, so a provider's
'water'/'landcover'/... no longer merge with the basemap's
identically-named layers.
0.39.6 - Fix missing base64 import (0.39.5 regression)
- 0.39.5 added the favicon using base64 but the module import was
missing, so HTML generation
raised NameError and no viewer could be written. Added the import;
full test suite green again.
0.39.5 - Resilient viewer: one bad layer no longer blanks the whole
map
- The viewer now adds data layers one at a time and skips (logs) any
layer MapLibre rejects, so a
single invalid layer can't reject the entire style and leave a blank
map.
- Duplicate layer ids (which MapLibre rejects outright) are renamed at
export; a fetched provider
GL style's layer ids are namespaced so generic names (water,
landcover, ...) don't collide with
the basemap. Fixes a blank map when a Carto vector basemap was added.
- The exported page now uses the MapSplat icon as its favicon (also
stops the favicon.ico 404).
0.39.4 - Use a vector tile layer's own GL style (fetch styleUrl)
- A vector tile (MVT) layer added in QGIS with a Style URL now
renders: MapSplat reads the styleUrl
from the layer source, fetches that Mapbox-GL style at export time,
and uses its layers (so e.g.
Carto basemaps 'just work' instead of being skipped). Provider
fonts/icons aren't bundled, so
labels/icons may be partial when a separate basemap is also used.
0.39.3 - Fix false PMTiles verify failures (benign zoom-header
mismatch)
- 'Verify PMTiles after export' no longer fails normal exports. GDAL's
PMTiles writer stamps
MinZoom=0 in the header even when small features only tile at a higher
zoom, so `pmtiles verify`
reported a header/tile zoom mismatch — a benign metadata quirk, not
corruption. That case is now
logged as a note and passes; real corruption (bad magic, structure)
still fails.
0.39.2 - Pre-upload hygiene: remove duplicate method, fix stale unit
tests, gate clean
- Removed a duplicate _plugin_version() in the dock (flake8 F811).
Fixed style_converter unit-test
mocks that had gone stale since the fill-paint refactor (missing
layerType/opacity/orderByEnabled)
— the full suite (173) now passes. flake8 clean; Bandit no
High/Medium; metadata + packaging valid.
0.39.1 - Layer ordering + unstyled MVT handling
- Tile/raster layers (e.g. an XYZ raster) now appear in the map + TOC
at their selected-layer
position instead of always at the bottom of the stack.
- A vector tile (MVT) layer with no usable style is now skipped
cleanly (no dead source in the
output) with actionable guidance, instead of leaving an empty,
non-rendering source.
0.39.0 - TOC entries for every layer (raster, XYZ, online, basemap)
- The viewer's layer list previously only showed vector layers (those
with a source-layer). Raster
layers, the XYZ raster basemap, online XYZ raster layers, and local
raster PMTiles had no toggle.
They now all get a TOC entry (checkbox + raster swatch + friendly
label) so users can switch any
visible layer off.
0.38.1 - Clearer self-hosting scope: label streaming (internet-only)
sources
- MapSplat bundles everything it can as PMTiles
(Caddy/static-servable, offline). Sources that
stream live from a remote server (XYZ basemap, online XYZ/MVT layers,
streamed Protomaps) now
carry a 🌐 marker in the UI and a tooltip explaining they need internet
and aren't served by
your own host. The export log flags any live-streaming source. New
README 'Hosting & self-hosting
scope' section spells out what's bundled vs streamed.
0.38.0 - Local MBTiles vector tiles -> bundled PMTiles (Story 18 Stage
2)
- A vector tile layer backed by a local .mbtiles file is now converted
to PMTiles and bundled into
the export (offline-capable; no terms-of-service concern since it's a
local file). Its Mapbox-GL
style is taken from the layer's custom property or the MBTiles
metadata table.
- Stage 3 (downloading ONLINE tile sources for offline use) remains
deferred — it is ToS-gated and
needs dedicated acknowledgment/progress UI; online tile layers still
stream live (Stage 1).
0.37.0 - XYZ raster basemap support (Story 16)
- New basemap mode: "XYZ raster" — use an online XYZ tile provider
(OpenStreetMap, Carto,
OpenTopoMap, Esri World Imagery, or a custom {z}/{x}/{y} URL) as the
basemap. It streams live in
the viewer, needs no pmtiles CLI, and adds the provider's attribution
automatically.
0.36.1 - Docs: Quick Start refresh, Troubleshooting, tutorial
storyboard
- README: crisp 5-step Quick Start (install -> first export) plus a
Troubleshooting table for the
common gotchas (pmtiles CLI, blank map/serve.py, missing layers,
rasters, online layers, tools).
- New docs/TUTORIAL_SCRIPT.md: shot-by-shot storyboard for a ~6-minute
demo video.
0.36.0 - Raster layer support (Story 15)
- Selected raster layers can now be tiled into the map: gdalwarp ->
EPSG:3857 (clipped to the
export extent) -> gdal_translate -of MBTiles (with overviews) ->
pmtiles convert, added as a
raster source below the vector layers with the layer's opacity.
RGB/RGBA and paletted rasters
are supported (paletted via an -expand rgba retry). Enable with the
new "Include raster layers"
checkbox (off by default; needs GDAL's MBTiles driver). Styled
single-band rasters (e.g. DEMs)
may not tile yet. Intermediate files are cleaned up; failures fold
into the export summary.
0.35.0 - Basemap extract caching (Story 17)
- Basemap extracts are now cached by source + extent + max zoom, so
repeat exports of the same
area reuse the previous download instead of re-extracting. Transient
network failures retry 3×,
and `pmtiles extract` runs with parallel download threads.
- New Advanced Options: "Refresh basemap cache (re-download)" checkbox
and a "Clear basemap cache"
button. Cache lives under the active QGIS profile.
0.34.0 - MVT / XYZ tile layers: pass-through export (Story 18 Stage 1)
- Vector tile layers (QgsVectorTileLayer, XYZ/MVT) and online XYZ
raster layers (OSM, imagery,
any {z}/{x}/{y}) are now exportable: their source URLs are referenced
directly in style.json so
the web map streams them live (no data copied — no provider
terms-of-service concern).
- Vector tile layers are now selectable (were disabled [Other]);
online layers are tagged 🌐 in the
layer list so you know the exported map needs internet for them.
- XYZ raster layers were previously selectable but silently dropped —
now they render.
0.33.0 - Export robustness: partial-failure summary + optional PMTiles
verify
- Per-layer export failures no longer pass silently: the run tracks
which layers had problems and
shows a summary dialog ("N of M layers exported") listing each failure
with its reason.
- New "Verify PMTiles after export" checkbox (Advanced Options, off by
default) runs `pmtiles
verify` on each written tile file; failures are logged and surfaced in
the summary.
0.32.0 - Graduated marker icons + dual-sprite fallback + embed-note
accuracy
- Graduated (range-based) SVG-marker point layers now render as
per-range sprite icons (a `step`
icon-image over the class attribute), matching the categorized
behaviour; they no longer fall
back to plain circles. Per-range icons also appear in the legend.
- Dual-sprite resilience: if a combined basemap+business sprite array
fails to load (e.g. the
remote basemap sprite is offline), the viewer now falls back to the
local business sprite so
your markers still render, instead of the whole array failing.
- Copy-embed accuracy: the <body> block's NOTE now says the whole
MAPSPLAT <head> block (assets
AND styles, inline when bundled) is required — not just the CDN tags.
0.31.0 - Toolbar polish + drawing interaction fixes
- Map tool buttons (reset, north, measure, draw, export) are now 29x29
with black line-art SVG
icons, matching MapLibre's native control buttons (e.g. the geolocate
button) instead of the
old mixed-size emoji buttons.
- Right-click now completes a drawing or measurement (was
double-click), avoiding stray points.
- Identify popups are suppressed while the measure or draw tool is
active, so they no longer get
in the way while sketching.
0.30.1 - Export tool now captures drawings + scale bar
- JPG/PDF export composites the map onto a 2D canvas and captures it
synchronously within a render
frame, so drawn/measured features reliably appear (previously the
async capture could miss them).
- The exported image now also includes a scale bar (when the on-screen
scale bar is enabled). The
legend/controls panel is still excluded (it is a separate HTML
overlay).
0.30.0 - Plugin tool framework + export tool + adjustable
units/colours
- Interactive viewer tools (measure, draw, export) are now
self-registering plugin objects that
talk to the map through a small stable interface (MapSplatTools host).
They use only long-stable
MapLibre APIs, so upgrading the MapLibre library no longer touches the
tools.
- New optional Export tool: save the current map image as JPG or PDF
(self-contained, no external
library; single-image PDF built in-page). Enable via the Viewer tab
"Export tool" checkbox.
- Viewers can now adjust units and colours at runtime: the measure
readout has a units toggle
(metric + imperial / metric / imperial) and the draw tool has a
per-feature colour picker.
Authors can set defaults via measure_units / draw_color in a config.
0.29.0 - Draw/sketch tool with GeoJSON/KML export (optional)
- New optional viewer tool: a pencil button to draw points, lines, and
polygons on the map and
export them as GeoJSON or KML (client-side download; nothing is
uploaded). Point/Line/Polygon
modes, Finish/Undo/Clear. Enable via the Viewer tab "Draw/sketch tool"
checkbox (off by
default). Measure and Draw are mutually exclusive (activating one
deactivates the other).
0.28.0 - Measure tool (optional)
- New optional viewer tool: a ruler button to measure distance and
area on the map. Click to add
points (live geodesic length), double-click to close a polygon (area).
Shows metric + imperial
units. Enable via the Viewer tab "Measure tool" checkbox (off by
default). Pure offline JS.
0.27.6 - Record MapSplat version in the export log
- The export log now records the plugin version in the run header and
as the first INFO line,
so a saved export.log is self-identifying (matches mapsplat:version in
style.json).
0.27.5 - Don't inject a solid line for marker/hash decorative lines
- Marker lines (symbols placed along a line, e.g. paw prints) and
hash/tick lines can't render as
symbols-on-a-line here. Previously they fell back to a plain solid
line, which muddied the real
line underneath (e.g. a solid underlay beneath the dashed
wandering_cat line). These sublayers
are now omitted so the intended (e.g. dashed) line renders cleanly.
Other unsupported line types
still get a solid colour stand-in.
0.27.4 - Dashed lines for categorized/graduated layers
- Categorized and graduated LINE layers now carry a dash pattern (were
always solid). MapLibre's
line-dasharray is not data-driven, so the layer carries one
representative dash (most common
across the classes); per-class color/width stay fully data-driven.
Uses the same width-correct
normalization as single-symbol lines (0.27.3).
0.27.3 - Dashed line rendering fix
- Dashed lines (e.g. wandering_cat) now render at the correct scale.
MapLibre's line-dasharray is
in units of LINE WIDTH, but the converter emitted absolute pixels, so
dashes came out ~3-4x too
large. Dash lengths are now divided by the line width. Qt preset pen
styles (dash/dot/dash-dot)
are also converted (were previously ignored -> rendered solid).
0.27.2 - Vertical legend layout
- Per-class legend entries now stack vertically BELOW their layer row
instead of floating to the
right (which stretched the legend wide). The legend panel is
width-capped and scrolls vertically.
0.27.1 - Marker legend classes always show
- Per-class marker icons now appear in the legend even when the
'advanced legend' option is off
(a marker layer's classes are essential to reading it). The
advanced-legend toggle still gates
the colour-inferred per-class breakdowns for fills/lines.
0.27.0 - Legend: per-class icons, QGIS groups, collapsing
- The legend now shows the real per-class SVG marker icon + label for
categorized marker
layers (was: no icon / a plain circle).
- QGIS layer-tree groups (e.g. 'My Layers') render as collapsible
sections, collapsed by default.
- Layers with more than 6 classes collapse their class list behind an
'N classes' toggle.
0.26.0 - Dual basemap+business sprites, serve.py startup banner
- Basemap + business icons now coexist: when the basemap ships its own
sprite, MapSplat
combines both via a MapLibre sprite ARRAY (business icons namespaced
'mapsplat:'), so
basemap shields/POIs AND your SVG markers render (was: business sprite
replaced the basemap's).
- serve.py prints a startup banner: the folder it's serving, project
name, MapSplat version,
layer/data-source summary, and a big warning if the folder is in the
Trash (stale export).
- The export style now records mapsplat:version / mapsplat:project in
metadata.
0.25.0 - Categorized SVG markers + MapLibre 5 sprite fix
- Categorized point layers with SVG markers now render each class's
real marker (via a
per-class sprite icon + data-driven icon-image), instead of falling
back to plain circles.
- Fixed: MapLibre GL JS 5 rejects a relative sprite URL, so ALL sprite
icons (including
single-symbol SVG markers) silently failed to load. The viewer now
resolves the sprite URL
to absolute at runtime. Class symbols are rendered crash-safely (no
symbolPreviewPixmap).
0.24.2 - serve.py no-cache (fixes stale re-exports)
- serve.py now sends no-store/no-cache headers so re-exporting a map
always shows the fresh
result. Browsers were caching style.json/index.html/tiles, making a
re-exported layer look
"missing" until a hard refresh. (Verified via headless render: the
data/style were always
correct.)
0.24.1 - Log the style build in the dock
- The Log tab now reports each layer as it's converted (renderer type
→ number of style
layers + label, and the source name), warns when a renderer converts
to 0 layers, and
prints a final "Style built / Final style" summary. Makes "missing
layer" issues visible.
0.24.0 - Sprite icon render fix
- Point layers using an SVG-marker sprite no longer render blank. The
viewer's
styleimagemissing handler was adding an empty placeholder for our own
sprite icons
when MapLibre requested them before the sprite finished loading,
permanently blanking
the marker. It now skips our sprite icons (recorded in style metadata)
so the sprite wins.
0.23.0 - Labels, background override & export robustness
- Label placement now reads the real QGIS 4 settings: the quadrant is
read from
pointSettings() (the old attribute silently defaulted), so labels pin
to QGIS's real
quadrant; 'exact' mode is fixed (no drift), 'auto' avoids overlaps. Y
offset sign fixed.
- New optional Background colour override (Viewer tab + config file);
blank = no change.
- serve.py auto-advances to a free port instead of crashing; layers
with an invalid/unset
CRS are skipped with a clear message instead of exporting to the wrong
place.
0.22.0 - Draw order, hatch angles & robustness
- Categorized polygons now honour QGIS feature draw order (order-by),
so overlapping
polygons stack the same as in QGIS (e.g. a big "bounds" polygon stays
in the back).
- Hatch line angle now matches QGIS (was mirrored); stacked line
patterns render as a
real crosshatch. Background colour is an optional override (default:
no change).
- Robustness: layers that fail to tile no longer leave a dangling
source reference, and
any orphan layer is pruned, so one bad reference can't blank the whole
map.
0.21.0 - Real hatch/pattern fills
- QGIS hatch fills (LinePatternFill) now render as actual MapLibre
fill-pattern hatching,
not just a flat alpha. Tileable hatch PNGs are generated at export
time (angle/spacing/
width/colour from the QGIS symbol) and loaded in the viewer via
styleimagemissing.
- Each hatched category gets its own filtered fill-pattern layer over
a semi-transparent
solid fallback, so a failed image load degrades gracefully instead of
blanking.
0.20.0 - Symbology fidelity fixes
- Categorized polygons/lines/points now render EVERY class (classes
whose bottom symbol layer
was a hatch/gradient were being dropped to invisible). Solid colours
are sampled from the
top-most visible fill layer, not just layer 0 (fixes wrong colours on
stacked symbols).
- Graduated renderers hardened the same way (no more dropped
interpolate stops).
- QGIS "Hairline" strokes now render as a 1px outline instead of
nothing.
- Full history:
https://github.com/johnzastrow/mapsplat4/blob/main/docs/CHANGELOG.md
0.13.1 - Security, packaging & licensing
- Passes Bandit (0 high/medium), detect-secrets, and flake8
(plugins.qgis.org gates)
- Removed the bundled go-pmtiles binary from the repo/zip; QGIS
forbids binaries. Core export
uses GDAL's PMTiles driver. The pmtiles CLI (offline-basemap mode
only) is installed by the user.
- Correct LICENSE (GPL-2.0-or-later; the old file was go-pmtiles'
BSD); no longer experimental
- Reliable self-verifying build (scripts/build_plugin.sh); dropped
dead compiled resources
- Full history:
https://github.com/johnzastrow/mapsplat4/blob/main/docs/CHANGELOG.md
yes
waterlover
2026-07-14T19:36:58.039204+00:00
4.0.0
4.99.0
no
Plugin Tags