chiitiler 1.15.0 → 1.16.0
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 +256 -268
- package/dist/index.d.ts +3 -1
- package/dist/index.js +6 -1
- package/dist/render/index.d.ts +14 -1
- package/dist/render/index.js +29 -2
- package/dist/server/index.d.ts +0 -2
- package/dist/server/index.js +28 -215
- package/dist/server/routes/camera.d.ts +36 -0
- package/dist/server/routes/camera.js +128 -0
- package/dist/server/routes/clip.d.ts +32 -0
- package/dist/server/routes/clip.js +104 -0
- package/dist/server/routes/tiles.d.ts +40 -0
- package/dist/server/routes/tiles.js +113 -0
- package/dist/server/utils.d.ts +7 -0
- package/dist/server/utils.js +28 -0
- package/dist/source/pmtiles.js +1 -2
- package/package.json +20 -17
package/README.md
CHANGED
|
@@ -1,326 +1,314 @@
|
|
|
1
|
-
# chiitiler
|
|
1
|
+
# chiitiler – Tiny MapLibre Server
|
|
2
2
|
|
|
3
3
|

|
|
4
|
-

|
|
5
|
+

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

|
|
8
|
+

|
|
9
9
|
|
|
10
|
-
|
|
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
11
|
|
|
12
|
-
##
|
|
12
|
+
## Overview
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
- I want a server accept style.json-url and respond raster tile, inspired by [developmentseed/titiler](https://github.com/developmentseed/titiler)
|
|
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.
|
|
16
15
|
|
|
17
|
-
|
|
16
|
+
### Highlights
|
|
18
17
|
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
18
|
+
- Zero-config startup: point Chiitiler at a style URL or POST a style object to receive tiles.
|
|
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.
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
### In Production
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
- [MIERUNE/tiles](https://github.com/MIERUNE/tiles) – see the live example [map](https://mierune.github.io/tiles/color.html#11.62/43.064/141.3375).
|
|
26
|
+
- [dayjournal/qgis-amazonlocationservice-plugin](https://github.com/dayjournal/qgis-amazonlocationservice-plugin) – powering QGIS integrations.
|
|
27
|
+
- [PLATEAU VIEW](https://plateauview.mlit.go.jp/) – serving Cesium.js imagery through the `/tiles` endpoint.
|
|
28
|
+
- [Allmaps Latest (Bluesky)](https://bsky.app/profile/latest.allmaps.org).
|
|
26
29
|
|
|
27
|
-
|
|
30
|
+
## Supported Data Protocols
|
|
28
31
|
|
|
29
|
-
|
|
30
|
-
http://localhost:3000/tiles/0/0/0.png?url=https://tile.openstreetmap.jp/styles/osm-bright/style.json
|
|
31
|
-
http://localhost:3000/tiles/0/0/0.webp?margin=100&url=https://tile.openstreetmap.jp/styles/maptiler-toner-en/style.json
|
|
32
|
-
http://localhost:3000/tiles/1/1/1.jpg?tileSize=256&quality=80&url=https://tile.openstreetmap.jp/styles/osm-bright/style.json
|
|
33
|
-
```
|
|
32
|
+
Chiitiler can load tiles, sprites, glyphs, and assets via:
|
|
34
33
|
|
|
35
|
-
|
|
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`)
|
|
36
41
|
|
|
37
|
-
|
|
42
|
+
## Project Layout
|
|
38
43
|
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
#
|
|
43
|
-
|
|
44
|
-
#
|
|
45
|
-
|
|
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
|
|
46
55
|
```
|
|
47
56
|
|
|
48
|
-
|
|
57
|
+
## Quick Start
|
|
49
58
|
|
|
50
|
-
|
|
59
|
+
### Requirements
|
|
51
60
|
|
|
52
|
-
|
|
61
|
+
- Node.js 20.10.0 or newer (`.node-version` is provided).
|
|
62
|
+
- System dependencies to support `sharp` (see [Dockerfile](./Dockerfile) for reference).
|
|
53
63
|
|
|
54
|
-
|
|
55
|
-
graph LR
|
|
56
|
-
subgraph sources
|
|
57
|
-
direction LR
|
|
58
|
-
A[style.json]
|
|
59
|
-
z/x/y.pbf
|
|
60
|
-
z/x/y.png/webp/jpg
|
|
61
|
-
sprite
|
|
62
|
-
glyphs
|
|
63
|
-
end
|
|
64
|
+
### Run From Source
|
|
64
65
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
66
|
+
```bash
|
|
67
|
+
git clone https://github.com/Kanahiro/chiitiler.git
|
|
68
|
+
cd chiitiler
|
|
69
|
+
npm install
|
|
70
|
+
npx tsx src/main.ts tile-server --port 3000 --debug
|
|
71
|
+
```
|
|
70
72
|
|
|
71
|
-
|
|
73
|
+
When the server starts you can request a tile:
|
|
72
74
|
|
|
73
|
-
|
|
75
|
+
```
|
|
76
|
+
http://localhost:3000/tiles/0/0/0.png?url=https://tile.openstreetmap.jp/styles/osm-bright/style.json
|
|
74
77
|
```
|
|
75
78
|
|
|
76
|
-
|
|
79
|
+
### Docker Image
|
|
77
80
|
|
|
78
|
-
|
|
81
|
+
```bash
|
|
82
|
+
docker pull ghcr.io/kanahiro/chiitiler:latest
|
|
83
|
+
docker run --rm -p 3000:3000 \
|
|
84
|
+
-e CHIITILER_CACHE_METHOD=memory \
|
|
85
|
+
-e CHIITILER_CACHE_TTL_SEC=600 \
|
|
86
|
+
ghcr.io/kanahiro/chiitiler:latest
|
|
87
|
+
```
|
|
79
88
|
|
|
80
|
-
|
|
81
|
-
docker pull ghcr.io/kanahiro/chiitiler
|
|
82
|
-
docker run -p 3000:3000 ghcr.io/kanahiro/chiitiler # -> tile-server
|
|
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.
|
|
83
90
|
|
|
84
|
-
|
|
85
|
-
docker run -p 3000:3000 -d \
|
|
86
|
-
-e CHIITILER_CACHE_METHOD=s3 \
|
|
87
|
-
-e CHIITILER_S3CACHE_BUCKET=bucketname \
|
|
88
|
-
-e CHIITILER_S3_REGION=ap-northeast-1 \
|
|
89
|
-
ghcr.io/kanahiro/chiitiler
|
|
90
|
-
```
|
|
91
|
+
#### docker-compose (local S3 + GCS emulation)
|
|
91
92
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
| env var | default | description |
|
|
97
|
-
| ---------------------------------- | -------- | ---------------------------------------------- |
|
|
98
|
-
| CHIITILER_PORT | 3000 | port number |
|
|
99
|
-
| CHIITILER_PROCESSES | 1 | num of chiitiler processes. 0 means all-CPUs |
|
|
100
|
-
| CHIITILER_DEBUG | false | debug mode |
|
|
101
|
-
| CHIITILER_STREAM_MODE | false | stream mode |
|
|
102
|
-
| CHIITILER_CACHE_METHOD | none | cache method, `none`, `memory`, `file`, `s3` or `gcs` |
|
|
103
|
-
| CHIITILER_CACHE_TTL_SEC | 3600 | cache ttl, effect to `memory` and `file` |
|
|
104
|
-
| CHIITILER_MEMORYCACHE_MAXITEMCOUNT | 1000 | max items for memorycache |
|
|
105
|
-
| CHIITILER_FILECACHE_DIR | .cache | filecache directory |
|
|
106
|
-
| CHIITILER_S3CACHE_BUCKET | | s3cache bucket name |
|
|
107
|
-
| CHIITILER_S3_REGION | us-east1 | s3 bucket region for caching/fetching |
|
|
108
|
-
| CHIITILER_S3_ENDPOINT | | s3 endpoint for caching/fetching |
|
|
109
|
-
| CHIITILER_S3_FORCE_PATH_STYLE | false | force path style for s3, needed for minio |
|
|
110
|
-
| CHIITILER_GCS_CACHE_BUCKE | | gcs cache bucket name |
|
|
111
|
-
| CHIITILER_GCS_CACHE_PREFIX | | gcs cache prefix |
|
|
112
|
-
| CHIITILER_GCS_PROJECT_ID | | gcs project id |
|
|
113
|
-
| CHIITILER_GCS_KEY_FILENAME | | gcs key filename |
|
|
114
|
-
| CHIITILER_GCS_API_ENDPOINT | | gcs api endpoint |
|
|
115
|
-
|
|
116
|
-
### debug page
|
|
117
|
-
|
|
118
|
-
- in debug mode, you can access:
|
|
119
|
-
- debug page: <http://localhost:3000/debug>
|
|
120
|
-
- You can pass style.json url: <http://localhost:3000/debug?url=https://tile.openstreetmap.jp/styles/osm-bright/style.json>
|
|
121
|
-
- editor page: <http://localhost:3000/editor>
|
|
122
|
-
|
|
123
|
-
## deployment
|
|
124
|
-
|
|
125
|
-
### AWS CDK
|
|
126
|
-
|
|
127
|
-
- you can deploy chiitiler with AWS CDK, check [cdk](./cdk)
|
|
128
|
-
|
|
129
|
-
## supported protocols in style.json
|
|
130
|
-
|
|
131
|
-
- `http://` or `https://` protocol are used in Style Specification
|
|
132
|
-
- In addition, chiitiler supports following protocols:
|
|
133
|
-
- `s3://` for S3 bucket
|
|
134
|
-
- `gs://` for Google Cloud Storage bucket
|
|
135
|
-
- `file://` for file system
|
|
136
|
-
- `mbtiles://` for MBTIles files
|
|
137
|
-
- `pmtiles://` for PMTiles, remote or local or s3
|
|
138
|
-
- `cog://` experimental, for Cloud Optimized GeoTIFF. CRS must be EPSG:3857.
|
|
139
|
-
- Only when `http://` and `https://` chiitiler cache them with a method you specified.
|
|
140
|
-
|
|
141
|
-
### example
|
|
142
|
-
|
|
143
|
-
[./localdata/style.json](./localdata/style.json)
|
|
144
|
-
|
|
145
|
-
```json
|
|
146
|
-
{
|
|
147
|
-
"version": "8",
|
|
148
|
-
"sources": {
|
|
149
|
-
"dir": {
|
|
150
|
-
"type": "vector",
|
|
151
|
-
"tiles": [
|
|
152
|
-
"file://localdata/tiles/{z}/{x}/{y}.pbf"
|
|
153
|
-
],
|
|
154
|
-
"maxzoom": 6
|
|
155
|
-
},
|
|
156
|
-
"mbtiles": {
|
|
157
|
-
"type": "vector",
|
|
158
|
-
"tiles": [
|
|
159
|
-
"mbtiles://localdata/school.mbtiles/{z}/{x}/{y}"
|
|
160
|
-
],
|
|
161
|
-
"maxzoom": 10
|
|
162
|
-
},
|
|
163
|
-
"pmtiles": {
|
|
164
|
-
"type": "vector",
|
|
165
|
-
"tiles": [
|
|
166
|
-
"pmtiles://localdata/school.pmtiles/{z}/{x}/{y}"
|
|
167
|
-
],
|
|
168
|
-
"maxzoom": 10
|
|
169
|
-
},
|
|
170
|
-
"s3": {
|
|
171
|
-
"type": "vector",
|
|
172
|
-
"tiles": [
|
|
173
|
-
"s3://tiles/{z}/{x}/{y}.pbf"
|
|
174
|
-
],
|
|
175
|
-
"maxzoom": 6
|
|
176
|
-
},
|
|
177
|
-
"gcs": {
|
|
178
|
-
"type": "vector",
|
|
179
|
-
"tiles": [
|
|
180
|
-
"gs://tiles/{z}/{x}/{y}.pbf"
|
|
181
|
-
],
|
|
182
|
-
"maxzoom": 6
|
|
183
|
-
},
|
|
184
|
-
"cog": {
|
|
185
|
-
"type": "raster",
|
|
186
|
-
"tiles": [
|
|
187
|
-
"cog://https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/54/T/WN/2024/9/S2A_54TWN_20240908_0_L2A/TCI.tif/{z}/{x}/{y}"
|
|
188
|
-
],
|
|
189
|
-
"tileSize": 256
|
|
190
|
-
}
|
|
191
|
-
},
|
|
192
|
-
"layers": [
|
|
193
|
-
{
|
|
194
|
-
"id": "dir",
|
|
195
|
-
"source": "dir",
|
|
196
|
-
"source-layer": "P2921",
|
|
197
|
-
"type": "circle",
|
|
198
|
-
"paint": {
|
|
199
|
-
"circle-radius": 10,
|
|
200
|
-
"circle-color": "red"
|
|
201
|
-
}
|
|
202
|
-
},
|
|
203
|
-
{
|
|
204
|
-
"id": "mbtiles",
|
|
205
|
-
"source": "mbtiles",
|
|
206
|
-
"source-layer": "P2921",
|
|
207
|
-
"type": "circle",
|
|
208
|
-
"paint": {
|
|
209
|
-
"circle-radius": 7,
|
|
210
|
-
"circle-color": "blue"
|
|
211
|
-
}
|
|
212
|
-
},
|
|
213
|
-
{
|
|
214
|
-
"id": "pmtiles",
|
|
215
|
-
"source": "pmtiles",
|
|
216
|
-
"source-layer": "P2921",
|
|
217
|
-
"type": "circle",
|
|
218
|
-
"paint": {
|
|
219
|
-
"circle-radius": 5,
|
|
220
|
-
"circle-color": "yellow"
|
|
221
|
-
}
|
|
222
|
-
},
|
|
223
|
-
{
|
|
224
|
-
"id": "s3",
|
|
225
|
-
"source": "s3",
|
|
226
|
-
"source-layer": "P2921",
|
|
227
|
-
"type": "circle",
|
|
228
|
-
"paint": {
|
|
229
|
-
"circle-radius": 3,
|
|
230
|
-
"circle-color": "green"
|
|
231
|
-
}
|
|
232
|
-
},
|
|
233
|
-
{
|
|
234
|
-
"id": "pmtiles-s3",
|
|
235
|
-
"source": "pmtiles-s3",
|
|
236
|
-
"source-layer": "P2921",
|
|
237
|
-
"type": "circle",
|
|
238
|
-
"paint": {
|
|
239
|
-
"circle-radius": 3,
|
|
240
|
-
"circle-color": "purple"
|
|
241
|
-
}
|
|
242
|
-
},
|
|
243
|
-
{
|
|
244
|
-
"id": "gcs",
|
|
245
|
-
"source": "gcs",
|
|
246
|
-
"source-layer": "P2921",
|
|
247
|
-
"type": "circle",
|
|
248
|
-
"paint": {
|
|
249
|
-
"circle-radius": 3,
|
|
250
|
-
"circle-color": "purple"
|
|
251
|
-
}
|
|
252
|
-
},
|
|
253
|
-
{
|
|
254
|
-
"id": "cog",
|
|
255
|
-
"source": "cog",
|
|
256
|
-
"type": "raster",
|
|
257
|
-
"paint": {
|
|
258
|
-
"raster-opacity": 0.5
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
]
|
|
262
|
-
}
|
|
93
|
+
The included [`docker-compose.yml`](./docker-compose.yml) spins up MinIO and `fake-gcs-server`:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
docker compose up
|
|
263
97
|
```
|
|
264
98
|
|
|
265
|
-
|
|
99
|
+
Volumes mount `localdata/` and `.cache/` so test assets and cached source data persist between runs.
|
|
100
|
+
|
|
101
|
+
## HTTP API
|
|
266
102
|
|
|
267
|
-
|
|
268
|
-
|
|
103
|
+
| Method | Path Pattern | Description |
|
|
104
|
+
| ------ | ------------ | ----------- |
|
|
105
|
+
| GET/POST | `/tiles/{z}/{x}/{y}.{ext}` | Render a raster tile (`png`, `jpeg`, `jpg`, `webp`). |
|
|
106
|
+
| GET/POST | `/clip.{ext}` | Render a bounding box image (`png`, `jpeg`, `jpg`, `webp`). |
|
|
107
|
+
| GET/POST | `/static/{lon},{lat},{zoom}[@{bearing}][,{pitch}]/{width}x{height}.{ext}` | Render a static image (`png`, `jpeg`, `jpg`, `webp`). |
|
|
108
|
+
| GET | `/debug` | Style explorer UI (requires debug mode). |
|
|
109
|
+
| GET | `/editor` | Lightweight style editor (requires debug mode). |
|
|
269
110
|
|
|
270
|
-
###
|
|
111
|
+
### Query Parameters
|
|
271
112
|
|
|
272
|
-
|
|
273
|
-
|
|
113
|
+
- `url` – Required when using GET. Points to a MapLibre Style JSON.
|
|
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`).
|
|
119
|
+
|
|
120
|
+
POST requests accept the style object directly in the JSON body (`{ "style": { ... } }`).
|
|
121
|
+
|
|
122
|
+
### Streaming Responses
|
|
123
|
+
|
|
124
|
+
Enable streaming (Sharp pipeline without buffering) by setting `CHIITILER_STREAM_MODE=true` or passing `--stream`.
|
|
125
|
+
|
|
126
|
+
## CLI Reference
|
|
127
|
+
|
|
128
|
+
Chiitiler exposes a single command: `tile-server`.
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
npx tsx src/main.ts tile-server --help
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
| Option | Description | Environment Fallback | Default |
|
|
135
|
+
| ------ | ----------- | -------------------- | ------- |
|
|
136
|
+
| `--cache <none/memory/file/s3/gcs>` | Select cache backend. | `CHIITILER_CACHE_METHOD` | `none` |
|
|
137
|
+
| `--cache-ttl <seconds>` | TTL for memory/file caches. | `CHIITILER_CACHE_TTL_SEC` | `3600` |
|
|
138
|
+
| `--memory-cache-max-item-count <n>` | Max items in memory cache. | `CHIITILER_MEMORYCACHE_MAXITEMCOUNT` | `1000` |
|
|
139
|
+
| `--file-cache-dir <dir>` | Disk cache directory. | `CHIITILER_FILECACHE_DIR` | `./.cache` |
|
|
140
|
+
| `--s3-cache-bucket <name>` | S3 bucket for caching. | `CHIITILER_S3CACHE_BUCKET` | `""` |
|
|
141
|
+
| `--s3-region <region>` | S3 region used for requests. | `CHIITILER_S3_REGION` | `us-east1` |
|
|
142
|
+
| `--s3-endpoint <url>` | S3-compatible endpoint. | `CHIITILER_S3_ENDPOINT` | `""` |
|
|
143
|
+
| `--s3-force-path-style` | Force path-style requests. | `CHIITILER_S3_FORCE_PATH_STYLE` (`true/false`) | `false` |
|
|
144
|
+
| `--gcs-cache-bucket <name>` | GCS bucket for caching. | `CHIITILER_GCS_CACHE_BUCKET` | `""` |
|
|
145
|
+
| `--gcs-project-id <id>` | GCP project ID. | `CHIITILER_GCS_PROJECT_ID` | `""` |
|
|
146
|
+
| `--gcs-key-filename <path>` | Service account JSON. | `CHIITILER_GCS_KEY_FILENAME` | `""` |
|
|
147
|
+
| `--gcs-cache-prefix <prefix>` | GCS object prefix. | `CHIITILER_GCS_CACHE_PREFIX` | `""` |
|
|
148
|
+
| `--gcs-api-endpoint <url>` | Custom GCS endpoint. | `CHIITILER_GCS_API_ENDPOINT` | `""` |
|
|
149
|
+
| `--port <number>` | HTTP listen port. | `CHIITILER_PORT` | `3000` |
|
|
150
|
+
| `--stream` | Enable streaming mode. | `CHIITILER_STREAM_MODE` | `false` |
|
|
151
|
+
| `--debug` | Enable debug UI routes. | `CHIITILER_DEBUG` | `false` |
|
|
152
|
+
|
|
153
|
+
Set `CHIITILER_PROCESSES` to control clustering (`0` uses all CPUs). When `>1`, the primary process forks workers that all share the same cache adapter.
|
|
154
|
+
|
|
155
|
+
## Environment Variables
|
|
156
|
+
|
|
157
|
+
In addition to the CLI options above, the server respects:
|
|
158
|
+
|
|
159
|
+
| Variable | Default | Notes |
|
|
160
|
+
| -------- | ------- | ----- |
|
|
161
|
+
| `CHIITILER_PROCESSES` | `1` | Number of worker processes; `0` = `availableParallelism()`. |
|
|
162
|
+
| `AWS_ACCESS_KEY_ID` / `AWS_SECRET_ACCESS_KEY` | – | Used by the S3 cache adapter. |
|
|
163
|
+
| `AWS_REGION` | – | Overrides SDK default region if set. |
|
|
164
|
+
| `GOOGLE_APPLICATION_CREDENTIALS` | – | Path to a service account JSON used by the GCS adapter. |
|
|
165
|
+
|
|
166
|
+
## Cache Backends
|
|
167
|
+
|
|
168
|
+
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.
|
|
169
|
+
|
|
170
|
+
- **none** – No caching; every request renders from scratch.
|
|
171
|
+
- **memory** – In-memory LRU cache with configurable TTL and max entries.
|
|
172
|
+
- **file** – Stores fetched source assets under `CHIITILER_FILECACHE_DIR`.
|
|
173
|
+
- **s3** – Uploads cached source assets to S3/MinIO; honors custom endpoint and path-style.
|
|
174
|
+
- **gcs** – Uploads cached source assets to Google Cloud Storage or `fake-gcs-server`.
|
|
175
|
+
|
|
176
|
+
Each adapter exposes the same `get`/`set` interface and can be reused when embedding Chiitiler as a library.
|
|
177
|
+
|
|
178
|
+
## Debug Tools
|
|
179
|
+
|
|
180
|
+
Run with `--debug` or `CHIITILER_DEBUG=true` to unlock:
|
|
181
|
+
|
|
182
|
+
- `/debug` – Inspect styles, test queries, and view response metadata.
|
|
183
|
+
- `/editor` – Lightweight MapLibre style editor with live preview.
|
|
184
|
+
|
|
185
|
+
## Development & Testing
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
npm run dev # Watch mode via tsx
|
|
189
|
+
npm run build # Bundle to build/main.cjs with esbuild
|
|
190
|
+
npm run test:unit # Vitest unit suite (src/**/*.test.ts)
|
|
191
|
+
npm run test:integration # End-to-end scenarios in tests/
|
|
192
|
+
npm run test:coverage # Unit coverage with V8 provider
|
|
193
|
+
npm run test:benchmark # Performance tests (see BENCHMARK.md)
|
|
274
194
|
```
|
|
275
195
|
|
|
276
|
-
|
|
196
|
+
Benchmark scenarios and recent measurements live in [BENCHMARK.md](./BENCHMARK.md).
|
|
197
|
+
|
|
198
|
+
## Library Usage
|
|
277
199
|
|
|
278
|
-
|
|
200
|
+
Chiitiler is also published as an npm library. Core helpers return Sharp instances or encoded buffers so you can integrate the renderer into other pipelines.
|
|
279
201
|
|
|
280
|
-
```
|
|
202
|
+
```ts
|
|
203
|
+
import { createWriteStream } from 'node:fs';
|
|
281
204
|
import {
|
|
282
|
-
getRenderedBboxBuffer,
|
|
283
205
|
getRenderedTileBuffer,
|
|
284
|
-
|
|
206
|
+
getRenderedBboxBuffer,
|
|
207
|
+
getRenderedImageBuffer,
|
|
208
|
+
getRenderedTileStream,
|
|
209
|
+
getRenderedBboxStream,
|
|
210
|
+
getRenderedImageStream,
|
|
211
|
+
ChiitilerCache,
|
|
285
212
|
} from 'chiitiler';
|
|
286
213
|
|
|
287
|
-
const
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
214
|
+
const cache = ChiitilerCache.fileCache({ dir: './.cache', ttl: 3600 });
|
|
215
|
+
|
|
216
|
+
const tile = await getRenderedTileBuffer({
|
|
217
|
+
stylejson: 'https://tile.openstreetmap.jp/styles/osm-bright/style.json',
|
|
218
|
+
z: 5,
|
|
219
|
+
x: 27,
|
|
220
|
+
y: 12,
|
|
221
|
+
tileSize: 512,
|
|
222
|
+
margin: 0,
|
|
223
|
+
ext: 'webp',
|
|
224
|
+
quality: 100,
|
|
225
|
+
cache,
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
const clip = await getRenderedBboxBuffer({
|
|
229
|
+
stylejson: 'file://localdata/style.json',
|
|
230
|
+
bbox: [123.4, 34.5, 124.5, 35.6],
|
|
231
|
+
size: 1024,
|
|
232
|
+
ext: 'png',
|
|
233
|
+
quality: 95,
|
|
234
|
+
cache: ChiitilerCache.noneCache(),
|
|
291
235
|
});
|
|
292
|
-
// credentials are loaded from environment variables: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY
|
|
293
236
|
|
|
294
|
-
const
|
|
295
|
-
|
|
237
|
+
const image = await getRenderedImageBuffer({
|
|
238
|
+
stylejson: 'file://localdata/style.json',
|
|
239
|
+
lat: 123.45,
|
|
240
|
+
lon: 67.89,
|
|
241
|
+
zoom: 10,
|
|
242
|
+
bearing: 180,
|
|
243
|
+
pitch: 60,
|
|
244
|
+
size: 1024,
|
|
245
|
+
ext: 'png',
|
|
246
|
+
quality: 95,
|
|
247
|
+
cache,
|
|
296
248
|
});
|
|
297
|
-
// credentials are loaded from environment variables: GOOGLE_APPLICATION_CREDENTIALS
|
|
298
249
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
250
|
+
// you can get Sharp streams directly
|
|
251
|
+
const tileStream = await getRenderedTileStream({
|
|
252
|
+
stylejson: 'https://tile.openstreetmap.jp/styles/osm-bright/style.json',
|
|
253
|
+
z: 5,
|
|
254
|
+
x: 27,
|
|
255
|
+
y: 12,
|
|
304
256
|
tileSize: 512,
|
|
305
|
-
ext: 'webp', // png, webp, jpg
|
|
306
|
-
cache: s3Cache,
|
|
307
|
-
quality: 80,
|
|
308
257
|
margin: 0,
|
|
258
|
+
ext: 'png',
|
|
259
|
+
quality: 90,
|
|
260
|
+
cache,
|
|
309
261
|
});
|
|
310
262
|
|
|
311
|
-
const
|
|
312
|
-
stylejson: 'file://
|
|
263
|
+
const bboxStream = await getRenderedBboxStream({
|
|
264
|
+
stylejson: 'file://localdata/style.json',
|
|
313
265
|
bbox: [123.4, 34.5, 124.5, 35.6],
|
|
314
266
|
size: 1024,
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
267
|
+
ext: 'jpeg',
|
|
268
|
+
quality: 85,
|
|
269
|
+
cache,
|
|
318
270
|
});
|
|
319
271
|
|
|
320
|
-
|
|
272
|
+
const imageStream = await getRenderedImageStream({
|
|
273
|
+
stylejson: 'file://localdata/style.json',
|
|
274
|
+
lat: 123.4,
|
|
275
|
+
lon: 34.5,
|
|
276
|
+
zoom: 10,
|
|
277
|
+
bearing: 180,
|
|
278
|
+
pitch: 60,
|
|
279
|
+
size: 1024,
|
|
280
|
+
ext: 'png',
|
|
281
|
+
quality: 95,
|
|
282
|
+
cache,
|
|
283
|
+
})
|
|
321
284
|
```
|
|
322
285
|
|
|
323
|
-
##
|
|
286
|
+
## Deployment
|
|
287
|
+
|
|
288
|
+
- **AWS CDK** – The [`cdk/`](./cdk) directory contains an AWS CDK app for provisioning Chiitiler on ECS/Fargate. See `cdk/README.md` for stack details.
|
|
289
|
+
- **Docker** – The provided `Dockerfile` installs runtime dependencies for `sharp` and exposes `tile-server` as the default entrypoint.
|
|
290
|
+
- **Bench setups** – `docker-compose.yml` provisions MinIO, Fake GCS, and sample data for local smoke tests.
|
|
291
|
+
|
|
292
|
+
## Architecture
|
|
293
|
+
|
|
294
|
+
```mermaid
|
|
295
|
+
graph LR
|
|
296
|
+
subgraph sources
|
|
297
|
+
direction LR
|
|
298
|
+
A[style.json]
|
|
299
|
+
z/x/y.pbf
|
|
300
|
+
z/x/y.png/webp/jpg
|
|
301
|
+
sprite
|
|
302
|
+
glyphs
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
subgraph chiitiler
|
|
306
|
+
cache
|
|
307
|
+
render
|
|
308
|
+
server
|
|
309
|
+
end
|
|
324
310
|
|
|
325
|
-
|
|
326
|
-
|
|
311
|
+
sources --> cache --> render --> server --/tiles/z/x/y--> png/webp/jpg
|
|
312
|
+
|
|
313
|
+
cache <--get/set--> memory/file/S3
|
|
314
|
+
```
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import { getRenderedBbox, getRenderedTile, GetRenderedBboxOptions, GetRenderedTileOptions } from './render/index.js';
|
|
1
|
+
import { getRenderedBbox, getRenderedTile, getRenderedImage, GetRenderedBboxOptions, GetRenderedTileOptions, GetRenderedImageOptions } from './render/index.js';
|
|
2
2
|
export declare function getRenderedBboxBuffer(options: GetRenderedBboxOptions): Promise<Buffer>;
|
|
3
3
|
export { getRenderedBbox as getRenderedBboxStream };
|
|
4
|
+
export declare function getRenderedImageBuffer(options: GetRenderedImageOptions): Promise<Buffer>;
|
|
5
|
+
export { getRenderedImage as getRenderedImageStream };
|
|
4
6
|
export declare function getRenderedTileBuffer(options: GetRenderedTileOptions): Promise<Buffer>;
|
|
5
7
|
export { getRenderedTile as getRenderedTileStream };
|
|
6
8
|
export * as ChiitilerCache from './cache/index.js';
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
|
-
import { getRenderedBbox, getRenderedTile, } from './render/index.js';
|
|
1
|
+
import { getRenderedBbox, getRenderedTile, getRenderedImage, } from './render/index.js';
|
|
2
2
|
export async function getRenderedBboxBuffer(options) {
|
|
3
3
|
const sharp = await getRenderedBbox(options);
|
|
4
4
|
return sharp.toBuffer();
|
|
5
5
|
}
|
|
6
6
|
export { getRenderedBbox as getRenderedBboxStream };
|
|
7
|
+
export async function getRenderedImageBuffer(options) {
|
|
8
|
+
const sharp = await getRenderedImage(options);
|
|
9
|
+
return sharp.toBuffer();
|
|
10
|
+
}
|
|
11
|
+
export { getRenderedImage as getRenderedImageStream };
|
|
7
12
|
export async function getRenderedTileBuffer(options) {
|
|
8
13
|
const sharp = await getRenderedTile(options);
|
|
9
14
|
return sharp.toBuffer();
|
package/dist/render/index.d.ts
CHANGED
|
@@ -23,4 +23,17 @@ type GetRenderedBboxOptions = {
|
|
|
23
23
|
quality: number;
|
|
24
24
|
};
|
|
25
25
|
declare function getRenderedBbox({ stylejson, bbox, size, cache, ext, quality, }: GetRenderedBboxOptions): Promise<sharp.Sharp>;
|
|
26
|
-
|
|
26
|
+
type GetRenderedImageOptions = {
|
|
27
|
+
stylejson: string | StyleSpecification;
|
|
28
|
+
cache: Cache;
|
|
29
|
+
ext: SupportedFormat;
|
|
30
|
+
quality: number;
|
|
31
|
+
bearing: number;
|
|
32
|
+
pitch: number;
|
|
33
|
+
zoom: number;
|
|
34
|
+
center: [number, number];
|
|
35
|
+
height: number;
|
|
36
|
+
width: number;
|
|
37
|
+
};
|
|
38
|
+
declare function getRenderedImage(options: GetRenderedImageOptions): Promise<sharp.Sharp>;
|
|
39
|
+
export { getRenderedTile, getRenderedBbox, getRenderedImage, type GetRenderedBboxOptions, type GetRenderedTileOptions, type GetRenderedImageOptions, type SupportedFormat, };
|
package/dist/render/index.js
CHANGED
|
@@ -121,7 +121,7 @@ async function getRenderedBbox({ stylejson, bbox, size, cache, ext, quality, })
|
|
|
121
121
|
height,
|
|
122
122
|
center,
|
|
123
123
|
}, cache, 'static');
|
|
124
|
-
|
|
124
|
+
const _sharp = sharp(pixels, {
|
|
125
125
|
raw: {
|
|
126
126
|
width,
|
|
127
127
|
height,
|
|
@@ -138,4 +138,31 @@ async function getRenderedBbox({ stylejson, bbox, size, cache, ext, quality, })
|
|
|
138
138
|
return _sharp.webp({ quality, effort: 0 });
|
|
139
139
|
}
|
|
140
140
|
}
|
|
141
|
-
|
|
141
|
+
async function getRenderedImage(options) {
|
|
142
|
+
const style = await loadStyle(options.stylejson, options.cache);
|
|
143
|
+
const pixels = await render(style, {
|
|
144
|
+
center: options.center,
|
|
145
|
+
height: options.height,
|
|
146
|
+
width: options.width,
|
|
147
|
+
zoom: options.zoom,
|
|
148
|
+
bearing: options.bearing,
|
|
149
|
+
pitch: options.pitch,
|
|
150
|
+
}, options.cache, 'static');
|
|
151
|
+
const _sharp = sharp(pixels, {
|
|
152
|
+
raw: {
|
|
153
|
+
width: options.width,
|
|
154
|
+
height: options.height,
|
|
155
|
+
channels: 4,
|
|
156
|
+
},
|
|
157
|
+
});
|
|
158
|
+
switch (options.ext) {
|
|
159
|
+
case 'png':
|
|
160
|
+
return _sharp.png();
|
|
161
|
+
case 'jpeg':
|
|
162
|
+
case 'jpg':
|
|
163
|
+
return _sharp.jpeg({ quality: options.quality });
|
|
164
|
+
case 'webp':
|
|
165
|
+
return _sharp.webp({ quality: options.quality, effort: 0 });
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
export { getRenderedTile, getRenderedBbox, getRenderedImage, };
|