chiitiler 1.20.0 → 1.20.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +123 -237
- package/dist/server/routes/camera.js +3 -2
- package/dist/server/routes/clip.js +3 -2
- package/dist/server/routes/tiles.js +3 -2
- package/dist/server/utils.js +2 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,285 +1,164 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-

|
|
5
|
-

|
|
6
|
-
[](https://codecov.io/gh/Kanahiro/chiitiler)
|
|
7
|
-
|
|
8
|
-

|
|
9
|
-
|
|
10
|
-
> Chiitiler is a tiny MapLibre server that renders raster tiles and map cut-outs from any MapLibre Style JSON, with built-in caching backends for source assets and a lightweight debug UI.
|
|
11
|
-
|
|
12
|
-
## Overview
|
|
13
|
-
|
|
14
|
-
Chiitiler accepts remote or local `style.json` definitions and serves raster tiles or bounding-box images on demand. It was inspired by [`maptiler/tileserver-gl`](https://github.com/maptiler/tileserver-gl) and [`developmentseed/titiler`](https://github.com/developmentseed/titiler) but is intentionally minimal, scriptable, and easy to self-host.
|
|
3
|
+
<img src="./logo.svg" alt="chiitiler" width="200" />
|
|
15
4
|
|
|
16
|
-
|
|
5
|
+
# chiitiler
|
|
17
6
|
|
|
18
|
-
|
|
19
|
-
- Optimized for ephemeral serverless runtimes such as AWS Lambda.
|
|
20
|
-
- Multiple cache adapters (`memory`, `file`, `s3`, `gcs`) to cache shared source assets (MVT tiles, glyphs, sprites) and reduce redundant fetches.
|
|
21
|
-
- Built-in `/debug` and `/editor` pages to preview styles during development.
|
|
7
|
+
**A tiny raster tile server for MapLibre styles.**
|
|
22
8
|
|
|
23
|
-
|
|
9
|
+
Point it at any `style.json` and get back PNG / WebP / JPEG tiles, static images, or map cut-outs.
|
|
24
10
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
## Supported Data Protocols
|
|
31
|
-
|
|
32
|
-
Chiitiler can load tiles, sprites, glyphs, and assets via:
|
|
33
|
-
|
|
34
|
-
- `http://` and `https://`
|
|
35
|
-
- `s3://` (AWS S3 or compatible endpoints)
|
|
36
|
-
- `gs://` (Google Cloud Storage)
|
|
37
|
-
- `file://`
|
|
38
|
-
- `mbtiles://`
|
|
39
|
-
- `pmtiles://`
|
|
40
|
-
- `cog://` (Cloud Optimized GeoTIFF, CRS must be `EPSG:3857`)
|
|
41
|
-
|
|
42
|
-
## Project Layout
|
|
11
|
+
[](https://github.com/Kanahiro/chiitiler/pkgs/container/chiitiler)
|
|
12
|
+
[](https://github.com/Kanahiro/chiitiler/actions)
|
|
13
|
+
[](https://github.com/Kanahiro/chiitiler/actions)
|
|
14
|
+
[](https://codecov.io/gh/Kanahiro/chiitiler)
|
|
15
|
+
[](./LICENSE)
|
|
43
16
|
|
|
44
|
-
|
|
45
|
-
src/
|
|
46
|
-
main.ts # CLI entry point and cluster bootstrap
|
|
47
|
-
cli.ts # Commander-based CLI definition
|
|
48
|
-
server/ # Hono HTTP server & debug UI
|
|
49
|
-
render/ # Rasterization and Sharp pipelines
|
|
50
|
-
cache/ # Cache adapters (none/memory/file/s3/gcs)
|
|
51
|
-
source/ # Helpers for reading external sources
|
|
52
|
-
tests/ # Vitest integration & benchmark suites
|
|
53
|
-
localdata/ # Sample styles and tiles for demos
|
|
54
|
-
cdk/ # AWS CDK deployment project
|
|
55
|
-
```
|
|
17
|
+
[Quickstart](#quickstart) · [HTTP API](#http-api) · [Library](#library-usage) · [Deployment](#deployment)
|
|
56
18
|
|
|
57
|
-
|
|
19
|
+
</div>
|
|
58
20
|
|
|
59
|
-
|
|
21
|
+
---
|
|
60
22
|
|
|
61
|
-
|
|
62
|
-
- System dependencies to support `sharp` (see [Dockerfile](./Dockerfile) for reference).
|
|
23
|
+
## From zero to a rendered tile in 30 seconds
|
|
63
24
|
|
|
64
|
-
|
|
25
|
+
**1. Run the server** — one command, no config file, no database, no API key.
|
|
65
26
|
|
|
66
27
|
```bash
|
|
67
|
-
|
|
68
|
-
cd chiitiler
|
|
69
|
-
npm install
|
|
70
|
-
npx tsx src/main.ts tile-server --port 3000 --debug
|
|
28
|
+
docker run --rm -p 3000:3000 ghcr.io/kanahiro/chiitiler:latest
|
|
71
29
|
```
|
|
72
30
|
|
|
73
|
-
|
|
31
|
+
**2. Open a tile in your browser** — pass any MapLibre style URL as `?url=`.
|
|
74
32
|
|
|
75
33
|
```
|
|
76
34
|
http://localhost:3000/tiles/0/0/0.png?url=https://tile.openstreetmap.jp/styles/osm-bright/style.json
|
|
77
35
|
```
|
|
78
36
|
|
|
79
|
-
|
|
37
|
+
You're done. That same endpoint works as an XYZ tile source for Leaflet, MapLibre, OpenLayers, QGIS, Cesium, or anywhere else that speaks `{z}/{x}/{y}`.
|
|
80
38
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
The container entrypoint wraps `node /app/build/main.cjs tile-server`, so command-line options can be provided via env vars or by overriding the container CMD explicitly.
|
|
39
|
+
> **No Docker?** `npx tsx` works too:
|
|
40
|
+
> ```bash
|
|
41
|
+
> git clone https://github.com/Kanahiro/chiitiler && cd chiitiler && npm i
|
|
42
|
+
> npx tsx src/main.ts tile-server --debug
|
|
43
|
+
> ```
|
|
44
|
+
> Then visit `http://localhost:3000/debug` to preview styles interactively.
|
|
90
45
|
|
|
91
|
-
|
|
46
|
+
## Features
|
|
92
47
|
|
|
93
|
-
|
|
48
|
+
- **Zero-config** — no config file, no YAML, no database. Just a style URL.
|
|
49
|
+
- **Works with any MapLibre style** — remote URL or `POST` the JSON inline
|
|
50
|
+
- **Multiple outputs** — slippy tiles (`/tiles`), bounding-box clips (`/clip`), free-form camera shots (`/camera`)
|
|
51
|
+
- **Serverless-friendly** — small footprint, runs on AWS Lambda via Web Adapter (see [`cdk/`](./cdk))
|
|
52
|
+
- **Pluggable caching** — `memory` · `file` · `s3` · `gcs` backends for shared source assets
|
|
53
|
+
- **Many protocols** — `http(s)` · `s3` · `gs` · `file` · `mbtiles` · `pmtiles` · `cog`
|
|
54
|
+
- **Library or server** — import the renderer directly into your Node.js pipeline
|
|
55
|
+
- **Built-in debug UI** — `/debug` and `/editor` for live style preview
|
|
94
56
|
|
|
95
|
-
|
|
96
|
-
docker compose up
|
|
97
|
-
```
|
|
57
|
+
## In Production
|
|
98
58
|
|
|
99
|
-
|
|
59
|
+
- **[MIERUNE/tiles](https://github.com/MIERUNE/tiles)** — [live example](https://mierune.github.io/tiles/color.html#11.62/43.064/141.3375)
|
|
60
|
+
- **[PLATEAU VIEW](https://plateauview.mlit.go.jp/)** — Cesium.js imagery via `/tiles`
|
|
61
|
+
- **[qgis-amazonlocationservice-plugin](https://github.com/dayjournal/qgis-amazonlocationservice-plugin)** — QGIS integration
|
|
62
|
+
- **[Allmaps Latest](https://bsky.app/profile/latest.allmaps.org)** — Bluesky bot
|
|
100
63
|
|
|
101
64
|
## HTTP API
|
|
102
65
|
|
|
103
|
-
| Method |
|
|
104
|
-
|
|
|
105
|
-
| GET/POST | `/tiles/{z}/{x}/{y}.{ext}` |
|
|
106
|
-
| GET/POST | `/clip.{ext}` |
|
|
107
|
-
| GET/POST | `/camera/{zoom}/{lat}/{lon}/{bearing}/{pitch}/{width}x{height}.{ext}` |
|
|
108
|
-
| GET | `/debug` |
|
|
109
|
-
| GET | `/editor` | Lightweight style editor (requires debug mode). |
|
|
66
|
+
| Method | Endpoint | Description |
|
|
67
|
+
| --- | --- | --- |
|
|
68
|
+
| `GET` / `POST` | `/tiles/{z}/{x}/{y}.{ext}` | Slippy-map raster tile |
|
|
69
|
+
| `GET` / `POST` | `/clip.{ext}` | Bounding-box cut-out |
|
|
70
|
+
| `GET` / `POST` | `/camera/{zoom}/{lat}/{lon}/{bearing}/{pitch}/{width}x{height}.{ext}` | Free-form camera shot |
|
|
71
|
+
| `GET` | `/debug`, `/editor` | Debug UI (requires `--debug`) |
|
|
110
72
|
|
|
111
|
-
|
|
73
|
+
`ext` is one of `png`, `jpeg`, `jpg`, `webp`.
|
|
112
74
|
|
|
113
|
-
|
|
114
|
-
- `tileSize` – Tile size in pixels (default `512`).
|
|
115
|
-
- `quality` – JPEG/WebP quality (default `100`).
|
|
116
|
-
- `margin` – Tile edge margin (default `0`).
|
|
117
|
-
- `bbox` – Bounding box for `/clip` as `minLon,minLat,maxLon,maxLat`.
|
|
118
|
-
- `size` – Longest edge of `/clip` output (default `1024`).
|
|
75
|
+
**Query parameters**
|
|
119
76
|
|
|
120
|
-
|
|
77
|
+
| Name | Default | Notes |
|
|
78
|
+
| --- | --- | --- |
|
|
79
|
+
| `url` | — | Style JSON URL (required for `GET`) |
|
|
80
|
+
| `tileSize` | `512` | Tile size in pixels |
|
|
81
|
+
| `quality` | `100` | JPEG / WebP quality |
|
|
82
|
+
| `margin` | `0` | Tile edge margin |
|
|
83
|
+
| `bbox` | — | `/clip` bounding box: `minLon,minLat,maxLon,maxLat` |
|
|
84
|
+
| `size` | `1024` | `/clip` longest edge in pixels |
|
|
121
85
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
Chiitiler exposes a single command: `tile-server`.
|
|
125
|
-
|
|
126
|
-
```bash
|
|
127
|
-
npx tsx src/main.ts tile-server --help
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
| Option | Description | Environment Fallback | Default |
|
|
131
|
-
| ------ | ----------- | -------------------- | ------- |
|
|
132
|
-
| `--cache <none/memory/file/s3/gcs>` | Select cache backend. | `CHIITILER_CACHE_METHOD` | `none` |
|
|
133
|
-
| `--cache-ttl <seconds>` | TTL for memory/file caches. | `CHIITILER_CACHE_TTL_SEC` | `3600` |
|
|
134
|
-
| `--memory-cache-max-item-count <n>` | Max items in memory cache. | `CHIITILER_MEMORYCACHE_MAXITEMCOUNT` | `1000` |
|
|
135
|
-
| `--file-cache-dir <dir>` | Disk cache directory. | `CHIITILER_FILECACHE_DIR` | `./.cache` |
|
|
136
|
-
| `--s3-cache-bucket <name>` | S3 bucket for caching. | `CHIITILER_S3CACHE_BUCKET` | `""` |
|
|
137
|
-
| `--s3-region <region>` | S3 region used for requests. | `CHIITILER_S3_REGION` | `us-east-1` |
|
|
138
|
-
| `--s3-endpoint <url>` | S3-compatible endpoint. | `CHIITILER_S3_ENDPOINT` | `""` |
|
|
139
|
-
| `--s3-force-path-style` | Force path-style requests. | `CHIITILER_S3_FORCE_PATH_STYLE` (`true/false`) | `false` |
|
|
140
|
-
| `--gcs-cache-bucket <name>` | GCS bucket for caching. | `CHIITILER_GCS_CACHE_BUCKET` | `""` |
|
|
141
|
-
| `--gcs-project-id <id>` | GCP project ID. | `CHIITILER_GCS_PROJECT_ID` | `""` |
|
|
142
|
-
| `--gcs-key-filename <path>` | Service account JSON. | `CHIITILER_GCS_KEY_FILENAME` | `""` |
|
|
143
|
-
| `--gcs-cache-prefix <prefix>` | GCS object prefix. | `CHIITILER_GCS_CACHE_PREFIX` | `""` |
|
|
144
|
-
| `--gcs-api-endpoint <url>` | Custom GCS endpoint. | `CHIITILER_GCS_API_ENDPOINT` | `""` |
|
|
145
|
-
| `--port <number>` | HTTP listen port. | `CHIITILER_PORT` | `3000` |
|
|
146
|
-
| `--debug` | Enable debug UI routes. | `CHIITILER_DEBUG` | `false` |
|
|
147
|
-
|
|
148
|
-
Set `CHIITILER_PROCESSES` to control clustering (`0` uses all CPUs). When `>1`, the primary process forks workers that all share the same cache adapter.
|
|
149
|
-
|
|
150
|
-
## Environment Variables
|
|
151
|
-
|
|
152
|
-
In addition to the CLI options above, the server respects:
|
|
153
|
-
|
|
154
|
-
| Variable | Default | Notes |
|
|
155
|
-
| -------- | ------- | ----- |
|
|
156
|
-
| `CHIITILER_PROCESSES` | `1` | Number of worker processes; `0` = `availableParallelism()`. |
|
|
157
|
-
| `AWS_ACCESS_KEY_ID` / `AWS_SECRET_ACCESS_KEY` | – | Used by the S3 cache adapter. |
|
|
158
|
-
| `AWS_REGION` | – | Overrides SDK default region if set. |
|
|
159
|
-
| `GOOGLE_APPLICATION_CREDENTIALS` | – | Path to a service account JSON used by the GCS adapter. |
|
|
160
|
-
|
|
161
|
-
## Cache Backends
|
|
162
|
-
|
|
163
|
-
Chiitiler caches the source material required for rendering (vector tiles, glyphs, sprites, spritesheets), not the final raster outputs. These cached assets are reused across requests to avoid refetching upstream sources.
|
|
164
|
-
|
|
165
|
-
- **none** – No caching; every request renders from scratch.
|
|
166
|
-
- **memory** – In-memory LRU cache with configurable TTL and max entries.
|
|
167
|
-
- **file** – Stores fetched source assets under `CHIITILER_FILECACHE_DIR`.
|
|
168
|
-
- **s3** – Uploads cached source assets to S3/MinIO; honors custom endpoint and path-style.
|
|
169
|
-
- **gcs** – Uploads cached source assets to Google Cloud Storage or `fake-gcs-server`.
|
|
170
|
-
|
|
171
|
-
Each adapter exposes the same `get`/`set` interface and can be reused when embedding Chiitiler as a library.
|
|
172
|
-
|
|
173
|
-
## Debug Tools
|
|
174
|
-
|
|
175
|
-
Run with `--debug` or `CHIITILER_DEBUG=true` to unlock:
|
|
176
|
-
|
|
177
|
-
- `/debug` – Inspect styles, test queries, and view response metadata.
|
|
178
|
-
- `/editor` – Lightweight MapLibre style editor with live preview.
|
|
179
|
-
|
|
180
|
-
## Development & Testing
|
|
181
|
-
|
|
182
|
-
```bash
|
|
183
|
-
npm run dev # Watch mode via tsx
|
|
184
|
-
npm run build # Bundle to build/main.cjs with esbuild
|
|
185
|
-
npm run test:unit # Vitest unit suite (src/**/*.test.ts)
|
|
186
|
-
npm run test:integration # End-to-end scenarios in tests/
|
|
187
|
-
npm run test:coverage # Unit coverage with V8 provider
|
|
188
|
-
npm run test:benchmark # Performance tests (see BENCHMARK.md)
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
Benchmark scenarios and recent measurements live in [BENCHMARK.md](./BENCHMARK.md).
|
|
86
|
+
For `POST`, send the style object as JSON body: `{ "style": { ... } }`.
|
|
192
87
|
|
|
193
88
|
## Library Usage
|
|
194
89
|
|
|
195
|
-
Chiitiler is also published
|
|
90
|
+
Chiitiler is also published to npm. Returns `Buffer` or `Sharp` streams.
|
|
196
91
|
|
|
197
92
|
```ts
|
|
198
|
-
import {
|
|
199
|
-
getRenderedTileBuffer,
|
|
200
|
-
getRenderedClipBuffer,
|
|
201
|
-
getRenderedCameraBuffer,
|
|
202
|
-
getRenderedTileStream,
|
|
203
|
-
getRenderedClipStream,
|
|
204
|
-
getRenderedCameraStream,
|
|
205
|
-
ChiitilerCache,
|
|
206
|
-
} from 'chiitiler';
|
|
93
|
+
import { getRenderedTileBuffer, ChiitilerCache } from 'chiitiler';
|
|
207
94
|
|
|
208
95
|
const cache = ChiitilerCache.fileCache({ dir: './.cache', ttl: 3600 });
|
|
209
96
|
|
|
210
|
-
const
|
|
97
|
+
const png = await getRenderedTileBuffer({
|
|
211
98
|
stylejson: 'https://tile.openstreetmap.jp/styles/osm-bright/style.json',
|
|
212
|
-
z: 5,
|
|
213
|
-
x: 27,
|
|
214
|
-
y: 12,
|
|
99
|
+
z: 5, x: 27, y: 12,
|
|
215
100
|
tileSize: 512,
|
|
216
|
-
|
|
217
|
-
ext: 'webp',
|
|
101
|
+
ext: 'png',
|
|
218
102
|
quality: 100,
|
|
103
|
+
margin: 0,
|
|
219
104
|
cache,
|
|
220
105
|
});
|
|
106
|
+
```
|
|
221
107
|
|
|
222
|
-
|
|
223
|
-
stylejson: 'file://localdata/style.json',
|
|
224
|
-
bbox: [123.4, 34.5, 124.5, 35.6],
|
|
225
|
-
size: 1024,
|
|
226
|
-
ext: 'png',
|
|
227
|
-
quality: 95,
|
|
228
|
-
cache: ChiitilerCache.noneCache(),
|
|
229
|
-
});
|
|
108
|
+
Available renderers: `getRenderedTileBuffer`, `getRenderedClipBuffer`, `getRenderedCameraBuffer`, and their `*Stream` variants (`Sharp` instances for further piping).
|
|
230
109
|
|
|
231
|
-
|
|
232
|
-
stylejson: 'file://localdata/style.json',
|
|
233
|
-
center: [139.69, 35.68],
|
|
234
|
-
zoom: 10,
|
|
235
|
-
bearing: 180,
|
|
236
|
-
pitch: 60,
|
|
237
|
-
width: 1024,
|
|
238
|
-
height: 1024,
|
|
239
|
-
ext: 'png',
|
|
240
|
-
quality: 95,
|
|
241
|
-
cache,
|
|
242
|
-
});
|
|
110
|
+
## Configuration
|
|
243
111
|
|
|
244
|
-
|
|
245
|
-
const tileStream = await getRenderedTileStream({
|
|
246
|
-
stylejson: 'https://tile.openstreetmap.jp/styles/osm-bright/style.json',
|
|
247
|
-
z: 5,
|
|
248
|
-
x: 27,
|
|
249
|
-
y: 12,
|
|
250
|
-
tileSize: 512,
|
|
251
|
-
margin: 0,
|
|
252
|
-
ext: 'png',
|
|
253
|
-
quality: 90,
|
|
254
|
-
cache,
|
|
255
|
-
});
|
|
112
|
+
All options can be set via CLI flag or environment variable.
|
|
256
113
|
|
|
257
|
-
|
|
258
|
-
stylejson: 'file://localdata/style.json',
|
|
259
|
-
bbox: [123.4, 34.5, 124.5, 35.6],
|
|
260
|
-
size: 1024,
|
|
261
|
-
ext: 'jpeg',
|
|
262
|
-
quality: 85,
|
|
263
|
-
cache,
|
|
264
|
-
});
|
|
114
|
+
### Server
|
|
265
115
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
116
|
+
| Flag | Env | Default |
|
|
117
|
+
| --- | --- | --- |
|
|
118
|
+
| `--port <n>` | `CHIITILER_PORT` | `3000` |
|
|
119
|
+
| `--debug` | `CHIITILER_DEBUG` | `false` |
|
|
120
|
+
| — | `CHIITILER_PROCESSES` | `1` (set `0` for all CPUs) |
|
|
121
|
+
|
|
122
|
+
### Cache
|
|
123
|
+
|
|
124
|
+
| Flag | Env | Default |
|
|
125
|
+
| --- | --- | --- |
|
|
126
|
+
| `--cache <none\|memory\|file\|s3\|gcs>` | `CHIITILER_CACHE_METHOD` | `none` |
|
|
127
|
+
| `--cache-ttl <seconds>` | `CHIITILER_CACHE_TTL_SEC` | `3600` |
|
|
128
|
+
| `--memory-cache-max-item-count <n>` | `CHIITILER_MEMORYCACHE_MAXITEMCOUNT` | `1000` |
|
|
129
|
+
| `--file-cache-dir <dir>` | `CHIITILER_FILECACHE_DIR` | `./.cache` |
|
|
130
|
+
| `--s3-cache-bucket <name>` | `CHIITILER_S3CACHE_BUCKET` | — |
|
|
131
|
+
| `--s3-region <region>` | `CHIITILER_S3_REGION` | `us-east-1` |
|
|
132
|
+
| `--s3-endpoint <url>` | `CHIITILER_S3_ENDPOINT` | — |
|
|
133
|
+
| `--s3-force-path-style` | `CHIITILER_S3_FORCE_PATH_STYLE` | `false` |
|
|
134
|
+
| `--gcs-cache-bucket <name>` | `CHIITILER_GCS_CACHE_BUCKET` | — |
|
|
135
|
+
| `--gcs-project-id <id>` | `CHIITILER_GCS_PROJECT_ID` | — |
|
|
136
|
+
| `--gcs-key-filename <path>` | `CHIITILER_GCS_KEY_FILENAME` | — |
|
|
137
|
+
| `--gcs-cache-prefix <prefix>` | `CHIITILER_GCS_CACHE_PREFIX` | — |
|
|
138
|
+
| `--gcs-api-endpoint <url>` | `CHIITILER_GCS_API_ENDPOINT` | — |
|
|
139
|
+
|
|
140
|
+
Chiitiler caches *source assets* (vector tiles, glyphs, sprites) — not final rasters — so cached data is reused across requests. Standard AWS / GCP credentials (`AWS_ACCESS_KEY_ID`, `GOOGLE_APPLICATION_CREDENTIALS`, etc.) are respected.
|
|
279
141
|
|
|
280
142
|
## Deployment
|
|
281
143
|
|
|
282
|
-
|
|
144
|
+
- **Docker** — `ghcr.io/kanahiro/chiitiler:latest` (entrypoint: `tile-server`)
|
|
145
|
+
- **Docker Compose** — see [`docker-compose.yml`](./docker-compose.yml) (includes MinIO + fake-gcs-server for local testing)
|
|
146
|
+
- **AWS Lambda** — ready-to-deploy CDK app in [`cdk/`](./cdk)
|
|
147
|
+
|
|
148
|
+
## Develop
|
|
149
|
+
|
|
150
|
+
Requires Node.js 24.12+ and `sharp` system deps (see [Dockerfile](./Dockerfile)).
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
git clone https://github.com/Kanahiro/chiitiler.git
|
|
154
|
+
cd chiitiler
|
|
155
|
+
npm install
|
|
156
|
+
npm run dev # tsx watch mode
|
|
157
|
+
npm run test:unit # vitest
|
|
158
|
+
npm run test:integration # end-to-end
|
|
159
|
+
npm run test:benchmark # see BENCHMARK.md
|
|
160
|
+
npm run build # bundle to build/main.cjs
|
|
161
|
+
```
|
|
283
162
|
|
|
284
163
|
## Architecture
|
|
285
164
|
|
|
@@ -288,10 +167,10 @@ graph LR
|
|
|
288
167
|
subgraph sources
|
|
289
168
|
direction LR
|
|
290
169
|
A[style.json]
|
|
291
|
-
z/x/y.pbf
|
|
292
|
-
z/x/y.png/webp/jpg
|
|
293
|
-
sprite
|
|
294
|
-
glyphs
|
|
170
|
+
B[z/x/y.pbf]
|
|
171
|
+
C[z/x/y.png/webp/jpg]
|
|
172
|
+
D[sprite]
|
|
173
|
+
E[glyphs]
|
|
295
174
|
end
|
|
296
175
|
|
|
297
176
|
subgraph chiitiler
|
|
@@ -300,7 +179,14 @@ graph LR
|
|
|
300
179
|
server
|
|
301
180
|
end
|
|
302
181
|
|
|
303
|
-
sources --> cache --> render --> server --/tiles/z/x/y--> png/webp/jpg
|
|
304
|
-
|
|
305
|
-
cache <--get/set--> memory/file/s3/gcs
|
|
182
|
+
sources --> cache --> render --> server --/tiles/z/x/y--> png/webp/jpg
|
|
183
|
+
cache <--get/set--> memory/file/s3/gcs
|
|
306
184
|
```
|
|
185
|
+
|
|
186
|
+
## Credits
|
|
187
|
+
|
|
188
|
+
Inspired by [`maptiler/tileserver-gl`](https://github.com/maptiler/tileserver-gl) and [`developmentseed/titiler`](https://github.com/developmentseed/titiler).
|
|
189
|
+
|
|
190
|
+
## License
|
|
191
|
+
|
|
192
|
+
[MIT](./LICENSE) © Kanahiro Iguchi
|
|
@@ -73,9 +73,10 @@ function createCameraRouter(options) {
|
|
|
73
73
|
})
|
|
74
74
|
.post('/:zoom/:lat/:lon/:bearing/:pitch/:dimensions_ext', async (c) => {
|
|
75
75
|
// body
|
|
76
|
-
const
|
|
77
|
-
if (!isValidStylejson(style))
|
|
76
|
+
const body = await c.req.json().catch(() => null);
|
|
77
|
+
if (!isValidStylejson(body?.style))
|
|
78
78
|
return c.body('invalid stylejson', 400);
|
|
79
|
+
const { style } = body;
|
|
79
80
|
// path params
|
|
80
81
|
const { zoom, lat, lon, bearing, pitch } = c.req.param();
|
|
81
82
|
const [_dimensions, ext] = c.req.param('dimensions_ext').split('.');
|
|
@@ -42,9 +42,10 @@ function createClipRouter(options) {
|
|
|
42
42
|
})
|
|
43
43
|
.post('/:filename_ext', async (c) => {
|
|
44
44
|
// body
|
|
45
|
-
const
|
|
46
|
-
if (!isValidStylejson(style))
|
|
45
|
+
const body = await c.req.json().catch(() => null);
|
|
46
|
+
if (!isValidStylejson(body?.style))
|
|
47
47
|
return c.body('invalid stylejson', 400);
|
|
48
|
+
const { style } = body;
|
|
48
49
|
// path params
|
|
49
50
|
const [filename, ext] = c.req.param('filename_ext').split('.');
|
|
50
51
|
if (filename !== 'clip')
|
|
@@ -50,9 +50,10 @@ function createTilesRouter(options) {
|
|
|
50
50
|
})
|
|
51
51
|
.post('/:z/:x/:y_ext', async (c) => {
|
|
52
52
|
// body
|
|
53
|
-
const
|
|
54
|
-
if (!isValidStylejson(style))
|
|
53
|
+
const body = await c.req.json().catch(() => null);
|
|
54
|
+
if (!isValidStylejson(body?.style))
|
|
55
55
|
return c.body('invalid stylejson', 400);
|
|
56
|
+
const { style } = body;
|
|
56
57
|
// path params
|
|
57
58
|
const z = Number(c.req.param('z'));
|
|
58
59
|
const x = Number(c.req.param('x'));
|
package/dist/server/utils.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { validateStyleMin, } from '@maplibre/maplibre-gl-style-spec';
|
|
2
2
|
function isValidStylejson(stylejson) {
|
|
3
|
+
if (stylejson === null || typeof stylejson !== 'object')
|
|
4
|
+
return false;
|
|
3
5
|
return validateStyleMin(stylejson).length === 0;
|
|
4
6
|
}
|
|
5
7
|
function isSupportedFormat(ext) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "chiitiler",
|
|
4
|
-
"version": "1.20.
|
|
4
|
+
"version": "1.20.2",
|
|
5
5
|
"description": "Tiny map rendering server for MapLibre Style Spec",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@aws-sdk/client-s3": "^3.1032.0",
|
|
39
39
|
"@google-cloud/storage": "^7.19.0",
|
|
40
|
-
"@hono/node-server": "^
|
|
40
|
+
"@hono/node-server": "^2.0.0",
|
|
41
41
|
"@mapbox/sphericalmercator": "^2.0.2",
|
|
42
42
|
"@mapbox/tilebelt": "^2.0.3",
|
|
43
43
|
"@maplibre/maplibre-gl-native": "^6.4.1",
|