MapboxGL Client的矢量图块不返回属性

我正在尝试在Node.js中设置一个Web服务器,该服务器提供使用MapboxGL JS在浏览器中显示的矢量图块。矢量图块的数据存储在PostGIS数据库中。

这是我的数据库方案:CREATE TABLE IF NOT EXISTS earthquakes( table_id SERIAL,properties jsonb not null,geom geometry(GeometryZ,4326),primary key (table_id));

地震在geojson内部具有属性,我将每个要素存储在数据库中。

例如,地震具有以下属性:"properties": { "id": "ak16994521","mag": 2.3,"time": 1507425650893,"felt": null,"tsunami": 0 }。您可以看到所有geojson here

我当前的设置似乎朝着正确的方向发展,因为我可以看到矢量图块正在加载并显示在浏览器中,并且渲染结果是正确的。

但是,当我单击某个功能时,仅返回table_id而不返回每个功能的属性。

如何发送属性?

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('/: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
    };

    makeVectorTile(options).then( (vectorTile) => {
        zlib.deflate(vectorTile,(err,data) => {
            if (err) return res.status(500).send(err.message);

            res.setHeader('Content-Encoding','deflate');
            res.setHeader('Content-Type','application/x-protobuf');
            return res.send(data);
        });
    });
});

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

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

    var layer = new mapnik.Layer(options.layerName);
    layer.datasource = new mapnik.Datasource({
        type: process.env.DB_TYPE,dbname: process.env.DB_DATABASE,table: options.layerName,user: process.env.DB_USER,password: process.env.DB_PASSWORD
    });

    layer.styles = ['default'];
    map.add_layer(layer);

    return new Promise( (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);
            console.log(`${vtile.getData().length} KB`);
            resolve(vtile.getData());
        });
    });
};

module.exports = app;
pangy521 回答:MapboxGL Client的矢量图块不返回属性

感谢所有帮助我的人。

这是带有查询的代码,可用于切片服务器。

我使用此查询来获取键数组:

  

const sql = SELECT ARRAY_AGG(f)作为密钥FROM(SELECT   jsonb_object_keys(properties)f由$ {options.layerName}分组,按f)   你;

     

随后,该函数创建一个查询以获取每个属性作为名为generateSQL的列。

我希望代码会有用。

/** CONSTANTS **/
const TILE_SIZE = 256;
const PROJECTION_STRING = '+init=epsg:3857';

/** LIBRARIES **/
var zlib = require('zlib');
var express = require('express');
var mapnik = require('mapnik');
var Promise = require('promise');
var SphericalMercator = require('sphericalmercator');

const { pool } = require('../postgressql/config');

var mercator = new SphericalMercator({
    size: TILE_SIZE
});

mapnik.register_default_input_plugins();

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 sql = `SELECT ARRAY_AGG(f) as keys FROM (SELECT jsonb_object_keys(properties) f FROM ${options.layerName} group by f) u`;
    try {
        pool.query(sql,(error,results) => {
            if (error) {
                return res.status(500).json({
                    ok: false,message: error
                });
            }

            const keys = (results && results.rows && results.rows.length > 0 && results.rows[0].keys && results.rows[0].keys.length >0) ? results.rows[0].keys.slice() : [];
            const sql = generateSQL(options,keys);

            makeVectorTile(options,sql).then( (vectorTile) => {
                zlib.deflate(vectorTile,(err,data) => {
                    if (err) {
                        return res.status(500).send(err.message);
                    }

                    res.setHeader('Content-Encoding','deflate');
                    res.setHeader('Content-Type','application/x-protobuf');
                    res.setHeader('Access-Control-Allow-Origin','*');
                    return res.send(data);
                });
            });
        });
    } catch (e) {
        res.status(404).send({
            error: e.toString(),});
    }
});

function generateSQL(options,keys) {

    if (keys.length === 0) {
        return `select table_id,geom from ${options.layerName}`;
    } else {
        let sql = "";
        keys.forEach( key => {
            sql = sql + `(properties->>'${key}') as ${key},`;
        });
        sql = `select table_id,${sql} geom from ${options.layerName}`
        return sql;
    }
};

function makeVectorTile(options,sql) {

    var extent = mercator.bbox(options.x,options.y,options.z,false,'3857');
    var map = new mapnik.Map(TILE_SIZE,TILE_SIZE,PROJECTION_STRING);
    map.extent = extent;

    var layer = new mapnik.Layer(options.layerName);
    layer.datasource = new mapnik.Datasource({
        type: process.env.DB_TYPE,dbname: process.env.DB_DATABASE,// table: options.layerName,table: `(${sql}) as tile`,user: process.env.DB_USER,password: process.env.DB_PASSWORD
    });

    layer.styles = ['default'];
    map.add_layer(layer);

    return new Promise( (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);
            }
            console.log(`${vtile.getData().length} KB`);
            resolve(vtile.getData());
        });
    });
};

module.exports = app;
本文链接:https://www.f2er.com/2907792.html

大家都在问