Search code examples
javascripthtmlofflinemaplibre-gl

maplibre-gl-js : load offline (local) glyphs, sprites and mbtiles - HTML website


I'm currently coding a simple HTML page with embedded Javascript to visualise a local mbtiles, including local glyphs and sprites.

The html index.html is :

...
<script src="https://unpkg.com/[email protected]/dist/maplibre-gl.js"></script>
<link href="https://unpkg.com/[email protected]/dist/maplibre-gl.css" rel="stylesheet" />
...
<body>
<div id="map"></div>
</body>
<script type="module" src="./index.js" async defer></script>

The javascript index.js is :

var map = new maplibregl.Map({
    container: 'map',
    style:
        'styles/style.json',
    center: [174.746344, -36.8899343],
    zoom: 11.15
});

and the goal is to load a style.json file that would define the mbtiles, sprites and glyphs local location.

I'm currently using the OSM Bright style, copied over locally on my machine, within the style.json file and the goal is to swap any connection to remote files by local files:

glyphs

"glyphs": "./glyphs/{fontstack}/{range}.pbf",

It works well for the glyphs

sprites

"sprite": "./sprites/sprite",

I have the following error : Unable to parse URL "./sprites/sprite"

mbtiles

"sources": {
    "openmaptiles": {
      "type": "vector",
      "url": "./mbtiles/country.mbtiles"
    }
  },

I got the following error : Error: Unexpected token 'S', "SQLite for"... is not valid JSON

I'm definitely missing some protocols here, and I can't find any answer to my question so far, knowing :

asset://sprites/sprite
or
mbtiles://country.mbtiles

but that doesn't work (neither for the glyphs, but it doesn't look like it's necessary any way)

  • this Load local .mbtiles with maplibre-gl-js looks like the closest to my need, but again the answer focus on application and not html, plus the question has not yet been fully resolved neither

So any help would be appreciated, especially I would be interested to know if this is even possible with the maplibre-gl.js library that I'm using as this might just not be possible. If that's the case, I would appreciate a similar answer with mapbox-gl.js if necessary, but still using local (offline) files.

In other words the main objective is to run a website (not an app) with maplibre (not mapbox - at least if possible) and only including local files.

Thanks for any feedback.


Solution

  • I know it's may be late, but nevertheless:
    mbtiles:// protocol only works with maplibre-gl not with maplibre-gl-js as I know.
    So I used pbf files. You can get them from mbtiles file with mbutil or from osm.pbf file with tilemaker.
    Before converting from osm.pbf with tilemaker you should modify field "compress" to "none" in config-openmaptiles.json, or map won't be rendered.

    For me only "glyphs" worked with relative path, but "sprite" and "tiles" with full path, like http://... (But I only tried python3 embedded http.server and uvicorn) This is my excerpt from style.json:

      "sources": {
        "openmaptiles": {
          "type": "vector",
          "tiles": ["http://localhost:8000/data/tiles/{z}/{x}/{y}.pbf"],
          "minzoom": 0,
          "maxzoom": 14
        }
      },
      "sprite": "http://localhost:8000/data/sprites/bright-v8",
      "glyphs": "data/glyphs/{fontstack}/{range}.pbf",
    

    "tiles" path should be in square brackets and you should provide "maxzoom" of your map (14 is a default for many maps, as I know) if you want overzoom to work.