Hosting sendiri kotak vektor Mapbox


81

Seperti yang disajikan dalam ceramah di FOSS4G Mapbox Studio memungkinkan untuk membuat petak vektor Mapbox dan mengekspornya sebagai .mbtilesfile.

The Mapbox-gl.js perpustakaan dapat digunakan untuk secara dinamis gaya dan membuat ubin vektor Mapbox pada klien (browser) sisi.

Bagian yang hilang: Bagaimana cara saya meng-host ubin vektor Mapbox ( .mbtiles) sehingga saya dapat mengkonsumsinya dengan mapbox-gl.js?

Saya tahu bahwa Mapbox Studio dapat mengunggah ubin vektor ke server Mapbox dan membiarkannya menjadi host ubin. Tapi itu bukan pilihan bagi saya, saya ingin meng-host ubin vektor di server saya sendiri.


Pendekatan TileStream di bawah ini ternyata jalan buntu. Lihat jawaban saya untuk solusi yang berfungsi dengan Tilelive.


Saya mencoba TileStream yang dapat menyajikan ubin gambar dari .mbtilesfile:

Halaman web saya menggunakan 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>

dan itu menciptakan mapboxgl.Map dalam skrip JavaScript:

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

File c.jsonstyle mengonfigurasi sumber ubin vektor:

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

... dengan spesifikasi TileJSON berikut di tile.json:

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

... yang menunjuk ke server TileStream saya berjalan di localhost:8888. TileStream telah dimulai dengan:

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

... di mana ..\tilesfolder tersebut berisi osm_roads.mbtilesfile saya .

Dengan pengaturan ini, saya dapat membuka halaman web saya tetapi hanya melihat lapisan latar belakang. Di jejak jaringan browser saya dapat melihat bahwa ubin memang dimuat ketika saya memperbesar, tapi konsol kesalahan JavaScript browser berisi beberapa kesalahan formulir

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

Karena ubin vektor bukan .pnggambar melainkan file ProtoBuf, URL ubin http://localhost:8888/v2/osm_roads/{z}/{x}/{y}.pbfsebenarnya lebih masuk akal, tetapi itu tidak berhasil.

Ada ide?

Jawaban:


53

Seperti yang ditunjukkan oleh @Greg, alih-alih TileStream (upaya pertama saya), Anda harus menggunakan Tilelive untuk meng-host ubin vektor Anda sendiri.

Tilelive bukan server itu sendiri tetapi kerangka kerja backend yang berurusan dengan ubin dalam format yang berbeda dari sumber yang berbeda. Tapi ini didasarkan pada Node.js sehingga Anda dapat mengubahnya menjadi server dengan cara yang sangat mudah. Untuk membaca petak dari .mbtilessumber seperti yang diekspor oleh Mapbox Studio, Anda memerlukan modul tilelive node-mbtiles .

Catatan: Studio Mapbox saat ini memiliki bug di bawah Windows dan OS X yang mencegah .mbtilesfile yang diekspor muncul di tujuan yang Anda pilih. Penanganan masalah: Ambil saja export-xxxxxxxx.mbtilesfile terbaru di ~/.mapbox-studio/cache.

Saya menemukan dua implementasi server ( ten20 tile server oleh alexbirkett dan TileServer oleh hanchao ) yang keduanya menggunakan Express.js sebagai server aplikasi web.

Inilah pendekatan minimalis saya yang secara longgar didasarkan pada implementasi ini:

  1. Instal Node.js
  2. Ambil paket node dengan npm install tilelive mbtiles express
  3. Terapkan server dalam 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'));
        });
    });

    Catatan: Access-Control-Allow-...Header memungkinkan berbagi sumber daya lintas-asal (CORS) sehingga halaman web yang dilayani dari server yang berbeda dapat mengakses ubin.

  4. Jalankan dengan node server.js

  5. Siapkan halaman web menggunakan Mapbox GL JS di 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. Tunjukkan lokasi sumber ubin dan beri style pada layer-layer berikut 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. Sajikan halaman web dan bersukacitalah.


2
perhatikan bahwa Anda memerlukan tiga ///untuk mendefinisikan file mbtiles di:tilelive.load('mbtiles://path/to/osm_roads.mbtiles', function(err, source) {
CDavis

@cdavis: Kelihatannya tergantung pada sistem operasi: Tiga ///diperlukan untuk Linux dan OS X seperti misalnya mbtiles:///usr/local/osm_roads.mbtiles. Namun pada Windows hanya //diperlukan dua jika Anda menentukan disk seperti mis mbtiles://D/data/osm_roads.mbtiles.
Andreas Bilger

Sangat membantu, terima kasih banyak, membantu saya melayani vektor mbtiles dalam 5 '!
Bwyss

Hai Andreas - Saya tidak bisa membuatnya berfungsi - peta ditampilkan, tetapi itu hanya kotak abu-abu besar yang kosong. Saya tidak yakin dari mana Anda mendapatkan sumber mbtiles Anda. Saya sudah mencoba mengekspor beberapa mbtiles default dari tilemill.
mheavers

Anda tampaknya menggunakan localhost: 7777 / v2 / ubin / untuk lokasi ke ubin Anda, tetapi di mana Anda mendapatkan jalur itu? Atau apa yang perlu Anda lakukan untuk memastikan file mbtiles yang diekspor menyajikan gambar ke jalur itu?
mheavers

26

Hosting ubin vektor Anda sendiri relatif mudah. MBTiles berisi file .pbf yang harus diekspos ke web. Itu dia.

Mungkin yang paling mudah adalah dengan menggunakan server open-source sederhana seperti TileServer-PHP dan meletakkan file MBTiles ke folder yang sama dengan file proyek. TileServer melakukan semua konfigurasi hosting untuk Anda (CORS, TileJSON, header gzip yang benar, dll.). Instalasi berarti hanya membongkar di server web yang diaktifkan PHP.

Jika Anda ingin memulai TileServer-PHP di laptop Anda, Anda bisa menggunakan Docker. Wadah yang siap digunakan ada di DockerHub . Di bawah Mac OS X dan Windows itu berjalan dalam beberapa menit dengan antarmuka pengguna grafis Kitematic: https://kitematic.com/ . Di Kitematic, cari "tileserver-php" dan mulai mesin container / virtual siap pakai dengan proyek di dalamnya. Kemudian klik "Volume" dan masukkan ke folder file MBTiles Anda. Anda mendapatkan hosting yang berjalan untuk ubin vektor Anda!

Ubin vektor tersebut dapat dibuka di MapBox Studio sebagai sumber, atau ditampilkan dengan MapBox GL JS WebGL viewer.

Secara teknis bahkan dimungkinkan untuk meng-host petak vektor sebagai folder biasa pada server web atau penyimpanan awan apa pun, atau bahkan GitHub, jika Anda membuka kemasan individu .pbf dari wadah MBtiles dengan utilitas seperti mbutil , atur CORS, TileJSON dan gzip dengan benar. Bellow adalah proyek GitHub yang menunjukkan pendekatan seperti itu juga.

Coba pemirsa ini: Penampil MapBox GL JS

dan lihat repo terkait:


1
Sejauh ini, ini adalah yang termudah dari semua opsi di atas untuk saya, terima kasih untuk posting.
mheavers

PGRestAPI, kedengarannya hebat, tetapi instalasi gagal untuk saya. Saya tidak pernah berhasil menginstal PGRestAPI. Jadi server ubin php ini adalah satu-satunya pilihan saya dan berfungsi dengan sempurna.
hoogw

Ini sangat menarik, bisakah Anda menguraikan pengaturan CORS dan TileJSON dengan benar untuk melayani file pbf? Saya telah mengunduh file pbf dari download.geofabrik.de/europe namun proyek yang ditautkan mengandung banyak direktori dengan banyak file pbf.
php_nub_qq

12

Bukan untuk membunyikan klakson saya sendiri, tetapi https://github.com/spatialdev/PGRestAPI adalah proyek yang telah saya kerjakan pada host tersebut .mbtiles ekspor ubin vektor dari Mapbox Studio.

Masih membutuhkan banyak dokumentasi, tetapi pada dasarnya, letakkan file .mbtiles Anda ke / data / pbf_mbtiles dan restart aplikasi node. Ini akan membaca melalui folder itu dan menawarkan titik akhir untuk ubin vektor Anda.

Ini juga akan terlihat melalui / data / shapefile, dan membuat Ubin Vektor Mapbox dinamis dengan cepat berdasarkan .shp Anda. Anda juga bisa menunjuk ke instance PostGIS dan mendapatkan petak vektor dinamis.

Kami menggunakannya bersama dengan https://github.com/SpatialServer/Leaflet.MapboxVectorTile , pustaka Vektor Tile Leaflet / Mapbox yang juga telah kami kerjakan.


1
Sayangnya, PGRestAPI tidak lagi dikembangkan secara aktif
raphael

10

Terima kasih atas pertanyaannya. Saya tidak tahu bahwa mereka akhirnya merilis versi stabil ubin vektor. Selain itu, Anda mungkin harus bekerja dengan jawaban ini karena ini adalah sumber ide untuk "ide Anda"? pertanyaan. Saya belum memiliki studio yang sedang berjalan.

Saya pikir salah satu masalah yang Anda hadapi adalah Anda menggunakan file tilejson. Anda memerlukan layanan tilejson untuk menggunakan file semacam itu. Karenanya, saya percaya Anda perlu mengubah bagian sumber Anda menjadi URL sebaris. Mencoba

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

atau

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

Ketika mereka menggunakan mapbox://sebagai protokol, itu adalah notasi alias / singkatan untuk layanan mereka. Bagian sumber dibahas secara singkat sekitar 8:40 video.

Salah satu langkah dari proses ubin vektor baru adalah mengumpulkan data vektor dengan menyesuaikan apa yang Anda inginkan dalam data. Langkah lainnya adalah membawa data vektor kembali ke MapBox Studio dan membuat data / membuat style sheet. osm_roads akan menjadi langkah pertama sementara file c.json Anda adalah style sheet. Anda mungkin memerlukan ubin server langsung ayat aliran ubin seperti yang dibahas sekitar 15:01 video. Video mengatakan bahwa Anda memerlukan data meta tambahan dalam file xml.

Keanehannya di sini adalah Anda mereferensikan .pbf dan style sheet di tempat lain tetapi url yang Anda berikan adalah ubin yang dihasilkan .png file yang dihasilkan dari data vektor.

Anda tidak mengatakan, jika Anda memiliki kunci MapBox. Untuk hosting Anda sendiri, saya yakin Anda harus menyalin gaya dan mesin terbang github ke server Anda sendiri. Perhatikan lagi bahwa ada kotak map: // protokol dalam tag mesin terbang. Kedua tag ini mungkin tidak diperlukan karena Anda memberikan garis dan poligon polos, bukan POI melalui ikon. Perlu dicoba.

Akhirnya, video mengatakan bahwa Anda dapat mengambil layer vektor yang dihasilkan kembali ke studio untuk mengubahnya. Anda mungkin ingin referensi layer vektor Anda dan menerapkan id Anda: latar belakang dan id: gaya jalan ada di studio terlebih dahulu. Video tersebut mengatakan bahwa ubin langsung adalah server di belakang layar MapBox Studio. Idenya di sini adalah untuk memastikan bahwa Anda memiliki semua langkah dua masalah dipahami dan diperbaiki sebelum Anda mencoba untuk melayani petak vektor terakhir yang secara dinamis diberikan.


Ok, terima kasih @Greg atas ide Anda. Akan menyelidiki lebih lanjut dan kembali dengan temuan saya.
Andreas Bilger



1

Super nanti, tapi sekarang GeoServer menyajikan pbf (format ubin vektor)


Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.