@opengis/gis 0.2.168 → 0.2.170
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/{CardIcon-DzERD2T8.js → CardIcon-DXaESte6.js} +1 -1
- package/dist/{EntityTablePage-DAVJRQLe.js → EntityTablePage-BwyMNhrm.js} +1 -1
- package/dist/{ExtentOutlineLayer.vue_vue_type_script_setup_true_lang-B-6axJUY.js → ExtentOutlineLayer.vue_vue_type_script_setup_true_lang-DrHke0pk.js} +1 -1
- package/dist/{HeaderActions.vue_vue_type_script_setup_true_lang-D1iwSeRN.js → HeaderActions.vue_vue_type_script_setup_true_lang-9Rm8Dhc4.js} +1 -1
- package/dist/{MapSettings-wVix8wMh.js → MapSettings-E1aNltts.js} +1 -1
- package/dist/{RastersTablePage-u3oN_h_n.js → RastersTablePage-CJblEi8a.js} +1 -1
- package/dist/{cartocss-BIveBlgY.js → cartocss-Dv2QILZ2.js} +5 -5
- package/dist/{import-utils-DkKPU_Nd.js → import-utils-CL-V2wSj.js} +1 -1
- package/dist/{index-C3bl1qBS.js → index-Bi60lcRm.js} +4768 -4718
- package/dist/index.css +1 -1
- package/dist/index.js +1 -1
- package/dist/index.umd.cjs +31 -31
- package/dist/{raster-CfTJZx5p.js → raster-nn-sOUb9.js} +3 -3
- package/dist/{register-dV5ipRhb.js → register-CjHXBGr5.js} +3 -3
- package/dist/{service-DWC5gq3L.js → service-l3Csdnxm.js} +8 -7
- package/dist/{vs-datatable-Cd2Gp4jo.js → vs-datatable-CJlE3-mz.js} +3 -2
- package/module/test/map/addr.json +303 -0
- package/module/test/map/{addr.yml → addr1.yml} +3 -1
- package/module/test/select/address.str_id.sql +3 -0
- package/package.json +10 -10
- package/plugin.js +21 -12
- package/server/plugins/mapnik/funcs/checkRasterFile.js +1 -3
- package/server/routes/cartocss/cartocss.route.js +31 -0
- package/server/routes/cartocss/cartocss.route.test.js +79 -0
- package/server/routes/cartocss/cartocss.schema.js +73 -0
- package/server/routes/{gis/cartocss → cartocss/functions}/add.cartocss.js +8 -11
- package/server/routes/{gis/cartocss → cartocss/functions}/get.cartocss.js +11 -13
- package/server/routes/gis/functions/checkXML.js +107 -0
- package/server/routes/gis/functions/dashboard.js +24 -0
- package/server/routes/gis/gis.route.js +26 -0
- package/server/routes/gis/gis.route.test.js +34 -0
- package/server/routes/gis/gis.schema.js +1 -0
- package/server/routes/map/{controllers → functions}/clearTiles.js +9 -8
- package/server/routes/map/{controllers → functions}/geojson.js +43 -43
- package/server/routes/map/{controllers → functions}/gis.convert.js +15 -23
- package/server/routes/map/{controllers → functions}/gis.icon.js +23 -10
- package/server/routes/map/{controllers → functions}/jsonData.js +72 -71
- package/server/routes/map/{controllers → functions}/layerList.js +17 -17
- package/server/routes/map/{controllers → functions}/map.js +8 -9
- package/server/routes/map/{controllers → functions}/mapCatalog.js +7 -7
- package/server/routes/map/functions/mapCatalogAttribute.js +54 -0
- package/server/routes/map/{controllers → functions}/mapFeatures.js +22 -18
- package/server/routes/map/{controllers → functions}/mapFormat.js +25 -28
- package/server/routes/map/{controllers → functions}/mapTiles.js +39 -30
- package/server/routes/map/{controllers → functions}/maps.js +3 -3
- package/server/routes/map/{controllers → functions}/marker_icon.js +1 -1
- package/server/routes/map/{controllers → functions}/parseGeoFile.js +10 -11
- package/server/routes/map/{controllers → functions}/pointHeight.js +3 -7
- package/server/routes/map/{controllers → functions}/vtile.js +5 -3
- package/server/routes/map/{vtile1.js → functions/vtile1.js} +39 -33
- package/server/routes/map/map.route.js +280 -0
- package/server/routes/map/map.route.test.js +503 -0
- package/server/routes/map/map.schema.js +356 -0
- package/server/routes/mapnik/{controllers → functions}/clearTiles.js +26 -29
- package/server/routes/mapnik/{controllers → functions}/createXml.js +17 -20
- package/server/routes/mapnik/{controllers → functions}/createXmlMulti.js +11 -15
- package/server/routes/mapnik/{controllers → functions}/fileSearch.js +6 -9
- package/server/routes/mapnik/functions/fileStat.js +28 -0
- package/server/routes/mapnik/{controllers → functions}/pretile.js +29 -35
- package/server/routes/mapnik/{controllers → functions}/rasterInfo.js +19 -10
- package/server/routes/mapnik/{controllers → functions}/readDir.js +4 -4
- package/server/routes/mapnik/functions/rtile.js +164 -0
- package/server/routes/mapnik/{controllers → functions}/uploadRaster.js +19 -24
- package/server/routes/mapnik/functions/uploadXML.js +27 -0
- package/server/routes/mapnik/mapnik.route.js +102 -0
- package/server/routes/mapnik/mapnik.route.test.js +371 -0
- package/server/routes/mapnik/mapnik.schema.mjs +190 -0
- package/server/routes/mapnik.prefixless/functions/mapnikLogger.js +31 -0
- package/server/routes/{mapnik/controllers → mapnik.prefixless/functions}/mapnikStat.js +7 -5
- package/server/routes/mapnik.prefixless/mapnik.prefixless.route.js +20 -0
- package/server/routes/mapnik.prefixless/mapnik.prefixless.route.test.js +91 -0
- package/server/routes/mapnik.prefixless/mapnik.prefixless.schema.mjs +27 -0
- package/server/routes/maps/functions/add.map.js +42 -0
- package/server/routes/{map/maps → maps/functions}/del.map.js +6 -7
- package/server/routes/{map/maps → maps/functions}/get.map.js +12 -11
- package/server/routes/maps/maps.route.js +58 -0
- package/server/routes/maps/maps.route.test.js +231 -0
- package/server/routes/maps/maps.schema.js +10 -0
- package/server/routes/metadata/functions/editMetadata.js +35 -0
- package/server/routes/metadata/functions/metadataXML.js +19 -0
- package/server/routes/metadata/metadata.route.js +26 -0
- package/server/routes/metadata/metadata.route.test.js +47 -0
- package/server/routes/metadata/metadata.schema.js +53 -0
- package/server/routes/{gis/ogc → ogc/functions}/map.info.point.js +22 -29
- package/server/routes/ogc/ogc.route.js +21 -0
- package/server/routes/ogc/ogc.route.test.js +54 -0
- package/server/routes/ogc/ogc.schema.js +16 -0
- package/server/routes/permissions/functions/catalog.permissions.edit.js +20 -0
- package/server/routes/permissions/functions/catalog.permissions.js +13 -0
- package/server/routes/permissions/{controllers → functions}/gis.catalog.js +10 -10
- package/server/routes/permissions/permissions.route.js +35 -0
- package/server/routes/permissions/permissions.route.test.js +35 -0
- package/server/routes/permissions/permissions.schema.js +44 -0
- package/server/routes/registers/functions/add.registry.js +37 -0
- package/server/routes/{gis/registers/funcs → registers/functions}/classifiers.js +2 -2
- package/server/routes/{gis/registers → registers/functions}/del.registry.js +5 -5
- package/server/routes/{gis/registers/funcs → registers/functions}/get.info.js +9 -5
- package/server/routes/{gis/registers → registers/functions}/gis.export.js +27 -21
- package/server/routes/{gis/registers → registers/functions}/gis.registry.js +22 -15
- package/server/routes/{gis/registers → registers/functions}/gis.registry.list.js +12 -10
- package/server/routes/{gis/registers/funcs → registers/functions}/handleRegistryRequest.js +12 -11
- package/server/routes/registers/registers.route.js +80 -0
- package/server/routes/registers/registers.route.test.js +145 -0
- package/server/routes/registers/registers.schema.js +246 -0
- package/server/routes/{gis/services → services/functions}/add.service.js +14 -16
- package/server/routes/services/functions/create.route.js +93 -0
- package/server/routes/{gis/services → services/functions}/del.service.js +5 -5
- package/server/routes/{gis/services → services/functions}/get.service.users.js +15 -13
- package/server/routes/services/functions/get.services.col.js +34 -0
- package/server/routes/{gis/services → services/functions}/get.services.js +21 -16
- package/server/routes/services/services.route.js +76 -0
- package/server/routes/services/services.route.test.js +168 -0
- package/server/routes/services/services.schema.js +278 -0
- package/server/routes/widgets/functions/add.widget.js +39 -0
- package/server/routes/widgets/functions/del.widget.js +18 -0
- package/server/routes/{map/widgets → widgets/functions}/get.widget.js +12 -11
- package/server/routes/widgets/widgets.route.js +61 -0
- package/server/routes/widgets/widgets.route.test.js +144 -0
- package/server/routes/widgets/widgets.schema.js +25 -0
- package/module/cls.json +0 -7
- package/module/gis/card/gis.metadata.table/main_info.hbs +0 -21
- package/module/gis/card/gis.metadata.table/metadata_info.hbs +0 -28
- package/module/gis/card/gis.metadata.table/other.hbs +0 -26
- package/module/gis/card/gis.rasters.table/main_info.hbs +0 -27
- package/module/gis/card/gis.registers.table/cls.hbs +0 -36
- package/module/gis/card/gis.registers.table/columns.hbs +0 -89
- package/module/gis/card/gis.registers.table/filters.hbs +0 -80
- package/module/gis/card/gis.registers.table/main_info.hbs +0 -35
- package/module/gis/card/gis.registers.table/source.hbs +0 -45
- package/module/gis/card/gis.services.table/attributes.hbs +0 -91
- package/module/gis/card/gis.services.table/filters.hbs +0 -83
- package/module/gis/card/gis.services.table/main_info.hbs +0 -27
- package/module/gis/card/gis.services.table/source.hbs +0 -26
- package/module/test/cls/bp_build_type.json +0 -37
- package/module/test/cls/doc_status.json +0 -32
- package/module/test/cls/ts.temp_status.json +0 -18
- package/module/test/cls/ts.temp_structure.ts_class.json +0 -50
- package/module/test/cls/ts.temp_type.json +0 -10
- package/module/test/layer/bp.json +0 -60
- package/module/test/layer/bp1.yml +0 -33
- package/module/test/layer/individual.yml +0 -54
- package/module/test/layer/ts.linking_passport.yml +0 -56
- package/module/test/layer/ts.temp_structure.yml +0 -51
- package/module/test/map/bp_myo.json +0 -44
- package/module/test/map/bpf.json +0 -44
- package/module/test/map/main.json +0 -39
- package/module/test/map/mbd.json +0 -92
- package/module/test/map/ts.json +0 -53
- package/module/test/select/address_id.json +0 -3
- package/module/test/select/address_id.sql +0 -8
- package/module/test/select/core.user_uid.sql +0 -1
- package/module/test/table/data_address.street.table.json +0 -70
- package/module/test/table/data_bp_myo.bp.table.json +0 -123
- package/server/routes/gis/checkXML.js +0 -117
- package/server/routes/gis/dashboard.js +0 -29
- package/server/routes/gis/index.mjs +0 -92
- package/server/routes/gis/metadata/editMetadata.js +0 -34
- package/server/routes/gis/metadata/metadataXML.js +0 -13
- package/server/routes/gis/registers/add.registry.js +0 -35
- package/server/routes/gis/registers/insert.columns.js +0 -107
- package/server/routes/gis/registers/insert.filters.js +0 -110
- package/server/routes/gis/services/create.route.js +0 -96
- package/server/routes/gis/services/get.services.col.js +0 -33
- package/server/routes/map/controllers/mapCatalogAttribute.js +0 -56
- package/server/routes/map/index.mjs +0 -259
- package/server/routes/map/maps/add.map.js +0 -43
- package/server/routes/map/widgets/add.widget.js +0 -39
- package/server/routes/map/widgets/del.widget.js +0 -23
- package/server/routes/mapnik/controllers/fileStat.js +0 -28
- package/server/routes/mapnik/controllers/mapnikLogger.js +0 -29
- package/server/routes/mapnik/controllers/rtile.js +0 -167
- package/server/routes/mapnik/index.js +0 -40
- package/server/routes/permissions/controllers/catalog.permissions.edit.js +0 -22
- package/server/routes/permissions/controllers/catalog.permissions.js +0 -8
- package/server/routes/permissions/index.mjs +0 -18
- /package/server/routes/map/{controllers/pin → pin}/circle1.svg +0 -0
- /package/server/routes/map/{controllers/pin → pin}/circle2.svg +0 -0
- /package/server/routes/map/{controllers/pin → pin}/none.svg +0 -0
- /package/server/routes/map/{controllers/pin → pin}/pin.svg +0 -0
- /package/server/routes/map/{controllers/pin → pin}/pin1.svg +0 -0
- /package/server/routes/map/{controllers/pin → pin}/pin2.svg +0 -0
- /package/server/routes/map/{controllers/pin → pin}/pin3.svg +0 -0
- /package/server/routes/map/{controllers/pin → pin}/pin4.svg +0 -0
- /package/server/routes/map/{controllers/pin → pin}/pin5.svg +0 -0
- /package/server/routes/map/{controllers/pin → pin}/pin6.svg +0 -0
- /package/server/routes/map/{controllers/pin → pin}/pin7.svg +0 -0
- /package/server/routes/permissions/{controllers/utils → functions}/get.permissions.js +0 -0
- /package/server/routes/{gis/registers/funcs → registers/functions}/columns.js +0 -0
- /package/server/routes/{gis/registers/funcs → registers/functions}/content.type.js +0 -0
- /package/server/routes/{gis/registers → registers/functions}/map.registry.js +0 -0
- /package/server/routes/{gis/services → services/functions}/get.layer.geom.js +0 -0
- /package/server/routes/{gis/services → services/functions}/legend.auto.js +0 -0
|
@@ -1,18 +1,19 @@
|
|
|
1
|
-
import SphericalMercator from '@mapbox/sphericalmercator';
|
|
1
|
+
import { SphericalMercator } from '@mapbox/sphericalmercator';
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
|
-
config, logger,
|
|
4
|
+
config, logger, pgClients,
|
|
5
5
|
} from '@opengis/fastify-table/utils.js';
|
|
6
|
+
import { BadRequestError, NotFoundError } from '@opengis/fastify-table/errors.js';
|
|
6
7
|
|
|
7
|
-
import convertBoundToTile from '
|
|
8
|
+
import convertBoundToTile from './convertBoundToTile.js';
|
|
8
9
|
import mapnik from '../../../plugins/mapnik/funcs/mapnik.js';
|
|
9
|
-
import cartoBounds from '../functions/cartoBounds.js';
|
|
10
|
-
import rasterInfo from './rasterInfo.js';
|
|
11
|
-
|
|
12
|
-
const { RenderTile } = mapnik();
|
|
10
|
+
// import cartoBounds from '../functions/cartoBounds.js';
|
|
11
|
+
// import rasterInfo from './rasterInfo.js';
|
|
13
12
|
|
|
14
13
|
const mercator = new SphericalMercator({ size: 256 });
|
|
15
14
|
|
|
15
|
+
const { RenderTile } = mapnik();
|
|
16
|
+
|
|
16
17
|
const MAX_LIMIT = 100000;
|
|
17
18
|
|
|
18
19
|
const CONCURRENCY = 5;
|
|
@@ -39,35 +40,31 @@ async function runPool(tasks, limit) {
|
|
|
39
40
|
const maxBounds = [23, 44, 40, 53];
|
|
40
41
|
|
|
41
42
|
export default async function pretile({
|
|
42
|
-
|
|
43
|
-
},
|
|
44
|
-
const { zoom = 11, max = 15 } = query || {};
|
|
45
|
-
|
|
43
|
+
id, zoom = 11, max = 15, callback = () => { },
|
|
44
|
+
}, pg = pgClients.client) {
|
|
46
45
|
if (zoom > max) {
|
|
47
|
-
|
|
46
|
+
throw BadRequestError('Error: querystring/max must be > querystring/zoom');
|
|
48
47
|
}
|
|
49
48
|
|
|
50
|
-
const data = await pg.query(`select *, geom::box2d as bounds, 'raster' as source_type from gis.rasters where raster_id=$1`, [
|
|
51
|
-
|| await pg.query(`select *, geom::box2d as bounds, 'css' as source_type from gis.cartocss where cartocss_id=$1`, [
|
|
49
|
+
const data = await pg.query(`select *, geom::box2d as bounds, 'raster' as source_type from gis.rasters where raster_id=$1`, [id]).then(r => r.rows?.[0])
|
|
50
|
+
|| await pg.query(`select *, geom::box2d as bounds, 'css' as source_type from gis.cartocss where cartocss_id=$1`, [id]).then(r => r.rows?.[0]);
|
|
52
51
|
|
|
53
52
|
if (!data) {
|
|
54
|
-
|
|
53
|
+
throw NotFoundError('raster/css not found');
|
|
55
54
|
}
|
|
56
55
|
|
|
57
56
|
if (!data.bounds || data.bounds === 'BOX(-180 -85.05112877980659,180 85.05112877980659)') {
|
|
58
|
-
|
|
57
|
+
throw BadRequestError('geom is not set');
|
|
59
58
|
}
|
|
60
59
|
|
|
61
|
-
const send = eventStream(reply);
|
|
62
|
-
|
|
63
60
|
try {
|
|
64
61
|
const relpath = data.source_type === 'raster' ? ['raster', config.mapnik?.folder, data.source_path].filter(Boolean).join('/') : null;
|
|
65
|
-
const name = data.source_type === 'css' ? ['vector', config.mapnik?.folder || '', data.source_path ||
|
|
62
|
+
const name = data.source_type === 'css' ? ['vector', config.mapnik?.folder || '', data.source_path || id].filter(Boolean).join('/') : null;
|
|
66
63
|
|
|
67
64
|
// refresh extent
|
|
68
65
|
const bounds = data.bounds.replace(')', '').substr(4).split(/[, ]/g).map((el) => el - 0);
|
|
69
66
|
|
|
70
|
-
|
|
67
|
+
callback(`start: ${data.name} ${id} ${bounds} ${data.srid} ${data.proj4}`);
|
|
71
68
|
|
|
72
69
|
bounds[0] = Math.max(bounds[0], maxBounds[0]);
|
|
73
70
|
bounds[1] = Math.max(bounds[1], maxBounds[1]);
|
|
@@ -75,7 +72,7 @@ export default async function pretile({
|
|
|
75
72
|
bounds[2] = Math.min(bounds[2], maxBounds[2]);
|
|
76
73
|
bounds[3] = Math.min(bounds[3], maxBounds[3]);
|
|
77
74
|
|
|
78
|
-
|
|
75
|
+
callback({
|
|
79
76
|
bounds, minzoom: zoom, maxzoom: max, maxBounds,
|
|
80
77
|
});
|
|
81
78
|
|
|
@@ -83,12 +80,12 @@ export default async function pretile({
|
|
|
83
80
|
bounds, minzoom: zoom, maxzoom: max, mercator,
|
|
84
81
|
});
|
|
85
82
|
|
|
86
|
-
|
|
83
|
+
callback(tiles);
|
|
87
84
|
|
|
88
85
|
const tileLen = tiles.reduce((acc, el) => acc + el.count, 0);
|
|
89
86
|
|
|
90
87
|
if (tileLen > MAX_LIMIT) {
|
|
91
|
-
|
|
88
|
+
callback({ MAX_LIMIT });
|
|
92
89
|
}
|
|
93
90
|
|
|
94
91
|
let tileNum = 0;
|
|
@@ -106,8 +103,8 @@ export default async function pretile({
|
|
|
106
103
|
return ys.map((y) => async () => {
|
|
107
104
|
if (tileNum > MAX_LIMIT) return;
|
|
108
105
|
|
|
109
|
-
const tilePath = `${
|
|
110
|
-
|
|
106
|
+
const tilePath = `${id}/${z}/${x}/${y}.png`;
|
|
107
|
+
callback(`Start ${tileNum + 1}/${tileLen} ${tilePath}`);
|
|
111
108
|
|
|
112
109
|
const time = Date.now();
|
|
113
110
|
|
|
@@ -115,12 +112,12 @@ export default async function pretile({
|
|
|
115
112
|
const render = await RenderTile({ path: relpath, name, bbox });
|
|
116
113
|
|
|
117
114
|
if (render?.err) {
|
|
118
|
-
|
|
115
|
+
callback(render.err);
|
|
119
116
|
return;
|
|
120
117
|
}
|
|
121
118
|
|
|
122
|
-
|
|
123
|
-
`${tileNum + 1}/${tileLen} ${config.local || config.debug ? render.tile_path :
|
|
119
|
+
callback(
|
|
120
|
+
`${tileNum + 1}/${tileLen} ${config.local || config.debug ? render.tile_path : id} len:${render.base64.length} cache: ${!!render?.cache} time:${Date.now() - time}ms`,
|
|
124
121
|
);
|
|
125
122
|
tileNum += 1;
|
|
126
123
|
});
|
|
@@ -129,16 +126,13 @@ export default async function pretile({
|
|
|
129
126
|
|
|
130
127
|
await runPool(tasks, CONCURRENCY);
|
|
131
128
|
|
|
132
|
-
|
|
129
|
+
callback('OK');
|
|
133
130
|
return 'OK';
|
|
134
131
|
}
|
|
135
132
|
catch (err) {
|
|
136
133
|
const error = config.local || config.debug ? err.toString() : 'pretile error';
|
|
137
|
-
|
|
138
|
-
logger.file('pretile.error', { error: err.toString(), stack: err.stack, id
|
|
139
|
-
|
|
140
|
-
}
|
|
141
|
-
finally {
|
|
142
|
-
send('finish', true);
|
|
134
|
+
callback(error);
|
|
135
|
+
logger.file('pretile.error', { error: err.toString(), stack: err.stack, id });
|
|
136
|
+
throw err;
|
|
143
137
|
}
|
|
144
138
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { config, pgClients } from '@opengis/fastify-table/utils.js';
|
|
2
2
|
|
|
3
3
|
import mapnik from '../../../plugins/mapnik/funcs/mapnik.js';
|
|
4
|
+
import { BadRequestError, NotImplementedError } from '@opengis/fastify-table/errors.js';
|
|
4
5
|
|
|
5
6
|
const { GetRasterInfo } = mapnik();
|
|
6
7
|
|
|
@@ -8,28 +9,36 @@ const { prefix = '/api' } = config;
|
|
|
8
9
|
|
|
9
10
|
// example: GET /api/gis-raster/9be8f8c51746
|
|
10
11
|
export default async function rasterInfo({
|
|
11
|
-
|
|
12
|
-
},
|
|
12
|
+
id, debug,
|
|
13
|
+
}, pg = pgClients.client) {
|
|
13
14
|
const time = Date.now();
|
|
15
|
+
|
|
16
|
+
if (!id) {
|
|
17
|
+
throw NotImplementedError('not enough params: id');
|
|
18
|
+
}
|
|
19
|
+
|
|
14
20
|
if (!config.mapnik?.server) {
|
|
15
|
-
|
|
21
|
+
throw NotImplementedError('mapnik server address needed');
|
|
16
22
|
}
|
|
17
23
|
|
|
18
24
|
const raster = pg.pk?.['gis.rasters']
|
|
19
|
-
? await pg.query('select raster_id, source_path, name, description, raster_key, is_active, is_public, srid, proj4, geom from gis.rasters where raster_id=$1::text', [
|
|
20
|
-
.then(
|
|
25
|
+
? await pg.query('select raster_id, source_path, name, description, raster_key, is_active, is_public, srid, proj4, st_asgeojson(geom)::json as geom from gis.rasters where raster_id=$1::text', [id])
|
|
26
|
+
.then(r => r.rows?.[0] || {})
|
|
21
27
|
: {};
|
|
22
28
|
|
|
23
29
|
if (raster.raster_id && !raster.source_path) {
|
|
24
|
-
|
|
30
|
+
throw BadRequestError('empty source_path');
|
|
25
31
|
}
|
|
26
32
|
|
|
27
33
|
if (!raster.raster_id) {
|
|
28
|
-
const decodedPath = Buffer.from(
|
|
34
|
+
const decodedPath = Buffer.from(id, 'base64url').toString('utf-8');
|
|
29
35
|
Object.assign(raster, { source_path: decodedPath });
|
|
30
36
|
}
|
|
31
37
|
|
|
32
|
-
const proj4 = raster.proj4
|
|
38
|
+
const proj4 = raster.proj4
|
|
39
|
+
|| (raster.srid && pg.pk?.['public.spatial_ref_sys']
|
|
40
|
+
? await pg.query('select proj4text from public.spatial_ref_sys where srid=$1', [raster.srid]).then(r => r.rows?.[0]?.proj4text)
|
|
41
|
+
: undefined);
|
|
33
42
|
|
|
34
43
|
const relpath = ['raster', config.mapnik?.folder, raster.source_path].filter(Boolean).join('/');
|
|
35
44
|
|
|
@@ -38,12 +47,12 @@ export default async function rasterInfo({
|
|
|
38
47
|
proj4,
|
|
39
48
|
}).catch(err => ({ error: err.toString() }));
|
|
40
49
|
|
|
41
|
-
if (
|
|
50
|
+
if (debug) {
|
|
42
51
|
return { data, cache, raster };
|
|
43
52
|
}
|
|
44
53
|
|
|
45
54
|
if (!raster.geom && Array.isArray(data?.extent)) {
|
|
46
|
-
await pg.query(`update gis.rasters set geom = ST_MakeEnvelope($
|
|
55
|
+
await pg.query(`update gis.rasters set geom = ST_MakeEnvelope($2,$3,$4,$5) where raster_id = $1`, [raster.raster_id, ...data.extent]);
|
|
47
56
|
}
|
|
48
57
|
|
|
49
58
|
return {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { config } from '@opengis/fastify-table/utils.js';
|
|
2
|
+
import { NotImplementedError } from '@opengis/fastify-table/errors.js';
|
|
2
3
|
|
|
3
4
|
import mapnik from '../../../plugins/mapnik/funcs/mapnik.js';
|
|
4
5
|
|
|
@@ -6,13 +7,12 @@ const { ReadDir } = mapnik();
|
|
|
6
7
|
|
|
7
8
|
// example: GET /api/gis-files?dir=raster/genplan
|
|
8
9
|
export default async function readDir({
|
|
9
|
-
|
|
10
|
-
}
|
|
10
|
+
dir,
|
|
11
|
+
}) {
|
|
11
12
|
if (!ReadDir) {
|
|
12
|
-
|
|
13
|
+
throw NotImplementedError('mapnik server address needed');
|
|
13
14
|
}
|
|
14
15
|
|
|
15
|
-
const { dir } = query;
|
|
16
16
|
const relpath = `raster/${[config.mapnik?.folder, dir].filter(Boolean).join('/')}`;
|
|
17
17
|
|
|
18
18
|
const {
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { createHash } from 'node:crypto';
|
|
3
|
+
|
|
4
|
+
import { SphericalMercator } from '@mapbox/sphericalmercator';
|
|
5
|
+
|
|
6
|
+
const mercator = new SphericalMercator({ size: 256 });
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
config, logger, pgClients,
|
|
10
|
+
} from '@opengis/fastify-table/utils.js';
|
|
11
|
+
|
|
12
|
+
import { BadRequestError, ForbiddenError, NotFoundError } from '@opengis/fastify-table/errors.js';
|
|
13
|
+
|
|
14
|
+
import mapnik from '../../../plugins/mapnik/funcs/mapnik.js';
|
|
15
|
+
|
|
16
|
+
const { RenderTile } = mapnik();
|
|
17
|
+
|
|
18
|
+
const meta = !!config?.mapnik?.meta;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Формування растрового tile cartoCss
|
|
22
|
+
*
|
|
23
|
+
* @method GET
|
|
24
|
+
* @alias rtile
|
|
25
|
+
* @param {String} bbox - bbox
|
|
26
|
+
* @param {Number} height - висота по координатам
|
|
27
|
+
* @param {Number} width - ширина по координатам
|
|
28
|
+
* @param {String} data - стилізація
|
|
29
|
+
* @param {String} lang - мова
|
|
30
|
+
* @param {String} z - координата z
|
|
31
|
+
* @param {String} x - координата y
|
|
32
|
+
* @param {String} y - координата x
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
export default async function gisRtile({
|
|
36
|
+
id, z, y, x, debug, nocache, nottl, uid,
|
|
37
|
+
}, pg = pgClients.client) {
|
|
38
|
+
if (!RenderTile) {
|
|
39
|
+
throw BadRequestError('mapnik server address needed');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (!id) {
|
|
43
|
+
throw BadRequestError('not enough params: id');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (!x || !y || !z) {
|
|
47
|
+
throw BadRequestError('not enough params: xyz');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const decodedPath = Buffer.from(id, 'base64url').toString('utf-8');
|
|
51
|
+
|
|
52
|
+
const data = pg.pk?.['gis.rasters']
|
|
53
|
+
? await pg.queryCache(`select raster_id as id, source_path, is_public, 'raster' as type from gis.rasters where raster_id=$1::text or source_path=$2::text`, { args: [id, decodedPath], table: 'gis.rasters' })
|
|
54
|
+
.then(r => r.rows?.[0] || {})
|
|
55
|
+
: {};
|
|
56
|
+
|
|
57
|
+
const carto = pg.pk?.['gis.cartocss']
|
|
58
|
+
? await pg.queryCache('select cartocss_id, source_path, is_public, is_static from gis.cartocss where cartocss_id=$1::text', { args: [id], table: 'gis.cartocss' }).then(r => r.rows?.[0] || {})
|
|
59
|
+
: {};
|
|
60
|
+
|
|
61
|
+
if (carto.cartocss_id) {
|
|
62
|
+
Object.assign(data, {
|
|
63
|
+
id: carto.cartocss_id,
|
|
64
|
+
source_path: carto.source_path,
|
|
65
|
+
is_public: carto.is_public,
|
|
66
|
+
is_static: carto.is_static,
|
|
67
|
+
type: 'css',
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (!uid && !config.local && data.is_public === false && process.env.NODE_ENV !== 'test' && !process.env.VITEST) {
|
|
72
|
+
throw ForbiddenError('access restricted');
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (!data.id && data.type !== 'css') {
|
|
76
|
+
Object.assign(data, { source_path: decodedPath });
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (!data.source_path && data.type !== 'css') {
|
|
80
|
+
throw NotFoundError('raster / cartocss not found');
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const bbox = mercator.bbox(y, x, z, false, '900913');
|
|
84
|
+
|
|
85
|
+
const ttl = (nocache ? '0' : null)
|
|
86
|
+
|| (data.type === 'css' && !data.is_static ? '1w' : null);
|
|
87
|
+
|
|
88
|
+
const md5 = data.source_path
|
|
89
|
+
? createHash('md5').update(data.source_path).digest('hex')
|
|
90
|
+
: undefined;
|
|
91
|
+
const base64 = data.source_path
|
|
92
|
+
? Buffer.from(data.source_path).toString('base64url')
|
|
93
|
+
: undefined;
|
|
94
|
+
|
|
95
|
+
const getParams = () => {
|
|
96
|
+
if (data.type === 'css' && data.source_path) {
|
|
97
|
+
return { name: path.posix.join('vector', config.mapnik?.folder || '', data.source_path) };
|
|
98
|
+
}
|
|
99
|
+
if (data.type === 'css') {
|
|
100
|
+
return { name: path.posix.join('xml', config.mapnik?.folder || '', id) };
|
|
101
|
+
}
|
|
102
|
+
return { path: path.posix.join('raster', config.mapnik?.folder || '', data.source_path) };
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
const { path: rpath, name } = getParams();
|
|
106
|
+
|
|
107
|
+
const param = {
|
|
108
|
+
path: rpath, // for rasters only
|
|
109
|
+
name, // required for cartocss
|
|
110
|
+
width: 256,
|
|
111
|
+
bbox,
|
|
112
|
+
ttl,
|
|
113
|
+
format: 'webp',
|
|
114
|
+
meta,
|
|
115
|
+
base64: false,
|
|
116
|
+
debug,
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
const result = await RenderTile(param);
|
|
120
|
+
|
|
121
|
+
if (result.err) {
|
|
122
|
+
logger.file('rtile/error', {
|
|
123
|
+
error: result.err, x, y, z, id: data.id, type: data.type,
|
|
124
|
+
});
|
|
125
|
+
throw new Error(result.err);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (meta) {
|
|
129
|
+
const accelPath = result.tile_path?.startsWith('/') ? result.tile_path : `/${result.tile_path}`;
|
|
130
|
+
const metaHeaders = {
|
|
131
|
+
'Content-Type': 'image/webp',
|
|
132
|
+
'Cache-Control': nocache || nottl ? 'no-store, no-cache, must-revalidate' : 'public, max-age=2592000',
|
|
133
|
+
'X-Accel-Redirect': accelPath,
|
|
134
|
+
};
|
|
135
|
+
if (debug) {
|
|
136
|
+
return {
|
|
137
|
+
headers: metaHeaders,
|
|
138
|
+
base64: result.base64,
|
|
139
|
+
z,
|
|
140
|
+
x,
|
|
141
|
+
y,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
return { headers: metaHeaders, code: 204 };
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (debug) {
|
|
148
|
+
return {
|
|
149
|
+
...result,
|
|
150
|
+
name,
|
|
151
|
+
path: rpath,
|
|
152
|
+
ttl,
|
|
153
|
+
md5_path: md5,
|
|
154
|
+
base64_path: base64,
|
|
155
|
+
raster: !!data.id,
|
|
156
|
+
carto: data.type === 'css',
|
|
157
|
+
is_static: data.type === 'css' ? data.is_static : true,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
const buffer = result.data || Buffer.from(result.base64, 'base64');
|
|
162
|
+
|
|
163
|
+
return { headers: { 'Content-Type': 'image/webp', 'Cache-Control': nocache || nottl ? 'no-store, no-cache, must-revalidate' : 'public, max-age=2592000' }, data: buffer };
|
|
164
|
+
}
|
|
@@ -3,9 +3,11 @@ import { ListObjectsV2Command } from '@aws-sdk/client-s3';
|
|
|
3
3
|
|
|
4
4
|
/* eslint-disable no-await-in-loop */
|
|
5
5
|
import {
|
|
6
|
-
config, isFileExists, logger, pgClients,
|
|
6
|
+
config, isFileExists, logger, pgClients, downloadFile, s3Client,
|
|
7
7
|
} from '@opengis/fastify-table/utils.js';
|
|
8
8
|
|
|
9
|
+
import { BadRequestError, NotFoundError, NotImplementedError } from '@opengis/fastify-table/errors.js';
|
|
10
|
+
|
|
9
11
|
import mapnik from '../../../plugins/mapnik/funcs/mapnik.js';
|
|
10
12
|
|
|
11
13
|
const { UploadRaster, GetRasterStatus } = mapnik();
|
|
@@ -26,7 +28,7 @@ async function uploadRasterFile({
|
|
|
26
28
|
id, prefix, relpath: relpathOriginal, callback = () => { },
|
|
27
29
|
}) {
|
|
28
30
|
const metadata = await isFileExists(relpathOriginal);
|
|
29
|
-
const relpath = relpathOriginal.replace(config.folder, '').
|
|
31
|
+
const relpath = ['raster', config.mapnik?.folder || '', relpathOriginal.replace(/\/\//, '/').replace(config.folder, '')].join('/');
|
|
30
32
|
|
|
31
33
|
let offset = 0;
|
|
32
34
|
|
|
@@ -95,29 +97,27 @@ async function uploadRasterFile({
|
|
|
95
97
|
}
|
|
96
98
|
|
|
97
99
|
export default async function uploadRaster({
|
|
98
|
-
|
|
99
|
-
},
|
|
100
|
+
id, callback = () => { },
|
|
101
|
+
}, pg = pgClients.client) {
|
|
100
102
|
if (!UploadRaster || !GetRasterStatus) {
|
|
101
|
-
|
|
103
|
+
throw NotImplementedError('mapnik server address needed');
|
|
102
104
|
}
|
|
103
105
|
|
|
104
|
-
const { id } = params;
|
|
105
|
-
|
|
106
106
|
if (!id) {
|
|
107
|
-
|
|
107
|
+
throw BadRequestError('not enough params: id');
|
|
108
108
|
}
|
|
109
109
|
|
|
110
110
|
const data = pg.pk?.['gis.rasters']
|
|
111
111
|
? await pg.query('select raster_id as id, source_path from gis.rasters where raster_id=$1::text', [id])
|
|
112
|
-
.then(
|
|
112
|
+
.then(r => r.rows?.[0])
|
|
113
113
|
: null;
|
|
114
114
|
|
|
115
115
|
if (!data?.id) {
|
|
116
|
-
|
|
116
|
+
throw NotFoundError('raster not found');
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
if (!data.source_path) {
|
|
120
|
-
|
|
120
|
+
throw BadRequestError('raster source_path not set');
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
const prefix = '/map/raster';
|
|
@@ -129,29 +129,24 @@ export default async function uploadRaster({
|
|
|
129
129
|
Prefix: path.join(config.folder, relpath).replace(/\\/g, '/'),
|
|
130
130
|
}));
|
|
131
131
|
if (!metadata.Contents?.length) {
|
|
132
|
-
|
|
133
|
-
error: 'invalid: raster source_path: not found / empty directory',
|
|
134
|
-
code: 404,
|
|
135
|
-
});
|
|
132
|
+
throw NotFoundError('invalid: raster source_path: not found / empty directory');
|
|
136
133
|
}
|
|
137
134
|
|
|
138
135
|
// list rasters, skip preview subdir content, skip folders from s3 directory name of which only starts with same characters, but does not exactly match
|
|
139
136
|
const files = metadata.Contents.map(file => file.Key).filter((file) => path.basename(path.dirname(file)) === path.basename(relpath) && !path.basename(path.dirname(file)).startsWith('preview') && path.extname(file).toLowerCase() === '.tif');
|
|
140
137
|
|
|
141
138
|
if (!files.length) {
|
|
142
|
-
|
|
143
|
-
error: 'invalid: raster source_path: no raster files at directory',
|
|
144
|
-
code: 400,
|
|
145
|
-
});
|
|
139
|
+
throw BadRequestError('invalid: raster source_path: no raster files at directory');
|
|
146
140
|
}
|
|
147
|
-
|
|
141
|
+
|
|
148
142
|
await sequence(files, { id, prefix, callback }, uploadRasterFile);
|
|
149
|
-
return
|
|
143
|
+
return 'uploaded';
|
|
150
144
|
}
|
|
151
145
|
|
|
152
|
-
|
|
146
|
+
|
|
153
147
|
await uploadRasterFile({
|
|
154
|
-
id, prefix, callback, relpath,
|
|
148
|
+
id, prefix, callback, relpath: data.source_path,
|
|
155
149
|
});
|
|
156
|
-
|
|
150
|
+
|
|
151
|
+
return 'uploaded';
|
|
157
152
|
}
|
|
@@ -18,6 +18,7 @@ const getGeomColumn = (geoms, customColumn) => {
|
|
|
18
18
|
};
|
|
19
19
|
|
|
20
20
|
import cartoBounds from './cartoBounds.js';
|
|
21
|
+
import { NotFoundError } from '@opengis/fastify-table/errors.js';
|
|
21
22
|
|
|
22
23
|
function cartoData(el, extent, pg) {
|
|
23
24
|
const minzoom = el.minzoom ? (+el.minzoom || 5) : 5;
|
|
@@ -53,6 +54,32 @@ export default async function uploadXML({
|
|
|
53
54
|
if (!id || !dataset?.length || Array.isArray(dataset) === false) {
|
|
54
55
|
return null;
|
|
55
56
|
}
|
|
57
|
+
|
|
58
|
+
const tlist = await pg
|
|
59
|
+
.query(
|
|
60
|
+
`SELECT
|
|
61
|
+
array_agg(
|
|
62
|
+
(
|
|
63
|
+
SELECT
|
|
64
|
+
nspname
|
|
65
|
+
FROM
|
|
66
|
+
pg_namespace
|
|
67
|
+
WHERE
|
|
68
|
+
oid = relnamespace
|
|
69
|
+
) || '.' || relname
|
|
70
|
+
) tlist
|
|
71
|
+
FROM
|
|
72
|
+
pg_class
|
|
73
|
+
WHERE
|
|
74
|
+
relkind IN ('r', 'v', 'm')`
|
|
75
|
+
)
|
|
76
|
+
.then((d) => d.rows[0].tlist);
|
|
77
|
+
|
|
78
|
+
const { table: missingTable } = dataset.find(el => el.active !== false && el.table && !tlist.includes(el.table)) || {};
|
|
79
|
+
if (missingTable) {
|
|
80
|
+
throw NotFoundError('table not found: ' + missingTable);
|
|
81
|
+
}
|
|
82
|
+
|
|
56
83
|
await Promise.all(dataset.filter((el) => el.active !== false).map(async el => {
|
|
57
84
|
const { table } = el;
|
|
58
85
|
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { eventStream } from '@opengis/fastify-table/utils.js';
|
|
2
|
+
|
|
3
|
+
import uploadRaster from './functions/uploadRaster.js';
|
|
4
|
+
import createXml from './functions/createXml.js';
|
|
5
|
+
import rtile from './functions/rtile.js';
|
|
6
|
+
import rasterInfo from './functions/rasterInfo.js';
|
|
7
|
+
|
|
8
|
+
import createXmlMulti from './functions/createXmlMulti.js';
|
|
9
|
+
import readDir from './functions/readDir.js';
|
|
10
|
+
import fileStat from './functions/fileStat.js';
|
|
11
|
+
import fileSearch from './functions/fileSearch.js';
|
|
12
|
+
import clearTiles from './functions/clearTiles.js';
|
|
13
|
+
import pretile from './functions/pretile.js';
|
|
14
|
+
|
|
15
|
+
import {
|
|
16
|
+
pretileSchema,
|
|
17
|
+
uploadRasterSchema,
|
|
18
|
+
gisXmlSchema,
|
|
19
|
+
gisRtileSchema,
|
|
20
|
+
gisRasterSchema,
|
|
21
|
+
createXmlMultiSchema,
|
|
22
|
+
readDirSchema,
|
|
23
|
+
fileStatSchema,
|
|
24
|
+
fileSearchSchema,
|
|
25
|
+
clearTilesSchema,
|
|
26
|
+
} from './mapnik.schema.mjs';
|
|
27
|
+
|
|
28
|
+
const publicParams = { config: { policy: 'L0' }, package: 'gis' }; // L0 === public
|
|
29
|
+
const adminParams = { config: { role: 'admin' }, package: 'gis' };
|
|
30
|
+
const privateParams = { config: { policy: 'L1' }, package: 'gis' }; // L1 === authorized only
|
|
31
|
+
|
|
32
|
+
export default function route(app) {
|
|
33
|
+
app.get('/gis-upload-raster/:id', { ...privateParams, schema: uploadRasterSchema }, async ({ params, pg }, reply) => {
|
|
34
|
+
const callback = process.env.NODE_ENV === 'test' || process.env.VITEST ? console.log : eventStream(reply);
|
|
35
|
+
const result = await uploadRaster({ id: params.id, callback }, pg).catch(err => ({ error: err.toString() }));
|
|
36
|
+
callback(result?.error || 'finish', true);
|
|
37
|
+
return result;
|
|
38
|
+
});
|
|
39
|
+
app.get('/gis-xml/:id', { ...publicParams, schema: gisXmlSchema }, async ({ params, query }, reply) => {
|
|
40
|
+
const callback = process.env.NODE_ENV === 'test' || process.env.VITEST ? console.log : eventStream(reply);
|
|
41
|
+
const result = await createXml({ id: params.id, vrt: query.vrt, debug: query.debug, nocache: query.nocache, callback }).catch(err => ({ error: err.toString() }));
|
|
42
|
+
callback(result?.error || 'finish', true);
|
|
43
|
+
return result;
|
|
44
|
+
});
|
|
45
|
+
app.get('/gis-rtile/:id/:z/:y/:x', { ...publicParams, schema: gisRtileSchema }, async ({ params, query, user, pg }, reply) => {
|
|
46
|
+
const result = await rtile({
|
|
47
|
+
id: params.id,
|
|
48
|
+
z: params.z,
|
|
49
|
+
y: params.y,
|
|
50
|
+
x: params.x.split('.')[0] - 0,
|
|
51
|
+
uid: user?.uid,
|
|
52
|
+
debug: query.debug,
|
|
53
|
+
nocache: query.nocache,
|
|
54
|
+
nottl: query.nottl,
|
|
55
|
+
}, pg);
|
|
56
|
+
if (query.debug) {
|
|
57
|
+
return result;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (result.code === 204) {
|
|
61
|
+
return reply.headers(result.headers).code(204).send();
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return reply.headers(result.headers).send(result.data);
|
|
65
|
+
});
|
|
66
|
+
app.get('/gis-raster/:id', { ...publicParams, schema: gisRasterSchema }, async ({ params, query, pg }) => {
|
|
67
|
+
const result = await rasterInfo({ id: params.id, debug: query.debug }, pg);
|
|
68
|
+
return result;
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
app.get('/gis-create-xml/:id?', { ...adminParams, schema: createXmlMultiSchema }, async ({ params, query, pg }, reply) => {
|
|
72
|
+
const callback = process.env.NODE_ENV === 'test' || process.env.VITEST ? console.log : eventStream(reply);
|
|
73
|
+
const result = await createXmlMulti({
|
|
74
|
+
id: params.id, nocache: query.nocache, callback
|
|
75
|
+
}, pg).catch(err => ({ error: err.toString() }));
|
|
76
|
+
callback(result?.error || 'finish', true);
|
|
77
|
+
return result;
|
|
78
|
+
});
|
|
79
|
+
app.get('/gis-files', { ...adminParams, schema: readDirSchema }, async ({ query }) => {
|
|
80
|
+
const result = await readDir({ dir: query.dir });
|
|
81
|
+
return result;
|
|
82
|
+
});
|
|
83
|
+
app.get('/gis-file-info', { ...adminParams, schema: fileStatSchema }, async ({ query }) => {
|
|
84
|
+
const result = await fileStat({ path: query.path });
|
|
85
|
+
return result;
|
|
86
|
+
});
|
|
87
|
+
app.get('/gis-file-search', { ...adminParams, schema: fileSearchSchema }, async ({ query }) => {
|
|
88
|
+
const { dir, key, period, size, page, limit } = query;
|
|
89
|
+
const result = await fileSearch({ dir, key, period, size, page, limit });
|
|
90
|
+
return result;
|
|
91
|
+
});
|
|
92
|
+
app.get('/gis-clear-rtile/:id', { ...adminParams, schema: clearTilesSchema }, async ({ params, query }) => {
|
|
93
|
+
const result = await clearTiles({ id: params.id, debug: query.debug });
|
|
94
|
+
return result;
|
|
95
|
+
});
|
|
96
|
+
app.get('/gis-pretile/:id', { ...adminParams, schema: pretileSchema }, async ({ params, query, pg }, reply) => {
|
|
97
|
+
const callback = process.env.NODE_ENV === 'test' || process.env.VITEST ? console.log : eventStream(reply);
|
|
98
|
+
const result = await pretile({ id: params.id, zoom: query.zoom, max: query.max, callback }, pg).catch(err => ({ error: err.toString() }));
|
|
99
|
+
callback(result?.error || 'finish', true);
|
|
100
|
+
return result;
|
|
101
|
+
});
|
|
102
|
+
}
|