/ / Samo hostowane kafle wektorowe dla klienta MapboxGL renderowane niepoprawnie - node.js, mapnik, mapbox-gl-js, kafle wektorowe

Samo hostowane kafle wektorowe dla klienta MapboxGL renderowane niepoprawnie - node.js, mapnik, mapbox-gl-js, kafle wektorowe

Próbuję skonfigurować serwer sieciowy w Node.js, który obsługuje kafle wektorowe wyświetlane w przeglądarce przy użyciu JS MapboxGL. Dane dotyczące płytek wektorowych są przechowywane w bazie danych PostGIS.

Moja obecna konfiguracja wydaje się iść w prawokierunek, ponieważ widzę załadowane i wyświetlane w przeglądarce kafelki wektorowe. Jednak renderowany wynik jest nieprawidłowy (jest to zrzut ekranu sekcji mojej mapy):

Nieprawidłowe kafelki

Górna połowa zielonych śladów budynku jestpowtórzone w dolnej połowie obrazu. Zauważyłem również, że budynki zmieniają pozycje podczas powiększania i pomniejszania, wskazując, że w jakiś sposób płytki są renderowane jako przesunięte lub w niewłaściwym zakresie ... Zaimportowane dane znajdują się w SRID 4326.

Oto mój kod:

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());
});
});
}

Niestandardowe wektorowe źródło danych jest zawarte na mapie w następujący sposób:

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"
}
});
});

Odpowiedzi:

4 dla odpowiedzi № 1

Mapa w powyższym przykładowym kodzie używa nieprawidłowych przestrzennych systemów odniesienia. Wykorzystanie płytek wektorowych Web Mercator Projection, ale Mapnik Map jest inicjowany w WGS84. Po wyraźnym udostępnieniu webccatora obu mercator.bbox metoda i mapnik.Map konstruktor, kafle wektorowe renderują się poprawnie w kliencie:

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

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