Skip to content

Instantly share code, notes, and snippets.

@stepankuzmin
Last active July 29, 2019 10:31
Show Gist options
  • Save stepankuzmin/b750d18e5f362677e2dc7ffc879c41d2 to your computer and use it in GitHub Desktop.
Save stepankuzmin/b750d18e5f362677e2dc7ffc879c41d2 to your computer and use it in GitHub Desktop.
PostGIS ST_AsMVT JSONB properties encoding bug
const fs = require("fs");
const geobuf = require("geobuf");
const Protobuf = require("pbf");
const pgp = require("pg-promise")();
const vt = require("vector-tile");
const db = pgp(process.env.DATABASE_URL);
const tile_with_properties_as_jsonb = `WITH data AS (
SELECT * FROM (VALUES
(1, 1.1, 0.1, ST_GeomFromEWKT('SRID=3857;POINT(1 1)')),
(2, 2.2, 0.2, ST_GeomFromEWKT('SRID=3857;POINT(2 2)')),
(3, 3.3, 0.3, ST_GeomFromEWKT('SRID=3857;POINT(3 3)'))
) AS t (id, num1, num2, geom)
)
SELECT
ST_AsMVT(tile, 'data', 4096, 'geom') FROM (
SELECT
ST_AsMVTGeom(
geom,
ST_GeomFromEWKT('SRID=3857;POLYGON((-20037508.34 20037508.34,-20037508.34 -20037508.34,20037508.34 -20037508.34,20037508.34 20037508.34,-20037508.34 20037508.34))'),
4096,
0,
true
) as geom,
jsonb_build_object(
'id', id,
'num1', num1,
'num2', num2
) as properties
FROM data
) as tile;`;
const tile_with_properties_as_json = `WITH data AS (
SELECT * FROM (VALUES
(1, 1.1, 0.1, ST_GeomFromEWKT('SRID=3857;POINT(1 1)')),
(2, 2.2, 0.2, ST_GeomFromEWKT('SRID=3857;POINT(2 2)')),
(3, 3.3, 0.3, ST_GeomFromEWKT('SRID=3857;POINT(3 3)'))
) AS t (id, num1, num2, geom)
)
SELECT
ST_AsMVT(tile, 'data', 4096, 'geom') FROM (
SELECT
ST_AsMVTGeom(
geom,
ST_GeomFromEWKT('SRID=3857;POLYGON((-20037508.34 20037508.34,-20037508.34 -20037508.34,20037508.34 -20037508.34,20037508.34 20037508.34,-20037508.34 20037508.34))'),
4096,
0,
true
) as geom,
json_build_object(
'id', id,
'num1', num1,
'num2', num2
) as properties
FROM data
) as tile;`;
const tile_with_plain_properties = `WITH data AS (
SELECT * FROM (VALUES
(1, 1.1, 0.1, ST_GeomFromEWKT('SRID=3857;POINT(1 1)')),
(2, 2.2, 0.2, ST_GeomFromEWKT('SRID=3857;POINT(2 2)')),
(3, 3.3, 0.3, ST_GeomFromEWKT('SRID=3857;POINT(3 3)'))
) AS t (id, num1, num2, geom)
)
SELECT
ST_AsMVT(tile, 'data', 4096, 'geom') FROM (
SELECT
ST_AsMVTGeom(
geom,
ST_GeomFromEWKT('SRID=3857;POLYGON((-20037508.34 20037508.34,-20037508.34 -20037508.34,20037508.34 -20037508.34,20037508.34 20037508.34,-20037508.34 20037508.34))'),
4096,
0,
true
) as geom,
id,
num1,
num2
FROM data
) as tile;`;
const tile2geojson = buffer => {
const tile = new vt.VectorTile(new Protobuf(buffer));
const layers = Object.keys(tile.layers);
var collection = { type: "FeatureCollection", features: [] };
layers.forEach(function(layerID) {
var layer = tile.layers[layerID];
if (layer) {
for (var i = 0; i < layer.length; i++) {
var feature = layer.feature(i).toGeoJSON(0, 0, 0);
if (layers.length > 1) feature.properties.vt_layer = layerID;
collection.features.push(feature);
}
}
});
return collection;
};
Promise.all([
db
.one(tile_with_properties_as_json)
.then(results => results.st_asmvt)
.then(tile2geojson),
db
.one(tile_with_properties_as_jsonb)
.then(results => results.st_asmvt)
.then(tile2geojson),
db
.one(tile_with_plain_properties)
.then(results => results.st_asmvt)
.then(tile2geojson)
])
.then(results => {
const [json, jsonb, plain] = results;
fs.writeFileSync("tile_json.geojson", JSON.stringify(json, null, 2));
fs.writeFileSync("tile_jsonb.geojson", JSON.stringify(jsonb, null, 2));
fs.writeFileSync("tile_plain.geojson", JSON.stringify(plain, null, 2));
})
.then(() => db.$pool.end());
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
WITH data AS (
SELECT * FROM (VALUES
(1, 1.1, 0.1, ST_GeomFromEWKT('SRID=3857;POINT(1 1)')),
(2, 2.2, 0.2, ST_GeomFromEWKT('SRID=3857;POINT(2 2)')),
(3, 3.3, 0.3, ST_GeomFromEWKT('SRID=3857;POINT(3 3)'))
) AS t (id, num1, num2, geom)
)
SELECT
ST_AsMVT(tile, 'data', 4096, 'geom') FROM (
SELECT
ST_AsMVTGeom(
geom,
ST_GeomFromEWKT('SRID=3857;POLYGON((-20037508.34 20037508.34,-20037508.34 -20037508.34,20037508.34 -20037508.34,20037508.34 20037508.34,-20037508.34 20037508.34))'),
4096,
0,
true
) as geom,
json_build_object(
'id', id,
'num1', num1,
'num2', num2
) as properties
FROM data
) as tile;
Display the source blob
Display the rendered blob
Raw
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
0,
0
]
},
"properties": {
"id": 1,
"num1": 1,
"num2": 0
}
},
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
0,
0
]
},
"properties": {
"id": 2,
"num1": 2,
"num2": 0
}
},
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
0,
0
]
},
"properties": {
"id": 3,
"num1": 3,
"num2": 0
}
}
]
}
WITH data AS (
SELECT * FROM (VALUES
(1, 1.1, 0.1, ST_GeomFromEWKT('SRID=3857;POINT(1 1)')),
(2, 2.2, 0.2, ST_GeomFromEWKT('SRID=3857;POINT(2 2)')),
(3, 3.3, 0.3, ST_GeomFromEWKT('SRID=3857;POINT(3 3)'))
) AS t (id, num1, num2, geom)
)
SELECT
ST_AsMVT(tile, 'data', 4096, 'geom') FROM (
SELECT
ST_AsMVTGeom(
geom,
ST_GeomFromEWKT('SRID=3857;POLYGON((-20037508.34 20037508.34,-20037508.34 -20037508.34,20037508.34 -20037508.34,20037508.34 20037508.34,-20037508.34 20037508.34))'),
4096,
0,
true
) as geom,
jsonb_build_object(
'id', id,
'num1', num1,
'num2', num2
) as properties
FROM data
) as tile;
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
WITH data AS (
SELECT * FROM (VALUES
(1, 1.1, 0.1, ST_GeomFromEWKT('SRID=3857;POINT(1 1)')),
(2, 2.2, 0.2, ST_GeomFromEWKT('SRID=3857;POINT(2 2)')),
(3, 3.3, 0.3, ST_GeomFromEWKT('SRID=3857;POINT(3 3)'))
) AS t (id, num1, num2, geom)
)
SELECT
ST_AsMVT(tile, 'data', 4096, 'geom') FROM (
SELECT
ST_AsMVTGeom(
geom,
ST_GeomFromEWKT('SRID=3857;POLYGON((-20037508.34 20037508.34,-20037508.34 -20037508.34,20037508.34 -20037508.34,20037508.34 20037508.34,-20037508.34 20037508.34))'),
4096,
0,
true
) as geom,
id,
num1,
num2
FROM data
) as tile;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment