Skip to content

Commit

Permalink
Merge pull request #87 from Kanahiro/chores
Browse files Browse the repository at this point in the history
Chores, refactor, tiny fix.
  • Loading branch information
Kanahiro authored Jun 9, 2024
2 parents 464932c + c0e36c4 commit d80606c
Show file tree
Hide file tree
Showing 8 changed files with 99 additions and 113 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"type": "module",
"name": "chiitiler",
"version": "1.10.4",
"version": "1.10.5",
"description": "Tiny map rendering server for MapLibre Style Spec",
"main": "dist/main.js",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion src/render/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export { renderTilePipeline, type SupportedFormat } from './sharp.js';
export { getRenderedTileBuffer, type SupportedFormat } from './sharp.js';
3 changes: 1 addition & 2 deletions src/render/pool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ async function getRenderPool(
create: async () => {
const map = new mbgl.Map({
request: function (req, callback) {
const ext = handleFileExt(req.url);
getSource(req.url, cache)
.then((buf) => {
const ext = handleFileExt(req.url);
if (buf) {
callback(undefined, { data: buf });
} else if (ext && TRANSPARENT_BUFFER[ext])
Expand All @@ -59,7 +59,6 @@ async function getRenderPool(
callback(undefined, { data: EMPTY_BUFFER });
})
.catch(() => {
const ext = handleFileExt(req.url);
if (ext && TRANSPARENT_BUFFER[ext])
callback(undefined, {
data: TRANSPARENT_BUFFER[ext],
Expand Down
16 changes: 8 additions & 8 deletions src/render/sharp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ async function loadStyle(stylejson: string | StyleSpecification, cache: Cache) {
return style;
}

async function renderTilePipeline({
async function getRenderedTileBuffer({
stylejson,
z,
x,
Expand All @@ -55,7 +55,7 @@ async function renderTilePipeline({
margin,
ext,
quality,
}: RenderTilePipelineOptions) {
}: RenderTilePipelineOptions): Promise<Buffer> {
const style = await loadStyle(stylejson, cache);

let pixels: Uint8Array;
Expand Down Expand Up @@ -108,20 +108,20 @@ async function renderTilePipeline({
.resize(tileSize, tileSize);
}

let pipeline: sharp.Sharp;
let buf: Buffer;
switch (ext) {
case 'png':
pipeline = _sharp.png();
buf = await _sharp.png().toBuffer();
break;
case 'jpeg':
case 'jpg':
pipeline = _sharp.jpeg({ quality });
buf = await _sharp.jpeg({ quality }).toBuffer();
break;
case 'webp':
pipeline = _sharp.webp({ quality, effort: 0 });
buf = await _sharp.webp({ quality, effort: 0 }).toBuffer();
break;
}
return pipeline;
return buf;
}

export { renderTilePipeline, type SupportedFormat };
export { getRenderedTileBuffer, type SupportedFormat };
6 changes: 3 additions & 3 deletions src/server/debug.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ function getDebugPage(c: Context) {
const url =
c.req.query('url') ?? 'https://demotiles.maplibre.org/style.json';
const margin = Number(c.req.query('margin') ?? 0);
const quality = Number(c.req.query('quality') ?? 0);
const quality = Number(c.req.query('quality') ?? 100);
const tileSize = Number(c.req.query('tileSize') ?? 512);

// show tile in MapLibre GL JS
Expand Down Expand Up @@ -69,7 +69,7 @@ function getDebugPage(c: Context) {
</html>`);
}

function postDebugPage(c: Context) {
function getEditorgPage(c: Context) {
return c.html(`<!DOCTYPE html>
<html>
<head>
Expand Down Expand Up @@ -204,4 +204,4 @@ function postDebugPage(c: Context) {
</html>`);
}

export { getDebugPage, postDebugPage };
export { getDebugPage, getEditorgPage };
98 changes: 83 additions & 15 deletions src/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,23 @@ import {
} from '@maplibre/maplibre-gl-style-spec';

import { type Cache } from '../cache/index.js';
import { getDebugPage, postDebugPage } from './debug.js';
import { tileResponse } from './response.js';
import { getDebugPage, getEditorgPage } from './debug.js';
import { getRenderedTileBuffer, type SupportedFormat } from '../render/index.js';

function isValidStylejson(stylejson: any): stylejson is StyleSpecification {
return validateStyleMin(stylejson).length === 0;
}

function isValidXyz(x: number, y: number, z: number) {
if (x < 0 || y < 0 || z < 0) return false;
if (x >= 2 ** z || y >= 2 ** z) return false;
return true;
}

function isSupportedFormat(ext: string): ext is SupportedFormat {
return ['png', 'jpeg', 'jpg', 'webp'].includes(ext);
}

type InitServerOptions = {
cache: Cache;
port: number;
Expand All @@ -23,31 +33,89 @@ function initServer(options: InitServerOptions) {
const hono = new Hono();
if (options.debug) {
hono.get('/debug', getDebugPage);
hono.get('/editor', postDebugPage);
hono.get('/editor', getEditorgPage);
}
hono.get('/health', (c) => c.text('OK'));

hono.get('/tiles/:z/:x/:y_ext', async (c) => {
const url = c.req.query('url') ?? null;
if (url === null) return c.body('url is required', 400);
const res = await tileResponse(c, {
mode: 'url',
cache: options.cache,
url,
});
return res;

// path params
const z = Number(c.req.param('z'));
const x = Number(c.req.param('x'));
let [_y, ext] = c.req.param('y_ext').split('.');
const y = Number(_y);

if (!isValidXyz(x, y, z)) return c.body('invalid xyz', 400);
if (!isSupportedFormat(ext)) return c.body('invalid format', 400);

// query params
const tileSize = Number(c.req.query('tileSize') ?? 512);
const quality = Number(c.req.query('quality') ?? 100);
const margin = Number(c.req.query('margin') ?? 0);

let buf: Buffer;
try {
buf = await getRenderedTileBuffer({
stylejson: url,
z,
x,
y,
tileSize,
cache: options.cache,
margin,
ext,
quality,
});
} catch (e) {
console.error(`render error: ${e}`);
return c.body('failed to render tile', 400);
}

c.header('Content-Type', `image/${ext}`);
return c.body(buf);
});

hono.post('/tiles/:z/:x/:y_ext', async (c) => {
// body
const { style } = await c.req.json();
if (!isValidStylejson(style)) return c.body('invalid stylejson', 400);
const res = await tileResponse(c, {
mode: 'style',
cache: options.cache,
style,
});
return res;

// path params
const z = Number(c.req.param('z'));
const x = Number(c.req.param('x'));
let [_y, ext] = c.req.param('y_ext').split('.');
const y = Number(_y);

if (!isValidXyz(x, y, z)) return c.body('invalid xyz', 400);
if (!isSupportedFormat(ext)) return c.body('invalid format', 400);

// query params
const tileSize = Number(c.req.query('tileSize') ?? 512);
const quality = Number(c.req.query('quality') ?? 100);
const margin = Number(c.req.query('margin') ?? 0);

let buf: Buffer;
try {
buf = await getRenderedTileBuffer({
stylejson: style,
z,
x,
y,
tileSize,
cache: options.cache,
margin,
ext,
quality,
});
} catch (e) {
console.error(`render error: ${e}`);
return c.body('failed to render tile', 400);
}

c.header('Content-Type', `image/${ext}`);
return c.body(buf);
});

return {
Expand Down
81 changes: 0 additions & 81 deletions src/server/response.ts

This file was deleted.

0 comments on commit d80606c

Please sign in to comment.