@opengis/gis 0.2.112 → 0.2.114

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.
@@ -12,7 +12,6 @@
12
12
  "list",
13
13
  "add"
14
14
  ],
15
- "access": "user",
16
15
  "order": "created_at desc",
17
16
  "meta": {
18
17
  "title": "name",
@@ -12,7 +12,6 @@
12
12
  "list",
13
13
  "add"
14
14
  ],
15
- "access": "user",
16
15
  "order": "created_at desc",
17
16
  "meta": {
18
17
  "title": "name",
@@ -12,7 +12,6 @@
12
12
  "list",
13
13
  "add"
14
14
  ],
15
- "access": "user",
16
15
  "order": "created_at desc",
17
16
  "meta": {
18
17
  "title": "name",
@@ -10,7 +10,6 @@
10
10
  "list",
11
11
  "add"
12
12
  ],
13
- "access": "user",
14
13
  "order": "cdate desc",
15
14
  "form": "admin.users.form",
16
15
  "meta": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengis/gis",
3
- "version": "0.2.112",
3
+ "version": "0.2.114",
4
4
  "type": "module",
5
5
  "author": "Softpro",
6
6
  "main": "./dist/index.js",
@@ -63,7 +63,6 @@ async function plugin(fastify, opts) {
63
63
  const { user } = req.session?.passport || {};
64
64
 
65
65
  if (!user && req.url.split('?')[0] !== '/login') {
66
- console.log(req.url);
67
66
  return reply.redirect(`/login?redirect=${req.url}`);
68
67
  }
69
68
  if (!isProduction) return null; // admin vite
@@ -1,7 +1,9 @@
1
1
  import { createReadStream } from 'node:fs';
2
2
  import { mkdir, writeFile } from 'node:fs/promises';
3
3
  import path from 'node:path';
4
- import { grpc, config, getMeta, getFolder, jsonToCsv } from '@opengis/fastify-table/utils.js';
4
+ import {
5
+ grpc, config, getMeta, getFolder, jsonToCsv,
6
+ } from '@opengis/fastify-table/utils.js';
5
7
 
6
8
  import getInfo from './funcs/get.info.js';
7
9
  import ContentType from './funcs/content.type.js';
@@ -13,7 +15,7 @@ const rootDir = getFolder(config, 'local');
13
15
  * Експорт даних реєстру
14
16
  * @param {Object} query - Об'єкт запиту з форматом.
15
17
  * @param {Object} params - Об'єкт параметрів з slug та type.
16
- * @param {Function} reply
18
+ * @param {Function} reply
17
19
  * @returns {boolean} File
18
20
  */
19
21
 
@@ -33,16 +35,16 @@ export default async function gisExport({ pg, query = {}, params = {} }, reply)
33
35
  registerInfo = await pg.query(
34
36
  `SELECT table_name, columns, query
35
37
  FROM gis.registers
36
- WHERE register_key = $1`,
37
- [slug]
38
+ WHERE $1 in (register_key,register_id)`,
39
+ [slug],
38
40
  );
39
41
  }
40
42
  if (type === 'service') {
41
43
  serviceInfo = await pg.query(
42
44
  `SELECT source_path as table_name, attributes as columns, query
43
45
  FROM gis.services
44
- WHERE service_key = $1`,
45
- [slug]
46
+ WHERE $1 in (service_key,service_id)`,
47
+ [slug],
46
48
  );
47
49
  }
48
50
  const finalInfo = registerInfo?.rows[0] || serviceInfo?.rows[0];
@@ -50,15 +52,17 @@ export default async function gisExport({ pg, query = {}, params = {} }, reply)
50
52
  const exportable = finalInfo?.columns?.filter(c => c.is_export);
51
53
  const colmodel = exportable.map(col => ({
52
54
  name: col.name,
53
- title: col.ua || col.name
55
+ title: col.ua || col.name,
54
56
  }));
55
- const { rows, table, srid, sqlList } = await getInfo({ finalInfo, format }, reply);
57
+ const {
58
+ rows, table, srid, sqlList,
59
+ } = await getInfo({ finalInfo, format }, reply);
56
60
  let filePath = ['csv', 'geojson', 'xlsx'].includes(format) ? path.join(rootDir, `/files/tmp/export_${table}_${Date.now()}.${format}`) : path.join(rootDir, `/files/tmp/export_${table}_${Date.now()}.zip`);
57
61
  const ext = path.extname(filePath);
58
62
  const filePathJSON = ['csv', 'geojson', 'shp'].includes(format) ? filePath.replace(ext, '.json') : filePath;
59
- let exportedZipPaths = [];
63
+ const exportedZipPaths = [];
60
64
 
61
- const meta = await getMeta({ pg, table: table });
65
+ const meta = await getMeta({ pg, table });
62
66
  if ((format === 'geojson' || format === 'shp') && !meta?.geom) {
63
67
  return reply.status(400).send('Ця таблиця не містить полів геометрії. Виберіть тип, який не потребує геометрії для вивантаження');
64
68
  }
@@ -146,4 +150,4 @@ export default async function gisExport({ pg, query = {}, params = {} }, reply)
146
150
 
147
151
  const fileStream = createReadStream(exportFilePath);
148
152
  return reply.send(fileStream);
149
- }
153
+ }
@@ -0,0 +1,34 @@
1
+ import path from 'node:path';
2
+ import { existsSync } from 'node:fs';
3
+ import {
4
+ rm, stat, readdir, mkdir,
5
+ } from 'node:fs/promises';
6
+
7
+ import rootFolder from '../../../plugins/mapnik/funcs/rootFolder.mjs';
8
+
9
+ export default async function clearTiles({
10
+ params, query, user,
11
+ }, reply) {
12
+ const filepath = path.join(rootFolder, 'vtile', params.id);
13
+
14
+ if (query.debug && user?.user_type?.includes?.('admin')) {
15
+ return filepath;
16
+ }
17
+
18
+ const exists = existsSync(filepath);
19
+ const isDirectory = exists ? await stat(filepath).then(el => el.isDirectory()) : false;
20
+
21
+ const count = isDirectory ? await readdir(filepath).then(el => el.length) : 0;
22
+
23
+ if (isDirectory && count === 0) {
24
+ return reply.status(404).send({ error: 'Тайли не знайдено', code: 404 });
25
+ }
26
+
27
+ if (isDirectory && exists) {
28
+ await rm(filepath, { force: true, recursive: true });
29
+ await mkdir(filepath, { recursive: true });
30
+ return reply.status(200).send({ message: 'Тайли очищено', code: 200 });
31
+ }
32
+
33
+ return reply.status(400).send({ error: 'Некорректний параметр: id', code: 400 });
34
+ }
@@ -4,9 +4,10 @@ import mapFeatures from './controllers/mapFeatures.js';
4
4
 
5
5
  import mapCatalog from './controllers/mapCatalog.js';
6
6
  import mapCatalogAttribute from './controllers/mapCatalogAttribute.js';
7
- // import rtile from './controllers/rtile.js';
7
+
8
8
  import vtile from './controllers/vtile.js';
9
9
  import vtile1 from './vtile1.js';
10
+ import clearTiles from './controllers/clearTiles.js';
10
11
  import geojson from './controllers/geojson.js';
11
12
  import jsonData from './controllers/jsonData.js';
12
13
  import layerList from './controllers/layerList.js';
@@ -133,6 +134,9 @@ export default async function route(app) {
133
134
  console.log('\x1b[34m%s\x1b[0m', 'add vtile from gis');
134
135
  app.get('/vtile/:layer/:lang/:z/:y/:x', publicParams, vtile1);
135
136
  }
137
+ if (!app.hasRoute({ method: 'GET', url: '/api/gis-clear-vtile/:id' })) {
138
+ app.get('/gis-clear-vtile/:id', publicParams, clearTiles);
139
+ }
136
140
 
137
141
  if (!app.hasRoute({ method: 'GET', url: '/api/geojson/:layer' })) {
138
142
  console.log('\x1b[34m%s\x1b[0m', 'add geojson from gis');
@@ -31,7 +31,7 @@ export default async function vtile({
31
31
  const { y, z } = params;
32
32
  const x = params.x.split('.')[0] - 0;
33
33
  const {
34
- type, nocache, sql, clusterZoom, filter,
34
+ type, nocache, sql, clusterZoom, filter, nottl,
35
35
  } = query;
36
36
 
37
37
  const hash = [type, clusterZoom, filter].join();
@@ -41,24 +41,27 @@ export default async function vtile({
41
41
  `/vtile/${params.layer}/${hash ? `${createHash('md5').update(hash).digest('hex')}/` : ''}${z}/${x}/${y}.vmt`,
42
42
  );
43
43
 
44
- if (existsSync(filepath) && +z < 13 && !nocache && !sql && process.env.NODE_ENV !== 'test') {
44
+ // layer
45
+ const [map, layer] = params.layer.includes(':') ? params.layer.split(':') : [null, params.layer];
46
+
47
+ // service
48
+ const data = await getTemplate('layer', layer) || await pg.query(`select * from gis.services where ${!user?.uid ? 'is_public and is_active' : '1=1'} and service_id=$1`, [layer]).then(el => el.rows?.[0]);
49
+ const style = typeof data?.style === 'object' ? data?.style : yaml.load(data?.style);
50
+
51
+ const cacheZoom = style?.cacheZoom || 13;
52
+ const ttl = typeof style?.ttl === 'number' && style.ttl >= 0 ? style.ttl : 86400000;
53
+
54
+ if (existsSync(filepath) && +z < cacheZoom && !nocache && !sql && process.env.NODE_ENV !== 'test') {
45
55
  const { birthtimeMs = Date.now() } = await stat(filepath);
46
56
  const ageInMs = Date.now() - birthtimeMs;
47
- if (ageInMs < 86400000) {
57
+ if (ageInMs < ttl) {
48
58
  const buffer = await readFile(filepath);
49
59
  return reply.status(200).headers(headers).send(buffer);
50
60
  }
51
61
  }
52
62
 
53
- // layer
54
- const [map, layer] = params.layer.includes(':') ? params.layer.split(':') : [null, params.layer];
55
-
56
- // service
57
- const data = await getTemplate('layer', layer) || await pg.query(`select * from gis.services where ${!user?.uid ? 'is_public and is_active' : '1=1'} and service_id=$1`, [layer]).then(el => el.rows?.[0]);
58
-
59
63
  const geom = data?.geometry_column || 'geom';
60
64
  const table = data?.source_path;
61
- const style = typeof data?.style === 'object' ? data?.style : yaml.load(data?.style);
62
65
  const filterList = data?.filters;
63
66
  const layerQuery = data?.query;
64
67
 
@@ -172,5 +175,5 @@ export default async function vtile({
172
175
  await writeFile(filepath, buffer, 'binary');
173
176
  }
174
177
 
175
- return reply.headers({ ...headers, 'Cache-Control': nocache ? 'no-cache' : headers['Cache-Control'] }).send(buffer);
178
+ return reply.headers({ ...headers, 'Cache-Control': nocache || nottl ? 'no-cache' : headers['Cache-Control'] }).send(buffer);
176
179
  }