ไทล์แผนที่เวกเตอร์ Mapbox ที่จัดการโฮสต์ด้วยตนเอง


81

ดังที่นำเสนอในการพูดคุยที่ FOSS4G Mapbox Studio ช่วยให้สามารถสร้างไทล์ Mapbox แบบเวกเตอร์และส่งออกเป็น.mbtilesไฟล์

mapbox-gl.jsห้องสมุดสามารถนำมาใช้กับรูปแบบไดนามิกและทำให้กระเบื้องเวกเตอร์ Mapbox บนไคลเอนต์ (เบราว์เซอร์) ด้าน

ส่วนที่ขาดหายไป: ฉันจะโฮสต์ไทล์แผนที่แบบเวกเตอร์ของ Mapbox ( .mbtiles) เพื่อให้ฉันสามารถกินด้วย mapbox-gl.js ได้อย่างไร

ฉันรู้ว่า Mapbox Studio สามารถอัปโหลดไทล์เวกเตอร์ไปยังเซิร์ฟเวอร์ Mapbox และปล่อยให้มันเป็นเจ้าภาพไทล์ แต่นั่นไม่ใช่ตัวเลือกสำหรับฉันฉันต้องการโฮสต์ไทล์เวกเตอร์บนเซิร์ฟเวอร์ของฉันเอง


วิธีการ TileStream ด้านล่างกลายเป็นจุดจบ ดูคำตอบของฉันสำหรับวิธีแก้ปัญหาการทำงานกับ Tilelive


ฉันลองTileStreamซึ่งสามารถให้บริการไฟล์ภาพจาก.mbtilesไฟล์:

หน้าเว็บของฉันใช้ 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>

และสร้าง mapboxgl.Map ในสคริปต์ JavaScript:

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

c.jsonไฟล์รูปแบบกำหนดค่าแหล่งกระเบื้องเวกเตอร์:

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

... ด้วยข้อกำหนด TileJSON ต่อไปนี้ในtile.json:

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

... ซึ่งชี้ไปยังเซิร์ฟเวอร์ TileStream localhost:8888ของฉันทำงานที่ TileStream เริ่มต้นด้วย:

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

... ที่..\tilesโฟลเดอร์มีosm_roads.mbtilesไฟล์ของฉัน

ด้วยการตั้งค่านี้ฉันสามารถเปิดเว็บเพจของฉัน แต่เห็นเลเยอร์พื้นหลังเท่านั้น ในการติดตามเครือข่ายของเบราว์เซอร์ฉันเห็นว่ามีการโหลดไทล์เมื่อฉันซูมเข้า แต่คอนโซลข้อผิดพลาดของเบราว์เซอร์ JavaScript มีข้อผิดพลาดหลายอย่างของแบบฟอร์ม

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

เนื่องจาก.pngไทล์เวกเตอร์ไม่ใช่ภาพ แต่เป็นไฟล์ ProtoBuf ดังนั้นไทล์ URL http://localhost:8888/v2/osm_roads/{z}/{x}/{y}.pbfจึงเหมาะสมกว่า แต่ก็ใช้ไม่ได้

ความคิดใด ๆ

คำตอบ:


53

ตามที่ระบุโดย @Greg แทนที่จะเป็นTileStream (ความพยายามครั้งแรกของฉัน) คุณควรใช้Tileliveเพื่อโฮสต์ไทล์เวกเตอร์ของคุณเอง

Tilelive ไม่ใช่เซิร์ฟเวอร์ แต่เป็นเฟรมเวิร์กเบื้องหลังที่จัดการกับไทล์ในรูปแบบที่แตกต่างจากแหล่งที่แตกต่างกัน แต่มันขึ้นอยู่กับNode.jsเพื่อให้คุณสามารถเปลี่ยนเป็นเซิร์ฟเวอร์ได้อย่างตรงไปตรงมา ในการอ่าน.mbtilesไทล์จากแหล่งที่ส่งออกโดย Mapbox Studio คุณต้องใช้โมดูล tilelive ของโหนด -mbtiles

หมายเหตุด้านข้าง: Mapbox Studio ปัจจุบันมีข้อบกพร่องภายใต้ Windows และ OS X ที่ป้องกันไม่ให้.mbtilesไฟล์ที่ส่งออกปรากฏขึ้นที่ปลายทางที่คุณเลือก วิธีแก้ปัญหา: เพิ่งคว้าexport-xxxxxxxx.mbtilesไฟล์ล่าสุด~/.mapbox-studio/cacheมา

ฉันพบการใช้งานเซิร์ฟเวอร์สองรายการ ( เซิร์ฟเวอร์ไทล์ ten20 โดย alexbirkettและTileServer โดย hanchao ) ซึ่งทั้งคู่ใช้Express.jsเป็นเซิร์ฟเวอร์เว็บแอป

นี่คือวิธีการที่เรียบง่ายของฉันซึ่งตั้งอยู่บนพื้นฐานของการใช้งานเหล่านี้อย่างอิสระ:

  1. ติดตั้งNode.js
  2. คว้าแพ็คเกจโหนดด้วย npm install tilelive mbtiles express
  3. ใช้เซิร์ฟเวอร์ในไฟล์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'));
        });
    });

    หมายเหตุ: Access-Control-Allow-...ส่วนหัวเปิดใช้งานการแชร์ทรัพยากรข้ามแหล่ง (CORS) ดังนั้นหน้าเว็บที่ให้บริการจากเซิร์ฟเวอร์ที่แตกต่างกันอาจเข้าถึงไทล์

  4. เรียกใช้ด้วย node server.js

  5. ตั้งค่าหน้าเว็บโดยใช้ Mapbox GL JS ใน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. ระบุตำแหน่งของแหล่งที่มาของไทล์และกำหนดเลเยอร์ดังต่อไปนี้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. แสดงหน้าเว็บและชื่นชมยินดี


2
โปรดทราบว่าคุณต้องการสาม///ไฟล์เพื่อกำหนดไฟล์ mbtiles ใน:tilelive.load('mbtiles://path/to/osm_roads.mbtiles', function(err, source) {
CDavis

@cdavis: ที่ดูเหมือนว่าจะขึ้นอยู่กับระบบปฏิบัติการ: สาม///มีความจำเป็นสำหรับ Linux และ Mac OS X mbtiles:///usr/local/osm_roads.mbtilesเหมือนเช่น บน Windows แต่เพียงสองที่มีความจำเป็นหากคุณระบุดิสก์เหมือนเช่น// mbtiles://D/data/osm_roads.mbtiles
Andreas Bilger

มีประโยชน์จริง ๆ ขอบคุณมากช่วยฉันรับใช้ mbtiles เวกเตอร์ใน 5 '!
Bwyss

สวัสดี Andreas - ฉันไม่สามารถทำงานนี้ได้ - แผนที่จะแสดง แต่มันเป็นเพียงสี่เหลี่ยมสีเทาขนาดใหญ่ที่ว่างเปล่า ฉันไม่แน่ใจว่าคุณได้รับแหล่ง mbtiles ของคุณอยู่ที่ไหน ฉันพยายามส่งออก mbtiles เริ่มต้นบางส่วนจาก tilemill
mheavers

ดูเหมือนว่าคุณจะใช้ localhost: 7777 / v2 / tiles / สำหรับตำแหน่งไปยังไทล์ของคุณ แต่คุณได้รับพา ธ นั้น หรือคุณต้องทำอะไรบ้างเพื่อให้แน่ใจว่าไฟล์ mbtiles ที่เอ็กซ์พอร์ตให้บริการอิมเมจไปยังพา ธ นั้น
mheavers

26

โฮสติ้งของกระเบื้องแบบเวกเตอร์ด้วยตัวคุณเองนั้นค่อนข้างตรงไปตรงมา MBTiles มีไฟล์. pbf ซึ่งจะต้องเปิดเผยต่อเว็บ แค่นั้นแหละ.

อาจจะง่ายที่สุดคือการใช้เซิร์ฟเวอร์โอเพ่นซอร์สอย่างง่ายเช่นTileServer-PHPและวางไฟล์ MBTiles ไว้ในโฟลเดอร์เดียวกับไฟล์โครงการ TileServer จัดการโฮสต์สำหรับคุณ (CORS, TileJSON, ส่วนหัว gzip ที่ถูกต้อง ฯลฯ ) การติดตั้งหมายถึงเพียงเปิดออกบนเว็บเซิร์ฟเวอร์ที่เปิดใช้งาน PHP

หากคุณต้องการเริ่มต้น TileServer-PHP บนแล็ปท็อปของคุณคุณสามารถใช้ Docker ได้ พร้อมที่จะใช้ภาชนะบรรจุอยู่ในDockerHub ภายใต้ Mac OS X และ Windows ทำงานในไม่กี่นาทีกับอินเตอร์เฟซผู้ใช้แบบกราฟิก Kitematic A: https://kitematic.com/ ใน Kitematic เพียงค้นหา "tileserver-php" และเริ่มพร้อมที่จะใช้เครื่องคอนเทนเนอร์ / เครื่องเสมือนกับโครงการภายใน จากนั้นคลิกที่ "เล่ม" และวางลงในโฟลเดอร์ไฟล์ MBTiles ของคุณ คุณได้โฮสติ้งที่กำลังทำงานสำหรับไทล์เวกเตอร์ของคุณ!

กระเบื้องแบบเวกเตอร์ดังกล่าวสามารถเปิดได้ใน MapBox Studio เป็นแหล่งข้อมูลหรือแสดงด้วยโปรแกรมดู MapBox GL JS WebGL

ในทางเทคนิคแล้วมันยังเป็นไปได้ที่จะจัดเก็บไพ่เรียงแบบเวกเตอร์เป็นโฟลเดอร์ธรรมดาบนเว็บเซิร์ฟเวอร์หรือที่เก็บข้อมูลบนคลาวด์หรือแม้กระทั่ง GitHub ถ้าคุณแกะแต่ละ. pbf ออกจากคอนเทนเนอร์ MBtiles ด้วยโปรแกรมอรรถประโยชน์เช่นmbutilให้ตั้งค่า CORS, TileJSON และ gzip อย่างถูกต้อง ร้องเป็นโครงการ GitHub แสดงให้เห็นถึงวิธีการดังกล่าวเช่นกัน

ลองใช้โปรแกรมดูนี้: ผู้ดู MapBox GL JS

และดู repos ที่เกี่ยวข้อง:


1
นี่เป็นวิธีที่ง่ายที่สุดสำหรับตัวเลือกทั้งหมดข้างต้นสำหรับฉันขอบคุณสำหรับการโพสต์
mheavers

PGRestAPI ฟังดูดี แต่การติดตั้งล้มเหลวสำหรับฉัน ฉันไม่สามารถติดตั้ง PGRestAPI ได้สำเร็จ ดังนั้นเซิร์ฟเวอร์กระเบื้อง php นี้เป็นตัวเลือกเดียวของฉันและทำงานได้อย่างสมบูรณ์แบบ
hoogw

สิ่งนี้น่าสนใจที่สุดคุณช่วยอธิบายการตั้งค่า CORS และ TileJSON อย่างถูกต้องเพื่อให้บริการไฟล์ pbf ได้ไหม? ฉันได้ดาวน์โหลดไฟล์ pbf จากdownload.geofabrik.de/europeอย่างไรก็ตามโครงการที่เชื่อมโยงมีหลายไดเรกทอรีที่มีไฟล์ pbf จำนวนมาก
php_nub_qq

12

ไม่ต้องตุ๊ดฮอร์นของฉันเอง แต่https://github.com/spatialdev/PGRestAPIเป็นโครงการที่ฉันทำงานกับโฮสต์นั้น. mbtiles การส่งออกไทล์ไทล์จาก Mapbox Studio

ยังคงต้องการเอกสารจำนวนมาก แต่โดยทั่วไปให้วางไฟล์. mbtiles ของคุณลงใน / data / pbf_mbtiles และรีสตาร์ทแอปพลิเคชันโหนด มันจะอ่านผ่านโฟลเดอร์นั้นและเสนอจุดสิ้นสุดสำหรับไทล์เวกเตอร์ของคุณ

นอกจากนี้ยังจะดูผ่าน / data / shapefiles และสร้าง Mapbox Vector Tiles แบบไดนามิกได้ทันทีตาม. shp ของคุณ คุณสามารถชี้ไปที่อินสแตนซ์ของ PostGIS และรับไทล์เวกเตอร์แบบไดนามิกได้

เราใช้พวกมันร่วมกับhttps://github.com/SpatialServer/Leaflet.MapboxVectorTileซึ่งเป็นไลบรารีแผ่นกระเบื้อง Vector / Leaflet ของ Mapbox ที่เราได้ทำงานด้วย


1
PGRestAPI ไม่ได้รับการพัฒนาอย่างน่าเสียดายอีกต่อไปแล้ว
ฟาเอล

10

ขอบคุณสำหรับคำถามที่ดีมาก ฉันไม่ทราบว่าในที่สุดพวกเขาก็ปล่อยกระเบื้องแบบเวกเตอร์ที่มีความเสถียร นอกจากนี้คุณอาจต้องทำงานกับคำตอบนี้เนื่องจากเป็นแหล่งความคิดสำหรับ "แนวคิดใด ๆ " ของคุณ คำถาม. ฉันยังไม่มีสตูดิโอทำงาน

ฉันคิดว่าหนึ่งในปัญหาที่คุณพบคือคุณกำลังใช้ไฟล์ tilejson คุณต้องใช้บริการ tilejsonเพื่อใช้ไฟล์ประเภทนั้น ดังนั้นฉันเชื่อว่าคุณต้องเปลี่ยนส่วนแหล่งที่มาของคุณเป็น URL ในบรรทัด ลอง

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

หรือ

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

เมื่อพวกเขาใช้mapbox://เป็นโปรโตคอลมันเป็นนามแฝง / ชวเลขย่อสำหรับบริการของพวกเขา ส่วนที่มาถูกกล่าวถึงสั้น ๆ ประมาณ 8:40 ของวิดีโอ

ขั้นตอนหนึ่งของกระบวนการไทล์เวกเตอร์ใหม่คือการดูแลข้อมูลเวกเตอร์ด้วยการปรับสิ่งที่คุณต้องการในข้อมูล อีกขั้นตอนหนึ่งคือการนำข้อมูลเวกเตอร์กลับมาที่ MapBox Studio และแสดงข้อมูล / สร้างสไตล์ชีท osm_roads จะเป็นขั้นตอนที่หนึ่งในขณะที่ไฟล์ c.json ของคุณเป็นสไตล์ชีต คุณอาจต้องใช้ไทล์เซิร์ฟเวอร์ถ่ายทอดสดสตรีมเรียงต่อกันตามที่กล่าวไว้ในรอบ 15:01 ของวิดีโอ วิดีโอบอกว่าคุณต้องการข้อมูลเมตาเพิ่มเติมในไฟล์ xml

ความผิดปกติที่นี่คือคุณอ้างอิง. pbf และสไตล์ชีทที่อื่น ๆ แต่ URL ที่คุณให้ไว้คือไฟล์. png แบบเรียงต่อกันซึ่งสร้างขึ้นจากข้อมูลเวกเตอร์

คุณไม่ได้พูดว่าถ้าคุณมีคีย์ MapBox สำหรับโฮสติ้งของคุณเองฉันเชื่อว่าคุณจะต้องคัดลอกรูปแบบ Github และร่ายมนตร์ไปยังเซิร์ฟเวอร์ของคุณเอง โปรดสังเกตอีกครั้งว่ามี mapbox: // protocol อยู่ในแท็ก glyphs อาจไม่จำเป็นต้องใช้แท็กสองแท็กนี้เนื่องจากคุณแสดงเส้นและรูปหลายเหลี่ยมและไม่ใช่จุดที่น่าสนใจผ่านไอคอน มันคุ้มค่าที่จะดู

ในที่สุดวิดีโอบอกว่าคุณสามารถนำเลเยอร์เวกเตอร์ที่สร้างขึ้นกลับเข้าไปในสตูดิโอเพื่อจัดวางสไตล์ คุณอาจต้องการอ้างอิงเลเยอร์เวกเตอร์ของคุณและใช้ id: พื้นหลังและ id: รูปแบบถนนในสตูดิโอก่อน วิดีโอบอกว่าไทล์ไลฟ์เป็นเซิร์ฟเวอร์ที่อยู่เบื้องหลังของ MapBox Studio แนวคิดที่นี่คือเพื่อให้แน่ใจว่าคุณมีปัญหาที่เข้าใจและแก้ไขได้ในขั้นตอนที่สองทั้งหมดก่อนที่คุณจะพยายามแสดงแผ่นกระเบื้องเวกเตอร์สุดท้ายที่แสดงผลแบบไดนามิก


ตกลงขอบคุณ @Greg สำหรับความคิดของคุณ จะตรวจสอบเพิ่มเติมและกลับมาพร้อมกับสิ่งที่ฉันค้นพบ
Andreas Bilger

4

https://github.com/osm2vectortiles/tileserver-gl-lightใช้งานง่ายกว่าโซลูชันหลักที่กล่าวถึง - ไม่ต้องเล่นซอกับไฟล์ JSON คุณเพียงแค่รันด้วย

tileserver-gl-light filename.mbtiles

จากนั้นมันจะให้บริการกระเบื้องสำหรับคุณ มันทำงานร่วมกับรูปแบบ Mapbox GL ที่กำหนดไว้ล่วงหน้าเช่น bright-v9; หลังจากเรียกใช้เซิร์ฟเวอร์คุณเพียงแค่ชี้สิ่งที่กำลังใช้ไพ่

http: // localhost: 8080 / รูปแบบ / สดใส v9.json


3

คุณอาจต้องการลองใช้เซิร์ฟเวอร์ tilehut.js ของเรา มันทำทุกสิ่งที่คุณต้องการ = โฮสติ้งไทล์เวกเตอร์และมาพร้อมกับตัวอย่างที่ดี / เอกสาร ... และใช้ร่วมกับ openshift มันเป็นสิ่งที่ติดตั้ง 5 นาที โปรดดู:

https://github.com/bg/tilehut https://github.com/bg/tilehut/tree/master/examples/simplemap_vector https://github.com/bg/tilehut#your-own-hosted-tileserver- ใน 5 นาที


1

Super ภายหลัง แต่ตอนนี้ GeoServer ให้บริการ pbf's (รูปแบบไทล์กระเบื้อง)


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.