Piastrelle vettoriali Mapbox self-hosting


81

Come presentato in un discorso a FOSS4G Mapbox Studio consente di creare riquadri vettoriali Mapbox ed esportarli come .mbtilesfile.

La libreria mapbox-gl.js può essere utilizzata per lo stile dinamico e il rendering dei riquadri vettoriali di Mapbox sul lato client (browser).

La parte mancante: Come posso ospitare autonomamente i riquadri vettoriali di Mapbox ( .mbtiles) in modo da poterli utilizzare con mapbox-gl.js?

So che Mapbox Studio può caricare i riquadri vettoriali sul server Mapbox e lasciarlo ospitare. Ma questa non è un'opzione per me, voglio ospitare i riquadri vettoriali sul mio server.


L'approccio TileStream di seguito si è rivelato essere un vicolo cieco. Vedi la mia risposta per una soluzione funzionante con Tilelive.


Ho provato TileStream che può servire da riquadri di immagini a .mbtilesfile:

La mia pagina web utilizza 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>

e crea un mapboxgl.Map in uno script JavaScript:

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

Il c.jsonfile di stile configura l'origine del riquadro vettoriale:

{
  "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"
    }
  }]
}

... con la seguente specifica TileJSON in tile.json:

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

... che punta al mio server TileStream in esecuzione su localhost:8888. TileStream è stato avviato con:

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

... dove la ..\tilescartella contiene il mio osm_roads.mbtilesfile.

Con questa configurazione, posso aprire la mia pagina web ma vedere solo il livello di sfondo. Nella traccia della rete del browser posso vedere che i riquadri vengono effettivamente caricati quando ingrandisco, ma la console degli errori JavaScript del browser contiene diversi errori del modulo

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

Poiché le tessere vettoriali non sono .pngimmagini ma piuttosto file ProtoBuf, l'URL delle tessere http://localhost:8888/v2/osm_roads/{z}/{x}/{y}.pbfavrebbe effettivamente più senso, ma non funziona.

Qualche idea?

Risposte:


53

Come sottolineato da @Greg, invece di TileStream (il mio primo tentativo) dovresti usare Tilelive per ospitare le tue tessere vettoriali.

Tilelive non è un server in sé ma un framework back-end che si occupa di tessere in formati diversi da fonti diverse. Ma è basato su Node.js, quindi puoi trasformarlo in un server in modo abbastanza diretto. Per leggere i .mbtilesriquadri da una fonte esportata da Mapbox Studio, è necessario il modulo tilelive node-mbtiles .

Nota a margine: Current Mapbox Studio presenta un bug in Windows e OS X che impedisce la visualizzazione di un .mbtilesfile esportato nella destinazione scelta. Soluzione alternativa: basta prendere l'ultimo export-xxxxxxxx.mbtilesfile in ~/.mapbox-studio/cache.

Ho trovato due implementazioni di server ( ten20 tile server di alexbirkett e TileServer di hanchao ) che utilizzano Express.js come server di app Web.

Ecco il mio approccio minimalista che è vagamente basato su queste implementazioni:

  1. Installa Node.js
  2. Prendi i pacchetti di nodi con npm install tilelive mbtiles express
  3. Implementare il server nel file 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'));
        });
    });

    Nota: le Access-Control-Allow-...intestazioni consentono la condivisione delle risorse tra le origini (CORS) in modo che le pagine Web servite da un server diverso possano accedere ai riquadri.

  4. Eseguilo con node server.js

  5. Imposta la pagina web usando Mapbox GL JS in 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. Indica la posizione della sorgente delle tessere e dai uno stile ai livelli con quanto segue 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. Servi la pagina web e rallegrati.


2
si noti che è necessario tre ///per definire il file mbtiles in:tilelive.load('mbtiles://path/to/osm_roads.mbtiles', function(err, source) {
CDavis

@cdavis: sembra dipendere dal sistema operativo: tre ///sono necessari per Linux e OS X come ad es mbtiles:///usr/local/osm_roads.mbtiles. Su Windows, tuttavia, //sono necessari solo due se si specifica il disco come ad es mbtiles://D/data/osm_roads.mbtiles.
Andreas Bilger,

Davvero utile, grazie mille, mi ha aiutato a servire mbtiles vettoriali in 5 '!
Bwyss,

Ciao Andreas - non sono riuscito a far funzionare tutto questo - la mappa viene visualizzata, ma è solo un grande quadrato grigio bianco. Non sono sicuro di dove hai preso la tua fonte di mbtiles. Ho provato ad esportare alcuni dei mbtiles predefiniti dal tilemill.
mheavers,

sembra che tu usi localhost: 7777 / v2 / tiles / per l'ubicazione delle tue tessere, ma dove stai prendendo quel percorso? O cosa devi fare per assicurarti che il file mbtiles esportato serva le immagini su quel percorso?
mheavers,

26

L'hosting delle tessere vettoriali da solo è relativamente semplice. I MBTiles contengono file .pbf che devono essere esposti al web. Questo è tutto.

Probabilmente il più semplice è usare un semplice server open source come TileServer-PHP e mettere il file MBTiles nella stessa cartella dei file di progetto. TileServer esegue tutte le configurazioni di hosting per te (CORS, TileJSON, intestazioni gzip corrette, ecc.). Installazione significa solo decomprimere su un server web abilitato per PHP.

Se vuoi avviare TileServer-PHP sul tuo laptop puoi farlo con Docker. Il contenitore pronto per l'uso è su DockerHub . Sotto Mac OS X e Windows funziona in un paio di minuti con l'interfaccia utente grafica di Kitematic: https://kitematic.com/ . In Kitematic basta cercare "tileserver-php" e avviare il container / macchina virtuale pronto all'uso con il progetto all'interno. Quindi fare clic su "Volumi" e rilasciare nella cartella il file MBTiles. Ottieni un hosting funzionante per le tue tessere vettoriali!

Tali riquadri vettoriali possono essere aperti in MapBox Studio come sorgente o visualizzati con il visualizzatore WebGL di MapBox GL JS.

Tecnicamente è anche possibile ospitare i riquadri vettoriali come una semplice cartella su qualsiasi server Web o archivio cloud, o anche GitHub, se si decomprime il singolo .pbf dal contenitore MBtiles con un'utilità come mbutil , impostare CORS, TileJSON e gzip correttamente. Bellow è un progetto GitHub che dimostra anche questo approccio.

Prova questo visualizzatore: Visualizzatore MapBox GL JS

e vedere i repository correlati:


1
Questa è stata di gran lunga la più semplice di tutte le opzioni sopra per me, grazie per la pubblicazione.
dal

PGRestAPI, suona alla grande, ma l'installazione non è riuscita per me. Non sarò mai in grado di installare con successo PGRestAPI. Quindi questo server php è la mia unica scelta e funziona perfettamente.
Hoogw,

Questo è molto interessante, potresti approfondire come impostare CORS e TileJSON correttamente per servire i file pbf? Ho scaricato un file pbf da download.geofabrik.de/europe, tuttavia il progetto collegato contiene molte directory con molti file pbf.
php_nub_qq

12

Non per suonare il mio corno, ma https://github.com/spatialdev/PGRestAPI è un progetto su cui ho lavorato che ospita le esportazioni di piastrelle vettoriali .mbtiles da Mapbox Studio.

Serve ancora molta documentazione, ma fondamentalmente, rilascia i tuoi file .mbtiles in / data / pbf_mbtiles e riavvia l'app nodo. Leggerà attraverso quella cartella e offrirà endpoint per i tuoi riquadri vettoriali.

Guarderà anche attraverso / data / shapefile e creerà al volo piastrelle dinamiche di Mapbox Vector basate sul tuo .shp. Puoi anche puntare a un'istanza PostGIS e ottenere riquadri vettoriali dinamici.

Li usiamo insieme a https://github.com/SpatialServer/Leaflet.MapboxVectorTile , una libreria di riquadri Vector Leaflet / Mapbox su cui stiamo lavorando.


1
Sfortunatamente PGRestAPI non viene più sviluppato attivamente
Raffaello,

10

Grazie per l'ottima domanda. Non sapevo che avevano finalmente rilasciato una versione stabile delle tessere vettoriali. Inoltre, potresti dover lavorare con questa risposta in quanto è una fonte di idee per le tue "idee?" domanda. Non ho ancora uno studio in esecuzione.

Penso che uno dei problemi in cui ti imbatti sia che stai usando un file tilejson. È necessario un servizio tilejson per utilizzare quel tipo di file. Pertanto, ritengo che sia necessario modificare la sezione delle fonti in un URL in linea. Provare

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

o

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

Quando usano mapbox://come protocollo, è una notazione alias / stenografia per i loro servizi. La sezione delle fonti è stata brevemente discussa intorno alle 8:40 del video.

Un passaggio del nuovo processo di affiancamento vettoriale consiste nel curare i dati vettoriali regolando ciò che si desidera nei dati. L'altro passaggio è riportare i dati vettoriali in MapBox Studio e renderizzare i dati / creare un foglio di stile. osm_roads sarebbe il primo passo mentre il tuo file c.json è il foglio di stile. Potrebbe essere necessario un server live di riquadri rispetto a un flusso di riquadri, come discusso alle 15:01 del video. Il video dice che hai bisogno di ulteriori metadati nel file xml.

La stranezza qui è che fai riferimento al .pbf e al foglio di stile altrove, ma l'URL che fornisci è il risultante file .png delle piastrelle che viene generato dai dati vettoriali.

Non dici, se hai una chiave MapBox. Per il tuo hosting, credo che dovrai copiare gli stili e glifi github sul tuo server. Notare ancora che c'è un protocollo mapbox: // nel tag glyphs. Questi due tag potrebbero non essere necessari perché stai visualizzando linee semplici e poligoni e non PDI tramite icone. Vale la pena dare un'occhiata.

Infine, il video dice che puoi riportare in studio un livello vettoriale generato per modellarlo. Potresti voler fare riferimento al tuo livello vettoriale e applicare prima lo stile id: background e id: roads nello studio. Il video dice che il live tile è il server dietro la scena di MapBox Studio. L'idea qui è di assicurarsi di avere capito e risolto tutti i problemi del passaggio due prima di provare a servire le tessere vettoriali finali che vengono dinamicamente renderizzate.


Ok, grazie @Greg per le tue idee. Investigherà ulteriormente e tornerà con le mie scoperte.
Andreas Bilger,



1

Super più tardi, ma ora GeoServer serve pbf (formato a tessere vettoriali)


0

Altre opzioni che puoi prendere in considerazione per servire le tessere;

Tegola (Written in Go)

Tiler

C'è una bella introduzione a questo argomento qui

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.