Самостоятельно размещаемые векторные плитки 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 вьюер

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

Klokan Technologies GmbH
источник
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
источник
Хорошо, спасибо @Greg за ваши идеи. Будем дополнительно расследовать и вернуться с моими выводами.
Андреас Билгер
4

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

tileserver-gl-light filename.mbtiles

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

HTTP: // локальный: 8080 / стили / ярко-v9.json

Mohan
источник
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 (векторный формат листов)

Bwyss
источник
0

Другие варианты, которые вы можете рассмотреть для подачи плитки;

Тегола (Написано на Го)

плиточник

Там хорошее введение в эту тему здесь

картография дом
источник