Tuiles vectorielles auto-hébergées Mapbox


81

Comme présenté lors d'une conférence à FOSS4G, Mapbox Studio permet de créer des tuiles vectorielles Mapbox et de les exporter sous forme de .mbtilesfichier.

La bibliothèque mapbox-gl.js peut être utilisée pour styler et restituer dynamiquement des tuiles vectorielles Mapbox côté client (navigateur).

La partie manquante: Comment puis-je auto-héberger des tuiles vectorielles Mapbox ( .mbtiles) afin de pouvoir les consommer avec mapbox-gl.js?

Je sais que Mapbox Studio peut télécharger les tuiles vectorielles sur le serveur Mapbox et le laisser héberger les tuiles. Mais ce n'est pas une option pour moi, je veux héberger les tuiles vectorielles sur mon propre serveur.


L’approche TileStream ci-dessous s’est révélée être une impasse. Voir ma réponse pour une solution de travail avec Tilelive.


J'ai essayé TileStream, qui peut servir de mosaïques d'images à partir de .mbtilesfichiers:

Ma page Web utilise mapbox-gl v0.4.0:

<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.4.0/mapbox-gl.css' rel='stylesheet' />
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.4.0/mapbox-gl.js'></script>

et il crée une mapboxgl.Map dans un script JavaScript:

  var map = new mapboxgl.Map({
    container: 'map',
    center: [46.8104, 8.2452],
    zoom: 9,
    style: 'c.json'
  });

Le c.jsonfichier de style configure la source de tuiles vectorielles:

{
  "version": 6,
  "sprite": "https://www.mapbox.com/mapbox-gl-styles/sprites/bright",
  "glyphs": "mapbox://fontstack/{fontstack}/{range}.pbf",
  "constants": {
    "@land": "#808080",
    "@earth": "#805040",
    "@water": "#a0c8f0",
    "@road": "#000000"
  },
  "sources": {
    "osm_roads": {
      "type": "vector",
      "url": "tile.json"
    }
  },
  "layers": [{
    "id": "background",
    "type": "background",
    "paint": {
      "background-color": "@land"
    }
  }, {
    "id": "roads",
    "type": "line",
    "source": "osm_roads",
    "source-layer": "roads",
    "paint": {
      "line-color": "@road"
    }
  }]
}

... avec la spécification TileJSON suivante dans tile.json:

{
  "tilejson": "2.1.0",
  "tiles": [
    "http://localhost:8888/v2/osm_roads/{z}/{x}/{y}.png"
  ],
  "minzoom": 0,
  "maxzoom": 12
}

... qui pointe vers mon serveur TileStream en cours d'exécution localhost:8888. TileStream a été lancé avec:

node index.js start --tiles="..\tiles"

... où le ..\tilesdossier contient mon osm_roads.mbtilesfichier.

Avec cette configuration, je peux ouvrir ma page Web mais ne voir que la couche d’arrière-plan. Dans la trace réseau du navigateur, je constate que les vignettes sont bien chargées lorsque je fais un zoom avant, mais la console d’erreur JavaScript du navigateur contient plusieurs erreurs de la forme.

Error: Invalid UTF-8 codepoint: 160      in mapbox-gl.js:7

Comme les tuiles vectorielles ne sont pas des .pngimages mais plutôt des fichiers ProtoBuf, l'URL des tuiles http://localhost:8888/v2/osm_roads/{z}/{x}/{y}.pbfaurait plus de sens, mais cela ne fonctionne pas.

Des idées?

Réponses:


53

Comme l'a souligné @Greg, au lieu de TileStream (ma première tentative), vous devez utiliser Tilelive pour héberger vos propres tuiles vectorielles.

Tilelive n'est pas un serveur en soi, mais un framework backend qui traite des tuiles dans différents formats et de différentes sources. Mais comme il est basé sur Node.js , vous pouvez le transformer en serveur de manière assez simple. Pour lire les vignettes à partir d'une .mbtilessource exportée par Mapbox Studio, vous avez besoin du module node-mbtiles tilelive.

Remarque secondaire: Sous Windows et OS X, Mapbox Studio actuel contient un bogue qui empêche l’affichage du .mbtilesfichier exporté à la destination choisie. Solution: il suffit de récupérer le dernier export-xxxxxxxx.mbtilesfichier dans ~/.mapbox-studio/cache.

J'ai trouvé deux implémentations de serveur ( serveur de tuiles Ten20 de alexbirkett et TileServer de hanchao ) qui utilisent Express.js en tant que serveur d'applications Web.

Voici mon approche minimaliste basée sur ces implémentations:

  1. Installez Node.js
  2. Prenez les paquets de noeuds avec npm install tilelive mbtiles express
  3. Implémentez le serveur dans le fichier server.js:

    var express = require('express');
    var http = require('http');
    var app = express();
    var tilelive = require('tilelive');
    require('mbtiles').registerProtocols(tilelive);
    
    //Depending on the OS the path might need to be 'mbtiles:///' on OS X and linux
    tilelive.load('mbtiles://path/to/osm_roads.mbtiles', function(err, source) {
    
        if (err) {
            throw err;
        }
        app.set('port', 7777);
    
        app.use(function(req, res, next) {
            res.header("Access-Control-Allow-Origin", "*");
            res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
            next();
        });
    
        app.get(/^\/v2\/tiles\/(\d+)\/(\d+)\/(\d+).pbf$/, function(req, res){
    
            var z = req.params[0];
            var x = req.params[1];
            var y = req.params[2];
    
            console.log('get tile %d, %d, %d', z, x, y);
    
            source.getTile(z, x, y, function(err, tile, headers) {
                if (err) {
                    res.status(404)
                    res.send(err.message);
                    console.log(err.message);
                } else {
                  res.set(headers);
                  res.send(tile);
                }
            });
        });
    
        http.createServer(app).listen(app.get('port'), function() {
            console.log('Express server listening on port ' + app.get('port'));
        });
    });

    Remarque: Les en- Access-Control-Allow-...têtes permettent le partage de ressources d'origine croisée (CORS) afin que les pages Web servies à partir d'un serveur différent puissent accéder aux mosaïques.

  4. Le courir avec node server.js

  5. Configurez la page Web à l'aide de Mapbox GL JS dans minimal.html:

    <!DOCTYPE html >
    <html>
      <head>
        <meta charset='UTF-8'/>
        <title>Mapbox GL JS rendering my own tiles</title>
        <link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.4.0/mapbox-gl.css' rel='stylesheet' />
        <script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.4.0/mapbox-gl.js'></script>
        <style>
          body { margin:0; padding:0 }
          #map { position:absolute; top:0; bottom:50px; width:100%; }
        </style>
      </head>
      <body>
        <div id='map'>
        </div>
        <script>
          var map = new mapboxgl.Map({
            container: 'map',
            center: [46.8, 8.5],
            zoom: 7,
            style: 'minimal.json'
          });
        </script>
      </body>
    </html>
  6. Indiquez l'emplacement de la source de mosaïque et dressez les styles avec les styles suivants minimal.json:

    {
      "version": 6,
      "constants": {
        "@background": "#808080",
        "@road": "#000000"
      },
      "sources": {
        "osm_roads": {
          "type": "vector",
          "tiles": [
            "http://localhost:7777/v2/tiles/{z}/{x}/{y}.pbf"
          ],
          "minzoom": 0,
          "maxzoom": 12
        }
      },
      "layers": [{
        "id": "background",
        "type": "background",
        "paint": {
          "background-color": "@background"
        }
      }, {
        "id": "roads",
        "type": "line",
        "source": "osm_roads",
        "source-layer": "roads",
        "paint": {
          "line-color": "@road"
        }
      }]
    }
  7. Servez la page Web et réjouissez-vous.


2
notez qu'il vous faut trois ///pour définir le fichier mbtiles dans:tilelive.load('mbtiles://path/to/osm_roads.mbtiles', function(err, source) {
CDavis

@cdavis: Cela semble dépendre du système d'exploitation. Trois ///sont nécessaires pour Linux et OS X, comme par exemple mbtiles:///usr/local/osm_roads.mbtiles. Sous Windows, cependant, deux seulement //sont nécessaires si vous spécifiez le disque, par exemple mbtiles://D/data/osm_roads.mbtiles.
Andreas Bilger

Vraiment serviable, merci beaucoup, m'a aidé à servir des mbtiles vectoriels en 5 '!
Bwyss

Bonjour Andreas - Je n'ai pas réussi à faire fonctionner cela - la carte s'affiche, mais il ne s'agit que d'un grand carré gris. Je ne sais pas où vous avez trouvé votre source de mbtiles. J'ai essayé d'exporter certains des mbtiles par défaut de tilemill.
Mheavers

vous semblez utiliser localhost: 7777 / v2 / tiles / pour l'emplacement de vos tuiles, mais où obtenez-vous ce chemin? Ou que devez-vous faire pour vous assurer que le fichier mbtiles exporté sert les images à ce chemin?
Mheavers

26

L'hébergement des tuiles vectorielles vous-même est relativement simple. Les MBTiles contiennent des fichiers .pbf qui doivent être exposés au Web. C'est ça.

Le plus simple est probablement d'utiliser un serveur open-source simple tel que TileServer-PHP et de placer le fichier MBTiles dans le même dossier que les fichiers de projet. Le TileServer fait toute la configuration d’hébergement pour vous (CORS, TileJSON, en-têtes gzip corrects, etc.). L’installation signifie simplement décompresser sur un serveur Web compatible PHP.

Si vous voulez démarrer le TileServer-PHP sur votre ordinateur portable, vous pouvez avec Docker. Le conteneur prêt à l'emploi est sur DockerHub . Sous Mac OS X et Windows, il s'exécute en quelques minutes avec l'interface graphique de Kitematic: https://kitematic.com/ . Dans Kitematic, recherchez simplement "tileserver-php" et démarrez le conteneur / la machine virtuelle prêt à être utilisé avec le projet à l'intérieur. Cliquez ensuite sur "Volumes" et déposez dans le dossier votre fichier MBTiles. Vous obtenez un hébergement en cours d'exécution pour vos tuiles vectorielles!

Ces mosaïques vectoriels peuvent être ouverts dans MapBox Studio en tant que source ou affichés avec le visualiseur MapBox GL JS WebGL.

Techniquement, il est même possible d’héberger les tuiles vectorielles sous forme de dossier ordinaire sur n’importe quel serveur Web ou stockage en nuage, ou même avec GitHub, si vous décompressez le fichier .pbf individuel du conteneur MBtiles avec un utilitaire tel que mbutil , définissez CORS, TileJSON. et gzip correctement. Bellow est un projet GitHub démontrant cette approche.

Essayez cette visionneuse: Visualiseur MapBox GL JS

et voir les pensions associées:


1
C'était de loin la plus facile de toutes les options ci-dessus pour moi, merci d'avoir posté.
Mheavers

PGRestAPI, ça sonne bien, mais l’installation a échoué pour moi. Je ne pourrai jamais installer PGRestAPI avec succès. Donc, ce serveur de tuiles php est mon seul choix et cela fonctionne parfaitement.
Hoogw

C’est très intéressant. Pourriez-vous préciser comment configurer CORS et TileJSON correctement pour servir les fichiers pbf? J'ai téléchargé un fichier pbf depuis download.geofabrik.de/europe, mais le projet lié contient de nombreux répertoires contenant de nombreux fichiers pbf.
php_nub_qq

12

Je ne travaille pas pour rien , mais https://github.com/spatialdev/PGRestAPI est un projet sur lequel je travaille et qui héberge des exportations de tuiles vectorielles .mbtiles à partir de Mapbox Studio.

Vous avez encore besoin de beaucoup de documentation, mais en gros, déposez vos fichiers .mbtiles dans / data / pbf_mbtiles et redémarrez l'application de nœud. Il lira ce dossier et proposera des points de terminaison pour vos tuiles vectorielles.

Il recherchera également dans / data / shapefiles et créera des tuiles vectorielles dynamiques Mapbox à la volée en fonction de votre .shp. Vous pouvez également pointer sur une instance PostGIS et obtenir des tuiles vectorielles dynamiques.

Nous les utilisons conjointement avec https://github.com/SpatialServer/Leaflet.MapboxVectorTile , une bibliothèque de tuiles Leaflet / Mapbox sur laquelle nous avons également travaillé.


1
Malheureusement, PGRestAPI n'est plus activement développé
raphael le

10

Merci pour la bonne question. Je ne savais pas qu'ils avaient finalement publié une version stable des tuiles vectorielles. De plus, vous devrez peut-être travailler avec cette réponse car elle est une source d’idées pour vos "idées?" question. Je n'ai pas encore de studio en cours d'exécution.

Je pense que l’un des problèmes que vous rencontrez est que vous utilisez un fichier tilejson. Vous avez besoin d’un service tilejson pour utiliser ce type de fichier. Par conséquent, je pense que vous devez modifier votre section sources en une URL en ligne. Essayer

"sources": {
"osm_roads": {
  "type": "vector",
  "url": "http://localhost:8888/v2/osm_roads/{z}/{x}/{y}.png"
 }
},

ou

"sources": { 
"osm_orads": {
  "type": "vector",
  "tiles": [
    "http://localhost:8888/v2/osm_roads/{z}/{x}/{y}.png"
  ],
  "minzoom": 0,
  "maxzoom": 12
 }
},

Quand ils utilisent mapbox://comme protocole, c'est une notation alias / raccourci pour leurs services. La section sources a été brièvement discutée autour de 8h40 de la vidéo.

L'une des étapes du nouveau processus de mosaïque de vecteur consiste à gérer les données vectorielles en ajustant ce que vous voulez dans les données. L'autre étape consiste à ramener les données vectorielles dans MapBox Studio et à restituer les données / créer une feuille de style. osm_roads serait la première étape, tandis que votre fichier c.json serait la feuille de style. Vous aurez peut-être besoin d'un serveur de tuiles en direct vers un flux de tuiles, comme indiqué à 15:01 de la vidéo. La vidéo indique que vous avez besoin de métadonnées supplémentaires dans le fichier XML.

La bizarrerie ici est que vous référencez le .pbf et la feuille de style ailleurs, mais l’url que vous fournissez correspond aux fichiers .png de mosaïques obtenus, générés à partir des données vectorielles.

Vous ne dites pas, si vous avez une clé MapBox. Pour votre propre hébergement, je pense que vous devrez copier les styles et les glyphes de github sur votre propre serveur. Notez à nouveau qu’il existe un protocole mapbox: // dans la balise glyphs. Ces deux balises peuvent ne pas être nécessaires car vous restituez des lignes et des polygones simples et non des points d'intérêt via des icônes. Cela vaut la peine de jeter un coup d'œil.

Enfin, la vidéo indique que vous pouvez ramener un calque vectoriel généré dans le studio pour le styler. Vous voudrez peut-être référencer votre calque vectoriel et appliquer d'abord votre style id: background et id: roads dans le studio. La vidéo indique que tile live est le serveur derrière la scène de MapBox Studio. L'idée ici est de vous assurer que tous les problèmes de l'étape deux sont compris et résolus avant d'essayer de servir les dernières tuiles vectorielles rendues de manière dynamique.


Ok, merci @Greg pour vos idées. Fera une enquête plus approfondie et reviendra avec mes conclusions.
Andreas Bilger

4

https://github.com/osm2vectortiles/tileserver-gl-light est beaucoup plus facile à utiliser que les solutions principales mentionnées - vous n'avez pas besoin de jouer avec les fichiers JSON. Vous venez de l'exécuter avec

tileserver-gl-light filename.mbtiles

et puis il sert les carreaux pour vous. Cela fonctionne avec les styles prédéfinis Mapbox GL tels que bright-v9; après avoir exécuté le serveur, il vous suffit de pointer tout ce qui consomme les tuiles à

http: // localhost: 8080 / styles / bright-v9.json


3

Vous voudrez peut-être essayer notre serveur tilehut.js. Il fait fondamentalement tout ce dont vous avez besoin = hébergement de tuiles vectorielles et vient avec de jolis exemples / documents ... et est combiné avec openshift, il s’agit d’une installation de 5 minutes. Jetez un coup d'oeil s'il vous plait:

https://github.com/bg/tilehut https://github.com/bg/tilehut/tree/master/examples/simplemap_vector https://github.com/bg/tilehut#your-own-own-hosted-tileserver- dans 5 minutes


1

Super plus tard, mais maintenant GeoServer sert pbf (format de tuile vectorielle)


En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.