@opengis/gis 0.2.77 → 0.2.79
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/dist/index.css +1 -1
- package/dist/index.js +6505 -5911
- package/dist/index.umd.cjs +70 -59
- package/module/gis/table/gis.cartocss.table.json +9 -2
- package/package.json +5 -5
- package/server/plugins/mapnik/map.proto +40 -0
- package/server/routes/gis/cartocss/get.cartocss.js +1 -1
- package/server/routes/map/controllers/layerList.js +6 -1
- package/server/routes/mapnik/controllers/clearTiles.js +94 -0
- package/server/routes/mapnik/controllers/createXml.js +4 -1
- package/server/routes/mapnik/controllers/fileSearch.js +34 -0
- package/server/routes/mapnik/controllers/fileStat.js +27 -0
- package/server/routes/mapnik/controllers/rasterInfo.js +12 -4
- package/server/routes/mapnik/controllers/readDir.js +19 -0
- package/server/routes/mapnik/controllers/rtile.js +14 -5
- package/server/routes/mapnik/functions/uploadXML.js +1 -1
- package/server/routes/mapnik/index.js +8 -0
|
@@ -15,6 +15,11 @@
|
|
|
15
15
|
"format": "text",
|
|
16
16
|
"link": "/gis.cartocss/{id}"
|
|
17
17
|
},
|
|
18
|
+
{
|
|
19
|
+
"ua": "Шлях",
|
|
20
|
+
"name": "source_path",
|
|
21
|
+
"format": "text"
|
|
22
|
+
},
|
|
18
23
|
{
|
|
19
24
|
"ua": "Опис",
|
|
20
25
|
"name": "description",
|
|
@@ -30,13 +35,15 @@
|
|
|
30
35
|
"ua": "Включений",
|
|
31
36
|
"name": "enabled",
|
|
32
37
|
"data": "yes_no",
|
|
33
|
-
"format": "
|
|
38
|
+
"format": "boolean",
|
|
39
|
+
"edit": true
|
|
34
40
|
},
|
|
35
41
|
{
|
|
36
42
|
"ua": "Публічний",
|
|
37
43
|
"name": "is_public",
|
|
38
44
|
"data": "yes_no",
|
|
39
|
-
"format": "
|
|
45
|
+
"format": "boolean",
|
|
46
|
+
"edit": true
|
|
40
47
|
}
|
|
41
48
|
],
|
|
42
49
|
"filterList": [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opengis/gis",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.79",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"author": "Softpro",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -52,12 +52,12 @@
|
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
54
|
"@opengis/core": "^0.0.23",
|
|
55
|
-
"@opengis/fastify-table": "^2.0.
|
|
55
|
+
"@opengis/fastify-table": "^2.0.132",
|
|
56
56
|
"@opengis/filter": "0.1.31",
|
|
57
57
|
"@opengis/form": "^0.0.103",
|
|
58
58
|
"@opengis/table": "^0.0.27",
|
|
59
59
|
"@vitejs/plugin-vue": "^5.2.4",
|
|
60
|
-
"axios": "^1.13.
|
|
60
|
+
"axios": "^1.13.5",
|
|
61
61
|
"eslint": "^8.57.1",
|
|
62
62
|
"eslint-config-airbnb": "19.0.4",
|
|
63
63
|
"eslint-plugin-import": "^2.32.0",
|
|
@@ -68,8 +68,8 @@
|
|
|
68
68
|
"sass-embedded": "1.86.3",
|
|
69
69
|
"typescript": "^5.9.3",
|
|
70
70
|
"vite": "^6.4.1",
|
|
71
|
-
"vue": "^3.5.
|
|
71
|
+
"vue": "^3.5.28",
|
|
72
72
|
"vue-router": "4.5.1",
|
|
73
73
|
"vuedraggable": "^4.1.0"
|
|
74
74
|
}
|
|
75
|
-
}
|
|
75
|
+
}
|
|
@@ -11,6 +11,8 @@ service MapService {
|
|
|
11
11
|
rpc RenderTile(RenderTileRequest) returns (RenderTileOut);
|
|
12
12
|
rpc ClearTile(ClearTileRequest) returns (ClearTileOut);
|
|
13
13
|
rpc ReadDir(ReadDirRequest) returns (ReadDirOut);
|
|
14
|
+
rpc FileStat(FileStatRequest) returns (FileStatOut);
|
|
15
|
+
rpc FileSearch(FileSearchRequest) returns (FileSearchOut);
|
|
14
16
|
rpc CreateXML(CreateXMLRequest) returns (stream JobProgress); // streaming XML creation
|
|
15
17
|
rpc UploadXML(UploadXMLRequest) returns (UploadXMLOut);
|
|
16
18
|
rpc UploadRaster(UploadRasterRequest) returns (UploadRasterOut);
|
|
@@ -50,6 +52,33 @@ message ClearTileOut {
|
|
|
50
52
|
string err = 2;
|
|
51
53
|
}
|
|
52
54
|
|
|
55
|
+
message FileStatRequest {
|
|
56
|
+
string path = 1;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
message FileStatOut {
|
|
60
|
+
bool exists = 1;
|
|
61
|
+
string name = 2;
|
|
62
|
+
int64 size = 3;
|
|
63
|
+
string adate = 4;
|
|
64
|
+
string cdate = 5;
|
|
65
|
+
string mdate = 6;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
message FileSearchRequest {
|
|
69
|
+
string path = 1;
|
|
70
|
+
string key = 2;
|
|
71
|
+
string period = 3;
|
|
72
|
+
int64 size = 4;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
message FileSearchOut {
|
|
76
|
+
bool exists = 1;
|
|
77
|
+
int32 count = 2;
|
|
78
|
+
repeated FileInfo files = 3;
|
|
79
|
+
repeated DirInfo directories = 4;
|
|
80
|
+
}
|
|
81
|
+
|
|
53
82
|
message ReadDirRequest {
|
|
54
83
|
string path = 1;
|
|
55
84
|
}
|
|
@@ -58,12 +87,21 @@ message FileInfo {
|
|
|
58
87
|
string name = 1;
|
|
59
88
|
int64 size = 2;
|
|
60
89
|
string date = 3;
|
|
90
|
+
string dir = 4;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
message DirInfo {
|
|
94
|
+
string name = 1;
|
|
95
|
+
int64 size = 2;
|
|
96
|
+
string date = 3;
|
|
97
|
+
int64 children = 4;
|
|
61
98
|
}
|
|
62
99
|
|
|
63
100
|
message ReadDirOut {
|
|
64
101
|
bool exists = 1;
|
|
65
102
|
int32 count = 2;
|
|
66
103
|
repeated FileInfo files = 3;
|
|
104
|
+
repeated DirInfo directories = 4;
|
|
67
105
|
}
|
|
68
106
|
|
|
69
107
|
message CreateXMLRequest {
|
|
@@ -75,6 +113,7 @@ message CreateXMLRequest {
|
|
|
75
113
|
string name = 6;
|
|
76
114
|
string debug = 7;
|
|
77
115
|
string nocache = 8;
|
|
116
|
+
string proj4 = 9;
|
|
78
117
|
}
|
|
79
118
|
|
|
80
119
|
message UploadXMLRequest {
|
|
@@ -145,6 +184,7 @@ message GetRasterInfoRequest {
|
|
|
145
184
|
string path = 1;
|
|
146
185
|
string ttl = 2;
|
|
147
186
|
int64 srid = 3;
|
|
187
|
+
string proj4 = 4;
|
|
148
188
|
}
|
|
149
189
|
|
|
150
190
|
message FileItem {
|
|
@@ -15,7 +15,7 @@ export default async function checkCarto({
|
|
|
15
15
|
return reply.status(400).send({ error: 'mapnik server address needed', code: 400 });
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
const cartocss = await pg.query('select config, ARRAY[ST_XMin(geom), ST_YMin(geom), ST_XMax(geom), ST_YMax(geom)] as bounds, cartocss_key,name,description,style,group_id,enabled,is_public from gis.cartocss where cartocss_id=$1', [params.id]).then(el => el.rows?.[0]);
|
|
18
|
+
const cartocss = await pg.query('select config, ARRAY[ST_XMin(geom), ST_YMin(geom), ST_XMax(geom), ST_YMax(geom)] as bounds, cartocss_key,name,description,style,group_id,enabled,is_public, source_path from gis.cartocss where cartocss_id=$1', [params.id]).then(el => el.rows?.[0]);
|
|
19
19
|
|
|
20
20
|
if (!cartocss) {
|
|
21
21
|
return reply.status(404).send({ error: `cartocss not found: ${params.id}`, code: 404 });
|
|
@@ -39,6 +39,11 @@ export default async function layerList({
|
|
|
39
39
|
)||'/{z}/{x}/{y}.png',null) as url, 'raster' as service, group_id,
|
|
40
40
|
null as popup, null as card, null as filters, source_path
|
|
41
41
|
from gis.rasters s where is_active and ${!user.uid ? 'is_public' : '1=1'}
|
|
42
|
+
union all
|
|
43
|
+
select cartocss_id as id, name, null as category, style, geom::box2d as bbox, st_asgeojson(geom)::json as geom,
|
|
44
|
+
coalesce('/api/gis-rtile/'||cartocss_id||'/{z}/{x}/{y}.png',null) as url, 'cartocss' as service, group_id,
|
|
45
|
+
null as popup, null as card, null as filters, source_path
|
|
46
|
+
from gis.cartocss where enabled and ${!user.uid ? 'is_public' : '1=1'}
|
|
42
47
|
`;
|
|
43
48
|
|
|
44
49
|
if (user.uid && sql) return q;
|
|
@@ -58,7 +63,7 @@ export default async function layerList({
|
|
|
58
63
|
}
|
|
59
64
|
|
|
60
65
|
// parse service style
|
|
61
|
-
rows.forEach(row => Object.assign(row, { style: row.style ? yml2json(row.style) :
|
|
66
|
+
rows.forEach(row => Object.assign(row, { style: row.style && ['vtile', 'geojson'].includes(row.service) ? yml2json(row.style) : row.style }));
|
|
62
67
|
// parse extent string to number[]
|
|
63
68
|
rows.filter(row => row.extent).forEach(row => Object.assign(row, {
|
|
64
69
|
extent: row.extent.match(/BOX\(([^)]+)\)/)?.[1]
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
|
|
3
|
+
import { config, logger, pgClients } from '@opengis/fastify-table/utils.js';
|
|
4
|
+
|
|
5
|
+
import mapnik from '../../../plugins/mapnik/funcs/mapnik.js';
|
|
6
|
+
|
|
7
|
+
const { ClearTile } = mapnik();
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Формування растрового tile cartoCss
|
|
11
|
+
*
|
|
12
|
+
* @method GET
|
|
13
|
+
* @alias rtile
|
|
14
|
+
* @param {String} bbox - bbox
|
|
15
|
+
* @param {Number} height - висота по координатам
|
|
16
|
+
* @param {Number} width - ширина по координатам
|
|
17
|
+
* @param {String} data - стилізація
|
|
18
|
+
* @param {String} lang - мова
|
|
19
|
+
* @param {String} z - координата z
|
|
20
|
+
* @param {String} x - координата y
|
|
21
|
+
* @param {String} y - координата x
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
export default async function clearTiles({
|
|
25
|
+
pg = pgClients.client, params, query,
|
|
26
|
+
}, reply) {
|
|
27
|
+
if (!ClearTile) {
|
|
28
|
+
return reply.status(400).send({ error: 'mapnik server address needed', code: 400 });
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (!params.id) {
|
|
32
|
+
return reply.status(400).send({ error: 'not enough params: id', code: 400 });
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const decodedPath = Buffer.from(params.id, 'base64url').toString('utf-8');
|
|
36
|
+
|
|
37
|
+
const raster = pg.pk?.['gis.rasters']
|
|
38
|
+
? await pg.query(`select raster_id, source_path from gis.rasters where raster_id=$1::text union all
|
|
39
|
+
select raster_id, source_path from gis.rasters where source_path=$2::text`, [params.id, decodedPath]).then(el => el.rows?.[0] || {})
|
|
40
|
+
: {};
|
|
41
|
+
|
|
42
|
+
const carto = pg.pk?.['gis.cartocss']
|
|
43
|
+
? await pg.query(`select cartocss_id, source_path from gis.cartocss where cartocss_id=$1::text union all
|
|
44
|
+
select cartocss_id, source_path from gis.cartocss where source_path=$2::text`, [params.id, decodedPath]).then(el => el.rows?.[0] || {})
|
|
45
|
+
: {};
|
|
46
|
+
|
|
47
|
+
if (!raster.raster_id && !carto.cartocss_id) {
|
|
48
|
+
Object.assign(raster, { source_path: decodedPath });
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (!raster.source_path && !carto.cartocss_id) {
|
|
52
|
+
return reply.status(404).send({ error: 'raster / cartocss not found', code: 404 });
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (query.debug) {
|
|
56
|
+
const md5 = raster.source_path
|
|
57
|
+
? createHash('md5').update(raster.source_path).digest('hex')
|
|
58
|
+
: undefined;
|
|
59
|
+
const base64 = raster.source_path
|
|
60
|
+
? Buffer.from(raster.source_path).toString('base64url')
|
|
61
|
+
: undefined;
|
|
62
|
+
return {
|
|
63
|
+
id: raster.raster_id || carto.cartocss_id,
|
|
64
|
+
carto: !!carto.cartocss_id,
|
|
65
|
+
raster: !!raster.raster_id,
|
|
66
|
+
md5_path: md5,
|
|
67
|
+
base64_path: base64,
|
|
68
|
+
source_path: raster.source_path || carto.source_path,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
try {
|
|
73
|
+
const data = await ClearTile({
|
|
74
|
+
path: carto.cartocss_id ? null : raster.source_path, // for rasters only
|
|
75
|
+
name: carto.cartocss_id && carto.source_path ? `vector/${carto.source_path}` : params.id, // required for cartocss
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
// if empty directory not found (no tiles rendered yet)
|
|
79
|
+
if (data.result === 'skip') {
|
|
80
|
+
return reply.status(200).send({ message: 'tiles directory not found', code: 200 });
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// if cache deleted or empty directory exists = ok
|
|
84
|
+
if (data.result === 'success') {
|
|
85
|
+
return reply.status(200).send({ message: 'ok', code: 200 });
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
throw new Error(data.err);
|
|
89
|
+
}
|
|
90
|
+
catch (err) {
|
|
91
|
+
logger.file('clearTiles/error', { error: err.toString(), stack: err.stack });
|
|
92
|
+
return reply.status(500).send({ error: config.local ? err.toString() : 'clearTiles error', code: 500 });
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -47,12 +47,15 @@ export default async function createXml({
|
|
|
47
47
|
|
|
48
48
|
const callback = eventStream(reply);
|
|
49
49
|
|
|
50
|
+
const proj4 = data.srid && pg.pk?.['public.spatial_ref_sys'] ? await pg.query('select proj4text from public.spatial_ref_sys where srid=$1', [data.srid]).then(el => el.rows?.[0]?.proj4text) : undefined;
|
|
51
|
+
|
|
50
52
|
// create at xml/:id with name only, always - by path
|
|
51
53
|
const resp = await CreateXML({
|
|
52
54
|
path: data.source_path,
|
|
53
55
|
name: id, // create additional xml named as primary key at xml directory
|
|
54
56
|
previewZoom: data.raster_zoom, // preview<=>detailed, default = 16 if file size > 1GB
|
|
55
|
-
srid: data.srid, // auto detected if not supplied
|
|
57
|
+
// srid: data.srid, // auto detected if not supplied
|
|
58
|
+
proj4,
|
|
56
59
|
vrt: query.vrt, // force vrt even if relpath leads to single raster file
|
|
57
60
|
debug: query.debug, // stream debug info
|
|
58
61
|
nocache: query.nocache, // recreate if exists
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import mapnik from '../../../plugins/mapnik/funcs/mapnik.js';
|
|
2
|
+
|
|
3
|
+
const { FileSearch } = mapnik();
|
|
4
|
+
|
|
5
|
+
const maxLimit = 100;
|
|
6
|
+
|
|
7
|
+
// example: GET /api/gis-files?dir=tiles/3828667893214610450/13/4884&key=1&size=1675&period=5m
|
|
8
|
+
export default async function fileSearch({
|
|
9
|
+
query,
|
|
10
|
+
}, reply) {
|
|
11
|
+
if (!FileSearch) {
|
|
12
|
+
return reply.status(400).send({ error: 'mapnik server address needed', code: 400 });
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const {
|
|
16
|
+
dir, key, period, size, page,
|
|
17
|
+
} = query;
|
|
18
|
+
|
|
19
|
+
const limit = Math.min(query.limit || 16, maxLimit);
|
|
20
|
+
const offset = page && page > 0 ? (page - 1) * limit : 0;
|
|
21
|
+
|
|
22
|
+
if (!key && !period && !size) {
|
|
23
|
+
return reply.status(400).send({ error: 'not enough query params: key / period / size', code: 400 });
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const result = await FileSearch({
|
|
27
|
+
path: dir, key, period, size,
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
return {
|
|
31
|
+
count: result.count,
|
|
32
|
+
data: (result.files || []).slice(offset, offset + limit).map(el => ({ type: 'file', ...el })),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { config } from '@opengis/fastify-table/utils.js';
|
|
2
|
+
|
|
3
|
+
import mapnik from '../../../plugins/mapnik/funcs/mapnik.js';
|
|
4
|
+
|
|
5
|
+
const { FileStat } = mapnik();
|
|
6
|
+
|
|
7
|
+
// example: GET /api/gis-files?path=tiles/3828667893214610450/13/4884/2828.png
|
|
8
|
+
export default async function fileStat({
|
|
9
|
+
query,
|
|
10
|
+
}, reply) {
|
|
11
|
+
if (!config.mapServerAddress) {
|
|
12
|
+
return reply.status(400).send({ error: 'mapnik server not configured', code: 400 });
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if (config.ready?.mapnik !== true) {
|
|
16
|
+
return reply.status(400).send({ error: 'mapnik server not ready', code: 400 });
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const { path } = query || {};
|
|
20
|
+
|
|
21
|
+
if (!path) {
|
|
22
|
+
return reply.status(400).send({ error: 'not enough query params: path', code: 400 });
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const data = await FileStat({ path });
|
|
26
|
+
return { data };
|
|
27
|
+
}
|
|
@@ -6,7 +6,7 @@ const { GetRasterInfo } = mapnik();
|
|
|
6
6
|
|
|
7
7
|
const { prefix = '/api' } = config;
|
|
8
8
|
|
|
9
|
-
export default async function
|
|
9
|
+
export default async function rasterInfo({
|
|
10
10
|
pg = pgClients.client, params, query,
|
|
11
11
|
}, reply) {
|
|
12
12
|
if (!config.mapServerAddress) {
|
|
@@ -14,7 +14,7 @@ export default async function rtile({
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
const raster = pg.pk?.['gis.rasters']
|
|
17
|
-
? await pg.query('select raster_id, source_path, name, description, raster_key, is_active, is_public from gis.rasters where raster_id=$1::text', [params.id])
|
|
17
|
+
? await pg.query('select raster_id, source_path, name, description, raster_key, is_active, is_public, srid from gis.rasters where raster_id=$1::text', [params.id])
|
|
18
18
|
.then(el => el.rows?.[0] || {})
|
|
19
19
|
: {};
|
|
20
20
|
|
|
@@ -27,12 +27,20 @@ export default async function rtile({
|
|
|
27
27
|
Object.assign(raster, { source_path: decodedPath });
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
const proj4 = raster.srid && pg.pk?.['public.spatial_ref_sys'] ? await pg.query('select proj4text from public.spatial_ref_sys where srid=$1', [raster.srid]).then(el => el.rows?.[0]?.proj4text) : undefined;
|
|
31
|
+
|
|
30
32
|
const { data, cache } = await GetRasterInfo({
|
|
31
33
|
path: raster.source_path,
|
|
34
|
+
// srid: raster.srid,
|
|
35
|
+
// proj4,
|
|
32
36
|
ttl: query.nocache ? '0' : '1h',
|
|
33
37
|
});
|
|
34
38
|
|
|
39
|
+
if (query.debug) {
|
|
40
|
+
return { data, cache, raster };
|
|
41
|
+
}
|
|
42
|
+
|
|
35
43
|
return {
|
|
36
|
-
|
|
37
|
-
};
|
|
44
|
+
...data, ...raster, cache, url: `${prefix}/gis-rtile/${Buffer.from(raster.source_path).toString('base64url')}/{z}/{x}/{y}.png`,
|
|
45
|
+
};
|
|
38
46
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import mapnik from '../../../plugins/mapnik/funcs/mapnik.js';
|
|
2
|
+
|
|
3
|
+
const { ReadDir } = mapnik();
|
|
4
|
+
|
|
5
|
+
// example: GET /api/gis-files?dir=tiles/3828667893214610450
|
|
6
|
+
export default async function readDir({
|
|
7
|
+
query,
|
|
8
|
+
}, reply) {
|
|
9
|
+
if (!ReadDir) {
|
|
10
|
+
return reply.status(400).send({ error: 'mapnik server address needed', code: 400 });
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const { dir } = query;
|
|
14
|
+
|
|
15
|
+
const {
|
|
16
|
+
exists = false, count = 0, files = [], directories = [],
|
|
17
|
+
} = await ReadDir({ path: dir });
|
|
18
|
+
return { exists, count, data: files.map(el => ({ type: 'file', ...el })).concat(directories.map(el => ({ type: 'directory', ...el }))) };
|
|
19
|
+
}
|
|
@@ -82,7 +82,7 @@ export default async function rtile({
|
|
|
82
82
|
|
|
83
83
|
const data = await RenderTile({
|
|
84
84
|
path: cartoExists ? null : raster.source_path, // for rasters only
|
|
85
|
-
name: cartoExists && carto.source_path ? carto.source_path : id, // required for cartocss
|
|
85
|
+
name: cartoExists && carto.source_path ? `vector/${carto.source_path}` : id, // required for cartocss
|
|
86
86
|
width: 256,
|
|
87
87
|
bbox,
|
|
88
88
|
ttl,
|
|
@@ -91,21 +91,30 @@ export default async function rtile({
|
|
|
91
91
|
|
|
92
92
|
if (query.debug) {
|
|
93
93
|
return {
|
|
94
|
-
...data,
|
|
94
|
+
...data,
|
|
95
|
+
ttl,
|
|
96
|
+
md5_path: md5,
|
|
97
|
+
base64_path: base64,
|
|
98
|
+
raster: !!raster.raster_id,
|
|
99
|
+
carto: cartoExists,
|
|
95
100
|
};
|
|
96
101
|
}
|
|
97
102
|
|
|
98
103
|
if (data.err) {
|
|
99
|
-
logger.file('rtile/error', {
|
|
104
|
+
logger.file('rtile/error', {
|
|
105
|
+
error: data.err, x, y, z, id: cartoExists ? carto.cartocss_id : raster.raster_id, type: cartoExists ? 'css' : 'raster',
|
|
106
|
+
});
|
|
100
107
|
return reply.status(500).send({ error: config.local ? data.err : 'render error', code: 500 });
|
|
101
108
|
}
|
|
102
109
|
|
|
103
110
|
const buffer = Buffer.from(data.base64, 'base64');
|
|
104
111
|
|
|
105
|
-
return reply.headers({ 'Content-Type': 'image/png', 'Cache-Control': query.nocache ? 'no-store, no-cache, must-revalidate' : 'public, max-age=2592000' }).send(buffer);
|
|
112
|
+
return reply.headers({ 'Content-Type': 'image/png', 'Cache-Control': query.nocache || query.nottl ? 'no-store, no-cache, must-revalidate' : 'public, max-age=2592000' }).send(buffer);
|
|
106
113
|
}
|
|
107
114
|
catch (err) {
|
|
108
|
-
logger.file('rtile/error', {
|
|
115
|
+
logger.file('rtile/error', {
|
|
116
|
+
error: err.toString(), stack: err.stack, x, y, z, id: cartoExists ? carto.cartocss_id : raster.raster_id, type: cartoExists ? 'css' : 'raster',
|
|
117
|
+
});
|
|
109
118
|
return reply.status(500).send({ error: config.local ? err.toString() : 'rtile error', code: 500 });
|
|
110
119
|
}
|
|
111
120
|
}
|
|
@@ -98,7 +98,7 @@ export default async function uploadXML({
|
|
|
98
98
|
throw new Error('xml generation error');
|
|
99
99
|
}
|
|
100
100
|
const { status } = await UploadXML({
|
|
101
|
-
path: relpath,
|
|
101
|
+
path: relpath ? `vector/${relpath}` : null,
|
|
102
102
|
name: relpath ? null : id,
|
|
103
103
|
xml: xmlFileText,
|
|
104
104
|
});
|
|
@@ -5,6 +5,10 @@ import rasterInfo from './controllers/rasterInfo.js';
|
|
|
5
5
|
import mapnikStat from './controllers/mapnikStat.js';
|
|
6
6
|
import mapnikLogger from './controllers/mapnikLogger.js';
|
|
7
7
|
import createXmlMulti from './controllers/createXmlMulti.js';
|
|
8
|
+
import readDir from './controllers/readDir.js';
|
|
9
|
+
import fileStat from './controllers/fileStat.js';
|
|
10
|
+
import fileSearch from './controllers/fileSearch.js';
|
|
11
|
+
import clearTiles from './controllers/clearTiles.js';
|
|
8
12
|
|
|
9
13
|
const publicParams = { config: { policy: 'L0' }, package: 'gis' }; // L0 === public
|
|
10
14
|
const adminParams = { config: { policy: 'L1', role: 'admin' }, package: 'gis' };
|
|
@@ -18,4 +22,8 @@ export default async function route(app) {
|
|
|
18
22
|
app.get('/gis-stat/:period?', adminParams, mapnikStat);
|
|
19
23
|
app.get('/gis-logger/*', adminParams, mapnikLogger);
|
|
20
24
|
app.get('/gis-create-xml/:id?', adminParams, createXmlMulti);
|
|
25
|
+
app.get('/gis-files', adminParams, readDir);
|
|
26
|
+
app.get('/gis-file-info', adminParams, fileStat);
|
|
27
|
+
app.get('/gis-file-search', adminParams, fileSearch);
|
|
28
|
+
app.get('/gis-clear-rtile/:id', adminParams, clearTiles);
|
|
21
29
|
}
|