@opengis/gis 0.2.100 → 0.2.102

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.
@@ -30,6 +30,13 @@
30
30
  "type": "Switcher",
31
31
  "data": "yes_no"
32
32
  },
33
+ "is_static": {
34
+ "ua": "Чи є карта статичною?",
35
+ "i": "Генерація тайлів без TTL",
36
+ "col": 6,
37
+ "type": "Switcher",
38
+ "data": "yes_no"
39
+ },
33
40
  "enabled": {
34
41
  "ua": "Чи включена карта?",
35
42
  "col": 6,
@@ -1,32 +1,32 @@
1
- [
2
- {
3
- "id": "1",
4
- "text": "Діючий",
5
- "color": "#1ab394"
6
- },
7
- {
8
- "id": "2",
9
- "text": "Зупинений",
10
- "color": "#ed82c8"
11
- },
12
- {
13
- "id": "3",
14
- "text": "Скасований",
15
- "color": "#4a4a4a"
16
- },
17
- {
18
- "id": "5",
19
- "text": "Проектний",
20
- "color": "#6495ed"
21
- },
22
- {
23
- "id": "7",
24
- "text": "Очікує розгляду",
25
- "color": "#92b8ef"
26
- },
27
- {
28
- "id": "10",
29
- "text": "Архівний",
30
- "color": "#d48428"
31
- }
1
+ [
2
+ {
3
+ "id": "1",
4
+ "text": "Діючий",
5
+ "color": "#1ab394"
6
+ },
7
+ {
8
+ "id": "2",
9
+ "text": "Зупинений",
10
+ "color": "#ed82c8"
11
+ },
12
+ {
13
+ "id": "3",
14
+ "text": "Скасований",
15
+ "color": "#4a4a4a"
16
+ },
17
+ {
18
+ "id": "5",
19
+ "text": "Проектний",
20
+ "color": "#6495ed"
21
+ },
22
+ {
23
+ "id": "7",
24
+ "text": "Очікує розгляду",
25
+ "color": "#92b8ef"
26
+ },
27
+ {
28
+ "id": "10",
29
+ "text": "Архівний",
30
+ "color": "#d48428"
31
+ }
32
32
  ]
@@ -1 +1 @@
1
- select uid, coalesce(coalesce(sur_name,'')||coalesce(' '||user_name,'') ||coalesce(' '||father_name,''),login) as text from admin.users
1
+ select uid, coalesce(coalesce(sur_name,'')||coalesce(' '||user_name,'') ||coalesce(' '||father_name,''),login) as text from admin.users
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengis/gis",
3
- "version": "0.2.100",
3
+ "version": "0.2.102",
4
4
  "type": "module",
5
5
  "author": "Softpro",
6
6
  "main": "./dist/index.js",
@@ -73,4 +73,4 @@
73
73
  "vue-router": "4.5.1",
74
74
  "vuedraggable": "^4.1.0"
75
75
  }
76
- }
76
+ }
@@ -14,6 +14,7 @@ create table if not exists gis.cartocss(
14
14
  group_id text constraint services_group_id_fkey references group_list,
15
15
  is_public boolean default false not null,
16
16
  enabled boolean default true not null,
17
+ is_static boolean not null default false,
17
18
  geom public.geometry
18
19
  );
19
20
 
@@ -23,3 +24,4 @@ alter table gis.cartocss add column if not exists card_auto boolean not null def
23
24
  alter table gis.cartocss add column if not exists card_html text;
24
25
  alter table gis.cartocss add column if not exists card_table text;
25
26
  alter table gis.cartocss add column if not exists card_columns text;
27
+ alter table gis.cartocss add column if not exists is_static boolean not null default false;
@@ -33,13 +33,13 @@ export default async function checkXML(req, reply) {
33
33
 
34
34
  if (uploadStatus.exists === false) {
35
35
  errors.raster += 1;
36
- send(`${idx}/${rasters.length} ERROR: GetRasterStatus: not uploaded (raster:${row.raster_id})`);
36
+ send(`${idx}/${rasters.length} ERROR: GetRasterStatus: not uploaded (raster:${row.raster_id}/${row.name})`);
37
37
  return null;
38
38
  }
39
39
 
40
40
  if (uploadStatus.finished === false) {
41
41
  errors.raster += 1;
42
- send(`${idx}/${rasters.length} ERROR: GetRasterStatus: upload not finished (raster:${row.raster_id})`);
42
+ send(`${idx}/${rasters.length} ERROR: GetRasterStatus: upload not finished (raster:${row.raster_id}/${row.name})`);
43
43
  return null;
44
44
  }
45
45
 
@@ -50,7 +50,7 @@ export default async function checkXML(req, reply) {
50
50
 
51
51
  if (rasterInfo.err) {
52
52
  errors.raster += 1;
53
- send(`${idx}/${rasters.length} ERROR: GetRasterInfo: ${rasterInfo.err} (raster:${row.raster_id})`);
53
+ send(`${idx}/${rasters.length} ERROR: GetRasterInfo: ${rasterInfo.err} (raster:${row.raster_id}/${row.name})`);
54
54
  return null;
55
55
  }
56
56
 
@@ -63,11 +63,11 @@ export default async function checkXML(req, reply) {
63
63
 
64
64
  if (data.err) {
65
65
  errors.raster += 1;
66
- send(`${idx}/${rasters.length} ERROR: RenderTile: ${data.err} (raster:${row.raster_id})`);
66
+ send(`${idx}/${rasters.length} ERROR: RenderTile: ${data.err} (raster:${row.raster_id}/${row.name})`);
67
67
  return null;
68
68
  }
69
69
 
70
- send(`${idx}/${rasters.length} OK: (raster:${row.raster_id})`);
70
+ send(`${idx}/${rasters.length} OK: (raster:${row.raster_id}/${row.name})`);
71
71
  successCount += 1;
72
72
  }),
73
73
  Promise.resolve(),
@@ -87,11 +87,11 @@ export default async function checkXML(req, reply) {
87
87
 
88
88
  if (data.err) {
89
89
  errors.css += 1;
90
- send(`${idx}/${css.length} ERROR: RenderTile: ${data.err} (css:${row.cartocss_id})`);
90
+ send(`${idx}/${css.length} ERROR: RenderTile: ${data.err} (css:${row.cartocss_id}/${row.name})`);
91
91
  return null;
92
92
  }
93
93
 
94
- send(`${idx}/${css.length} OK: (css:${row.cartocss_id})`);
94
+ send(`${idx}/${css.length} OK: (css:${row.cartocss_id}/${row.name})`);
95
95
  successCount += 1;
96
96
  }),
97
97
  Promise.resolve(),
@@ -41,7 +41,7 @@ const editMetadataSchema = {
41
41
  params: {
42
42
  type: 'object',
43
43
  properties: {
44
- type: { type: 'string', enum: ['raster', 'css', 'dataset'] },
44
+ type: { type: 'string', enum: ['raster', 'css', 'dataset', 'service'] },
45
45
  id: { type: 'string' },
46
46
  },
47
47
  required: ['type', 'id'],
@@ -9,7 +9,7 @@ export default async function editMetadata(req, reply) {
9
9
  raster: 'select 1 from gis.rasters where raster_id = $1',
10
10
  css: 'select 1 from gis.cartocss where cartocss_id = $1',
11
11
  dataset: 'select 1 from gis.dataset where dataset_id = $1',
12
-
12
+ service: 'select 1 from gis.services where service_id = $1',
13
13
  }[type];
14
14
 
15
15
  if (!q) {
@@ -6,31 +6,28 @@ import {
6
6
  const excluded = ['created_by', 'created_at', 'updated_by', 'geom', 'id', 'uid', 'updated_at', 'cdate', 'editor_date', 'editor_id'];
7
7
 
8
8
  function getLayerTableQuery({
9
- el, id, point, srids, nogeom,
9
+ el, id, point, nogeom, radius,
10
10
  }, pg = pgClients.client) {
11
11
  const {
12
12
  gcol: geom = 'geom', table, pk = pg.pk[el.table], query: tableQuery, srid, columns,
13
13
  } = el;
14
- const step = srids.length && srids.includes(srid - 0) && srid !== 4326 ? 10 : 0.001;
14
+ const buffer = `ST_Buffer('${point}'::geography, ${radius || 50})::geometry`;
15
15
  const q = `SELECT
16
16
  ${pk} as "id"
17
17
  ,'${el.key}' as "key"
18
18
  ${nogeom ? '' : `,st_asgeojson(${srid !== 4326 ? `st_transform(${geom}, 4326)` : geom})::json as geom`}, ${srid !== 4326 ? `st_transform(${geom}, 4326)` : geom}::box2d as box2d, ${columns ? `row_to_json(t)` : 'null'} as "data"
19
19
  ${point ? `,st_distance(${el.srid !== 4326 ? `st_transform(${geom}, 4326)` : geom},'${point} ') as distance` : ''}
20
20
  FROM ${table} t WHERE ${tableQuery || '1 = 1'} and st_isvalid(${geom}) and st_srid(${geom}) > 0
21
- and ${point ? `case
22
- when ST_GeometryType(${geom}) in ('ST_Polygon','ST_MultiPolygon')
23
- then st_intersects(${srid !== 4326 ? `st_transform(${geom}, 4326)` : geom},st_buffer('${point}',${step}))
24
-
25
- when ST_GeometryType(${geom}) in ('ST_LineString','ST_MultiLineString', 'ST_MultiPoint', 'ST_Point')
26
- then st_distance(${srid !== 4326 ? `st_transform(${geom}, 4326)` : geom},'${point}') < ${step}
27
- else false end` : `${id ? `${pk}='${id.replace(/'/g, "")}'` : '2=2'}`
28
- } ${point ? 'order by distance' : ''} limit 1`;
21
+ and ${point
22
+ ? `case when ST_GeometryType(${geom}) in ('ST_Polygon','ST_MultiPolygon', 'ST_LineString','ST_MultiLineString', 'ST_MultiPoint', 'ST_Point') then st_intersects(${srid !== 4326 ? `st_transform(${geom}, 4326)` : geom}, ${buffer}) else false end`
23
+ : '1=1'}
24
+ and ${id ? `${pk}='${id.replace(/'/g, "")}'` : '2=2'}
25
+ ${point ? 'order by distance' : ''} limit 10`;
29
26
  return q;
30
27
  }
31
28
 
32
29
  async function getLayersData({
33
- id, lng, lat, cartocss, nogeom,
30
+ id, lng, lat, cartocss, nogeom, radius,
34
31
  }, pg = pgClients.client) {
35
32
  if (!(lng && lat) && !id) {
36
33
  return { error: 'not enough params: lat / lng' };
@@ -42,14 +39,12 @@ async function getLayersData({
42
39
 
43
40
  const point = lng && lat ? `srid=4326;point(${lng} ${lat})`.replace(/'/g, "''") : null;
44
41
 
45
- const srids = pg?.queryCache ? await pg.queryCache('select json_agg(srid) from public.spatial_ref_sys').then(el => el.rows?.[0]?.json_agg || []) : [];
46
-
47
42
  const q = cartocss.card_table
48
43
  ? getLayerTableQuery({
49
- el: { key: cartocss.card_table, table: cartocss.card_table, columns: cartocss.card_columns }, id, point, srids, nogeom,
44
+ el: { key: cartocss.card_table, table: cartocss.card_table, columns: cartocss.card_columns }, id, point, nogeom, radius,
50
45
  }, pg)
51
46
  : cartocss.config.filter((el, idx, arr) => el.key && el.table && pg.pk?.[el.table] && arr.map(item => item.table).indexOf(el.table) === idx).map(el => getLayerTableQuery({
52
- el, id, point, srids, nogeom,
47
+ el, id, point, nogeom, radius,
53
48
  }, pg)).join(' union all ');
54
49
 
55
50
  // console.time(q);
@@ -79,6 +74,7 @@ async function getLayersData({
79
74
  : Object.keys(rows[0] || {}).map(key => ({ name: key, format: 'text' }));
80
75
 
81
76
  return {
77
+ ids: rows.map(row => row.id),
82
78
  rows,
83
79
  data,
84
80
  columns,
@@ -88,7 +84,7 @@ async function getLayersData({
88
84
  }
89
85
 
90
86
  async function getTableData({
91
- service, layer, id, user,
87
+ service, layer, id, user, nogeom,
92
88
  }, pg = pgClients.client) {
93
89
  const {
94
90
  source_path: tname, card, template,
@@ -115,7 +111,7 @@ async function getTableData({
115
111
  const filteredColumns = columnNames.filter(name => !excluded.includes(name));
116
112
 
117
113
  const rows = await pg.query(
118
- `SELECT ${pk} as "id", st_asgeojson(geom)::json as geom, geom::box2d as box2d ${filteredColumns?.length > 0 ? ',' : ''} ${filteredColumns.map((n) => `"${n}"`).join(', ')} FROM ${tname} WHERE ${pk} = $1`,
114
+ `SELECT ${pk} as "id", ${!nogeom ? 'st_asgeojson(geom)::json as geom, geom::box2d as box2d' : ''} ${!nogeom && filteredColumns?.length > 0 ? ',' : ''} ${filteredColumns.map((n) => `"${n}"`).join(', ')} FROM ${tname} WHERE ${pk} = $1`,
119
115
  [id],
120
116
  ).then(el => el.rows || []);
121
117
 
@@ -142,7 +138,7 @@ async function getTableData({
142
138
 
143
139
  export default async function mapFormat({ pg = pgClients.client, query = {}, user }, reply) {
144
140
  const {
145
- layer, id, lat, lng, nogeom,
141
+ layer, id, lat, lng, nogeom, radius = 50,
146
142
  } = query;
147
143
 
148
144
  const t1 = Date.now();
@@ -158,7 +154,7 @@ export default async function mapFormat({ pg = pgClients.client, query = {}, use
158
154
  return reply.status(400).send({ error: 'not enough query params: id', code: 400 });
159
155
  }
160
156
 
161
- if (cartocss && !cartocss.config?.length) {
157
+ if (cartocss && !(cartocss.config?.length || cartocss.card_table)) {
162
158
  return reply.status(400).send({ error: 'invalid layer settings: empty config', code: 400 });
163
159
  }
164
160
 
@@ -167,10 +163,10 @@ export default async function mapFormat({ pg = pgClients.client, query = {}, use
167
163
  }
168
164
 
169
165
  const {
170
- rows, data, columns, classifiers, tname, template, error, code = 500, htmlTemplate,
166
+ ids, rows, data, columns, classifiers, tname, template, error, code = 500, htmlTemplate,
171
167
  } = cartocss
172
168
  ? await getLayersData({
173
- cartocss, id, lng, lat, nogeom,
169
+ cartocss, id, lng, lat, radius, nogeom,
174
170
  }, pg)
175
171
  : await getTableData({
176
172
  service, layer, id, user, nogeom,
@@ -210,8 +206,9 @@ export default async function mapFormat({ pg = pgClients.client, query = {}, use
210
206
 
211
207
  const res = {
212
208
  time: Date.now() - t1,
209
+ ids,
213
210
  id: fullRow.id,
214
- rows: fullRow,
211
+ data: fullRow,
215
212
  columns,
216
213
  template,
217
214
  html,
@@ -47,6 +47,29 @@ const schemaInfo = {
47
47
  },
48
48
  };
49
49
 
50
+ const mapFormatSchema = {
51
+ querystring: {
52
+ type: 'object',
53
+ properties: {
54
+ lat: {
55
+ type: 'number',
56
+ minimum: 1,
57
+ maximum: 90,
58
+ },
59
+ lng: {
60
+ type: 'number',
61
+ minimum: -180,
62
+ maximum: 180,
63
+ },
64
+ radius: {
65
+ type: 'number',
66
+ minimum: 1,
67
+ maximum: 1000,
68
+ },
69
+ },
70
+ },
71
+ };
72
+
50
73
  const publicParams = { config: { policy: 'L0' }, schema: schemaInfo, package: 'gis' }; // * L0 === public
51
74
  const privilegedParams = { config: { policy: 'L1', role: 'admin' }, schema: schemaInfo, package: 'gis' }; // ? just auth or admin
52
75
 
@@ -137,6 +160,6 @@ export default async function route(app) {
137
160
  }
138
161
 
139
162
  if (!app.hasRoute({ method: 'GET', url: '/api/map-format' })) {
140
- app.get('/map-format', publicParams, mapFormat);
163
+ app.get('/map-format', { ...publicParams, schema: mapFormatSchema }, mapFormat);
141
164
  }
142
165
  }
@@ -3,7 +3,7 @@ import { createHash } from 'node:crypto';
3
3
  import Sphericalmercator from '@mapbox/sphericalmercator';
4
4
 
5
5
  import {
6
- config, logger, pgClients, dataUpdate,
6
+ config, logger, pgClients,
7
7
  } from '@opengis/fastify-table/utils.js';
8
8
 
9
9
  import mapnik from '../../../plugins/mapnik/funcs/mapnik.js';
@@ -54,7 +54,7 @@ export default async function rtile({
54
54
  : {};
55
55
 
56
56
  const carto = pg.pk?.['gis.cartocss']
57
- ? await pg.queryCache('select cartocss_id, source_path, is_public from gis.cartocss where cartocss_id=$1::text', { args: [id], table: 'gis.cartocss' }).then(el => el.rows?.[0] || {})
57
+ ? 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(el => el.rows?.[0] || {})
58
58
  : {};
59
59
 
60
60
  if (carto.cartocss_id) {
@@ -62,6 +62,7 @@ export default async function rtile({
62
62
  id: carto.cartocss_id,
63
63
  source_path: carto.source_path,
64
64
  is_public: carto.is_public,
65
+ is_static: carto.is_static,
65
66
  type: 'css',
66
67
  });
67
68
  }
@@ -82,7 +83,7 @@ export default async function rtile({
82
83
 
83
84
  try {
84
85
  const ttl = (query.nocache ? '0' : null)
85
- || (data.type === 'css' ? '1h' : null);
86
+ || (data.type === 'css' && !data.is_static ? '1w' : null);
86
87
 
87
88
  const md5 = data.source_path
88
89
  ? createHash('md5').update(data.source_path).digest('hex')
@@ -110,6 +111,7 @@ export default async function rtile({
110
111
  base64_path: base64,
111
112
  raster: !!data.id,
112
113
  carto: data.type === 'css',
114
+ is_static: data.type === 'css' ? data.is_static : true,
113
115
  };
114
116
  }
115
117