为什么 MapboxGL 客户端的服务器矢量切片渲染不正确
Why Server Vector Tiles for MapboxGL Client rendered incorrectly
我正在尝试在 Node.js 中设置一个 Web 服务器,该服务器使用 MapboxGL JS 提供要在浏览器中显示的矢量切片。矢量切片的数据存储在 PostGIS 数据库中。
我收到一个 geojson 文件并处理它,用下一句话创建一个数据库:CREATE TABLE IF NOT EXISTS countries ( table_id SERIAL, properties jsonb not null, geom geometry(GeometryZ,4326), primary key (table_id));
我当前的设置似乎在朝着正确的方向发展,因为我可以看到矢量切片正在加载并显示在浏览器中。但是渲染结果不正确(这是我地图的一部分的屏幕截图):
什么渲染不正确???
代码如下:
var express = require('express');
var SphericalMercator = require('sphericalmercator');
var mercator = new SphericalMercator({
size: 256 //tile size
});
const { pool } = require('../postgressql/config');
var app = express();
app.get('/:namelayer/:z/:x/:y.pbf', (req, res, next) => {
var options = {
x: parseInt(req.params.x),
y: parseInt(req.params.y),
z: parseInt(req.params.z),
layerName: req.params.namelayer
};
const bbox = mercator.bbox(options.x, options.y, options.z, false, '3857');
const sql = `
SELECT ST_AsMVT(q, '${options.layerName}', 4096, 'geom')
FROM (
SELECT
table_id, properties,
ST_AsMVTGeom(
geom,
ST_MakeEnvelope(${bbox[0]}, ${bbox[1]}, ${bbox[2]}, ${bbox[3]}, 4326),
4096,
256,
false
) AS geom
FROM ${'public.'+options.layerName} c
) q;
`;
try {
pool.query(sql, (error, results) => {
if (error) {
return res.status(500).json({
ok: false,
message: error
});
}
const tile = results.rows[0];
// set the response header content type
res.setHeader('Content-Type', 'application/x-protobuf');
// trigger catch if the vector tile has no data, (return a 204)
if (tile.st_asmvt.length === 0) {
res.status(204);
}
// send the tile!
res.send(tile.st_asmvt);
});
} catch (e) {
res.status(404).send({
error: e.toString(),
});
}
});
module.exports = app;
我使用了这个网站的想法:
很明显,你的投影有问题。看起来黑色叠加层比底图更垂直地向两极延伸,并且向北移动。
很难确定问题出在哪里,因为您没有包含客户端代码。矢量切片可能在 EPSG:3857 投影中完美呈现,但您将它们叠加在略有不同的投影上(可能是 EPSG:3785)。
您禁用 ST_AsMVTGeom
s clip_geom
参数的事实也表明您的边界框计算不正确,您正在解决这个问题。
在 gis.stackexchange.com
上发布问题可能会得到更好的答案
我正在尝试在 Node.js 中设置一个 Web 服务器,该服务器使用 MapboxGL JS 提供要在浏览器中显示的矢量切片。矢量切片的数据存储在 PostGIS 数据库中。
我收到一个 geojson 文件并处理它,用下一句话创建一个数据库:CREATE TABLE IF NOT EXISTS countries ( table_id SERIAL, properties jsonb not null, geom geometry(GeometryZ,4326), primary key (table_id));
我当前的设置似乎在朝着正确的方向发展,因为我可以看到矢量切片正在加载并显示在浏览器中。但是渲染结果不正确(这是我地图的一部分的屏幕截图):
什么渲染不正确???
代码如下:
var express = require('express');
var SphericalMercator = require('sphericalmercator');
var mercator = new SphericalMercator({
size: 256 //tile size
});
const { pool } = require('../postgressql/config');
var app = express();
app.get('/:namelayer/:z/:x/:y.pbf', (req, res, next) => {
var options = {
x: parseInt(req.params.x),
y: parseInt(req.params.y),
z: parseInt(req.params.z),
layerName: req.params.namelayer
};
const bbox = mercator.bbox(options.x, options.y, options.z, false, '3857');
const sql = `
SELECT ST_AsMVT(q, '${options.layerName}', 4096, 'geom')
FROM (
SELECT
table_id, properties,
ST_AsMVTGeom(
geom,
ST_MakeEnvelope(${bbox[0]}, ${bbox[1]}, ${bbox[2]}, ${bbox[3]}, 4326),
4096,
256,
false
) AS geom
FROM ${'public.'+options.layerName} c
) q;
`;
try {
pool.query(sql, (error, results) => {
if (error) {
return res.status(500).json({
ok: false,
message: error
});
}
const tile = results.rows[0];
// set the response header content type
res.setHeader('Content-Type', 'application/x-protobuf');
// trigger catch if the vector tile has no data, (return a 204)
if (tile.st_asmvt.length === 0) {
res.status(204);
}
// send the tile!
res.send(tile.st_asmvt);
});
} catch (e) {
res.status(404).send({
error: e.toString(),
});
}
});
module.exports = app;
我使用了这个网站的想法:
很明显,你的投影有问题。看起来黑色叠加层比底图更垂直地向两极延伸,并且向北移动。
很难确定问题出在哪里,因为您没有包含客户端代码。矢量切片可能在 EPSG:3857 投影中完美呈现,但您将它们叠加在略有不同的投影上(可能是 EPSG:3785)。
您禁用 ST_AsMVTGeom
s clip_geom
参数的事实也表明您的边界框计算不正确,您正在解决这个问题。
在 gis.stackexchange.com
上发布问题可能会得到更好的答案