tileblaster 1.0.11 → 1.0.13

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.
@@ -9,8 +9,8 @@ module.exports = function convert({ opts, data }, next){
9
9
  return next();
10
10
  };
11
11
 
12
- // check if tile should be optimized
13
- if (!["png","jpeg","jpg","gif"].includes(data.tile.type)) {
12
+ // check if the tile should be converted
13
+ if (!["png","jpeg","jpg","gif","webp","avif","heif"].includes(data.tile.type)) {
14
14
  debug.warn("Convert: Unsupported file type: %s", data.tile.type);
15
15
  return next();
16
16
  };
@@ -31,19 +31,20 @@ module.exports = function convert({ opts, data }, next){
31
31
 
32
32
  // fix tile
33
33
  tile.buffer = buffer;
34
- tile.path = tile.path+"."+method;
35
34
  tile.type = method;
36
35
  tile.mimetype = "image/"+method;
37
36
  tile.headers = { ...tile.headers };
38
37
 
38
+ // remove main tile from stack
39
+ data.tiles = data.tiles.filter(t=>(t.path!==tile.path));
40
+
39
41
  // add to tile stack
40
42
  data.tiles.unshift(tile);
41
43
 
42
- // set primary if smaller
43
- if (buffer.length < data.tile.buffer.length) {
44
- debug.info("Converted '%s': -%db", tile.path.magenta, data.tile.buffer.length-buffer.length);
45
- data.tile = tile;
46
- };
44
+ // add as main tile
45
+ data.tile = tile;
46
+
47
+ debug.info("Converted '%s'", tile.path.magenta);
47
48
 
48
49
  resolve();
49
50
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tileblaster",
3
- "version": "1.0.11",
3
+ "version": "1.0.13",
4
4
  "description": "a quick and versatile map tile caching proxy",
5
5
  "main": "tileblaster.js",
6
6
  "bin": {
package/docs/config.md DELETED
@@ -1,360 +0,0 @@
1
- # tileblaster configuration
2
-
3
- tileblaster configuration lives in a javascript (common js) file, that exports an object containing the configuration.
4
-
5
- ## Example
6
-
7
- See [config.dist.js](./config.dist.js)
8
-
9
- ## Properties
10
-
11
- #### `version`
12
-
13
- config file format version. Always `1` fro now.
14
-
15
- #### `id`
16
-
17
- id of the tileblaster instance, in case you want to run more than one; default: `tileblaster`
18
-
19
- #### `treads`
20
-
21
- number of worker threads in cluster, default: 1
22
-
23
- #### `queue`
24
-
25
- number of concurrently processed tiles per worker, default: 12
26
-
27
- #### `server.url`
28
-
29
- public url including subdirectory
30
-
31
- #### `server.mount`
32
-
33
- mountpoint override, default: pathname of `config.paths.url`
34
-
35
- #### `paths.work`
36
-
37
- the base directory where files (sockets, logs, plugins, ...) go; default: `~/tileblaster`
38
-
39
- #### `paths.data`
40
-
41
- the directory in which cached tiles are saved; default: `${config.paths.work}/data`
42
-
43
- #### `paths.logs`
44
-
45
- the directory in which cached tiles are saved; default: `${config.paths.work}/logs`
46
-
47
- #### `paths.plugins`
48
-
49
- the directory from which plugins ar loaded; default: `${config.paths.work}/plugins`
50
-
51
- #### `paths.sockets`
52
-
53
- the directory i nwhich sockets are created; default: `${config.paths.work}/sockets`
54
-
55
- ### `listen`
56
-
57
- an array of server listen configurations. these contain either `port` or `socket`
58
-
59
- ``` js
60
- listen: [{
61
- port: 8080, // required
62
- host: "localhost", // default localhost
63
- },{
64
- socket: "test.socket", // required, absolute path or relative to ${config.paths.socket}
65
- mode: 0o660, // change socket mode to this id
66
- group: 1000, // change socket group to this is
67
- }],
68
- ```
69
-
70
- ### `plugins`
71
-
72
- plugins, relative or absolute paths for local files, npm module names otherwise
73
-
74
- ``` js
75
- plugins: {
76
- resize: "./resize.js", // relative path, starting with ./
77
- convert: "/path/to/convert.js", // absolute path
78
- optimize: "someplugin", // npm module
79
- },
80
- ```
81
-
82
- ### `maps`
83
-
84
- each property of this object represents a map and its workflow. the workflow is an array
85
- of `builtin` and `plugin` directives, that get processed in the order of their definition.
86
-
87
- ``` js
88
- {
89
- // a map with id "example"
90
- example: [{
91
- // a builtin directive, processed first
92
- builtin: "something",
93
- // ...
94
- },{
95
- // a plugin directive, processed second
96
- plugin: "some-plugin",
97
- // ...
98
- },{
99
- // ...
100
- }],
101
- anoterMap: {
102
- // ...
103
- }
104
- }
105
- ```
106
-
107
- ### Builtins
108
-
109
- #### `cors`
110
-
111
- Send [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) Headers to the client. Can be limited by Origin.
112
- You should do this in your reverse proxy though.
113
-
114
- ``` js
115
- {
116
- builtin: "cors",
117
- origins: [ "https://example.org/" ],
118
- // origins: [ "*" ], // ← allow anyone
119
- }
120
- ```
121
-
122
- #### `parse`
123
-
124
- Parse a client request. You can override this with your own parse function in case
125
- your client requires the use of a non-standard request uri or uses GET/POST data or whatever.
126
-
127
- ``` js
128
- {
129
- builtin: "parse", // /z/x/y@r.ext, other formats need plugins; set params and dest
130
- parse: function(req, next){ // override parse function, req is the raw request
131
- // do things to get parameters from path
132
- next(null, {
133
- params: { param: "1" }, // deliver parameters
134
- dest: "/path/to/tile/{param}/{param}/blub.{e}{c}", // template for destination
135
- });
136
- },
137
- }
138
- ```
139
-
140
- #### `check`
141
-
142
- Limits request dependent on parameters. You can deny access to tiles to certain zoom levels,
143
- within a bounding box, to specific extensions and densities, or use your own check function.
144
-
145
- ``` js
146
- {
147
- builtin: "check",
148
- zoom: [ 0, 22 ], // min, max
149
- bbox: [ -180, -90, 180, 90 ], // west, south, east, north
150
- extensions: [ "png", "jpeg" ], // allowed extensions
151
- density: [ "", "@2x", "@3x" ], // allowed density markeers
152
- check: function(params, fn) { // override check function, params from parse
153
- fn(new Error("Check failed")); // deliver error if check failed
154
- },
155
- status: 204, // http status code delivered on fail; default: 204
156
- hints: false, // send `x-tileblaster-hint` header with error message
157
- }
158
- ```
159
-
160
- #### `cache`
161
-
162
- Local tile cache.
163
-
164
- ##### Retrieve cached tiles
165
-
166
- When no main tile is availabe, try to load it from cache.
167
-
168
- ``` js
169
- {
170
- builtin: "cache",
171
- skipto: "deliver", // skip to this builtin when tile loaded from cache
172
- }
173
- ```
174
-
175
- ##### Store tiles
176
-
177
- If a tile is set, store it in the local cache.
178
-
179
- ``` js
180
- {
181
- builtin: "cache",
182
- expires: "30d", // duration or seconds or `true` or `false`
183
- }
184
- ```
185
-
186
- * `expires: 300` - Expires after this amount of seconds
187
- * `expires: "5y 2w 1d 5h 30m 4s"` - Expires after this [duration](https://www.npmjs.com/package/dur#user-content-time-units)
188
- * `expires: false` - Expires never
189
- * `expires: true` - Expires instantly
190
-
191
- #### `noop`
192
-
193
- Does nothing and has no real purpose.
194
-
195
- #### `tileserver`
196
-
197
- Fetch a tile from a tileserver via http(s).
198
-
199
- ``` js
200
- {
201
- builtin: "tileserver",
202
- url: "https://{s}.tileserver.example/test/{z}/{x}/{y}{r}.{e}",
203
- subdomains: [ "a", "b", "x" ], // random chosen and passed in as {s}
204
- tms: true, // y coordinate is inverted
205
- headers: {}, // additional headers sent to the backend tileserver
206
- status: [ 200 ], // expected status code(s)
207
- mimetypes: [ "image/png", "image/jpeg" ], // expected mime types
208
- mimetype: "image/png", // overwrite mime type from server
209
- }
210
- ```
211
-
212
- #### `versatiles`
213
-
214
- Fetch a tile from a local or remote [versatiles](https://versatiles.org) container.
215
-
216
- *Pro Tip:* Don't pay MapBox or "Open"MapTiles for limited access to Open Data! You can get completely free Vectortiles in [Shortbread Schema](https://shortbread.geofabrik.de/schema/) at [download.versatiles.org](https://download.versatiles.org/).
217
-
218
- ``` js
219
- {
220
- // get tile from versatiles container
221
- builtin: "versatiles",
222
- url: "https://cdn.example/planet.versatiles",
223
- // url: "/path/to/planet.versatiles",
224
- tms: false, // y coordinate is inverted
225
- headers: { // headers sent to versatiles server
226
- "X-Tileblaster": "True",
227
- },
228
- }
229
- ```
230
-
231
- #### `pmtiles`
232
-
233
- Fetch a tile from a pmtiles container.
234
-
235
- ``` js
236
- {
237
- // get tile from versatiles container
238
- builtin: "pmtiles",
239
- url: "https://cdn.example/planet.pmtiles",
240
- // url: "/path/to/planet.pmtiles",
241
- }
242
- ```
243
- #### `mbtiles`
244
-
245
- Retrieve a tile from a mbtiles database.
246
-
247
- ``` js
248
- {
249
- // get tile from versatiles container
250
- builtin: "mbtiles",
251
- file: "/path/to/planet.mbtiles",
252
- }
253
- ```
254
-
255
- #### `edit`
256
-
257
- Edit vectortiles
258
-
259
- ``` js
260
- {
261
- builtin: "edit",
262
- edit: function(layers){
263
-
264
- // remove unused layer
265
- layers = layers.filter(function(layer){
266
- return (layer.name !== "unused-layer");
267
- });
268
-
269
- return layers;
270
- },
271
- }
272
- ```
273
-
274
- #### `resize`
275
-
276
- **Not yet implemented** FIXME
277
-
278
- #### `convert`
279
-
280
- Convert raster tiles to differen Formats.
281
- The resulting tile with the smallest size becomes the main tile.
282
-
283
- ``` js
284
- {
285
- builtin: "convert",
286
- jpeg: {
287
- quality: 90,
288
- mozjpeg: true,
289
- },
290
- }
291
- ```
292
-
293
- #### `modernize`
294
-
295
- Convert JPEG or PNG raster tiles to WebP or AVIF.
296
- The resulting tile with the smallest size and a format the client supports becomes the main tile.
297
-
298
- ``` js
299
- {
300
- builtin: "modernize",
301
- webp: {
302
- quality: 90,
303
- effort: 4,
304
- },
305
- avif: {
306
- quality: 90,
307
- effort: 5,
308
- },
309
- }
310
- ```
311
-
312
- #### `optimize`
313
-
314
- Optimise raster tiles with `mozjpeg` or `optipng`. Only results smaller than the original are kept.
315
-
316
- ``` js
317
- {
318
- plugin: "optimize",
319
- png: { o: 4 }, // true or opts for optipng
320
- jpeg: true, // true or opts for mozjpeg
321
- }
322
- ```
323
-
324
- #### `compress`
325
-
326
- Compresses all `data.tiles` with brotli and/or gzip. The tile with the smallest size and a compression the client supports becomes the main tile.
327
-
328
- ``` js
329
- {
330
- builtin: "compress",
331
- brotli: 8, // true or <level> or {opts}
332
- gzip: true, // true or <level> or {opts}
333
- }
334
- ```
335
-
336
-
337
- #### `deliver`
338
-
339
- Sends `data.tile` to the client. Adds configured response headers.
340
-
341
- ``` js
342
- {
343
- "builtin": "deliver",
344
- "headers": {
345
- "X-My-Header": "This is a very good header"
346
- }
347
- }
348
- ```
349
-
350
- #### `dump`
351
-
352
- Ends all processing and dumps the contents of `data` the console and browser.
353
-
354
- Useful for debugging.
355
-
356
- ``` js
357
- {
358
- "builtin": "dump"
359
- }
360
- ```
package/docs/examples.md DELETED
@@ -1,257 +0,0 @@
1
- # Examples
2
-
3
- ## Tileserver
4
-
5
- Serve tiles from a tileserver
6
-
7
- ``` js
8
- {
9
- example: [{
10
- // takes a request for /map/0/1/2@2x.png and breaks it down into z=0, x=1, y=2, r=@2x and e=png
11
- builtin: "parse",
12
- /* but you can override this if you need to
13
- parse: function(req, fn){
14
- // `req` is the http request object
15
- let fragments = req.url.split("/").pop().split(".");
16
- // fn is a callback to deliver the pares parameters
17
- fn(null, {
18
- z: fragments[0], x: fragments[1], y: fragments[2],
19
- e: fragments[3], // extension
20
- r: "@2x", // density marker
21
- d: 2, // density
22
- w: 512, // tile width
23
- });
24
- }
25
- */
26
- },{
27
- // source tileserver
28
- builtin: "tileserver",
29
- url: "https://{s}.tileserver.example/{z}/{x}/{y}{r}.{e}?access_token=YOUR_OPENDATAGRIFTBOXTILER_ACCESS_TOKEN",
30
- // optional:
31
- subdomains: [ "a", "b", "c" ], // random chosen and passed in as {s}
32
- tms: false, // {y} is inverted
33
- headers: { // additional headers sent to tileserver
34
- "Origin": "https://totally-legit-website.example/",
35
- "User-Agent": "uncoolest-mobile-map-app"
36
- },
37
- status: [ 200 ], // expected status code(s)
38
- mimetypes: [ "image/png", "image/jpeg" ], // expected mime types
39
- },{
40
- builtin: "deliver"
41
- }]
42
- }
43
- ```
44
-
45
- ## Versatiles
46
-
47
- Serve tiles from a versatiles container
48
-
49
- ``` js
50
- {
51
- example: [{
52
- builtin: "parse",
53
- },{
54
- builtin: "versatiles",
55
- url: "https://cdn.example/planet.versatiles",
56
- },{
57
- builtin: "deliver"
58
- }]
59
- }
60
- ```
61
-
62
- ## PMTiles
63
-
64
- Serve tiles from a pmtiles container
65
-
66
- ``` js
67
- {
68
- example: [{
69
- builtin: "parse",
70
- },{
71
- builtin: "pmtiles",
72
- url: "https://cdn.example/planet.pmtiles",
73
- },{
74
- builtin: "deliver"
75
- }]
76
- }
77
- ```
78
-
79
- ## MBTiles
80
-
81
- Serve tiles from an mbtile database
82
-
83
- ``` js
84
- {
85
- example: [{
86
- builtin: "parse",
87
- },{
88
- builtin: "mbtiles",
89
- file: "/path/to/file.mbtiles",
90
- },{
91
- builtin: "deliver"
92
- }]
93
- }
94
- ```
95
-
96
- ## Check parameters
97
-
98
- Limit access to tiles by zoom level, bbox, extension or density marker with `check` builtin
99
-
100
- ``` js
101
- {
102
- example: [{
103
- builtin: "parse",
104
- },{
105
- builtin: "check",
106
- zoom: [ 0, 10 ], // min, max
107
- bbox: [ -180, -85, 180, 85 ], // west, south, east, north
108
- extensions: [ "png", "jpeg" ], // allowed extensions
109
- density: [ "", "@2x" ], // allowed density markers
110
- },{
111
- // source tileserver
112
- builtin: "tileserver",
113
- url: "https://tileserver.example/{z}/{x}/{y}{r}.{e}",
114
- },{
115
- builtin: "deliver"
116
- }]
117
- }
118
- ```
119
-
120
- ## Raster tile optimization and conversion
121
-
122
- `optimize` will attemt to reduce the raster tile size by applying image optimization, `mozjpeg` for `jpeg` tiles, `optipng` for `png` tiles.
123
- `modernize` will convert raster tiles to `webp` and `avif` format (using `sharp`) and deliver those to capable clients.
124
-
125
- ``` js
126
- {
127
- example: [{
128
- builtin: "parse",
129
- },{
130
- // source tileserver
131
- builtin: "tileserver",
132
- url: "https://tileserver.example/{z}/{x}/{y}.{e}",
133
- },{
134
- builtin: "optimize",
135
- jpeg: {}, // use mozjpeg via wasm for jpeg tiles
136
- png: { o: "3", strip: "all" }, // use optipng via wasm for png tiles
137
- },{
138
- builtin: "modernize",
139
- webp: {
140
- quality: 85, // good enough quality
141
- effort: 3, // don't use much effort
142
- },
143
- avif: {
144
- quality: 100, // 100% quality
145
- lossless: true, // lossless only
146
- effort: 9, // a lot of effort
147
- }
148
- },{
149
- builtin: "deliver"
150
- }]
151
- }
152
- ```
153
-
154
- ## Raster tile image manipulation
155
-
156
- Use [sharp](https://www.npmjs.com/package/sharp) to manipulate raster tiles.
157
- Example: convert a raster tile to "dark mode" by inverting the colors and rotating the hue.
158
-
159
- ``` js
160
- {
161
- example: [{
162
- builtin: "parse",
163
- },{
164
- // source tileserver
165
- builtin: "tileserver",
166
- url: "https://tileserver.example/{z}/{x}/{y}.png",
167
- },{
168
- builtin: "sharp", // use builtin sharp
169
- negate: {}, // invert colors using sharp.negate()
170
- modulate: { hue: 180 }, // rotate hue by 180° using sharp.modulate({ hue: 180 })
171
- },{
172
- builtin: "deliver"
173
- }]
174
- }
175
- ```
176
-
177
- ## Edit vector tiles
178
-
179
- Use [vtt](https://npmjs.com/package/vtt) to edit vectortiles.
180
-
181
- ``` js
182
- {
183
- example: [{
184
- builtin: "parse",
185
- },{
186
- builtin: "tileserver",
187
- url: "https://tileserver.example/{z}/{x}/{y}.pbf",
188
- },{
189
- builtin: "edit", // use builtin edit
190
- edit: function(layers){
191
- // `layers` is ja JSON representation of the layers in a tile
192
- // return the edited `layers` data
193
- return layers.filter(function(layer){
194
- return layer.name !== "pois"; // remove "pois" layer
195
- });
196
- }
197
- },{
198
- builtin: "deliver"
199
- }]
200
- }
201
- ```
202
-
203
- ## Compression
204
-
205
- Precompress tiles with brotli and gzip and deliver them to capable clients.
206
- Use with compressible tiles (vectortiles, json, svg) and not raster tiles.
207
-
208
- ``` js
209
- {
210
- example: [{
211
- builtin: "parse",
212
- },{
213
- builtin: "tileserver",
214
- url: "https://tileserver.example/{z}/{x}/{y}.pbf",
215
- },{
216
- builtin: "compress",
217
- brotli: 6, // brotli compression level 6
218
- gzip: 4, // gzip compression level 4
219
- },{
220
- builtin: "deliver"
221
- }]
222
- }
223
- ```
224
-
225
- ## Caching
226
-
227
- ``` js
228
- {
229
- example: [{
230
- builtin: "parse",
231
- },{
232
- builtin: "cache", // before tile retrieved: check if tile is in cache
233
- skipto: "deliver", // skip to this builtin/plugin at cache hit
234
- },{
235
- // get tile from tileserver
236
- builtin: "tileserver",
237
- url: "https://tileserver.example/{z}/{x}/{y}",
238
- },{
239
- builtin: "cache", // after tile retrieved: store tile in cache
240
- expires: "30d", // keep in cache for 30 days
241
- },{
242
- builtin: "deliver",
243
- }]
244
- }
245
- ```
246
-
247
- ## CORS
248
-
249
- Allow Cross-origin resource sharing for certain domains
250
-
251
- ``` js
252
- {
253
- builtin: "cors",
254
- origins: [ "https://example.org/" ], // "*" for any domain
255
- }
256
- ```
257
-
Binary file
@@ -1,261 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
- <!-- Created with Inkscape (http://www.inkscape.org/) -->
3
-
4
- <svg
5
- width="150mm"
6
- height="150mm"
7
- viewBox="0 50 150 150"
8
- version="1.1"
9
- id="svg29401"
10
- inkscape:version="1.2 (dc2aeda, 2022-05-15)"
11
- sodipodi:docname="tileblaster.svg"
12
- inkscape:export-filename="tileblaster.png"
13
- inkscape:export-xdpi="86.698669"
14
- inkscape:export-ydpi="86.698669"
15
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
16
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
17
- xmlns:xlink="http://www.w3.org/1999/xlink"
18
- xmlns="http://www.w3.org/2000/svg"
19
- xmlns:svg="http://www.w3.org/2000/svg">
20
- <sodipodi:namedview
21
- id="namedview29403"
22
- pagecolor="#505050"
23
- bordercolor="#eeeeee"
24
- borderopacity="1"
25
- inkscape:showpageshadow="0"
26
- inkscape:pageopacity="0"
27
- inkscape:pagecheckerboard="0"
28
- inkscape:deskcolor="#505050"
29
- inkscape:document-units="mm"
30
- showgrid="false"
31
- showguides="true"
32
- inkscape:zoom="1"
33
- inkscape:cx="382.5"
34
- inkscape:cy="333.5"
35
- inkscape:window-width="1859"
36
- inkscape:window-height="1027"
37
- inkscape:window-x="61"
38
- inkscape:window-y="229"
39
- inkscape:window-maximized="0"
40
- inkscape:current-layer="layer1">
41
- <sodipodi:guide
42
- position="74.999999,38.875"
43
- orientation="-1,0"
44
- id="guide32273"
45
- inkscape:locked="false"
46
- inkscape:label=""
47
- inkscape:color="rgb(0,134,229)" />
48
- <sodipodi:guide
49
- position="24.694444,74.999999"
50
- orientation="0,1"
51
- id="guide34465"
52
- inkscape:locked="false"
53
- inkscape:label=""
54
- inkscape:color="rgb(0,134,229)" />
55
- <sodipodi:guide
56
- position="104.51042,150"
57
- orientation="0,-1"
58
- id="guide35193"
59
- inkscape:locked="false" />
60
- <sodipodi:guide
61
- position="94.368055,0"
62
- orientation="0,-1"
63
- id="guide35195"
64
- inkscape:locked="false" />
65
- <sodipodi:guide
66
- position="0,54.309027"
67
- orientation="1,0"
68
- id="guide35197"
69
- inkscape:locked="false" />
70
- <sodipodi:guide
71
- position="150,32.260416"
72
- orientation="1,0"
73
- id="guide35199"
74
- inkscape:locked="false" />
75
- </sodipodi:namedview>
76
- <defs
77
- id="defs29398">
78
- <linearGradient
79
- inkscape:collect="always"
80
- xlink:href="#linearGradient29346-1"
81
- id="linearGradient31371"
82
- gradientUnits="userSpaceOnUse"
83
- gradientTransform="matrix(2.9999997,2.3590334e-8,-2.3590334e-8,2.9999997,-800.00007,-894.07809)"
84
- x1="400.00006"
85
- y1="468.68973"
86
- x2="325.00006"
87
- y2="425.38846" />
88
- <linearGradient
89
- inkscape:collect="always"
90
- id="linearGradient29346-1">
91
- <stop
92
- style="stop-color:#8332ff;stop-opacity:1;"
93
- offset="0"
94
- id="stop29342-0" />
95
- <stop
96
- style="stop-color:#e816ff;stop-opacity:0.99492383;"
97
- offset="1"
98
- id="stop29344-8" />
99
- </linearGradient>
100
- <filter
101
- inkscape:collect="always"
102
- style="color-interpolation-filters:sRGB"
103
- id="filter35252"
104
- x="-0.090126778"
105
- y="-0.084742466"
106
- width="1.1802536"
107
- height="1.1694849">
108
- <feGaussianBlur
109
- inkscape:collect="always"
110
- stdDeviation="3.6361132"
111
- id="feGaussianBlur35254" />
112
- </filter>
113
- <filter
114
- inkscape:collect="always"
115
- style="color-interpolation-filters:sRGB"
116
- id="filter35272"
117
- x="-0.060782709"
118
- y="-0.070185916"
119
- width="1.1215654"
120
- height="1.1403718">
121
- <feGaussianBlur
122
- inkscape:collect="always"
123
- stdDeviation="11.396758"
124
- id="feGaussianBlur35274" />
125
- </filter>
126
- </defs>
127
- <g
128
- inkscape:label="Ebene 1"
129
- inkscape:groupmode="layer"
130
- id="layer1"
131
- transform="translate(179.53655,1.2883869)">
132
- <g
133
- id="g35304"
134
- transform="matrix(1.1361953,0,0,1.1361953,14.238481,-16.847521)">
135
- <path
136
- style="fill:#191919;fill-opacity:1;stroke-width:1.17621;stroke-linecap:round"
137
- d="m -160.68486,91.293103 -1e-5,64.834477 56.14832,32.41724 56.148303,-32.41724 1e-5,-64.834477 -56.148323,-32.417242 z"
138
- id="path31292" />
139
- <g
140
- id="g35262"
141
- transform="matrix(0.22459324,-0.12966896,0.12966896,0.22459324,-210.22972,70.313386)"
142
- style="opacity:0.123762;mix-blend-mode:normal;fill:#31e2ff;fill-opacity:1;filter:url(#filter35272)">
143
- <path
144
- id="path35256"
145
- style="fill:#31e2ff;fill-opacity:1;stroke-width:13.6062;stroke-linecap:round"
146
- d="M 137.49989,187.23365 24.999997,382.08718 137.50003,576.943 l 149.99996,-4e-5 -37.49998,-64.95187 -75.00001,5e-5 -74.99999,-129.90395 37.49998,-64.95114 h 75.00002 l -37.50002,64.95113 74.99999,129.90235 150,10e-6 L 475,382.08718 399.99997,252.18485 H 324.99998 L 362.5,187.23369 287.49999,187.23368 250,252.18485 l -75.00002,10e-6 37.50004,-64.95117 z m 150.00001,129.90234 74.99999,-10e-6 37.5,64.95115 -37.49999,64.95117 -75.00001,-2e-5 -37.49997,-64.95115 z"
147
- sodipodi:nodetypes="cccccccccccccccccccccccccccc" />
148
- <path
149
- id="path35258"
150
- style="opacity:0.180328;fill:#31e2ff;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
151
- d="M 137.5,187.23242 25,382.08789 150,208.88281 212.5,187.23242 Z m 150,0 -37.5,64.95117 50,-43.30078 62.5,-21.64843 z" />
152
- <path
153
- id="path35260"
154
- style="opacity:0.180328;fill:#31e2ff;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
155
- d="m 225,295.48438 -87.5,21.65039 h 75 z M 475,382.08789 387.5,490.33984 250,511.99023 H 400 Z M 275,555.29297 137.5,576.94336 h 150 z" />
156
- </g>
157
- <path
158
- id="path29308"
159
- style="fill:#840577;fill-opacity:0.399267;stroke-width:3.5286;stroke-linecap:round"
160
- d="m -154.03095,95.1353 -2.6e-4,58.35052 50.53349,29.17555 33.688976,-19.45035 -16.844482,-9.72517 -16.844494,9.72519 -33.689,-19.45038 1e-4,-19.45018 16.8445,-9.72517 -1.1e-4,19.45017 33.688789,19.45003 33.688993,-19.45036 1.86e-4,-38.900359 -33.688797,-19.450003 -16.844481,9.725168 9e-5,-19.450177 -16.8445,9.725176 -8e-5,19.450179 -16.84451,9.725176 1.1e-4,-19.450187 z m 50.53329,9.72484 16.844493,-9.725173 16.844384,9.725003 -8.8e-5,19.45018 -16.844492,9.72516 -16.844397,-9.725 z"
161
- sodipodi:nodetypes="cccccccccccccccccccccccccccc" />
162
- <g
163
- id="g31384"
164
- transform="matrix(0.22459324,-0.12966896,0.12966896,0.22459324,-210.22972,70.313386)">
165
- <path
166
- id="path31363"
167
- style="fill:url(#linearGradient31371);fill-opacity:1;stroke-width:13.6062;stroke-linecap:round"
168
- d="M 137.49989,187.23365 24.999997,382.08718 137.50003,576.943 l 149.99996,-4e-5 -37.49998,-64.95187 -75.00001,5e-5 -74.99999,-129.90395 37.49998,-64.95114 h 75.00002 l -37.50002,64.95113 74.99999,129.90235 150,10e-6 L 475,382.08718 399.99997,252.18485 H 324.99998 L 362.5,187.23369 287.49999,187.23368 250,252.18485 l -75.00002,10e-6 37.50004,-64.95117 z m 150.00001,129.90234 74.99999,-10e-6 37.5,64.95115 -37.49999,64.95117 -75.00001,-2e-5 -37.49997,-64.95115 z"
169
- sodipodi:nodetypes="cccccccccccccccccccccccccccc" />
170
- <path
171
- id="path31365"
172
- style="opacity:0.180328;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
173
- d="M 137.5,187.23242 25,382.08789 150,208.88281 212.5,187.23242 Z m 150,0 -37.5,64.95117 50,-43.30078 62.5,-21.64843 z" />
174
- <path
175
- id="path31373"
176
- style="opacity:0.180328;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
177
- d="m 225,295.48438 -87.5,21.65039 h 75 z M 475,382.08789 387.5,490.33984 250,511.99023 H 400 Z M 275,555.29297 137.5,576.94336 h 150 z" />
178
- </g>
179
- <path
180
- id="path35201"
181
- style="opacity:0.576733;mix-blend-mode:normal;fill:#010101;fill-opacity:1;stroke-width:0.23538;filter:url(#filter35252)"
182
- d="m -71.411808,72.221289 -5.095817,2.941939 v 5.884913 l -15.288461,8.826334 h -10.192134 l -5.09633,2.942456 -5.09633,2.942456 -5.09581,2.94194 -8.28994,4.786273 -1.20147,0.6935 -0.70125,0.40462 -25.48062,14.71125 v 17.6537 l 5.09633,2.94246 10.19214,-5.8844 5.09633,2.94194 v 35.30689 l 5.09582,2.94246 20.3848,-11.76879 -5.09633,-2.94246 v -5.8844 -23.53809 l 10.19266,-5.8844 v -5.88439 -5.2e-4 l 5.095807,-2.94194 v -5.8844 l 5.096327,-2.94245 v -5.8844 l 35.672739,-20.595639 -5.096327,-2.942456 v -5.884396 l -5.095807,2.941939 z"
183
- transform="matrix(0.98017487,0,0,0.98017487,-2.0724487,2.4525763)" />
184
- <g
185
- id="g29366"
186
- transform="matrix(0.19980409,-0.11535694,0.11535694,0.19980409,-191.07133,74.765286)">
187
- <path
188
- style="fill:#949fab;fill-opacity:1"
189
- d="m 75.000005,338.78592 12.499997,21.65063 -75,129.90381 12.500003,21.65064 H 125.00001 L 112.5,490.34036 200,338.78592 Z"
190
- id="path25198"
191
- sodipodi:nodetypes="cccccccc" />
192
- <path
193
- style="fill:#e6e9ed;fill-opacity:1;stroke-width:4.53543;stroke-linecap:round"
194
- d="M 12.499997,317.13529 50,252.18338 h 250 l 37.5,21.65064 -37.5,64.9519 H 25.000006 Z"
195
- id="path25379"
196
- sodipodi:nodetypes="ccccccc" />
197
- <path
198
- style="fill:#ed5564;fill-opacity:1;stroke-width:4.53543;stroke-linecap:round"
199
- d="m 187.5,360.43655 h 50 L 225,382.08719 h -50 z"
200
- id="path25444"
201
- sodipodi:nodetypes="ccccc" />
202
- <path
203
- style="fill:#8994a2;fill-opacity:1;stroke-width:4.53543;stroke-linecap:round"
204
- d="M 300,252.18338 275,295.48465 262.5,273.83402 275,252.18338 H 250 L 225,295.48465 213.13802,274.9391 225,252.18338 h -25 l -25,43.30127 -12.35149,-21.39341 12.3515,-21.90786 H 275 Z"
205
- id="path25509"
206
- sodipodi:nodetypes="cccccccccccccc" />
207
- <path
208
- style="fill:#949fab;fill-opacity:1;stroke-width:4.53543;stroke-linecap:round"
209
- d="m 337.5,273.83401 -12.5,21.65064 -12.5,21.65064 175,-10e-6 -12.5,-21.65063 12.5,-21.65063 z"
210
- id="path26345"
211
- sodipodi:nodetypes="ccccccc" />
212
- <path
213
- style="fill:#8994a2;fill-opacity:1;stroke-width:4.53543;stroke-linecap:round"
214
- d="m 412.49999,273.83402 12.5,-21.65064 H 450 l 12.5,21.65064 h -50.00001"
215
- id="path26420" />
216
- <path
217
- style="fill:#8994a2;fill-opacity:1;stroke-width:4.53543;stroke-linecap:round"
218
- d="m 200,338.78591 75,10e-6 -12.50001,21.65063 H 187.5 Z"
219
- id="path26432"
220
- sodipodi:nodetypes="ccccc" />
221
- <path
222
- style="fill:#ffffff;fill-opacity:0.0967742;stroke-width:4.53543;stroke-linecap:round"
223
- d="M 12.499997,317.13529 50,252.18338 H 300 L 62.500003,273.83402 Z"
224
- id="path26937" />
225
- <path
226
- style="fill:#000000;fill-opacity:0.0967742;stroke-width:4.53543;stroke-linecap:round"
227
- d="M 112.5,490.34036 99.999998,468.68973 175,338.78592 h 100 l -87.5,21.65063 z"
228
- id="path28766" />
229
- <path
230
- style="fill:#ffffff;fill-opacity:0.0967742;stroke-width:4.53543;stroke-linecap:round"
231
- d="m 325,295.48465 12.5,-21.65063 h 150 z"
232
- id="path28831" />
233
- <path
234
- style="fill:#000000;fill-opacity:0.0967742;stroke-width:4.53543;stroke-linecap:round"
235
- d="M 312.5,317.13529 475,295.48465 487.49999,317.13529 Z"
236
- id="path28833" />
237
- <path
238
- style="fill:#000000;fill-opacity:0.0967742;stroke-width:4.53543;stroke-linecap:round"
239
- d="M 337.5,273.83401 275,338.78592 h 25 z"
240
- id="path28835" />
241
- <path
242
- style="fill:#ffffff;fill-opacity:0.0967742;stroke-width:4.53543;stroke-linecap:round"
243
- d="M 87.500002,360.43655 25.000006,511.991 12.500002,490.34036 Z"
244
- id="path28837"
245
- sodipodi:nodetypes="cccc" />
246
- <path
247
- style="fill:#000000;fill-opacity:0.131086;stroke-width:4.53543;stroke-linecap:round"
248
- d="m 175,382.08719 h -25 l 12.5,21.65063 h -25 l 12.5,21.65064 h -25 l 12.5,21.65063 h -25 l 12.5,21.65064 z"
249
- id="path28914" />
250
- <path
251
- style="fill:#000000;fill-opacity:0.131086;stroke-width:4.53543;stroke-linecap:round"
252
- d="m 175,382.08719 12.5,-21.65064 h 50 z"
253
- id="path28979" />
254
- <path
255
- style="fill:#ffffff;fill-opacity:0.131086;stroke-width:4.53543;stroke-linecap:round"
256
- d="m 412.5,273.83402 12.49999,-21.65064 H 450 Z"
257
- id="path28981" />
258
- </g>
259
- </g>
260
- </g>
261
- </svg>
package/docs/todo.md DELETED
@@ -1,140 +0,0 @@
1
- # Todo
2
-
3
- ## Roadmap
4
-
5
- ### 1.0 Release
6
-
7
- * [x] Config format
8
- * [x] Map format
9
- * [x] Tasks fomat
10
- * [x] HTTP Server, Port and Socket
11
- * [x] Graceful shutdown
12
- * [x] Debug Library → `lib/debug.js`
13
- * [x] Optional Module Loader → `lib/load.js`
14
- * [x] HTTPs Abstraction (~got or~ phin) → `lib/retrieve.js`
15
- * [x] Plugin Interface / Task Runner
16
- * [x] Builtins
17
- * [x] CORS
18
- * [x] Parse Request
19
- * [x] Check Request
20
- * [x] Tile Backends
21
- * [x] ZXY Webtiles → `builtin/tileserver.js`
22
- * [x] TMS Webtiles → `builtin/tileserver.js`
23
- * [x] Versatiles
24
- * [x] PMTiles
25
- * [x] MBTiles
26
- * [x] Optimization (optipng, mozjpeg, svgo?, pbfcrop?)
27
- * [x] Modernize Raster Formats (png,jpeg → webp,avif)
28
- * [x] Caching to Disk
29
- * [x] Reading cached tile from Disk
30
- * [x] Skipping Jobs
31
- * [x] Etag Headers
32
- * [x] Last-Modified Headers
33
- * [x] Don't store if expired
34
- * [x] Expires Headers
35
- * [x] Don't update if already cached (in case of store-only)
36
- * [x] ~Cache-Control Headers~ → Set via `deliver` builtin
37
- * [x] Delivery
38
- * [x] Debug Dump
39
- * [x] Vectortile Editing
40
- * [x] Full image manipulation for raster tiles → https://www.npmjs.com/package/sharp
41
- * [x] Vectortiles Editor → https://www.npmjs.com/package/vtt
42
- * [x] Cache Cleaning Worker
43
- * [x] Documentation
44
- * [x] What is Tileblaster, what is the benefit for the user
45
- * [x] What can't tileblaster do
46
- * [x] All config options
47
- * [x] All builtins
48
- * [x] Example Config
49
- * [x] Example Nginx Config
50
- * [x] How to use it, Standalone or behind Proxy
51
- * [x] Core concepts explained (maps, work queue, builtins and plugins)
52
- * [x] Examples
53
- * [x] Caching proxy for a tileserver
54
- * [x] Serve tiles from container
55
- * [x] Raster editing: "Dark mode"
56
- * [x] Vector editing: remove unused layers
57
- * How to contribute, bug reports
58
- * [x] CLI
59
- * [x] Cluster Support
60
- * [x] PM2 Integration
61
- * [x] Rudimentary Dev Server
62
- * [x] Request Queue to throttle unfulfilled requests
63
- * [x] Fancy Default Page
64
- * [x] Custom String Template function for {x} replacement instead of regex
65
-
66
- ### Next
67
-
68
- * [ ] Redirects
69
- * [ ] Convert Geojson ↔ Topojson
70
- * [ ] Map Web Interface, Configurable
71
- * [ ] Configurable Index Page
72
- * [ ] Support for Glyphs and Styles, tile.json proxy
73
- * [x] Better Error Handling
74
- * [x] Error wrapper (to pass along http status etc)?
75
- * [x] Skip for nonexistant tiles
76
- * [ ] Render Vector Tiles with MapLibreGL-Native
77
- * [ ] Improve Debug Consistency
78
- * [ ] Documentation: How to write a plugin
79
-
80
- ### Later
81
-
82
- * [ ] Screencast
83
- * [ ] Monitoring / Status / Statistics Interface
84
- * [ ] Integration with Nginx-Cache
85
- * [ ] Memcache → https://www.npmjs.com/package/iomem
86
- * [ ] Backends
87
- [ ] tilebase https://www.npmjs.com/package/tilebase
88
- [ ] Geotiff?
89
- [ ] PostGIS database via ST_AsMVT?
90
- * [ ] Conversions
91
- * [ ] pbf → svg
92
- * [ ] svg → raster
93
- * [ ] geotif → raster
94
-
95
- ### Probably Never
96
-
97
- * [ ] v0 Config Migration?
98
- * [ ] use mbtiles database as cache?
99
- * [ ] Standalone Logging?
100
- * [ ] Config Web Interface
101
- * [ ] Standalone Daemon with pid files?
102
- * [ ] Cache: Store in MBTiles or similar?
103
- * [ ] GDAL?
104
- * [ ] Footprint
105
- * [ ] Replace Phin?
106
- * [ ] ~Nginx Cache Hydration~ (Problem: different file owners)
107
-
108
- ## Format Support
109
-
110
- * [x] Vector
111
- * [x] mvt/pbf
112
- * [ ] svg
113
- * [x] Raster
114
- * [x] png
115
- * [x] jpeg
116
- * [x] webp
117
- * [x] avif
118
- * [ ] geotif (readonly)
119
- * [ ] Data
120
- * [ ] GeoJSON
121
- * [ ] TopoJSON
122
- * [ ] JSON
123
- * [ ] ArcJSON?
124
- * [ ] WKT? → https://en.wikipedia.org/w/index.php?title=Well-known_text_representation_of_geometry
125
-
126
- ## Conversions
127
-
128
- * [ ] GeoJSON ↔ TopoJSON
129
- * [ ] WKT → GeoJSON TopoJSON
130
- * [ ] GeoJSON TopoJSON → SVG
131
- * [ ] PNG JPEG WEBP AVIF TIF SVG → PNG JPEG WEBP AVIF
132
- * [ ] MVT → SVG
133
- * [ ] MVT → GeoJSON TopoJSON
134
-
135
- ## Etag
136
-
137
- ``` js
138
- // nginx etag — for consistency
139
- etag = util.format('"%s-%s"', Math.floor(mtimeMs/1000).toString(16), filesize.toString(16));
140
- ```