为MapboxGL客户端自行托管的矢量磁贴不正确地提交

问题描述:

我正在尝试在Node.js中设置一个Web服务器,该服务器将使用MapboxGL JS在浏览器中显示矢量磁贴。矢量切片的数据存储在PostGIS数据库中。为MapboxGL客户端自行托管的矢量磁贴不正确地提交

我目前的设置似乎正确的方向,因为我可以看到矢量瓷砖被加载和显示在浏览器中。然而,渲染结果是不正确(这是我的地图的部分截图):

Incorrect tiles

绿色建筑足迹的上半部分重复图像的下半部分。我也注意到建筑物放大和缩小时“改变”的位置,表明在某种程度上瓷砖呈现偏移或不正确的程度...导入的数据是在SRID 4326

这里是我的代码:

var zlib = require('zlib'); 

var express = require('express'); 
var mapnik = require('mapnik'); 
var Promise = require('promise'); 
var SphericalMercator = require('sphericalmercator'); 

var mercator = new SphericalMercator({ 
    size: 256 //tile size 
}); 

mapnik.register_default_input_plugins(); 

var app = express(); 

app.get('/vector-tiles/:layerName/:z/:x/:y.pbf', function(req, res) { 
    var options = { 
     x: parseInt(req.params.x), 
     y: parseInt(req.params.y), 
     z: parseInt(req.params.z), 
     layerName: req.params.layerName 
    }; 
    makeVectorTile(options).then(function(vectorTile) { 
     zlib.deflate(vectorTile, function(err, data) { 
      if (err) return res.status(500).send(err.message); 
      res.setHeader('Content-Encoding', 'deflate'); 
      res.setHeader('Content-Type', 'application/x-protobuf'); 
      res.send(data); 
     }); 
    }); 
}); 

function makeVectorTile(options) { 
    var extent = mercator.bbox(options.x, options.y, options.z, false, '4326'); 

    var map = new mapnik.Map(256, 256); 
    map.extent = extent; 

    var layer = new mapnik.Layer(options.layerName); 
    layer.datasource = new mapnik.Datasource({ 
     type: 'postgis', 
     dbname: 'databasename', 
     table: options.layerName, 
     user: 'username', 
     password: 'password' 
    }); 
    layer.styles = ['default']; 
    map.add_layer(layer); 
    return new Promise(function (resolve, reject) { 
     var vtile = new mapnik.VectorTile(parseInt(options.z), parseInt(options.x), parseInt(options.y)); 
     map.render(vtile, function (err, vtile) { 
      if (err) return reject(err); 
      resolve(vtile.getData()); 
     }); 
    }); 
} 

定制矢量数据源被包括在地图这样的:

var map = new mapboxgl.Map({ 
    container: 'map', 
    style: 'mapbox://styles/mapbox/light-v8', 
    zoom: 10, 
    center: [13.739910, 51.051151] 
}); 

map.on('style.load', function() { 
    map.addSource('local', { 
     type: 'vector', 
     tiles: ["http://localhost:3333/vector-tiles/building/{z}/{x}/{y}.pbf"] 
    }); 
    map.addLayer({ 
     "id": "park", 
     "source": "local", 
     "type": "fill", 
     "source-layer": "building", 
     "paint": { 
      "fill-color": "#5DC73A" 
     } 
    }); 
}); 

在上面的示例代码的地图使用不正确的空间参照系。矢量瓷砖使用Web Mercator Projection,但mapnik地图在WGS84中初始化。当明确提供网页mercator到mercator.bbox方法和mapnik.Map构造函数时,矢量磁贴在客户端中正确呈现:

var extent = mercator.bbox(options.x, options.y, options.z, false, '3857'); 

var map = new mapnik.Map(256, 256, '+init=epsg:3857');