Skip to content
章节导航

postgis

1. 添加扩展

扩展的添加可以通过新建数据库的时候选择空间模板,如在新建的时候没有选择空间模板,可在数据库创建完后通过如下命令添加。

sql
create extension postgis

2. 空间函数

postgis中的空间函数可分为几类:几何创建、几何编辑、几何计算、坐标转换等。常见的postgis空间函数及说明如下表所示。

更多的可参阅其官方说明文档。

示例: ❐ 查看

3. 矢量切片

通过node和pg搭建一个矢量切片服务。后端工程的搭建可参考项目-接口实现的操作。核心实现代码如下:

js
const pgConfig = require('../config/pgConfig');
const pg = require('pg');
const pool = new pg.Pool(pgConfig);

let spatialMvt = {
  // 动态矢量切片
  getMvt: function (req, res, next) {
    let {x, y, z} = {
      x: parseInt(req.url.split('/')[3]),
      y: parseInt(req.url.split('/')[4]),
      z: parseInt(req.url.split('/')[2]),
    }

    // layer_capital
    let sql1 = ` 
      SELECT ST_AsMVT(P,'layer_capital',4096,'geom') AS "mvt"
      FROM
      (
	      SELECT name, ST_AsMVTGeom(ST_Transform(geom,3857), ST_TileEnvelope(${z}, ${x}, ${y}), 4096, 64, TRUE) geom
	      FROM "layer_capital"
        WHERE ST_Intersects(geom, ST_transform(ST_TileEnvelope(${z}, ${x}, ${y}), 4326))
      ) AS P
    `

    // layer_city
    let sql2 = ` 
      SELECT ST_AsMVT ( P,'layer_pcity',4096,'geom' ) AS "mvt"
      FROM
      (
          SELECT name, ST_AsMVTGeom(ST_Transform(geom,3857), ST_TileEnvelope(${z}, ${x}, ${y}), 4096, 64, TRUE) geom
	      FROM "layer_pcity"
        WHERE ST_Intersects(geom, ST_transform(ST_TileEnvelope(${z}, ${x}, ${y}), 4326))
      ) AS P 
    `

    // layer_province
    let sql3 = ` 
      SELECT ST_AsMVT ( P,'layer_province',4096,'geom' ) AS "mvt"
      FROM
      (
        SELECT ST_AsMVTGeom(ST_Transform(geom,3857), ST_TileEnvelope(${z}, ${x}, ${y}), 4096, 64, TRUE) geom
	      FROM "layer_province"
        WHERE ST_Intersects(geom, ST_transform(ST_TileEnvelope(${z}, ${x}, ${y}), 4326))
      ) AS P
    `

    // layer_bbox
    let sql4 = ` 
      SELECT ST_AsMVT (P, 'layer_bbox', 4096, 'geom' ) AS "mvt"
      FROM
      (
        SELECT (cast(${z} as VARCHAR)||'-'||cast(${x} as VARCHAR)||'-'||cast(${y} as VARCHAR)) as label ,
          ST_AsMVTGeom(
            ST_TileEnvelope(${z}, ${x}, ${y}),
            ST_TileEnvelope(${z}, ${x}, ${y}), 
            4096,
            64, 
            TRUE
          ) geom
      ) AS P
    `

    // layer_water
    let sql5 = ` 
      SELECT ST_AsMVT ( P,'layer_water',4096,'geom' ) AS "mvt"
      FROM
      (
        SELECT ST_AsMVTGeom(ST_Transform(geom,3857), ST_TileEnvelope(${z}, ${x}, ${y}), 4096, 64, TRUE) geom
	      FROM "layer_water"
        WHERE ST_Intersects(geom, ST_transform(ST_TileEnvelope(${z}, ${x}, ${y}), 4326))
      ) AS P
    `

    let SQL = `
      SELECT (${sql1}) || (${sql2}) || (${sql3}) || (${sql4}) || (${sql5}) AS mvt
    `;
    pool.connect((isErr, client, done) => {
      client.query(
        SQL,
        function (isErr, result) {
          done();
          if (isErr) {
            res.json(isErr);
          } else {
            const data = result.rows[0].mvt
            res.send(data);
          }
        }
      );
    })
  },
};

module.exports = spatialMvt