Kafelki wektorowe Mapbox


81

Jak przedstawiono w wykładzie na FOSS4G Mapbox Studio pozwala tworzyć kafelki wektorowe Mapbox i eksportować je jako .mbtilesplik.

Biblioteki mapbox-gl.js można dynamicznie stylizować i renderować kafelki wektorowe Mapbox po stronie klienta (przeglądarki).

Brakująca część: w jaki sposób mogę samodzielnie hostować kafelki wektorowe Mapbox ( .mbtiles), aby móc je konsumować za pomocą mapbox-gl.js?

Wiem, że Mapbox Studio może przesyłać kafelki wektorowe na serwer Mapbox i pozwolić mu hostować kafelki. Ale to nie jest dla mnie opcja, chcę hostować kafelki wektorowe na własnym serwerze.


Podejście TileStream poniżej okazało się ślepym zaułkiem. Zobacz moją odpowiedź na działające rozwiązanie z Tilelive.


Wypróbowałem TileStream, który może wyświetlać kafelki z .mbtilesplików:

Moja strona używa 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>

i tworzy mapboxgl.Map w skrypcie JavaScript:

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

Plik c.jsonstylu konfiguruje źródło kafelków wektorowych:

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

... z następującą specyfikacją TileJSON w tile.json:

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

... co wskazuje na mój serwer TileStream działający w localhost:8888. TileStream został uruchomiony z:

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

... gdzie ..\tilesfolder zawiera mój osm_roads.mbtilesplik.

Dzięki tej konfiguracji mogę otworzyć swoją stronę internetową, ale widzę tylko warstwę tła. W śledzeniu sieci przeglądarki widzę, że kafelki są ładowane podczas powiększania, ale konsola błędów JavaScript w przeglądarce zawiera kilka błędów formularza

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

Ponieważ kafelki wektorowe nie są .pngobrazami, a raczej plikami ProtoBuf, adres URL kafelków http://localhost:8888/v2/osm_roads/{z}/{x}/{y}.pbfmiałby większy sens, ale to nie działa.

Jakieś pomysły?

Odpowiedzi:


53

Jak wskazał @Greg, zamiast TileStream (moja pierwsza próba) powinieneś użyć Tilelive do hostowania własnych płytek wektorowych.

Tilelive nie jest samym serwerem, ale strukturą zaplecza, która zajmuje się kafelkami w różnych formatach z różnych źródeł. Jest jednak oparty na Node.js, dzięki czemu można go przekształcić w serwer w bardzo prosty sposób. Aby odczytać kafelki ze .mbtilesźródła wyeksportowanego przez Mapbox Studio, potrzebujesz modułu tilelive node-mbtiles .

Uwaga dodatkowa: Bieżący Mapbox Studio ma błąd w systemie Windows i OS X, który uniemożliwia wyeksportowanie .mbtilespliku do wybranego miejsca docelowego. Obejście: Wystarczy pobrać najnowszy export-xxxxxxxx.mbtilesplik ~/.mapbox-studio/cache.

Znalazłem dwie implementacje serwera ( serwer kafelkowy ten20 autorstwa alexbirkett i TileServer autorstwa hanchao ), które używają Express.js jako serwera aplikacji WWW.

Oto moje minimalistyczne podejście, które luźno opiera się na tych implementacjach:

  1. Zainstaluj Node.js
  2. Chwyć pakiety węzłów za pomocą npm install tilelive mbtiles express
  3. Zaimplementuj serwer w pliku 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'));
        });
    });

    Uwaga: Access-Control-Allow-...Nagłówki umożliwiają współdzielenie zasobów pochodzących z różnych źródeł (CORS), aby strony obsługiwane z innego serwera mogły uzyskać dostęp do kafelków.

  4. Uruchom to z node server.js

  5. Skonfiguruj stronę internetową za pomocą Mapbox GL JS w 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. Wskaż lokalizację źródła kafelków i stylizuj warstwy, wykonując następujące czynności 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. Podaj stronę internetową i ciesz się.


2
zauważ, że potrzebujesz trzech, ///aby zdefiniować plik mbtiles w:tilelive.load('mbtiles://path/to/osm_roads.mbtiles', function(err, source) {
CDavis

@cdavis: Wygląda na to, że zależy to od systemu operacyjnego: trzy ///są potrzebne dla systemu Linux i OS X, np mbtiles:///usr/local/osm_roads.mbtiles. W systemie Windows tylko dwa //są potrzebne, jeśli określisz dysk, np mbtiles://D/data/osm_roads.mbtiles.
Andreas Bilger

Naprawdę pomocna, dzięki bardzo, pomogła mi serwować wektorowe mbtiles w 5 '!
Bwyss,

Cześć Andreas - Nie mogłem tego uruchomić - mapa wyświetla się, ale jest to tylko duży pusty szary kwadrat. Nie jestem pewien, skąd masz źródło mbtiles. Próbowałem wyeksportować niektóre domyślne MBTiles z tilemill.
mheavers

wydaje się, że używasz localhost: 7777 / v2 / tiles / do lokalizacji swoich kafelków, ale skąd ta ścieżka? Lub co musisz zrobić, aby upewnić się, że eksportowany plik mbtiles obsługuje obrazy na tej ścieżce?
mheavers

26

Samo hostowanie kafelków wektorowych jest stosunkowo proste. MBTiles zawiera pliki .pbf, które muszą być udostępnione w Internecie. Otóż ​​to.

Prawdopodobnie najłatwiej jest użyć prostego serwera typu open source, takiego jak TileServer-PHP i umieścić plik MBTiles w tym samym folderze, co pliki projektu. TileServer wykonuje całą konfigurację hostingu dla Ciebie (CORS, TileJSON, poprawne nagłówki gzip itp.). Instalacja oznacza po prostu rozpakowanie na serwerze WWW z obsługą PHP.

Jeśli chcesz uruchomić TileServer-PHP na swoim laptopie, możesz to zrobić dzięki Docker. Gotowy do użycia pojemnik znajduje się w DockerHub . W systemach Mac OS X i Windows działa za kilka minut z graficznym interfejsem użytkownika Kitematic: https://kitematic.com/ . W Kitematic po prostu wyszukaj „tileserver-php” i uruchom gotowy do użycia kontener / maszynę wirtualną z projektem w środku. Następnie kliknij „Woluminy” i upuść w folderze plik MBTiles. Dostajesz działający hosting dla swoich płytek wektorowych!

Takie kafelki wektorowe można otworzyć w MapBox Studio jako źródło lub wyświetlić za pomocą przeglądarki MapBox GL JS WebGL.

Technicznie możliwe jest nawet hostowanie kafelków wektorowych jako zwykłego folderu na dowolnym serwerze internetowym lub w chmurze, a nawet w GitHub, jeśli rozpakujesz poszczególne pliki .pbf z kontenera MBtiles za pomocą narzędzia takiego jak mbutil , ustaw CORS, TileJSON i gzip poprawnie. Bellow to projekt GitHub demonstrujący również takie podejście.

Wypróbuj tę przeglądarkę: Przeglądarka MapBox GL JS

i zobacz powiązane repozytorium:


1
To była dla mnie najłatwiejsza ze wszystkich powyższych opcji, dziękuję za wysłanie.
mheavers

PGRestAPI, brzmi świetnie, ale instalacja zakończyła się niepowodzeniem. Nigdy nie będę w stanie pomyślnie zainstalować PGRestAPI. Tak więc ten serwer kafelków php jest moim jedynym wyborem i działa idealnie.
hoogw

To jest najciekawsze, czy mógłbyś rozwinąć kwestię ustawienia CORS i TileJSON poprawnie do obsługi plików pbf? Pobrałem plik PBF z download.geofabrik.de/europe, jednak połączony projekt zawiera wiele katalogów z wieloma plikami PBF.
php_nub_qq

12

Nie trącić własnym rogiem, ale https://github.com/spatialdev/PGRestAPI to projekt, nad którym pracuję, który obsługuje eksport kafelków wektorowych .mbtiles z Mapbox Studio.

Nadal potrzebuje dużo dokumentacji, ale w zasadzie upuść pliki .mbtiles do / data / pbf_mbtiles i zrestartuj aplikację węzła. Czyta przez ten folder i oferuje punkty końcowe dla twoich płytek wektorowych.

Będzie również wyglądać przez / data / shapefiles i tworzyć dynamiczne kafelki wektorowe Mapbox w locie na podstawie twojego .shp. Możesz także wskazać instancję PostGIS i uzyskać dynamiczne kafelki wektorowe.

Używamy ich w połączeniu z https://github.com/SpatialServer/Leaflet.MapboxVectorTile , biblioteką wektorową Ulotki / Mapbox, nad którą również pracowaliśmy.


1
Niestety PGRestAPI nie jest już aktywnie rozwijany
raphael

10

Dzięki za świetne pytanie. Nie wiedziałem, że w końcu wydali stabilną wersję kafelków wektorowych. Co więcej, być może będziesz musiał pracować z tą odpowiedzią, ponieważ jest ona źródłem pomysłów na Twoje „jakieś pomysły”? pytanie. Nie mam jeszcze działającego studia.

Myślę, że jednym z problemów, na które napotykasz, jest to, że używasz pliku tilejson. Aby skorzystać z tego rodzaju pliku, potrzebujesz usługi tilejson . Dlatego uważam, że musisz zmienić sekcję źródeł na wbudowany adres URL. Próbować

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

lub

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

Gdy używają mapbox://jako protokołu, jest to alias / skrót dla ich usług. Sekcja źródeł została krótko omówiona około 8:40 filmu.

Jednym z etapów nowego procesu kafelkowego wektora jest wyselekcjonowanie danych wektorowych poprzez dostosowanie tego, co chcesz w danych. Drugim krokiem jest przywrócenie danych wektorowych z powrotem do MapBox Studio i renderowanie danych / utworzenie arkusza stylów. osm_roads byłby krokiem pierwszym, podczas gdy plik c.json jest arkuszem stylów. Może być potrzebny serwer kafelkowy na żywo , który przekazuje strumień kafelków, jak omówiono około 15:01 filmu. Film mówi, że potrzebujesz dodatkowych metadanych w pliku xml.

Dziwne jest to, że odwołujesz się do pliku .pbf i arkusza stylów w innym miejscu, ale adres URL, który podajesz, to wynikowe pliki .png kafelków generowane z danych wektorowych.

Nie mów, jeśli masz klucz MapBox. W przypadku własnego hostingu uważam, że będziesz musiał skopiować style i glify github na własny serwer. Zauważ ponownie, że w znaczniku glifów znajduje się protokół mapbox: //. Te dwa tagi mogą nie być potrzebne, ponieważ renderujesz proste linie i wielokąty, a nie UM-y za pomocą ikon. Warto się przyjrzeć.

Wreszcie wideo mówi, że możesz zabrać wygenerowaną warstwę wektorową z powrotem do studia, aby ją nadać styl. Możesz odwołać się do swojej warstwy wektorowej i najpierw zastosować w studio styl id: background i id: drogi. Film mówi, że kafelek na żywo to serwer stojący za sceną MapBox Studio. Chodzi o to, aby upewnić się, że wszystkie problemy z kroku drugiego zostały zrozumiane i naprawione, zanim spróbujesz podać końcowe płytki wektorowe, które są renderowane dynamicznie.


Ok, dziękuję @Greg za twoje pomysły. Zbadam dalej i wrócę z moimi ustaleniami.
Andreas Bilger,



1

Super później, ale teraz GeoServer obsługuje pbf (format kafelków wektorowych)


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.