Selbsthosting von Mapbox-Vektorkacheln

81

Wie in einem Vortrag auf der FOSS4G vorgestellt, können mit Mapbox Studio Mapbox-Vektorkacheln erstellt und als .mbtilesDatei exportiert werden.

Mit der Bibliothek mapbox-gl.js können Mapbox-Vektorkacheln auf der Client- (Browser-) Seite dynamisch formatiert und gerendert werden.

Der fehlende Teil: Wie kann ich Mapbox-Vektorkacheln ( .mbtiles) selbst hosten , damit ich sie mit mapbox-gl.js verwenden kann?

Ich weiß, dass Mapbox Studio die Vektorkacheln auf den Mapbox-Server hochladen und die Kacheln hosten kann. Aber das ist für mich keine Option, ich möchte die Vektorkacheln auf meinem eigenen Server hosten.


Der unten stehende TileStream-Ansatz erwies sich als Sackgasse. Siehe meine Antwort für eine funktionierende Lösung mit Tilelive.


Ich habe TileStream ausprobiert , mit dem Bildkacheln aus .mbtilesDateien bereitgestellt werden können :

Meine Webseite benutzt 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>

und es erstellt eine mapboxgl.Map in einem JavaScript-Skript:

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

Die c.jsonStildatei konfiguriert die Quelle der Vektorkacheln:

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

... mit der folgenden TileJSON-Spezifikation in tile.json:

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

... was auf meinen TileStream-Server zeigt, auf dem ausgeführt wird localhost:8888. TileStream wurde gestartet mit:

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

... wo der ..\tilesOrdner meine osm_roads.mbtilesDatei enthält .

Mit diesem Setup kann ich meine Webseite öffnen, aber nur die Hintergrundebene sehen. Im Browser-Netzwerk-Trace kann ich sehen, dass beim Vergrößern zwar Kacheln geladen werden, die JavaScript-Fehlerkonsole des Browsers jedoch mehrere Fehler des Formulars enthält

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

Da Vektorkacheln keine .pngBilder, sondern ProtoBuf-Dateien sind, wäre die Kachel-URL http://localhost:8888/v2/osm_roads/{z}/{x}/{y}.pbfeigentlich sinnvoller, aber das funktioniert nicht.

Irgendwelche Ideen?

Andreas Bilger
quelle

Antworten:

53

Wie von @Greg hervorgehoben, sollten Sie anstelle von TileStream (meinem ersten Versuch) Tilelive verwenden , um Ihre eigenen Vektorkacheln zu hosten.

Tilelive ist kein Server selbst, sondern ein Backend-Framework, das Kacheln in verschiedenen Formaten aus verschiedenen Quellen verarbeitet. Es basiert jedoch auf Node.js, sodass Sie es auf einfache Weise in einen Server verwandeln können. Um Kacheln aus einer .mbtilesvon Mapbox Studio exportierten Quelle zu lesen , benötigen Sie das Modul node-mbtiles tilelive.

Randnotiz: Gegenwärtige Mapbox Studio hat einen Fehler unter Windows und OS X, der verhindert, dass eine exportierte .mbtilesDatei an Ihrem gewählten Ziel angezeigt wird . Problemumgehung: Nehmen Sie einfach die neueste export-xxxxxxxx.mbtilesDatei auf ~/.mapbox-studio/cache.

Ich fand zwei Server - Implementierungen ( Ten20 Kachel - Server von alexbirkett und TileServer von Hanchao ) , die beide verwenden Express.js als Web - App - Server.

Hier ist mein minimalistischer Ansatz, der lose auf diesen Implementierungen basiert:

  1. Installieren Sie Node.js
  2. Greifen Sie nach den Knotenpaketen mit npm install tilelive mbtiles express
  3. Implementieren Sie den Server in der Datei 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'));
        });
    });

    Hinweis: Die Access-Control-Allow-...Header ermöglichen die gemeinsame Nutzung von ursprungsübergreifenden Ressourcen (CORS), sodass Webseiten, die von einem anderen Server bereitgestellt werden, möglicherweise auf die Kacheln zugreifen.

  4. Führen Sie es mit node server.js

  5. Richten Sie die Webseite mit Mapbox GL JS ein 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. Geben Sie die Position der Kachelquelle an und gestalten Sie die Ebenen wie folgt 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. Servieren Sie die Webseite und freuen Sie sich.

Andreas Bilger
quelle
2
Beachten Sie, dass Sie drei benötigen ///, um die mbtiles-Datei zu definieren:tilelive.load('mbtiles://path/to/osm_roads.mbtiles', function(err, source) {
CDavis
@cdavis: Das scheint vom Betriebssystem abzuhängen: Drei ///werden für Linux und OS X benötigt wie zB mbtiles:///usr/local/osm_roads.mbtiles. Unter Windows werden jedoch nur zwei //benötigt, wenn Sie die Festplatte wie z mbtiles://D/data/osm_roads.mbtiles.
Andreas Bilger
Wirklich hilfreich, vielen Dank, hat mir geholfen, vector mbtiles in 5 'zu bedienen!
Bwyss
Hallo Andreas - ich konnte das nicht zum Laufen bringen - die Karte wird angezeigt, aber es ist nur ein großes leeres graues Quadrat. Ich bin nicht sicher, woher Sie Ihre mbtiles-Quelle haben. Ich habe versucht, einige der Standard-MBTiles von Tilemill zu exportieren.
Mheavers
Sie scheinen localhost: 7777 / v2 / tiles / für die Position Ihrer Kacheln zu verwenden, aber woher erhalten Sie diesen Pfad? Oder was müssen Sie tun, um sicherzustellen, dass die exportierte mbtiles-Datei die Bilder auf diesem Pfad liefert?
Mheavers
26

Das Hosting der Vektorkacheln auf eigene Faust ist relativ unkompliziert. Die MBTiles enthalten .pbf-Dateien, die für das Web verfügbar gemacht werden müssen. Das ist es.

Am einfachsten ist es wahrscheinlich, einen einfachen Open-Source-Server wie TileServer-PHP zu verwenden und die MBTiles-Datei im selben Ordner wie die Projektdateien abzulegen. Der TileServer führt die gesamte Hosting-Konfiguration für Sie durch (CORS, TileJSON, korrekte gzip-Header usw.). Installation bedeutet nur das Auspacken auf einem PHP-fähigen Webserver.

Wenn Sie den TileServer-PHP auf Ihrem Laptop starten wollen, können Sie mit Docker. Der gebrauchsfertige Container befindet sich auf DockerHub . Unter Mac OS X und Windows läuft es in wenigen Minuten mit der grafischen Benutzeroberfläche von Kitematic: https://kitematic.com/ . Suchen Sie in Kitematic nach "tileserver-php" und starten Sie den einsatzbereiten Container / die virtuelle Maschine mit dem Projekt darin. Klicken Sie dann auf "Volumes" und legen Sie in dem Ordner Ihre MBTiles-Datei ab. Sie erhalten ein laufendes Hosting für Ihre Vektorkacheln!

Solche Vektorkacheln können in MapBox Studio als Quelle geöffnet oder mit MapBox GL JS WebGL Viewer angezeigt werden.

Technisch ist es sogar möglich, die Vektorkacheln als einfachen Ordner auf einem beliebigen Webserver oder Cloud-Speicher oder sogar in GitHub zu hosten, wenn Sie die einzelne .pbf-Datei mit einem Dienstprogramm wie mbutil aus dem MBtiles-Container entpacken und CORS, TileJSON, festlegen und gzip richtig. Bellow ist ein GitHub-Projekt, das diesen Ansatz ebenfalls demonstriert.

Probieren Sie diesen Viewer aus: MapBox GL JS Viewer

und siehe die zugehörigen Repos:

Klokan Technologies GmbH
quelle
1
Dies war bei weitem die einfachste aller oben genannten Optionen für mich, danke für das Posten.
Mheavers
PGRestAPI, hört sich toll an, aber die Installation ist für mich fehlgeschlagen. Ich kann PGRestAPI nie erfolgreich installieren. Dieser PHP-Kachelserver ist also meine einzige Wahl und funktioniert perfekt.
Hoogw
Dies ist am interessantesten. Könnten Sie näher erläutern, wie CORS und TileJSON für die Bereitstellung der pbf-Dateien richtig eingestellt werden? Ich habe eine pbf-Datei von download.geofabrik.de/europe heruntergeladen, das verknüpfte Projekt enthält jedoch viele Verzeichnisse mit vielen pbf-Dateien.
php_nub_qq
12

Nicht um mein eigenes Horn zu betätigen , sondern um https://github.com/spatialdev/PGRestAPI ist ein Projekt, an dem ich gearbeitet habe und das Exporte von .mbtiles-Vektorkacheln aus Mapbox Studio hostet.

Benötigt noch viel Dokumentation, aber im Grunde genommen legen Sie Ihre .mbtiles-Dateien in / data / pbf_mbtiles ab und starten Sie die Node-App neu. Es wird durch diesen Ordner gelesen und Endpunkte für Ihre Vektorkacheln angeboten.

Es wird auch durch / data / shapefiles schauen und dynamisch Mapbox Vector Tiles on the fly basierend auf Ihrer .shp erstellen. Sie können auch auf eine PostGIS-Instanz zeigen und dynamische Vektorkacheln abrufen.

Wir verwenden sie in Verbindung mit https://github.com/SpatialServer/Leaflet.MapboxVectorTile , einer Leaflet / Mapbox Vector Tile-Bibliothek, an der wir ebenfalls gearbeitet haben.

Ryan Whitley
quelle
1
PGRestAPI wird leider nicht mehr aktiv weiterentwickelt
raphael
10

Danke für die tolle Frage. Ich wusste nicht, dass sie endlich eine stabile Version der Vektorkacheln veröffentlicht hatten. Darüber hinaus müssen Sie möglicherweise mit dieser Antwort arbeiten, da sie eine Ideenquelle für Ihre "irgendwelche Ideen?" Ist. Frage. Ich habe noch kein Laufstudio.

Ich denke, eines der Probleme, auf das Sie stoßen, ist, dass Sie eine tilejson-Datei verwenden. Sie benötigen einen Tilejson-Dienst , um eine solche Datei zu verwenden. Daher glaube ich, dass Sie Ihren Quellenabschnitt in eine Inline-URL ändern müssen. Versuchen

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

oder

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

Wenn sie mapbox://als Protokoll verwenden, handelt es sich um eine Alias- / Kurznotation für ihre Dienste. Der Abschnitt mit den Quellen wurde kurz um 8:40 des Videos besprochen.

Ein Schritt des neuen Vektorkachelprozesses besteht darin, die Vektordaten durch Anpassen der gewünschten Daten zu kuratieren. Der andere Schritt besteht darin, die Vektordaten wieder in MapBox Studio zu importieren und die Daten zu rendern / ein Stylesheet zu erstellen. osm_roads wäre Schritt eins, während Ihre c.json-Datei das Stylesheet ist. Möglicherweise benötigen Sie einen Kachel-Live- Server und einen Kachel-Stream, wie um 15:01 Uhr im Video beschrieben. Das Video besagt, dass Sie zusätzliche Metadaten in der XML-Datei benötigen.

Die Kuriosität dabei ist, dass Sie auf die .pbf-Datei und das Stylesheet an einer anderen Stelle verweisen als auf die URL, die Sie bereitstellen .png-Dateien mit den resultierenden Kacheln, die aus den Vektordaten generiert werden.

Sie sagen nicht, ob Sie einen MapBox-Schlüssel haben. Ich glaube, dass Sie für Ihr eigenes Hosting die Github-Stile und -Glyphen auf Ihren eigenen Server kopieren müssen . Beachten Sie erneut, dass das Tag glyphs ein mapbox: // -Protokoll enthält. Diese beiden Tags werden möglicherweise nicht benötigt, da Sie einfache Linien und Polygone und keine POIs über Symbole rendern. Ein Blick lohnt sich.

Schließlich heißt es in dem Video, dass Sie eine generierte Vektorebene zurück ins Studio bringen können, um sie zu stylen. Möglicherweise möchten Sie auf Ihre Vektorebene verweisen und dort im Studio zuerst Ihren Stil id: background und id: roads anwenden. Das Video besagt, dass Tile Live der Server hinter den Kulissen von MapBox Studio ist. Die Idee hier ist, sicherzustellen, dass Sie alle Probleme in Schritt zwei verstanden und behoben haben, bevor Sie versuchen, die endgültigen Vektorkacheln bereitzustellen, die dynamisch gerendert werden.

Greg
quelle
Ok, danke @Greg für deine Ideen. Ich werde weiter nachforschen und auf meine Erkenntnisse zurückkommen.
Andreas Bilger
3

Vielleicht möchten Sie unseren Server tilehut.js ausprobieren. Es macht im Grunde alles, was Sie brauchen = Hosten von Vektorkacheln und kommt mit netten Beispielen / Dokumenten ... und ist in Kombination mit OpenShift eine 5-minütige Einrichtungssache. Bitte guck dir das an:

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

Benedikt Groß
quelle
1

Super später, aber jetzt bedient GeoServer pbfs (Vektor-Kachel-Format)

Bwyss
quelle
0

Weitere Optionen, die Sie für das Servieren von Kacheln in Betracht ziehen können.

Tegola (geschrieben in Go)

Fliesenleger

Es gibt eine schöne Einführung zu diesem Thema hier

Zuordnung dom
quelle