chiitiler 1.17.0 → 1.19.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 +8 -13
- package/dist/cli.js +0 -14
- package/dist/index.d.ts +5 -5
- package/dist/index.js +7 -7
- package/dist/render/index.d.ts +5 -5
- package/dist/render/index.js +3 -3
- package/dist/server/index.d.ts +0 -1
- package/dist/server/index.js +0 -3
- package/dist/server/routes/camera.d.ts +196 -7
- package/dist/server/routes/camera.js +7 -28
- package/dist/server/routes/clip.d.ts +114 -7
- package/dist/server/routes/clip.js +7 -28
- package/dist/server/routes/tiles.d.ts +110 -7
- package/dist/server/routes/tiles.js +4 -25
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -119,10 +119,6 @@ Volumes mount `localdata/` and `.cache/` so test assets and cached source data p
|
|
|
119
119
|
|
|
120
120
|
POST requests accept the style object directly in the JSON body (`{ "style": { ... } }`).
|
|
121
121
|
|
|
122
|
-
### Streaming Responses
|
|
123
|
-
|
|
124
|
-
Enable streaming (Sharp pipeline without buffering) by setting `CHIITILER_STREAM_MODE=true` or passing `--stream`.
|
|
125
|
-
|
|
126
122
|
## CLI Reference
|
|
127
123
|
|
|
128
124
|
Chiitiler exposes a single command: `tile-server`.
|
|
@@ -147,7 +143,6 @@ npx tsx src/main.ts tile-server --help
|
|
|
147
143
|
| `--gcs-cache-prefix <prefix>` | GCS object prefix. | `CHIITILER_GCS_CACHE_PREFIX` | `""` |
|
|
148
144
|
| `--gcs-api-endpoint <url>` | Custom GCS endpoint. | `CHIITILER_GCS_API_ENDPOINT` | `""` |
|
|
149
145
|
| `--port <number>` | HTTP listen port. | `CHIITILER_PORT` | `3000` |
|
|
150
|
-
| `--stream` | Enable streaming mode. | `CHIITILER_STREAM_MODE` | `false` |
|
|
151
146
|
| `--debug` | Enable debug UI routes. | `CHIITILER_DEBUG` | `false` |
|
|
152
147
|
|
|
153
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.
|
|
@@ -202,11 +197,11 @@ Chiitiler is also published as an npm library. Core helpers return Sharp instanc
|
|
|
202
197
|
```ts
|
|
203
198
|
import {
|
|
204
199
|
getRenderedTileBuffer,
|
|
205
|
-
|
|
206
|
-
|
|
200
|
+
getRenderedClipBuffer,
|
|
201
|
+
getRenderedCameraBuffer,
|
|
207
202
|
getRenderedTileStream,
|
|
208
|
-
|
|
209
|
-
|
|
203
|
+
getRenderedClipStream,
|
|
204
|
+
getRenderedCameraStream,
|
|
210
205
|
ChiitilerCache,
|
|
211
206
|
} from 'chiitiler';
|
|
212
207
|
|
|
@@ -224,7 +219,7 @@ const tile = await getRenderedTileBuffer({
|
|
|
224
219
|
cache,
|
|
225
220
|
});
|
|
226
221
|
|
|
227
|
-
const clip = await
|
|
222
|
+
const clip = await getRenderedClipBuffer({
|
|
228
223
|
stylejson: 'file://localdata/style.json',
|
|
229
224
|
bbox: [123.4, 34.5, 124.5, 35.6],
|
|
230
225
|
size: 1024,
|
|
@@ -233,7 +228,7 @@ const clip = await getRenderedBboxBuffer({
|
|
|
233
228
|
cache: ChiitilerCache.noneCache(),
|
|
234
229
|
});
|
|
235
230
|
|
|
236
|
-
const
|
|
231
|
+
const camera = await getRenderedCameraBuffer({
|
|
237
232
|
stylejson: 'file://localdata/style.json',
|
|
238
233
|
center: [139.69, 35.68],
|
|
239
234
|
zoom: 10,
|
|
@@ -259,7 +254,7 @@ const tileStream = await getRenderedTileStream({
|
|
|
259
254
|
cache,
|
|
260
255
|
});
|
|
261
256
|
|
|
262
|
-
const
|
|
257
|
+
const clipStream = await getRenderedClipStream({
|
|
263
258
|
stylejson: 'file://localdata/style.json',
|
|
264
259
|
bbox: [123.4, 34.5, 124.5, 35.6],
|
|
265
260
|
size: 1024,
|
|
@@ -268,7 +263,7 @@ const bboxStream = await getRenderedBboxStream({
|
|
|
268
263
|
cache,
|
|
269
264
|
});
|
|
270
265
|
|
|
271
|
-
const
|
|
266
|
+
const cameraStream = await getRenderedCameraStream({
|
|
272
267
|
stylejson: 'file://localdata/style.json',
|
|
273
268
|
center: [139.69, 35.68],
|
|
274
269
|
zoom: 10,
|
package/dist/cli.js
CHANGED
|
@@ -81,17 +81,6 @@ function parseDebug(debug) {
|
|
|
81
81
|
// undefined or invalid
|
|
82
82
|
return false;
|
|
83
83
|
}
|
|
84
|
-
function parseStream(stream) {
|
|
85
|
-
// command-line option
|
|
86
|
-
if (stream)
|
|
87
|
-
return true;
|
|
88
|
-
// command-line is not specified or false -> try to read from env
|
|
89
|
-
const streamEnv = process.env.CHIITILER_STREAM_MODE;
|
|
90
|
-
if (streamEnv !== undefined)
|
|
91
|
-
return streamEnv === 'true';
|
|
92
|
-
// undefined or invalid
|
|
93
|
-
return false;
|
|
94
|
-
}
|
|
95
84
|
export function createProgram() {
|
|
96
85
|
const program = new Command();
|
|
97
86
|
program
|
|
@@ -110,7 +99,6 @@ export function createProgram() {
|
|
|
110
99
|
.option('-gcsp --gcs-cache-prefix <prefix>', 'gcs cache prefix', '')
|
|
111
100
|
.option('-gcse --gcs-api-endpoint <api-endpoint>', 'gcs api endpoint', '')
|
|
112
101
|
.option('-p --port <port>', 'port number')
|
|
113
|
-
.option('-r --stream', 'stream mode')
|
|
114
102
|
.option('-D --debug', 'debug mode')
|
|
115
103
|
.action((options) => {
|
|
116
104
|
const serverOptions = {
|
|
@@ -130,14 +118,12 @@ export function createProgram() {
|
|
|
130
118
|
}),
|
|
131
119
|
port: parsePort(options.port),
|
|
132
120
|
debug: parseDebug(options.debug),
|
|
133
|
-
stream: parseStream(options.stream),
|
|
134
121
|
};
|
|
135
122
|
if (serverOptions.debug) {
|
|
136
123
|
console.log(`running server: http://localhost:${serverOptions.port}`);
|
|
137
124
|
console.log(`cache method: ${serverOptions.cache.name}`);
|
|
138
125
|
console.log(`debug page: http://localhost:${serverOptions.port}/debug`);
|
|
139
126
|
console.log(`editor page: http://localhost:${serverOptions.port}/editor`);
|
|
140
|
-
console.log('stream mode:', serverOptions.stream ? 'enabled' : 'disabled');
|
|
141
127
|
}
|
|
142
128
|
const { start } = initServer(serverOptions);
|
|
143
129
|
start();
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare function
|
|
3
|
-
export {
|
|
4
|
-
export declare function
|
|
5
|
-
export {
|
|
1
|
+
import { getRenderedClip, getRenderedTile, getRenderedCamera, GetRenderedClipOptions, GetRenderedTileOptions, GetRenderedCameraOptions } from './render/index.js';
|
|
2
|
+
export declare function getRenderedClipBuffer(options: GetRenderedClipOptions): Promise<Buffer>;
|
|
3
|
+
export { getRenderedClip as getRenderedClipStream };
|
|
4
|
+
export declare function getRenderedCameraBuffer(options: GetRenderedCameraOptions): Promise<Buffer>;
|
|
5
|
+
export { getRenderedCamera as getRenderedCameraStream };
|
|
6
6
|
export declare function getRenderedTileBuffer(options: GetRenderedTileOptions): Promise<Buffer>;
|
|
7
7
|
export { getRenderedTile as getRenderedTileStream };
|
|
8
8
|
export * as ChiitilerCache from './cache/index.js';
|
package/dist/index.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export async function
|
|
3
|
-
const sharp = await
|
|
1
|
+
import { getRenderedClip, getRenderedTile, getRenderedCamera, } from './render/index.js';
|
|
2
|
+
export async function getRenderedClipBuffer(options) {
|
|
3
|
+
const sharp = await getRenderedClip(options);
|
|
4
4
|
return sharp.toBuffer();
|
|
5
5
|
}
|
|
6
|
-
export {
|
|
7
|
-
export async function
|
|
8
|
-
const sharp = await
|
|
6
|
+
export { getRenderedClip as getRenderedClipStream };
|
|
7
|
+
export async function getRenderedCameraBuffer(options) {
|
|
8
|
+
const sharp = await getRenderedCamera(options);
|
|
9
9
|
return sharp.toBuffer();
|
|
10
10
|
}
|
|
11
|
-
export {
|
|
11
|
+
export { getRenderedCamera as getRenderedCameraStream };
|
|
12
12
|
export async function getRenderedTileBuffer(options) {
|
|
13
13
|
const sharp = await getRenderedTile(options);
|
|
14
14
|
return sharp.toBuffer();
|
package/dist/render/index.d.ts
CHANGED
|
@@ -14,7 +14,7 @@ type GetRenderedTileOptions = {
|
|
|
14
14
|
};
|
|
15
15
|
type SupportedFormat = 'png' | 'jpeg' | 'jpg' | 'webp';
|
|
16
16
|
declare function getRenderedTile({ stylejson, z, x, y, tileSize, cache, margin, ext, quality, }: GetRenderedTileOptions): Promise<sharp.Sharp>;
|
|
17
|
-
type
|
|
17
|
+
type GetRenderedClipOptions = {
|
|
18
18
|
stylejson: string | StyleSpecification;
|
|
19
19
|
bbox: [number, number, number, number];
|
|
20
20
|
size: number;
|
|
@@ -22,8 +22,8 @@ type GetRenderedBboxOptions = {
|
|
|
22
22
|
ext: SupportedFormat;
|
|
23
23
|
quality: number;
|
|
24
24
|
};
|
|
25
|
-
declare function
|
|
26
|
-
type
|
|
25
|
+
declare function getRenderedClip({ stylejson, bbox, size, cache, ext, quality, }: GetRenderedClipOptions): Promise<sharp.Sharp>;
|
|
26
|
+
type GetRenderedCameraOptions = {
|
|
27
27
|
stylejson: string | StyleSpecification;
|
|
28
28
|
cache: Cache;
|
|
29
29
|
ext: SupportedFormat;
|
|
@@ -35,5 +35,5 @@ type GetRenderedImageOptions = {
|
|
|
35
35
|
height: number;
|
|
36
36
|
width: number;
|
|
37
37
|
};
|
|
38
|
-
declare function
|
|
39
|
-
export { getRenderedTile,
|
|
38
|
+
declare function getRenderedCamera(options: GetRenderedCameraOptions): Promise<sharp.Sharp>;
|
|
39
|
+
export { getRenderedTile, getRenderedClip, getRenderedCamera, type GetRenderedClipOptions, type GetRenderedTileOptions, type GetRenderedCameraOptions, type SupportedFormat, };
|
package/dist/render/index.js
CHANGED
|
@@ -112,7 +112,7 @@ const calcRenderingParams = (bbox, size) => {
|
|
|
112
112
|
const center = mercator.ll(mercCenter, 25); // latlon
|
|
113
113
|
return { zoom, width, height, center };
|
|
114
114
|
};
|
|
115
|
-
async function
|
|
115
|
+
async function getRenderedClip({ stylejson, bbox, size, cache, ext, quality, }) {
|
|
116
116
|
const style = await loadStyle(stylejson, cache);
|
|
117
117
|
const { zoom, width, height, center } = calcRenderingParams(bbox, size);
|
|
118
118
|
const pixels = await render(style, {
|
|
@@ -138,7 +138,7 @@ async function getRenderedBbox({ stylejson, bbox, size, cache, ext, quality, })
|
|
|
138
138
|
return _sharp.webp({ quality, effort: 0 });
|
|
139
139
|
}
|
|
140
140
|
}
|
|
141
|
-
async function
|
|
141
|
+
async function getRenderedCamera(options) {
|
|
142
142
|
const style = await loadStyle(options.stylejson, options.cache);
|
|
143
143
|
const pixels = await render(style, {
|
|
144
144
|
center: options.center,
|
|
@@ -165,4 +165,4 @@ async function getRenderedImage(options) {
|
|
|
165
165
|
return _sharp.webp({ quality: options.quality, effort: 0 });
|
|
166
166
|
}
|
|
167
167
|
}
|
|
168
|
-
export { getRenderedTile,
|
|
168
|
+
export { getRenderedTile, getRenderedClip, getRenderedCamera, };
|
package/dist/server/index.d.ts
CHANGED
package/dist/server/index.js
CHANGED
|
@@ -13,15 +13,12 @@ function initServer(options) {
|
|
|
13
13
|
hono.get('/health', (c) => c.text('OK'));
|
|
14
14
|
hono.route('/camera', createCameraRouter({
|
|
15
15
|
cache: options.cache,
|
|
16
|
-
stream: options.stream,
|
|
17
16
|
}));
|
|
18
17
|
hono.route('/tiles', createTilesRouter({
|
|
19
18
|
cache: options.cache,
|
|
20
|
-
stream: options.stream,
|
|
21
19
|
}));
|
|
22
20
|
hono.route('/', createClipRouter({
|
|
23
21
|
cache: options.cache,
|
|
24
|
-
stream: options.stream,
|
|
25
22
|
}));
|
|
26
23
|
return {
|
|
27
24
|
app: hono,
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Cache } from '../../cache/index.js';
|
|
2
2
|
declare function createCameraRouter(options: {
|
|
3
3
|
cache: Cache;
|
|
4
|
-
stream: boolean;
|
|
5
4
|
}): import("hono/hono-base").HonoBase<import("hono/types").BlankEnv, {
|
|
6
5
|
"/:zoom/:lat/:lon/:bearing/:pitch/:dimensions_ext": {
|
|
7
6
|
$get: {
|
|
@@ -20,9 +19,104 @@ declare function createCameraRouter(options: {
|
|
|
20
19
|
dimensions_ext: string;
|
|
21
20
|
};
|
|
22
21
|
};
|
|
23
|
-
output:
|
|
24
|
-
outputFormat:
|
|
25
|
-
status:
|
|
22
|
+
output: "invalid format";
|
|
23
|
+
outputFormat: "body";
|
|
24
|
+
status: 400;
|
|
25
|
+
} | {
|
|
26
|
+
input: {
|
|
27
|
+
param: {
|
|
28
|
+
zoom: string;
|
|
29
|
+
} & {
|
|
30
|
+
lat: string;
|
|
31
|
+
} & {
|
|
32
|
+
lon: string;
|
|
33
|
+
} & {
|
|
34
|
+
bearing: string;
|
|
35
|
+
} & {
|
|
36
|
+
pitch: string;
|
|
37
|
+
} & {
|
|
38
|
+
dimensions_ext: string;
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
output: "url is required";
|
|
42
|
+
outputFormat: "body";
|
|
43
|
+
status: 400;
|
|
44
|
+
} | {
|
|
45
|
+
input: {
|
|
46
|
+
param: {
|
|
47
|
+
zoom: string;
|
|
48
|
+
} & {
|
|
49
|
+
lat: string;
|
|
50
|
+
} & {
|
|
51
|
+
lon: string;
|
|
52
|
+
} & {
|
|
53
|
+
bearing: string;
|
|
54
|
+
} & {
|
|
55
|
+
pitch: string;
|
|
56
|
+
} & {
|
|
57
|
+
dimensions_ext: string;
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
output: Uint8Array<ArrayBuffer>;
|
|
61
|
+
outputFormat: "body";
|
|
62
|
+
status: import("hono/utils/http-status").ContentfulStatusCode;
|
|
63
|
+
} | {
|
|
64
|
+
input: {
|
|
65
|
+
param: {
|
|
66
|
+
zoom: string;
|
|
67
|
+
} & {
|
|
68
|
+
lat: string;
|
|
69
|
+
} & {
|
|
70
|
+
lon: string;
|
|
71
|
+
} & {
|
|
72
|
+
bearing: string;
|
|
73
|
+
} & {
|
|
74
|
+
pitch: string;
|
|
75
|
+
} & {
|
|
76
|
+
dimensions_ext: string;
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
output: "invalid dimensions";
|
|
80
|
+
outputFormat: "body";
|
|
81
|
+
status: 400;
|
|
82
|
+
} | {
|
|
83
|
+
input: {
|
|
84
|
+
param: {
|
|
85
|
+
zoom: string;
|
|
86
|
+
} & {
|
|
87
|
+
lat: string;
|
|
88
|
+
} & {
|
|
89
|
+
lon: string;
|
|
90
|
+
} & {
|
|
91
|
+
bearing: string;
|
|
92
|
+
} & {
|
|
93
|
+
pitch: string;
|
|
94
|
+
} & {
|
|
95
|
+
dimensions_ext: string;
|
|
96
|
+
};
|
|
97
|
+
};
|
|
98
|
+
output: "invalid camera";
|
|
99
|
+
outputFormat: "body";
|
|
100
|
+
status: 400;
|
|
101
|
+
} | {
|
|
102
|
+
input: {
|
|
103
|
+
param: {
|
|
104
|
+
zoom: string;
|
|
105
|
+
} & {
|
|
106
|
+
lat: string;
|
|
107
|
+
} & {
|
|
108
|
+
lon: string;
|
|
109
|
+
} & {
|
|
110
|
+
bearing: string;
|
|
111
|
+
} & {
|
|
112
|
+
pitch: string;
|
|
113
|
+
} & {
|
|
114
|
+
dimensions_ext: string;
|
|
115
|
+
};
|
|
116
|
+
};
|
|
117
|
+
output: "failed to render static image";
|
|
118
|
+
outputFormat: "body";
|
|
119
|
+
status: 400;
|
|
26
120
|
};
|
|
27
121
|
};
|
|
28
122
|
} & {
|
|
@@ -43,9 +137,104 @@ declare function createCameraRouter(options: {
|
|
|
43
137
|
dimensions_ext: string;
|
|
44
138
|
};
|
|
45
139
|
};
|
|
46
|
-
output:
|
|
47
|
-
outputFormat:
|
|
48
|
-
status:
|
|
140
|
+
output: "invalid format";
|
|
141
|
+
outputFormat: "body";
|
|
142
|
+
status: 400;
|
|
143
|
+
} | {
|
|
144
|
+
input: {
|
|
145
|
+
param: {
|
|
146
|
+
zoom: string;
|
|
147
|
+
} & {
|
|
148
|
+
lat: string;
|
|
149
|
+
} & {
|
|
150
|
+
lon: string;
|
|
151
|
+
} & {
|
|
152
|
+
bearing: string;
|
|
153
|
+
} & {
|
|
154
|
+
pitch: string;
|
|
155
|
+
} & {
|
|
156
|
+
dimensions_ext: string;
|
|
157
|
+
};
|
|
158
|
+
};
|
|
159
|
+
output: Uint8Array<ArrayBuffer>;
|
|
160
|
+
outputFormat: "body";
|
|
161
|
+
status: import("hono/utils/http-status").ContentfulStatusCode;
|
|
162
|
+
} | {
|
|
163
|
+
input: {
|
|
164
|
+
param: {
|
|
165
|
+
zoom: string;
|
|
166
|
+
} & {
|
|
167
|
+
lat: string;
|
|
168
|
+
} & {
|
|
169
|
+
lon: string;
|
|
170
|
+
} & {
|
|
171
|
+
bearing: string;
|
|
172
|
+
} & {
|
|
173
|
+
pitch: string;
|
|
174
|
+
} & {
|
|
175
|
+
dimensions_ext: string;
|
|
176
|
+
};
|
|
177
|
+
};
|
|
178
|
+
output: "invalid dimensions";
|
|
179
|
+
outputFormat: "body";
|
|
180
|
+
status: 400;
|
|
181
|
+
} | {
|
|
182
|
+
input: {
|
|
183
|
+
param: {
|
|
184
|
+
zoom: string;
|
|
185
|
+
} & {
|
|
186
|
+
lat: string;
|
|
187
|
+
} & {
|
|
188
|
+
lon: string;
|
|
189
|
+
} & {
|
|
190
|
+
bearing: string;
|
|
191
|
+
} & {
|
|
192
|
+
pitch: string;
|
|
193
|
+
} & {
|
|
194
|
+
dimensions_ext: string;
|
|
195
|
+
};
|
|
196
|
+
};
|
|
197
|
+
output: "invalid camera";
|
|
198
|
+
outputFormat: "body";
|
|
199
|
+
status: 400;
|
|
200
|
+
} | {
|
|
201
|
+
input: {
|
|
202
|
+
param: {
|
|
203
|
+
zoom: string;
|
|
204
|
+
} & {
|
|
205
|
+
lat: string;
|
|
206
|
+
} & {
|
|
207
|
+
lon: string;
|
|
208
|
+
} & {
|
|
209
|
+
bearing: string;
|
|
210
|
+
} & {
|
|
211
|
+
pitch: string;
|
|
212
|
+
} & {
|
|
213
|
+
dimensions_ext: string;
|
|
214
|
+
};
|
|
215
|
+
};
|
|
216
|
+
output: "failed to render static image";
|
|
217
|
+
outputFormat: "body";
|
|
218
|
+
status: 400;
|
|
219
|
+
} | {
|
|
220
|
+
input: {
|
|
221
|
+
param: {
|
|
222
|
+
zoom: string;
|
|
223
|
+
} & {
|
|
224
|
+
lat: string;
|
|
225
|
+
} & {
|
|
226
|
+
lon: string;
|
|
227
|
+
} & {
|
|
228
|
+
bearing: string;
|
|
229
|
+
} & {
|
|
230
|
+
pitch: string;
|
|
231
|
+
} & {
|
|
232
|
+
dimensions_ext: string;
|
|
233
|
+
};
|
|
234
|
+
};
|
|
235
|
+
output: "invalid stylejson";
|
|
236
|
+
outputFormat: "body";
|
|
237
|
+
status: 400;
|
|
49
238
|
};
|
|
50
239
|
};
|
|
51
240
|
}, "/", "/:zoom/:lat/:lon/:bearing/:pitch/:dimensions_ext">;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Hono } from 'hono';
|
|
2
|
-
import { stream } from 'hono/streaming';
|
|
3
2
|
import { isSupportedFormat, isValidStylejson } from '../utils.js';
|
|
4
|
-
import {
|
|
3
|
+
import { getRenderedCamera } from '../../render/index.js';
|
|
5
4
|
function isValidCamera({ zoom, lat, lon, bearing, pitch, }) {
|
|
6
5
|
if (Number.isNaN(lat) || lat < -90 || lat > 90)
|
|
7
6
|
return false;
|
|
@@ -52,7 +51,7 @@ function createCameraRouter(options) {
|
|
|
52
51
|
const quality = Number(c.req.query('quality') ?? 100);
|
|
53
52
|
c.header('Content-Type', `image/${ext}`);
|
|
54
53
|
try {
|
|
55
|
-
const sharp = await
|
|
54
|
+
const sharp = await getRenderedCamera({
|
|
56
55
|
stylejson: url,
|
|
57
56
|
cache: options.cache,
|
|
58
57
|
ext,
|
|
@@ -64,18 +63,8 @@ function createCameraRouter(options) {
|
|
|
64
63
|
height: _height,
|
|
65
64
|
width: _width,
|
|
66
65
|
});
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
return stream(c, async (stream) => {
|
|
70
|
-
for await (const chunk of sharp) {
|
|
71
|
-
stream.write(chunk);
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
else {
|
|
76
|
-
const buf = await sharp.toBuffer();
|
|
77
|
-
return c.body(buf);
|
|
78
|
-
}
|
|
66
|
+
const buf = await sharp.toBuffer();
|
|
67
|
+
return c.body(buf);
|
|
79
68
|
}
|
|
80
69
|
catch (e) {
|
|
81
70
|
console.error(`render error: ${e}`);
|
|
@@ -115,7 +104,7 @@ function createCameraRouter(options) {
|
|
|
115
104
|
const quality = Number(c.req.query('quality') ?? 100);
|
|
116
105
|
c.header('Content-Type', `image/${ext}`);
|
|
117
106
|
try {
|
|
118
|
-
const sharp = await
|
|
107
|
+
const sharp = await getRenderedCamera({
|
|
119
108
|
stylejson: style,
|
|
120
109
|
cache: options.cache,
|
|
121
110
|
ext,
|
|
@@ -127,18 +116,8 @@ function createCameraRouter(options) {
|
|
|
127
116
|
height: _height,
|
|
128
117
|
width: _width,
|
|
129
118
|
});
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
return stream(c, async (stream) => {
|
|
133
|
-
for await (const chunk of sharp) {
|
|
134
|
-
stream.write(chunk);
|
|
135
|
-
}
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
|
-
else {
|
|
139
|
-
const buf = await sharp.toBuffer();
|
|
140
|
-
return c.body(buf);
|
|
141
|
-
}
|
|
119
|
+
const buf = await sharp.toBuffer();
|
|
120
|
+
return c.body(buf);
|
|
142
121
|
}
|
|
143
122
|
catch (e) {
|
|
144
123
|
console.error(`render error: ${e}`);
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Cache } from '../../cache/index.js';
|
|
2
2
|
declare function createClipRouter(options: {
|
|
3
3
|
cache: Cache;
|
|
4
|
-
stream: boolean;
|
|
5
4
|
}): import("hono/hono-base").HonoBase<import("hono/types").BlankEnv, {
|
|
6
5
|
"/:filename_ext": {
|
|
7
6
|
$get: {
|
|
@@ -10,9 +9,63 @@ declare function createClipRouter(options: {
|
|
|
10
9
|
filename_ext: string;
|
|
11
10
|
};
|
|
12
11
|
};
|
|
13
|
-
output:
|
|
14
|
-
outputFormat:
|
|
15
|
-
status:
|
|
12
|
+
output: "invalid format";
|
|
13
|
+
outputFormat: "body";
|
|
14
|
+
status: 400;
|
|
15
|
+
} | {
|
|
16
|
+
input: {
|
|
17
|
+
param: {
|
|
18
|
+
filename_ext: string;
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
output: "url is required";
|
|
22
|
+
outputFormat: "body";
|
|
23
|
+
status: 400;
|
|
24
|
+
} | {
|
|
25
|
+
input: {
|
|
26
|
+
param: {
|
|
27
|
+
filename_ext: string;
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
output: Uint8Array<ArrayBuffer>;
|
|
31
|
+
outputFormat: "body";
|
|
32
|
+
status: import("hono/utils/http-status").ContentfulStatusCode;
|
|
33
|
+
} | {
|
|
34
|
+
input: {
|
|
35
|
+
param: {
|
|
36
|
+
filename_ext: string;
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
output: "failed to render tile";
|
|
40
|
+
outputFormat: "body";
|
|
41
|
+
status: 400;
|
|
42
|
+
} | {
|
|
43
|
+
input: {
|
|
44
|
+
param: {
|
|
45
|
+
filename_ext: string;
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
output: "not found";
|
|
49
|
+
outputFormat: "body";
|
|
50
|
+
status: 404;
|
|
51
|
+
} | {
|
|
52
|
+
input: {
|
|
53
|
+
param: {
|
|
54
|
+
filename_ext: string;
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
output: "bbox is required";
|
|
58
|
+
outputFormat: "body";
|
|
59
|
+
status: 400;
|
|
60
|
+
} | {
|
|
61
|
+
input: {
|
|
62
|
+
param: {
|
|
63
|
+
filename_ext: string;
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
output: "invalid bbox";
|
|
67
|
+
outputFormat: "body";
|
|
68
|
+
status: 400;
|
|
16
69
|
};
|
|
17
70
|
};
|
|
18
71
|
} & {
|
|
@@ -23,9 +76,63 @@ declare function createClipRouter(options: {
|
|
|
23
76
|
filename_ext: string;
|
|
24
77
|
};
|
|
25
78
|
};
|
|
26
|
-
output:
|
|
27
|
-
outputFormat:
|
|
28
|
-
status:
|
|
79
|
+
output: "invalid format";
|
|
80
|
+
outputFormat: "body";
|
|
81
|
+
status: 400;
|
|
82
|
+
} | {
|
|
83
|
+
input: {
|
|
84
|
+
param: {
|
|
85
|
+
filename_ext: string;
|
|
86
|
+
};
|
|
87
|
+
};
|
|
88
|
+
output: Uint8Array<ArrayBuffer>;
|
|
89
|
+
outputFormat: "body";
|
|
90
|
+
status: import("hono/utils/http-status").ContentfulStatusCode;
|
|
91
|
+
} | {
|
|
92
|
+
input: {
|
|
93
|
+
param: {
|
|
94
|
+
filename_ext: string;
|
|
95
|
+
};
|
|
96
|
+
};
|
|
97
|
+
output: "failed to render tile";
|
|
98
|
+
outputFormat: "body";
|
|
99
|
+
status: 400;
|
|
100
|
+
} | {
|
|
101
|
+
input: {
|
|
102
|
+
param: {
|
|
103
|
+
filename_ext: string;
|
|
104
|
+
};
|
|
105
|
+
};
|
|
106
|
+
output: "not found";
|
|
107
|
+
outputFormat: "body";
|
|
108
|
+
status: 404;
|
|
109
|
+
} | {
|
|
110
|
+
input: {
|
|
111
|
+
param: {
|
|
112
|
+
filename_ext: string;
|
|
113
|
+
};
|
|
114
|
+
};
|
|
115
|
+
output: "bbox is required";
|
|
116
|
+
outputFormat: "body";
|
|
117
|
+
status: 400;
|
|
118
|
+
} | {
|
|
119
|
+
input: {
|
|
120
|
+
param: {
|
|
121
|
+
filename_ext: string;
|
|
122
|
+
};
|
|
123
|
+
};
|
|
124
|
+
output: "invalid bbox";
|
|
125
|
+
outputFormat: "body";
|
|
126
|
+
status: 400;
|
|
127
|
+
} | {
|
|
128
|
+
input: {
|
|
129
|
+
param: {
|
|
130
|
+
filename_ext: string;
|
|
131
|
+
};
|
|
132
|
+
};
|
|
133
|
+
output: "invalid stylejson";
|
|
134
|
+
outputFormat: "body";
|
|
135
|
+
status: 400;
|
|
29
136
|
};
|
|
30
137
|
};
|
|
31
138
|
}, "/", "/:filename_ext">;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Hono } from 'hono';
|
|
2
|
-
import { stream } from 'hono/streaming';
|
|
3
2
|
import { isSupportedFormat, isValidStylejson } from '../utils.js';
|
|
4
|
-
import {
|
|
3
|
+
import { getRenderedClip } from '../../render/index.js';
|
|
5
4
|
function createClipRouter(options) {
|
|
6
5
|
const clip = new Hono()
|
|
7
6
|
.get('/:filename_ext', async (c) => {
|
|
@@ -25,7 +24,7 @@ function createClipRouter(options) {
|
|
|
25
24
|
const size = Number(c.req.query('size') ?? 1024);
|
|
26
25
|
c.header('Content-Type', `image/${ext}`);
|
|
27
26
|
try {
|
|
28
|
-
const sharp = await
|
|
27
|
+
const sharp = await getRenderedClip({
|
|
29
28
|
stylejson: url,
|
|
30
29
|
bbox: [minx, miny, maxx, maxy],
|
|
31
30
|
size,
|
|
@@ -33,18 +32,8 @@ function createClipRouter(options) {
|
|
|
33
32
|
ext,
|
|
34
33
|
quality,
|
|
35
34
|
});
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
return stream(c, async (stream) => {
|
|
39
|
-
for await (const chunk of sharp) {
|
|
40
|
-
stream.write(chunk);
|
|
41
|
-
}
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
else {
|
|
45
|
-
const buf = await sharp.toBuffer();
|
|
46
|
-
return c.body(buf);
|
|
47
|
-
}
|
|
35
|
+
const buf = await sharp.toBuffer();
|
|
36
|
+
return c.body(buf);
|
|
48
37
|
}
|
|
49
38
|
catch (e) {
|
|
50
39
|
console.error(`render error: ${e}`);
|
|
@@ -73,7 +62,7 @@ function createClipRouter(options) {
|
|
|
73
62
|
const size = Number(c.req.query('size') ?? 1024);
|
|
74
63
|
c.header('Content-Type', `image/${ext}`);
|
|
75
64
|
try {
|
|
76
|
-
const sharp = await
|
|
65
|
+
const sharp = await getRenderedClip({
|
|
77
66
|
stylejson: style,
|
|
78
67
|
bbox: [minx, miny, maxx, maxy],
|
|
79
68
|
size,
|
|
@@ -81,18 +70,8 @@ function createClipRouter(options) {
|
|
|
81
70
|
ext,
|
|
82
71
|
quality,
|
|
83
72
|
});
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
return stream(c, async (stream) => {
|
|
87
|
-
for await (const chunk of sharp) {
|
|
88
|
-
stream.write(chunk);
|
|
89
|
-
}
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
else {
|
|
93
|
-
const buf = await sharp.toBuffer();
|
|
94
|
-
return c.body(buf);
|
|
95
|
-
}
|
|
73
|
+
const buf = await sharp.toBuffer();
|
|
74
|
+
return c.body(buf);
|
|
96
75
|
}
|
|
97
76
|
catch (e) {
|
|
98
77
|
console.error(`render error: ${e}`);
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Cache } from '../../cache/index.js';
|
|
2
2
|
declare function createTilesRouter(options: {
|
|
3
3
|
cache: Cache;
|
|
4
|
-
stream: boolean;
|
|
5
4
|
}): import("hono/hono-base").HonoBase<import("hono/types").BlankEnv, {
|
|
6
5
|
"/:z/:x/:y_ext": {
|
|
7
6
|
$get: {
|
|
@@ -14,9 +13,61 @@ declare function createTilesRouter(options: {
|
|
|
14
13
|
y_ext: string;
|
|
15
14
|
};
|
|
16
15
|
};
|
|
17
|
-
output:
|
|
18
|
-
outputFormat:
|
|
19
|
-
status:
|
|
16
|
+
output: "invalid format";
|
|
17
|
+
outputFormat: "body";
|
|
18
|
+
status: 400;
|
|
19
|
+
} | {
|
|
20
|
+
input: {
|
|
21
|
+
param: {
|
|
22
|
+
z: string;
|
|
23
|
+
} & {
|
|
24
|
+
x: string;
|
|
25
|
+
} & {
|
|
26
|
+
y_ext: string;
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
output: "url is required";
|
|
30
|
+
outputFormat: "body";
|
|
31
|
+
status: 400;
|
|
32
|
+
} | {
|
|
33
|
+
input: {
|
|
34
|
+
param: {
|
|
35
|
+
z: string;
|
|
36
|
+
} & {
|
|
37
|
+
x: string;
|
|
38
|
+
} & {
|
|
39
|
+
y_ext: string;
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
output: Uint8Array<ArrayBuffer>;
|
|
43
|
+
outputFormat: "body";
|
|
44
|
+
status: import("hono/utils/http-status").ContentfulStatusCode;
|
|
45
|
+
} | {
|
|
46
|
+
input: {
|
|
47
|
+
param: {
|
|
48
|
+
z: string;
|
|
49
|
+
} & {
|
|
50
|
+
x: string;
|
|
51
|
+
} & {
|
|
52
|
+
y_ext: string;
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
output: "failed to render tile";
|
|
56
|
+
outputFormat: "body";
|
|
57
|
+
status: 400;
|
|
58
|
+
} | {
|
|
59
|
+
input: {
|
|
60
|
+
param: {
|
|
61
|
+
z: string;
|
|
62
|
+
} & {
|
|
63
|
+
x: string;
|
|
64
|
+
} & {
|
|
65
|
+
y_ext: string;
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
output: "invalid xyz";
|
|
69
|
+
outputFormat: "body";
|
|
70
|
+
status: 400;
|
|
20
71
|
};
|
|
21
72
|
};
|
|
22
73
|
} & {
|
|
@@ -31,9 +82,61 @@ declare function createTilesRouter(options: {
|
|
|
31
82
|
y_ext: string;
|
|
32
83
|
};
|
|
33
84
|
};
|
|
34
|
-
output:
|
|
35
|
-
outputFormat:
|
|
36
|
-
status:
|
|
85
|
+
output: "invalid format";
|
|
86
|
+
outputFormat: "body";
|
|
87
|
+
status: 400;
|
|
88
|
+
} | {
|
|
89
|
+
input: {
|
|
90
|
+
param: {
|
|
91
|
+
z: string;
|
|
92
|
+
} & {
|
|
93
|
+
x: string;
|
|
94
|
+
} & {
|
|
95
|
+
y_ext: string;
|
|
96
|
+
};
|
|
97
|
+
};
|
|
98
|
+
output: Uint8Array<ArrayBuffer>;
|
|
99
|
+
outputFormat: "body";
|
|
100
|
+
status: import("hono/utils/http-status").ContentfulStatusCode;
|
|
101
|
+
} | {
|
|
102
|
+
input: {
|
|
103
|
+
param: {
|
|
104
|
+
z: string;
|
|
105
|
+
} & {
|
|
106
|
+
x: string;
|
|
107
|
+
} & {
|
|
108
|
+
y_ext: string;
|
|
109
|
+
};
|
|
110
|
+
};
|
|
111
|
+
output: "failed to render tile";
|
|
112
|
+
outputFormat: "body";
|
|
113
|
+
status: 400;
|
|
114
|
+
} | {
|
|
115
|
+
input: {
|
|
116
|
+
param: {
|
|
117
|
+
z: string;
|
|
118
|
+
} & {
|
|
119
|
+
x: string;
|
|
120
|
+
} & {
|
|
121
|
+
y_ext: string;
|
|
122
|
+
};
|
|
123
|
+
};
|
|
124
|
+
output: "invalid xyz";
|
|
125
|
+
outputFormat: "body";
|
|
126
|
+
status: 400;
|
|
127
|
+
} | {
|
|
128
|
+
input: {
|
|
129
|
+
param: {
|
|
130
|
+
z: string;
|
|
131
|
+
} & {
|
|
132
|
+
x: string;
|
|
133
|
+
} & {
|
|
134
|
+
y_ext: string;
|
|
135
|
+
};
|
|
136
|
+
};
|
|
137
|
+
output: "invalid stylejson";
|
|
138
|
+
outputFormat: "body";
|
|
139
|
+
status: 400;
|
|
37
140
|
};
|
|
38
141
|
};
|
|
39
142
|
}, "/", "/:z/:x/:y_ext">;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { Hono } from 'hono';
|
|
2
|
-
import { stream } from 'hono/streaming';
|
|
3
2
|
import { isSupportedFormat, isValidStylejson } from '../utils.js';
|
|
4
3
|
import { getRenderedTile } from '../../render/index.js';
|
|
5
4
|
function isValidXyz(x, y, z) {
|
|
@@ -41,18 +40,8 @@ function createTilesRouter(options) {
|
|
|
41
40
|
ext,
|
|
42
41
|
quality,
|
|
43
42
|
});
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
return stream(c, async (stream) => {
|
|
47
|
-
for await (const chunk of sharp) {
|
|
48
|
-
stream.write(chunk);
|
|
49
|
-
}
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
else {
|
|
53
|
-
const buf = await sharp.toBuffer();
|
|
54
|
-
return c.body(buf);
|
|
55
|
-
}
|
|
43
|
+
const buf = await sharp.toBuffer();
|
|
44
|
+
return c.body(buf);
|
|
56
45
|
}
|
|
57
46
|
catch (e) {
|
|
58
47
|
console.error(`render error: ${e}`);
|
|
@@ -90,18 +79,8 @@ function createTilesRouter(options) {
|
|
|
90
79
|
ext,
|
|
91
80
|
quality,
|
|
92
81
|
});
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
return stream(c, async (stream) => {
|
|
96
|
-
for await (const chunk of sharp) {
|
|
97
|
-
stream.write(chunk);
|
|
98
|
-
}
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
else {
|
|
102
|
-
const buf = await sharp.toBuffer();
|
|
103
|
-
return c.body(buf);
|
|
104
|
-
}
|
|
82
|
+
const buf = await sharp.toBuffer();
|
|
83
|
+
return c.body(buf);
|
|
105
84
|
}
|
|
106
85
|
catch (e) {
|
|
107
86
|
console.error(`render error: ${e}`);
|