Самостоятельно размещаемые векторные плитки 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 node-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 и OS X, например, например mbtiles:///usr/local/osm_roads.mbtiles. Однако в Windows //требуется только два , если указать диск, например, например mbtiles://D/data/osm_roads.mbtiles.
— Андреас Билгер

Действительно полезно, большое спасибо, помогло мне обслуживать векторные mbtiles в 5 '!
— Bwyss

Привет, Андреас - я не смог заставить это работать - карта отображается, но это просто большой пустой серый квадрат. Я не уверен, где вы взяли свой источник мобильной связи. Я попытался экспортировать некоторые из mbtiles по умолчанию из плитки.
— Mheavers

вы, кажется, используете localhost: 7777 / v2 /iles / для расположения ваших плиток, но где вы получаете этот путь? Или что нужно сделать, чтобы убедиться, что экспортированный файл mbtiles отправляет изображения по этому пути?
— Mheavers

26

Хостинг векторных плиток самостоятельно относительно прост. MBTiles содержит файлы .pbf, которые должны быть доступны в Интернете. Вот и все.

Вероятно, проще всего использовать простой сервер с открытым исходным кодом, такой как TileServer-PHP, и поместить файл MBTiles в ту же папку, что и файлы проекта. TileServer выполняет всю конфигурацию хостинга за вас (CORS, TileJSON, правильные заголовки gzip и т. Д.). Установка означает просто распаковку на веб-сервере с поддержкой PHP.

Если вы хотите запустить TileServer-PHP на своем ноутбуке, вы можете использовать Docker. Готовый контейнер находится на DockerHub . В Mac OS X и Windows он запускается через пару минут с графическим интерфейсом пользователя Kitematic: https://kitematic.com/ . В Kitematic просто найдите «tileserver-php» и запустите готовый контейнер / виртуальную машину с проектом внутри. Затем нажмите «Тома» и поместите в папку файл MBTiles. Вы получаете работающий хостинг для ваших векторных плиток!

Такие векторные плитки можно открывать в MapBox Studio как источник или отображать в программе просмотра MapBox GL JS WebGL.

Технически можно даже разместить векторные плитки в виде простой папки на любом веб-сервере, в облачном хранилище или даже на GitHub, если вы распакуете отдельный файл .pbf из контейнера MBtiles с помощью утилиты, такой как mbutil , установите CORS, TileJSON. и gzip правильно. Bellow - это проект GitHub, демонстрирующий такой подход.

Попробуйте этот просмотрщик: MapBox GL JS вьюер

и посмотреть соответствующие репозитории:


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 на лету на основе вашего .shp. Вы также можете указать на экземпляр PostGIS и получить динамические векторные плитки.

Мы используем их вместе с https://github.com/SpatialServer/Leaflet.MapboxVectorTile , библиотекой векторных листов Leaflet / Mapbox, над которой мы также работаем.


1
Не PGRestAPI уже не активно развивается , к сожалению
— Raphael

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 на ваш собственный сервер. Еще раз обратите внимание, что в теге glyphs есть протокол mapbox: //. Эти два тега могут не понадобиться, поскольку вы отображаете простые линии и полигоны, а не POI с помощью значков. Стоит взглянуть.

Наконец, видео говорит о том, что вы можете взять сгенерированный векторный слой обратно в студию для его стилизации. Возможно, вы захотите сослаться на свой векторный слой и вначале применить стиль id: background и id: roads в студии. Видео говорит о том, что плитка вживую является сервером за сценой MapBox Studio. Идея здесь состоит в том, чтобы убедиться, что у вас есть все проблемы второго шага, которые были поняты и исправлены, прежде чем вы попытаетесь обработать окончательные векторные листы, которые отображаются динамически.


Хорошо, спасибо @Greg за ваши идеи. Будем дополнительно расследовать и вернуться с моими выводами.
— Андреас Билгер

4

https://github.com/osm2vectortiles/tileserver-gl-light намного проще в использовании, чем упомянутые основные решения - не нужно возиться с файлами JSON. Вы просто запускаете это с

tileserver-gl-light filename.mbtiles

а потом он подает плитки для вас. Он работает с предопределенными стилями Mapbox GL, такими как bright-v9; после запуска сервера вы просто указываете, что потребляет плитки

HTTP: // локальный: 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

Супер позже, но теперь GeoServer обслуживает pbf (векторный формат листов)


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.