Mosaicos vectoriales de Mapbox con alojamiento propio

81

Como se presentó en una charla en FOSS4G, Mapbox Studio permite crear mosaicos vectoriales de Mapbox y exportarlos como un .mbtilesarchivo.

La biblioteca mapbox-gl.js se puede usar para diseñar y representar dinámicamente mosaicos vectoriales de Mapbox en el lado del cliente (navegador).

La parte que falta: ¿cómo puedo alojar los mosaicos vectoriales de Mapbox ( .mbtiles) para poder consumirlos con mapbox-gl.js?

Sé que Mapbox Studio puede cargar los mosaicos vectoriales en el servidor de Mapbox y dejar que aloje los mosaicos. Pero esa no es una opción para mí, quiero alojar los mosaicos de vectores en mi propio servidor.


El enfoque de TileStream a continuación resultó ser un callejón sin salida. Vea mi respuesta para una solución de trabajo con Tilelive.


Intenté TileStream, que puede servir mosaicos de imágenes de .mbtilesarchivos:

Mi página web usa 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>

y crea un mapboxgl.Map en un script JavaScript:

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

El c.jsonarchivo de estilo configura la fuente de mosaico vectorial:

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

... con la siguiente especificación TileJSON en tile.json:

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

... que apunta a mi servidor TileStream ejecutándose en localhost:8888. TileStream se ha iniciado con:

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

... donde la ..\tilescarpeta contiene mi osm_roads.mbtilesarchivo.

Con esta configuración, puedo abrir mi página web pero solo ver la capa de fondo. En el rastreo de la red del navegador, puedo ver que los mosaicos se cargan cuando hago un acercamiento, pero la consola de errores de JavaScript del navegador contiene varios errores del formulario

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

Dado que los mosaicos vectoriales no son .pngimágenes, sino más bien archivos ProtoBuf, la URL de los mosaicos en http://localhost:8888/v2/osm_roads/{z}/{x}/{y}.pbfrealidad tendría más sentido, pero eso no funciona.

¿Algunas ideas?

Andreas Bilger
fuente

Respuestas:

53

Como señaló @Greg, en lugar de TileStream (mi primer intento) debería usar Tilelive para alojar sus propios mosaicos vectoriales.

Tilelive no es un servidor en sí mismo, sino un marco de back-end que trata con mosaicos en diferentes formatos de diferentes fuentes. Pero está basado en Node.js, por lo que puede convertirlo en un servidor de una manera bastante directa. Para leer mosaicos de una .mbtilesfuente exportada por Mapbox Studio, necesita el módulo node-mbtiles tilelive.

Nota al margen: Mapbox Studio actual tiene un error en Windows y OS X que impide que un .mbtilesarchivo exportado aparezca en el destino elegido. Solución alternativa: solo tome el export-xxxxxxxx.mbtilesarchivo más reciente ~/.mapbox-studio/cache.

Encontré dos implementaciones de servidor ( ten20 tile server de alexbirkett y TileServer de hanchao ) que utilizan Express.js como servidor de aplicaciones web.

Aquí está mi enfoque minimalista que se basa libremente en estas implementaciones:

  1. Instalar Node.js
  2. Agarra los paquetes de nodos con npm install tilelive mbtiles express
  3. Implemente el servidor en el archivo 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'));
        });
    });
    

    Nota: Los Access-Control-Allow-...encabezados permiten el intercambio de recursos de origen cruzado (CORS) para que las páginas web servidas desde un servidor diferente puedan acceder a los mosaicos.

  4. Ejecútalo con node server.js

  5. Configure la página web usando Mapbox GL JS en 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. Indique la ubicación de la fuente de mosaico y diseñe las capas con lo siguiente 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. Servir a la página web y alegrarse.

Andreas Bilger
fuente
2
tenga en cuenta que necesita tres ///para definir el archivo mbtiles en:tilelive.load('mbtiles://path/to/osm_roads.mbtiles', function(err, source) {
CDavis
@cdavis: Eso parece depender del sistema operativo: ///se necesitan tres para Linux y OS X como por ejemplo mbtiles:///usr/local/osm_roads.mbtiles. En Windows sin embargo, sólo dos //son necesarios si se especifica el disco, como por ejemplo mbtiles://D/data/osm_roads.mbtiles.
Andreas Bilger
Realmente útil, muchas gracias, ¡me ayudó a servir vectores mbtiles en 5 '!
Bwyss
Hola Andreas, no pude hacer que esto funcionara, el mapa se muestra, pero es solo un gran cuadrado gris en blanco. No estoy seguro de dónde obtuviste tu fuente de mbtiles. Intenté exportar algunos de los mbtiles predeterminados de tilemill.
mheavers
parece que usa localhost: 7777 / v2 / tiles / para la ubicación de sus mosaicos, pero ¿de dónde obtiene ese camino? ¿O qué necesita hacer para asegurarse de que el archivo mbtiles exportado sirva las imágenes a esa ruta?
mheavers
26

El alojamiento de los mosaicos vectoriales por su cuenta es relativamente sencillo. Los MBTiles contienen archivos .pbf que deben exponerse a la web. Eso es.

Probablemente lo más fácil es usar un servidor de código abierto simple como TileServer-PHP y colocar el archivo MBTiles en la misma carpeta que los archivos del proyecto. TileServer hace toda la configuración de alojamiento por usted (CORS, TileJSON, encabezados gzip correctos, etc.). La instalación significa simplemente desempacar en un servidor web habilitado para PHP.

Si desea iniciar TileServer-PHP en su computadora portátil, puede hacerlo con Docker. El contenedor listo para usar está en DockerHub . En Mac OS X y Windows, se ejecuta en un par de minutos con la interfaz gráfica de usuario de Kitematic: https://kitematic.com/ . En Kitematic solo busque "tileserver-php" e inicie la máquina virtual / contenedor lista para usar con el proyecto dentro. Luego haga clic en "Volúmenes" y suelte en la carpeta su archivo MBTiles. ¡Obtienes un hosting para tus mosaicos vectoriales!

Dichos mosaicos vectoriales podrían abrirse en MapBox Studio como fuente, o mostrarse con el visor MapBox GL JS WebGL.

Técnicamente, incluso es posible alojar los mosaicos vectoriales como una carpeta simple en cualquier servidor web o almacenamiento en la nube, o incluso GitHub, si desempaqueta el .pbf individual del contenedor de MBtiles con una utilidad como mbutil , configure CORS, TileJSON y gzip correctamente. Bellow es un proyecto de GitHub que demuestra ese enfoque también.

Prueba este visor: Visor MapBox GL JS

y ver los repositorios relacionados:

Klokan Technologies GmbH
fuente
1
Esta fue, con mucho, la más fácil de todas las opciones anteriores para mí, gracias por publicar.
mheavers
PGRestAPI, suena genial, pero la instalación falló para mí. Nunca podré instalar con éxito PGRestAPI. Así que este servidor de mosaico php es mi única opción y funciona perfecto.
hoogw
Esto es muy interesante, ¿podría explicar cómo configurar CORS y TileJSON correctamente para servir los archivos pbf? He descargado un archivo pbf de download.geofabrik.de/europe, sin embargo, el proyecto vinculado contiene muchos directorios con muchos archivos pbf.
php_nub_qq
12

No para sonar mi propia bocina, pero https://github.com/spatialdev/PGRestAPI es un proyecto en el que he estado trabajando que aloja las exportaciones de mosaicos de vectores .mbtiles de Mapbox Studio.

Todavía necesita mucha documentación, pero básicamente, suelte sus archivos .mbtiles en / data / pbf_mbtiles y reinicie la aplicación de nodo. Leerá a través de esa carpeta y ofrecerá puntos finales para sus mosaicos vectoriales.

También se verá a través de / data / shapefiles, y creará mosaicos vectoriales dinámicos de Mapbox sobre la marcha en función de su .shp. También puede apuntar a una instancia de PostGIS y obtener mosaicos vectoriales dinámicos.

Los usamos junto con https://github.com/SpatialServer/Leaflet.MapboxVectorTile , una biblioteca de mosaicos vectoriales de folleto / mapa en la que también hemos estado trabajando.

Ryan Whitley
fuente
1
Desafortunadamente, PGRestAPI ya no se desarrolla activamente
raphael
10

Gracias por la gran pregunta. No sabía que finalmente habían lanzado una versión estable de los mosaicos vectoriales. Además, es posible que tenga que trabajar con esta respuesta, ya que es una fuente de ideas para sus "¿alguna idea?" pregunta. Todavía no tengo un estudio de funcionamiento.

Creo que uno de los problemas con los que se encuentra es que está utilizando un archivo tilejson. Necesita un servicio tilejson para usar ese tipo de archivo. Por lo tanto, creo que debe cambiar su sección de fuentes a una URL en línea. Tratar

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

o

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

Cuando se usan mapbox://como protocolo, es una notación de alias / abreviatura para sus servicios. La sección de fuentes se discutió brevemente alrededor de las 8:40 del video.

Un paso del nuevo proceso de mosaico de vectores es curar los datos del vector ajustando lo que desea en los datos. El otro paso es traer los datos del vector nuevamente a MapBox Studio y renderizar los datos / crear una hoja de estilo. osm_roads sería el primer paso mientras que su archivo c.json es la hoja de estilo. Es posible que necesite un servidor de mosaico en vivo con una secuencia de mosaico como se discutió alrededor de las 15:01 del video. El video dice que necesita metadatos adicionales en el archivo xml.

Lo extraño aquí es que hace referencia al .pbf y la hoja de estilo en otro lugar, pero la url que proporciona son los archivos .png de mosaicos resultantes que se generan a partir de los datos vectoriales.

No diga si tiene una clave MapBox. Para su propio alojamiento, creo que tendrá que copiar los estilos y glifos de github a su propio servidor. Observe nuevamente que hay un protocolo mapbox: // en la etiqueta de glifos. Es posible que estas dos etiquetas no sean necesarias porque representa líneas planas y polígonos y no PDI a través de iconos. Vale la pena echarle un vistazo.

Finalmente, el video dice que puedes llevar una capa vectorial generada nuevamente al estudio para darle estilo. Es posible que desee hacer referencia a su capa vectorial y aplicar primero su estilo id: fondo e id: carreteras en el estudio. El video dice que tile live es el servidor detrás de la escena de MapBox Studio. La idea aquí es asegurarse de que tiene todos los problemas del paso dos entendidos y solucionados antes de intentar servir los mosaicos de vectores finales que se representan dinámicamente.

Greg
fuente
Ok, gracias @Greg por tus ideas. Investigaré más y volveré con mis hallazgos.
Andreas Bilger
1

Súper más tarde, pero ahora GeoServer sirve pbf (formato de mosaico vectorial)

Bwyss
fuente
0

Otras opciones que puede considerar para servir azulejos;

Tegola (Escrito en Go)

Solador

Hay una buena introducción a este tema aquí

mapeo dom
fuente