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