npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@deepinnet/service-mvt-middleware-core

v0.0.1

Published

Core tile engine, shared types, and PostgreSQL adapters for DeepInNet vector tile services.

Downloads

147

Readme

@deepinnet/service-mvt-middleware-core

底层核心包,提供:

  • 图层配置类型
  • 二维 / 三维瓦片引擎
  • PostgreSQL / PostGIS adapter
  • filter / cluster / gzip 等核心能力

这个包不负责 HTTP 路由。如果你想要开箱即用的 NestJS 路由层,请使用:

  • @deepinnet/service-mvt-middleware

如果你要自己接 Express、Fastify、Koa、原生 Node HTTP、Serverless handler,或者只想在服务内部直接拿到瓦片二进制结果,这个包就是直接使用层。

安装

pnpm add @deepinnet/service-mvt-middleware-core

这个包怎么接入

最常见的接入方式分两种:

  1. 直接用内置 PostgreSQL adapter
    你只提供图层配置和数据库连接,createTileEngine(...) 自动完成二维 / 三维查询。

  2. 自己实现查询执行器
    你把 queryExecutor / query3DExecutor 接到自己的数据层,这样可以脱离 PostgreSQL adapter。

方式一:直接用内置 PostgreSQL adapter

import { createTileEngine } from "@deepinnet/service-mvt-middleware-core";

const engine = createTileEngine({
  layers: [
    {
      layer: "data",
      sourceType: "table",
      sourceObject: "public.geom",
      idField: "id",
      geomField: "geometry",
      geom3dField: "geometry3d",
      sourceCrs: "4326",
      defaultOutputCrs: "gcj02",
      supportedOutputCrs: ["4326", "gcj02"],
      propertyWhitelist: ["name", "color"],
      gzip: {
        enabled: true,
      },
      clusterEnabled: true,
      clusterMaxZoom: 15,
      clusterCellSize: 256,
      clusterMaxFeatures: 2048,
      clusterFields: {
        color: {
          field: "color",
          op: "top",
        },
      },
    },
  ],
  database: {
    connectionString: process.env.DATABASE_URL,
  },
  defaults: {
    sourceCrs: "4326",
    defaultOutputCrs: "gcj02",
  },
  tile: {
    extent: 4096,
    buffer: 64,
    maxFeatures: 20000,
  },
});

方式二:自己提供二维 / 三维查询执行器

import { createTileEngine } from "@deepinnet/service-mvt-middleware-core";

const engine = createTileEngine({
  layers: [
    {
      layer: "data",
      sourceType: "table",
      sourceObject: "public.geom",
      idField: "id",
      geomField: "geometry",
    },
  ],
  queryExecutor: async (context) => {
    // 这里由你自己返回二维 MVT 二进制
    return {
      body: new Uint8Array(),
      contentType: "application/vnd.mapbox-vector-tile",
    };
  },
  query3DExecutor: async (context) => {
    // 这里由你自己返回三维自定义 PBF 二进制
    return {
      body: new Uint8Array(),
      contentType: "application/octet-stream",
    };
  },
});

如何请求二维 / 三维瓦片

这个包本身不处理 HTTP,但你最终通常会把外部请求参数映射到:

  • engine.queryTile(input)
    返回二维 MVT

  • engine.query3DTile(input)
    返回三维自定义 PBF

最小调用示例

二维:

const result = await engine.queryTile({
  layer: "data",
  z: 8,
  x: 209,
  y: 111,
  crs: "gcj02",
  fields: ["name", "color"],
});

三维:

const result = await engine.query3DTile({
  layer: "data",
  z: 8,
  x: 209,
  y: 111,
  crs: "gcj02",
});

返回结果 TileQueryResult 中最常用的字段:

| 字段 | 含义 | | --- | --- | | status | HTTP 语义状态码,通常是 200204。 | | headers | 额外响应头,通常是缓存或扩展头。 | | body | 瓦片二进制内容。 | | contentType | 二维通常是 application/vnd.mapbox-vector-tile,三维通常是 application/octet-stream。 | | isEmpty | 是否为空瓦片。 | | compression | 压缩标志,例如 { gzip: true }。是否真正写出 Content-Encoding 取决于你的 HTTP 层。 |

如果你要自己接 HTTP

最常见的模式,是把 URL 和 query 参数手动映射成 TileQueryInput

Express 示例

import express from "express";
import { createTileEngine } from "@deepinnet/service-mvt-middleware-core";

const app = express();
const engine = createTileEngine({
  layers: [
    {
      layer: "data",
      sourceType: "table",
      sourceObject: "public.geom",
      idField: "id",
      geomField: "geometry",
      geom3dField: "geometry3d",
    },
  ],
  database: {
    connectionString: process.env.DATABASE_URL,
  },
});

function parseFields(value?: string): string[] | undefined {
  if (!value) {
    return undefined;
  }

  return value
    .split(",")
    .map((field) => field.trim())
    .filter(Boolean);
}

app.get("/tiles/:layer/:z/:x/:y.pbf", async (req, res) => {
  const result = await engine.queryTile({
    layer: req.params.layer,
    z: Number(req.params.z),
    x: Number(req.params.x),
    y: Number(req.params.y),
    crs: req.query.crs as "4326" | "gcj02" | undefined,
    minZoom: req.query.minZoom ? Number(req.query.minZoom) : undefined,
    maxZoom: req.query.maxZoom ? Number(req.query.maxZoom) : undefined,
    fields: parseFields(req.query.fields as string | undefined),
    from: req.query.from as string | undefined,
    to: req.query.to as string | undefined,
    version: req.query.v as string | undefined,
  });

  if (result.contentType) {
    res.setHeader("Content-Type", result.contentType);
  }

  for (const [key, value] of Object.entries(result.headers)) {
    res.setHeader(key, value);
  }

  if (result.compression?.gzip) {
    res.setHeader("Content-Encoding", "gzip");
  }

  res.status(result.status).send(Buffer.from(result.body));
});

TileQueryInput.filter 仍然可用,但建议由服务端内部逻辑填充。默认的 Nest middleware 不会把它暴露成公开 query 参数;如果你自己接 HTTP,请按自己的安全边界决定是否注入该字段。

参数怎么传

TileQueryInput

queryTile(...)query3DTile(...) 使用同一组查询输入。

| 参数 | 类型 | 是否必填 | 含义 | 示例 | | --- | --- | --- | --- | --- | | layer | string | 是 | 图层名,必须命中 layers 配置中的某一项。 | "data" | | z | number | 是 | 缩放级别,必须是大于等于 0 的整数。 | 8 | | x | number | 是 | 当前 z 层级下的瓦片列号。 | 209 | | y | number | 是 | 当前 z 层级下的瓦片行号。 | 111 | | crs | "4326" \| "gcj02" | 否 | 输出坐标系。未传时使用图层的 defaultOutputCrs。 | "gcj02" | | minZoom | number | 否 | 请求级最小缩放限制,会与图层和默认配置一起合并。 | 6 | | maxZoom | number | 否 | 请求级最大缩放限制,会与图层和默认配置一起合并。 | 16 | | fields | string[] | 否 | 希望返回的属性字段数组,最终仍受 propertyWhitelist 限制。 | ["name", "color"] | | filter | TileFilterExpression | 否 | 结构化过滤条件,适合由服务端内部逻辑注入。 | { op: "eq", field: "name", value: "point-1" } | | from | string | 否 | 起始时间,要求图层配置了 timeField。 | "2026-01-01T00:00:00Z" | | to | string | 否 | 结束时间,要求图层配置了 timeField。 | "2026-12-31T23:59:59Z" | | version | string | 否 | 版本字符串,主要参与缓存键区分。 | "2026-04-30" |

filter 怎么写

当前支持的结构化过滤操作符:

  • eq
  • in
  • range
  • and
  • or

eq

{
  op: "eq",
  field: "name",
  value: "point-1",
}

in

{
  op: "in",
  field: "color",
  values: ["#ff0000", "#00ff00"],
}

range

{
  op: "range",
  field: "created_at",
  min: "2026-01-01T00:00:00Z",
  max: "2026-12-31T23:59:59Z",
}

and

{
  op: "and",
  filters: [
    { op: "eq", field: "name", value: "point-1" },
    { op: "in", field: "color", values: ["#ff0000", "#00ff00"] },
  ],
}

or

{
  op: "or",
  filters: [
    { op: "eq", field: "name", value: "point-1" },
    { op: "eq", field: "name", value: "point-2" },
  ],
}

该怎么配置图层

LayerConfigInput

图层配置决定某个 layer 的数据来源和行为。

| 参数 | 类型 | 是否必填 | 含义 | | --- | --- | --- | --- | | layer | string | 是 | 图层名,也是查询时传入的 layer 标识。 | | sourceType | "table" \| "view" \| "sql" | 是 | 数据源类型。当前 PostgreSQL adapter 只支持 tableview。 | | sourceObject | string | 是 | 源表名或视图名,例如 public.geom。 | | idField | string | 是 | 主键字段,用于返回要素 id。 | | geomField | string | 条件必填 | 二维几何字段。与 wktField 至少提供一个。 | | geom3dField | string | 否 | 三维几何字段。三维查询优先使用它。 | | wktField | string | 条件必填 | WKT 文本字段,可作为 geomField 的替代输入。 | | timeField | string | 否 | 时间字段,启用 from/to 过滤时必须提供。 | | sourceCrs | "4326" \| "gcj02" | 否 | 源数据坐标系。 | | defaultOutputCrs | "4326" \| "gcj02" | 否 | 请求未显式传 crs 时的默认输出坐标系。 | | supportedOutputCrs | OutputCrs[] | 否 | 当前图层允许输出的坐标系集合。 | | propertyWhitelist | string[] | 否 | 允许暴露给客户端的属性字段白名单。 | | minZoom | number | 否 | 图层级最小缩放限制。 | | maxZoom | number | 否 | 图层级最大缩放限制。 | | clusterEnabled | boolean | 否 | 是否启用 cluster。 | | clusterMaxZoom | number | 条件必填 | 当 clusterEnabled=true 时必须配置,表示 z <= clusterMaxZoom 时走聚合路径。 | | clusterCellSize | number | 否 | cluster 网格尺寸,数值越大聚合越粗。 | | clusterMaxFeatures | number | 否 | cluster 结果最多输出多少条聚合要素。 | | clusterFields | Record<string, TileClusterFieldConfig> | 否 | 聚合属性字段配置。 | | clusterAltitudeMode | "max" | 否 | 三维 cluster 高程聚合规则,当前只支持 max。 | | gzip | { enabled?: boolean } | 否 | 响应压缩配置,gzip.enabled=true 时结果会标记为 gzip。 |

clusterFields 要怎么写

clusterFields 的 key 是聚合后输出的属性名,value 用来指定源字段和聚合算子。

clusterFields: {
  color: {
    field: "color",
    op: "top",
  },
  maxHeight: {
    field: "height",
    op: "max",
  },
}

当前支持的聚合算子:

  • sum
  • min
  • max
  • first
  • top

约束:

  • 输出别名不能与系统保留字段冲突,如 idcountisClusterclusterId
  • 源字段必须出现在 propertyWhitelist

默认配置怎么传

TileEngineDefaults

defaults 用来提供图层缺省值。

| 参数 | 类型 | 含义 | | --- | --- | --- | | sourceCrs | "4326" \| "gcj02" | 图层未显式声明时的默认源坐标系。 | | defaultOutputCrs | "4326" \| "gcj02" | 图层未显式声明时的默认输出坐标系。 | | minZoom | number | 图层未显式声明时的默认最小缩放限制。 | | maxZoom | number | 图层未显式声明时的默认最大缩放限制。 | | clusterEnabled | boolean | 图层未显式声明时是否默认启用 cluster。 | | clusterMaxZoom | number | 图层未显式声明时的 cluster 阈值。 | | clusterCellSize | number | 图层未显式声明时的 cluster 网格尺寸。 | | clusterMaxFeatures | number | 图层未显式声明时的 cluster 输出上限。 | | clusterFields | object | 图层未显式声明时的聚合属性配置。 | | clusterAltitudeMode | "max" | 图层未显式声明时的三维聚合高程规则。 | | gzip | { enabled?: boolean } | 图层未显式声明时的响应压缩配置。 |

createTileEngine(...) 还能接哪些参数

TileEngineOptions

除了 layersdefaults,还支持这些选项:

| 参数 | 类型 | 含义 | | --- | --- | --- | | database | PostgresDatabaseOptions | PostgreSQL / PostGIS 连接配置。 | | tile | TileRenderOptions | 瓦片渲染参数,例如 extentbuffermaxFeatures。 | | queryExecutor | TileQueryExecutor | 自定义二维查询执行器,会覆盖默认 PostgreSQL adapter。 | | query3DExecutor | TileQueryExecutor | 自定义三维查询执行器,会覆盖默认 PostgreSQL adapter。 | | metadataResolver | TileMetadataResolver | 自定义 metadata 扩展逻辑。 | | cacheKeyVersion | string | 缓存键版本号,用于主动打断旧缓存。 |

PostgresDatabaseOptions

| 参数 | 类型 | 含义 | | --- | --- | --- | | pool | Pool | 已存在的 pg.Pool 实例。 | | connectionString | string | 连接字符串,例如 postgresql://user:pass@host:5432/db。 | | poolConfig | PoolConfig | pg 的细粒度连接池配置。 | | healthCheckQuery | string | 健康检查 SQL,默认是 SELECT 1。 |

TileRenderOptions

| 参数 | 类型 | 含义 | | --- | --- | --- | | extent | number | MVT 渲染 extent。 | | buffer | number | 瓦片边缘缓冲区。 | | maxFeatures | number | 单次查询允许返回的最大要素数。 |

常见接入模式

只做二维 MVT 服务

  • geomField
  • queryTile(...)
  • 不一定需要 geom3dField

同时做二维和三维

  • 同时配 geomFieldgeom3dField
  • 二维走 queryTile(...)
  • 三维走 query3DTile(...)

只做三维

  • 推荐配 geom3dField
  • 如果没有 geom3dField,但有 geomField / wktField,三维链路会尝试回退并补 z=0

默认行为与约束

  • crs 当前仅支持 4326gcj02
  • fields 最终受 propertyWhitelist 限制。
  • filter 不是任意 SQL 字符串,而是结构化 JSON 条件。
  • from/to 要求图层配置了 timeField
  • minZoom/maxZoom 会和图层配置、默认配置一起合并。
  • clusterEnabled=true 时必须提供 clusterMaxZoom
  • 三维 clusterAltitudeMode 当前仅支持 max
  • gzip.enabled=true 时结果会带 gzip 压缩标志,是否真正写成 HTTP Content-Encoding 取决于你的 HTTP 层。
  • PostgreSQL adapter 当前只支持 tableview,不支持 sql 数据源。
  • 如果 supportedOutputCrs 配了值,请求里的 crs 必须命中该集合。

主要导出

主入口:

  • createTileEngine
  • buildCacheKey
  • loadLayerConfig
  • TileError
  • isTileError

PostgreSQL 入口:

  • createPostgresTileExecutor
  • createPostgres3DTileExecutor
  • createPostgresPool
  • createPostgresHealthIndicator
  • DEFAULT_POSTGRES_HEALTH_QUERY
  • DEFAULT_TILE_RENDER_OPTIONS

主要能力

  • 二维标准 MVT 查询
  • 三维自定义 PBF 查询
  • JSON filter 表达式
  • 二维 / 三维 gzip 压缩标志
  • 二维 / 三维 cluster
  • PostgreSQL / PostGIS 查询适配
  • 4326 / gcj02 输出转换

导入示例

import { createTileEngine } from "@deepinnet/service-mvt-middleware-core";
import { createPostgresTileExecutor } from "@deepinnet/service-mvt-middleware-core/postgres";

协议

本包按 Apache-2.0 协议分发。