Tự lưu trữ gạch vector Mapbox


81

Như được trình bày trong một cuộc nói chuyện tại FOSS4G Mapbox Studio cho phép tạo các ô vector Mapbox và xuất chúng dưới dạng .mbtilestệp.

Các mapbox-gl.js thư viện có thể được sử dụng để tự động phong cách pha trộn và trình gạch vector Mapbox trên client (trình duyệt) bên.

Phần còn thiếu: Làm cách nào tôi có thể tự lưu trữ các ô vectơ Mapbox ( .mbtiles) để tôi có thể sử dụng chúng với mapbox-gl.js?

Tôi biết rằng Mapbox Studio có thể tải các ô vector lên máy chủ Mapbox và cho phép nó lưu trữ các ô đó. Nhưng đó không phải là lựa chọn cho tôi, tôi muốn lưu trữ các ô vector trên máy chủ của riêng tôi.


Cách tiếp cận TileStream dưới đây hóa ra là một ngõ cụt. Xem câu trả lời của tôi cho một giải pháp làm việc với Tilelive.


Tôi đã thử TileStream có thể phục vụ các ô hình ảnh trong số .mbtilescác tệp:

Trang web của tôi sử dụng 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>

và nó tạo ra mapboxgl.Map trong tập lệnh JavaScript:

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

Tệp c.jsonkiểu cấu hình nguồn vector vector:

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

... với thông số kỹ thuật của TileJSON sau đây trong tile.json:

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

... trỏ đến máy chủ TileStream của tôi đang chạy localhost:8888. TileStream đã được bắt đầu với:

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

... nơi ..\tilesthư mục chứa osm_roads.mbtilestập tin của tôi .

Với thiết lập này, tôi có thể mở trang web của mình nhưng chỉ nhìn thấy lớp nền. Trong theo dõi mạng trình duyệt, tôi có thể thấy rằng các ô thực sự được tải khi tôi phóng to, nhưng bảng điều khiển lỗi trình duyệt JavaScript có một số lỗi của biểu mẫu

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

Vì các ô xếp vectơ không phải là .pnghình ảnh mà là các tệp ProtoBuf, URL của ô http://localhost:8888/v2/osm_roads/{z}/{x}/{y}.pbfthực sự sẽ có ý nghĩa hơn, nhưng điều đó không hoạt động.

Có ý kiến ​​gì không?

Câu trả lời:


53

Như @Greg đã chỉ ra, thay vì TileStream (lần thử đầu tiên của tôi), bạn nên sử dụng Tilelive để lưu trữ các ô vector của riêng bạn.

Tilelive không phải là một máy chủ mà là một khung phụ trợ liên quan đến các ô ở các định dạng khác nhau từ các nguồn khác nhau. Nhưng nó dựa trên Node.js để bạn có thể biến nó thành một máy chủ theo cách khá đơn giản. Để đọc gạch từ một .mbtilesnguồn như xuất khẩu bởi Mapbox Studio, bạn cần nút-mbtiles mô-đun tilelive.

Lưu ý bên lề: Mapbox Studio hiện tại có lỗi trong Windows và OS X, ngăn .mbtilestệp xuất xuất hiện ở đích bạn đã chọn. Giải pháp thay thế: Chỉ cần lấy export-xxxxxxxx.mbtilestập tin mới nhất trong ~/.mapbox-studio/cache.

Tôi đã tìm thấy hai triển khai máy chủ ( ten20 máy chủ gạch của alexbirkettTileServer của hanchao ), cả hai đều sử dụng Express.js làm máy chủ ứng dụng web.

Đây là cách tiếp cận tối giản của tôi dựa trên những triển khai này:

  1. Cài đặt Node.js
  2. Lấy các gói nút với npm install tilelive mbtiles express
  3. Triển khai máy chủ trong tệp 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'));
        });
    });
    

    Lưu ý: Các Access-Control-Allow-...tiêu đề cho phép chia sẻ tài nguyên nguồn gốc chéo (CORS) để các trang web được cung cấp từ một máy chủ khác có thể truy cập vào các ô.

  4. Chạy nó với node server.js

  5. Thiết lập trang web bằng Mapbox GL JS trong 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. Chỉ ra vị trí của nguồn gạch và định kiểu các lớp bằng cách sau 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. Phục vụ trang web và vui mừng.


2
lưu ý rằng bạn cần ba ///để xác định tệp mbtiles trong:tilelive.load('mbtiles://path/to/osm_roads.mbtiles', function(err, source) {
CDavis

@cdavis: Điều đó dường như phụ thuộc vào hệ điều hành: Cần ba cái ///cho Linux và OS X như vd mbtiles:///usr/local/osm_roads.mbtiles. Tuy nhiên, trên Windows chỉ cần hai cái //nếu bạn chỉ định đĩa như vd mbtiles://D/data/osm_roads.mbtiles.
Andreas Bilger

Thực sự hữu ích, cảm ơn rất nhiều, đã giúp tôi phục vụ mbtiles vector trong 5 '!
Bwyss 16/07/2015

Xin chào Andreas - Tôi không thể làm việc này - bản đồ hiển thị, nhưng nó chỉ là một hình vuông lớn màu xám trống. Tôi không chắc chắn nơi bạn có nguồn mbtiles của bạn. Tôi đã thử xuất một số mbtiles mặc định từ tilemill.
mapsvers

bạn dường như sử dụng localhost: 7777 / v2 / gạch / cho vị trí cho các ô của mình, nhưng bạn đang đi đến đâu? Hoặc bạn cần làm gì để đảm bảo tệp mbtiles đã xuất phục vụ hình ảnh cho đường dẫn đó?
mapsvers

26

Việc lưu trữ các gạch vector trên của riêng bạn là tương đối đơn giản. MBTiles chứa các tệp .pbf phải được hiển thị trên web. Đó là nó.

Có lẽ dễ nhất là sử dụng một máy chủ nguồn mở đơn giản như TileServer-PHP và đặt tệp MBTiles vào cùng thư mục với các tệp dự án. Máy chủ Ngói thực hiện tất cả cấu hình lưu trữ cho bạn (CORS, TileJSON, tiêu đề gzip chính xác, v.v.). Cài đặt có nghĩa là chỉ giải nén trên máy chủ web hỗ trợ PHP.

Nếu bạn muốn khởi động TileServer-PHP trên máy tính xách tay của mình, bạn có thể với Docker. Container sẵn sàng để sử dụng là trên DockerHub . Trong Mac OS X và Windows, nó sẽ chạy trong vài phút với giao diện người dùng đồ họa Kitical: https://kitematic.com/ . Trong Kitical chỉ cần tìm kiếm "brickerver-php" và bắt đầu sẵn sàng sử dụng container / máy ảo với dự án bên trong. Sau đó nhấp vào "Tập" và thả vào thư mục tệp MBTiles của bạn. Bạn nhận được một lưu trữ đang chạy cho gạch vector của bạn!

Các ô vectơ như vậy có thể được mở trong MapBox Studio dưới dạng nguồn hoặc được hiển thị với trình xem WebGL của MapBox GL JS.

Về mặt kỹ thuật, thậm chí có thể lưu trữ các ô vectơ dưới dạng một thư mục đơn giản trên bất kỳ máy chủ web hoặc bộ lưu trữ đám mây hoặc thậm chí GitHub, nếu bạn giải nén .pbf ra khỏi bộ chứa MBtiles bằng một tiện ích như mbutil , hãy đặt CORS, TileJSON và gzip chính xác. Bellow là một dự án GitHub thể hiện cách tiếp cận như vậy là tốt.

Hãy thử người xem này: Trình xem MapBox GL JS

và xem các repos liên quan:


1
Đây là cách dễ nhất trong tất cả các tùy chọn ở trên đối với tôi, cảm ơn vì đã đăng.
mapsvers

PGRestAPI, nghe có vẻ hay, nhưng không cài đặt được cho tôi. Tôi không bao giờ có thể cài đặt thành công PGRestAPI. Vì vậy, máy chủ gạch php này là lựa chọn duy nhất của tôi và nó hoạt động hoàn hảo.
hoogw

Điều này là thú vị nhất, bạn có thể giải thích chính xác về việc thiết lập CORS và TileJSON để phục vụ các tệp pbf không? Tôi đã tải xuống một tệp pbf từ download.geofabrik.de/europe tuy nhiên dự án được liên kết chứa nhiều thư mục có nhiều tệp pbf.
php_nub_qq

12

Không phát ra tiếng còi của riêng tôi, nhưng https://github.com/spatialdev/PGRestAPI là một dự án tôi đã làm việc trên máy chủ đó. Xuất khẩu gạch vector .mbtiles từ Mapbox Studio.

Vẫn cần rất nhiều tài liệu, nhưng về cơ bản, hãy thả các tệp .mbtiles của bạn vào / data / pbf_mbtiles và khởi động lại ứng dụng nút. Nó sẽ đọc thông qua thư mục đó và cung cấp các điểm cuối cho các ô vector của bạn.

Nó cũng sẽ xem thông qua / dữ liệu / shapefiles và tạo các ô Vector Mapbox động khi đang di chuyển dựa trên .shp của bạn. Bạn cũng có thể trỏ vào một ví dụ PostGIS và nhận các ô vector động.

Chúng tôi sử dụng chúng cùng với https://github.com/SpatialServer/Leaflet.MapboxVectorTile , thư viện Ngói Vector / Tờ rơi / Mapbox mà chúng tôi cũng đang làm việc.


1
PGRestAPI không còn được phát triển tích cực một cách đáng tiếc
raphael

10

Cảm ơn vì câu hỏi tuyệt vời của bạn. Tôi không biết rằng cuối cùng họ đã phát hành một phiên bản ổn định của gạch vector. Hơn nữa, bạn có thể phải làm việc với câu trả lời này vì đây là nguồn ý tưởng cho "bất kỳ ý tưởng nào của bạn?" câu hỏi Tôi chưa có một studio chạy.

Tôi nghĩ rằng một trong những vấn đề mà bạn đang gặp phải là bạn đang sử dụng tệp brickjson. Bạn cần một dịch vụ brickjson để sử dụng loại tệp đó. Do đó, tôi tin rằng bạn cần thay đổi phần nguồn của mình thành một URL nội tuyến. Thử

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

hoặc là

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

Khi họ sử dụng mapbox://làm giao thức, đó là ký hiệu bí danh / tốc ký cho các dịch vụ của họ. Phần nguồn được thảo luận ngắn gọn khoảng 8:40 của video.

Một bước của quy trình gạch vector mới là quản lý dữ liệu vectơ bằng cách điều chỉnh những gì bạn muốn trong dữ liệu. Bước khác là đưa dữ liệu vectơ trở lại vào MapBox Studio và hiển thị dữ liệu / tạo biểu định kiểu. osm_roads sẽ là bước một trong khi tệp c.json của bạn là biểu định kiểu. Bạn có thể cần một máy chủ trực tiếp xếp câu một luồng như đã thảo luận vào khoảng 15:01 của video. Video nói rằng bạn cần thêm dữ liệu meta trong tệp xml.

Điều kỳ lạ ở đây là bạn tham chiếu .pbf và biểu định kiểu ở nơi khác nhưng url mà bạn cung cấp là các tệp .png kết quả được tạo từ dữ liệu vectơ.

Bạn không nói, nếu bạn có khóa MapBox. Đối với lưu trữ của riêng bạn, tôi tin rằng bạn sẽ phải sao chép các kiểu github và glyphs vào máy chủ của riêng bạn. Một lần nữa lưu ý rằng có một giao thức mapbox: // trong thẻ glyphs. Hai thẻ này có thể không cần thiết bởi vì bạn đang hiển thị các đường thẳng và đa giác chứ không phải POI thông qua các biểu tượng. Đó là giá trị xem xét.

Cuối cùng, video nói rằng bạn có thể đưa một lớp vectơ được tạo trở lại phòng thu để tạo kiểu cho nó. Bạn có thể muốn tham chiếu lớp vectơ của mình và áp dụng id: nền và id: đường phong cách có trong studio trước. Video nói rằng lát xếp trực tiếp là máy chủ đằng sau bối cảnh của MapBox Studio. Ý tưởng ở đây là đảm bảo rằng bạn có tất cả các bước hai vấn đề được hiểu và khắc phục trước khi bạn cố gắng phục vụ các ô vectơ cuối cùng được hiển thị động.


Ok, cảm ơn @Greg vì ý tưởng của bạn. Sẽ tiếp tục điều tra và trở lại với những phát hiện của tôi.
Andreas Bilger

4

https://github.com/osm2vectortiles/tileserver-gl-light dễ sử dụng hơn rất nhiều so với các giải pháp chính được đề cập - không cần thiết với các tệp JSON cần thiết. Bạn chỉ cần chạy nó với

tileserver-gl-light filename.mbtiles

và sau đó nó phục vụ gạch cho bạn. Nó hoạt động với các kiểu Mapbox GL được xác định trước như sáng-v9; Sau khi chạy máy chủ, bạn chỉ cần trỏ bất cứ thứ gì đang tiêu thụ gạch

http: // localhost: 8080 / style / sáng-v9.json


3

Bạn có thể muốn dùng thử máy chủ brickhut.js của chúng tôi. Về cơ bản, nó thực hiện tất cả những gì bạn cần = lưu trữ các vectơ vector và đi kèm với các ví dụ / tài liệu đẹp ... và kết hợp với openshift, đó là một điều thiết lập 5 phút. Xin hãy xem:

https://github.com/bg/tilehut https://github.com/bg/tilehut/tree/master/examples/simplemap_vector https://github.com/bg/tilehut#your-own-hosted-tileserver- trong 5 phút


1

Siêu muộn hơn, nhưng bây giờ GeoServer phục vụ pbf's (định dạng gạch vector)


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.