Skip to content

Commit

Permalink
Merge pull request #20 from DurstDog87/pass-client
Browse files Browse the repository at this point in the history
Pass client
  • Loading branch information
DurstDog87 authored Jul 1, 2024
2 parents d66916d + 1a6265a commit 4d39e8d
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 37 deletions.
23 changes: 14 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
🚧 **work in progress** 🚧
#### This project is in active development and not stable
#### Things might change at any time

# Drop In Tileservice

A drop in vector tile service using pg for turning any postres backend into a tileserver.

### Pre Requisites:

- [PostgreSQL](https://www.postgresql.org/) with [PostGIS](http://postgis.net/) installed.
- [PostgreSQL](https://www.postgresql.org/) with the [PostGIS](http://postgis.net/) extension added.
- This Package requires the [node-postgres](https://node-postgres.com/) package

### Installation
Expand Down Expand Up @@ -39,19 +35,22 @@ const connection_params = {

const pool = new Pool(connection_params)

const tileService = new Tileserver(pool)
const tileService = new Tileserver()
//SQL to be run against the pool db
tileservice.setQuery("SELECT id, geom FROM schema.table WHERE prop = 44")
tileservice.setSrid(2252) //Michigan Central

app.get("/tiles/:z/:x/:y", async (req, res) => {
try {
const tiles = await ts.query(req.params.z, req.params.x, req.params.y, {
const conn = await pool.connect()
const tiles = await ts.query(req.params.z, req.params.x, req.params.y, conn, {
layername: "default"
})
res.status(200).send(tiles) //protobuf sent as result
} catch (e) {
console.log(e)
} finally {
await conn.release()
}

})
Expand All @@ -65,13 +64,16 @@ tileservice.setSrid(2252) //Michigan Central

app.get("/tiles/:z/:x/:y", async (req, res) => {
try {
const tiles = await ts.query(req.params.z, req.params.x, req.params.y, {
const conn = await pool.connect()
const tiles = await ts.query(req.params.z, req.params.x, req.params.y, conn, {
params: [44],
layername: "default"
})
res.status(200).send(tiles) //protobuf sent as result
} catch (e) {
console.log(e)
} finally {
await conn.release()
}
})
```
Expand All @@ -81,7 +83,8 @@ app.get("/tiles/:z/:x/:y", async (req, res) => {
```javascript
app.get("/tiles/:z/:x/:y", async (req, res) => {
try {
const tiles = await ts.query(req.params.z, req.params.x, req.params.y, {
const conn = await pool.connect()
const tiles = await ts.query(req.params.z, req.params.x, req.params.y, conn, {
queryString: "SELECT id, geom FROM schema.table WHERE prop = $1",
srid: 2252,
params: [44],
Expand All @@ -90,6 +93,8 @@ app.get("/tiles/:z/:x/:y", async (req, res) => {
res.status(200).send(tiles) //protobuf sent as result
} catch (e) {
console.log(e)
} finally {
await conn.release()
}
})
```
4 changes: 2 additions & 2 deletions src/__tests__/tile.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { describe, expect, test } from '@jest/globals';
import { tileExt, nTiles, makeEnvelopeFromTileCoord, validateTileCoords } from '../util/tile';
import { tileExt, nTiles, makeBboxFromTileCoord, validateTileCoords } from '../util/tile';

describe('tile utilities', () => {
test('find tile extent at given zoom', () => {
Expand All @@ -13,7 +13,7 @@ describe('tile utilities', () => {
});

test('find the envelope for and zxy set', () => {
const res = makeEnvelopeFromTileCoord(3, 3, 4);
const res = makeBboxFromTileCoord(3, 3, 4);
expect(res).toStrictEqual({
xMin: -5009377.085697301,
xMax: 0.0,
Expand Down
39 changes: 16 additions & 23 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,27 @@
import { Pool, QueryResult } from 'pg';
import { Client, QueryResult } from 'pg';
import { IQueryOptions } from './types';
import { makeBboxFromTileCoord } from './util/tile';

export const DEFAULT_SRID = 4269;
export const DEFAULT_EXTENT = 4096;
export const DEFAULT_BUFFER = 256;
export const DEFAULT_CLIP_GEOM = true;

export class Tileserver {
pool: Pool;
srid: number;
extent: number;
buffer: number;
clip_geom: boolean;
queryString: string;

constructor(pool: Pool) {
this.pool = pool;
constructor() {
this.srid = DEFAULT_SRID;
this.extent = DEFAULT_EXTENT;
this.buffer = DEFAULT_BUFFER;
this.clip_geom = DEFAULT_CLIP_GEOM;
this.queryString = '';
}

setPool(pool: Pool) {
this.pool = pool;
}

setQuery(query: string) {
this.queryString = query;
}
Expand All @@ -35,7 +30,7 @@ export class Tileserver {
this.srid = srid;
}

async query(z: number, x: number, y: number, options: IQueryOptions = {}): Promise<ArrayBuffer> {
async query(z: number, x: number, y: number, client: Client, options: IQueryOptions = {}): Promise<ArrayBuffer> {
if (z === undefined || x === undefined || y === undefined) {
throw EvalError('tile coordinates not defined');
}
Expand All @@ -44,32 +39,30 @@ export class Tileserver {
throw EvalError('no query string set');
}

const query = `
const query = `--sql
WITH mvtgeom AS (
SELECT ST_AsMVTGeom(
ST_Transform(geom, 3857),
ST_TileEnvelope($1,$2,$3),
ST_MakeEnvelope($1,$2,$3,$4, 4326),
${options.extent ?? this.extent},
${options.buffer ?? this.buffer},
${options.clip_geom ?? this.clip_geom}
) AS mvtgeom, dat.*
FROM (${(options.queryString ?? this.queryString).replace(/;$/g, '')}) AS dat
WHERE ST_Intersects(
geom,
ST_Transform(ST_TileEnvelope($1,$2,$3), ${options.srid ?? this.srid}))
)
ST_Transform(ST_MakeEnvelope($1,$2,$3,$4, ${options.srid ?? this.srid}), ${options.srid ?? this.srid})
))
SELECT ST_AsMVT(mvtgeom.*, '${options.layerName ?? 'default'}') AS mvt FROM mvtgeom;
`;

const conn = await this.pool.connect();

try {
const result: QueryResult<{ mvt: ArrayBuffer }> = await conn.query(query, [z, x, y]);
return result.rows[0].mvt;
} catch (e) {
throw e;
} finally {
conn.release();
}
const bbox = makeBboxFromTileCoord(z, x, y);
const result: QueryResult<{ mvt: ArrayBuffer }> = await client.query(query, [
bbox.xMin,
bbox.yMin,
bbox.xMax,
bbox.yMax,
]);
return result.rows[0].mvt;
}
}
2 changes: 1 addition & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export interface ITileEnvelope {
export interface ITileBbox {
xMin: number;
xMax: number;
yMin: number;
Expand Down
4 changes: 2 additions & 2 deletions src/util/tile.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ITileEnvelope } from '../types';
import { ITileBbox } from '../types';

export function tileExt(zoom: number): number {
//tile width at zoom level `zoom`
Expand All @@ -10,7 +10,7 @@ export function nTiles(zoom: number): number {
return 2 ** (2 * zoom);
}

export function makeEnvelopeFromTileCoord(z: number, x: number, y: number): ITileEnvelope {
export function makeBboxFromTileCoord(z: number, x: number, y: number): ITileBbox {
const webMercMax = 20037508.3427892;
const webMercMin = -1 * webMercMax;
const worldSize = webMercMax - webMercMin;
Expand Down

0 comments on commit 4d39e8d

Please sign in to comment.