How to use OpenMapTiles server for MapBox GL JS?

4.1k views Asked by At

In OpenMapTiles' docs it is said, that it can serve vector tiles for MapBox GL JS.

But digging docs for both projects I didn't find an option: how to configure self-hosted MapBox GL JS library to use tiles from my self-hosted OpenMapTiles server?

3

There are 3 answers

2
Craig  Hicks On BEST ANSWER

I was also use able to successfully use Klokantech's tileserver-gl

However, I really wanted something even more minimalist than that. Something smaller and more suited to my low intelligence.

As it happens there is an MBTiles module in npm. That made setting up a node tileserver very easy. I explain it in a blog here and here. They are both the same blog.

Here is the js code for the server (borrowed in part from this Git GIST by manuelroth). I recommend reading the above blog (here and here) which shows a minimalist example combining display and server sides. (There are a few gotchas which can be avoided by looking at the example).

var express = require("express"),
    app = express(),
    MBTiles = require('mbtiles'),
    p = require("path");


// Enable CORS and set correct mime type/content encoding
var header = {
  "Access-Control-Allow-Origin":"*",
  "Access-Control-Allow-Headers":"Origin, X-Requested-With, Content-Type, Accept",
  "Content-Type":"application/x-protobuf",
  "Content-Encoding":"gzip"
};

// Serve the fonts as static files
//app.use('/fonts', express.static('fonts'))
app.use('/fonts', express.static('fonts', {
    setHeaders: function setHeaders(res, path, stat) {
        res.header('Access-Control-Allow-Origin', '*');
        res.header('Access-Control-Allow-Methods', 'GET');
        res.header('Access-Control-Allow-Headers', 'Content-Type');
    }
}))

app.use('/sprite', express.static('sprite', {
    setHeaders: function setHeaders(res, path, stat) {
        res.header('Access-Control-Allow-Origin', '*');
        res.header('Access-Control-Allow-Methods', 'GET');
        res.header('Access-Control-Allow-Headers', 'Content-Type');
    }
}))


// Route which handles requests like the following: /<mbtiles-name>/0/1/2.pbf
app.get('/:source/:z/:x/:y.pbf', function(req, res) {
    console.log('req.params.source : ' + req.params.source)
    console.log('MBTiles file : ' +  p.join(__dirname, req.params.source + '.mbtiles'))
    console.log(req.params.z + '/' + req.params.x + '/' + req.params.y)
  new MBTiles(p.join(__dirname, req.params.source + '.mbtiles'), function(err, mbtiles) {
    mbtiles.getTile(req.params.z, req.params.x, req.params.y, function(err, tile, headers) {
      if (err) {
        res.set({"Content-Type": "text/plain"});
        res.status(404).send('Tile rendering error: ' + err + '\n');
      } else {
        res.set(header);
        res.send(tile);
      }
    });
    if (err) console.log("error opening database");
  });
});

// Starts up the server on port 3000
console.log('__dirname : ' + __dirname)
console.log('command line args:')
process.argv.forEach(function (val, index, array) {
  console.log(index + ': ' + val);
});
console.log('Listening on port: ' + 3000);
app.listen(3000);
0
AudioBubble On

You can use mapbox-gl-js server offline example that has a good example to do this.

0
MapTiler On

If you install https://openmaptiles.com/server/ you will get a self-hosted vector tile maps with all assets including a local copy of Mapbox GL JS.

If you click on the "Viewer" button next to the style you get a sample viewer - running even without an internet connection - using the local vector tiles, local assets and local JavaScript.

This is the place to start to develop your application.