@opengis/gis 0.2.86 → 0.2.88

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.
@@ -1,33 +1,33 @@
1
- source_path: data_bp_myo.bp
2
- name: Будівельні паспорти Template
3
- visible: true
4
- style:
5
- type: point
6
- color: '#d970d5'
7
- width: 2
8
- radius: 10
9
- border: 1
10
- opacity: 0.4
11
- popup:
12
- - ua: Назва замовника
13
- name: bp_customer_name
14
- meta: title
15
- - label: Реєстраційний номер БП
16
- name: bp_code
17
- format: badge
18
- - label: Адреса
19
- name: address
20
- card:
21
- - label: Реєстраційний номер БП
22
- name: bp_code
23
- - ua: Адреса
24
- name: address
25
- - ua: Вид будівництва
26
- data: bp_build_type
27
- name: bp_build_type
28
- - ua: Назва замовника
29
- name: bp_customer_name
30
- - ua: Статус документа
31
- data: doc_status
32
- name: bp_doc_status
33
-
1
+ source_path: data_bp_myo.bp
2
+ name: Будівельні паспорти Template
3
+ visible: true
4
+ style:
5
+ type: point
6
+ color: '#d970d5'
7
+ width: 2
8
+ radius: 10
9
+ border: 1
10
+ opacity: 0.4
11
+ popup:
12
+ - ua: Назва замовника
13
+ name: bp_customer_name
14
+ meta: title
15
+ - label: Реєстраційний номер БП
16
+ name: bp_code
17
+ format: badge
18
+ - label: Адреса
19
+ name: address
20
+ card:
21
+ - label: Реєстраційний номер БП
22
+ name: bp_code
23
+ - ua: Адреса
24
+ name: address
25
+ - ua: Вид будівництва
26
+ data: bp_build_type
27
+ name: bp_build_type
28
+ - ua: Назва замовника
29
+ name: bp_customer_name
30
+ - ua: Статус документа
31
+ data: doc_status
32
+ name: bp_doc_status
33
+
package/package.json CHANGED
@@ -1,76 +1,76 @@
1
- {
2
- "name": "@opengis/gis",
3
- "version": "0.2.86",
4
- "type": "module",
5
- "author": "Softpro",
6
- "main": "./dist/index.js",
7
- "files": [
8
- "dist/*",
9
- "module/*",
10
- "server/*",
11
- "plugin.js",
12
- "utils.js",
13
- "config.js",
14
- "README.md",
15
- "LICENSE"
16
- ],
17
- "scripts": {
18
- "dump": "bun ./node_modules/@opengis/fastify-table/dist/script/dump.js",
19
- "migrate": "MIGRATE=true bun ./node_modules/@opengis/fastify-table/dist/script/migrate.js",
20
- "start": "bun server",
21
- "start:kyiv-demo": "bun --env-file=.env.kyiv-demo server",
22
- "kamyanske": "bun --env-file=.env.kamyanske server",
23
- "start:kr": "bun --env-file=.env.kr server",
24
- "poltava": "bun --env-file=.env.poltava --hot server",
25
- "dev:kyiv-demo": "bun --env-file=.env.kyiv-demo --hot server",
26
- "dev:kamyanske": "bun --env-file=.env.kamyanske --hot server",
27
- "dev:kr": "bun --env-file=.env.kr --hot server",
28
- "lint": "eslint src --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts",
29
- "fix": "eslint src --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix",
30
- "patch": "npm version patch && git push && npm publish",
31
- "dev": "bun --hot server",
32
- "front": "vite dev",
33
- "build-lib": "vite build",
34
- "build:admin": "vite build admin",
35
- "build": "vite build",
36
- "preview": "vite preview",
37
- "prod": "NODE_ENV=production node server",
38
- "docs:install": "npm install --prefix ./docs",
39
- "docs:dev": "npm run --prefix ./docs docs:dev",
40
- "docs:build": "npm run --prefix ./docs docs:build",
41
- "docs:preview": "npm run --prefix ./docs docs:preview",
42
- "prepublishOnly": "npm run build"
43
- },
44
- "dependencies": {
45
- "@mapbox/sphericalmercator": "1.2.0",
46
- "carto": "0.16.3"
47
- },
48
- "peerDependencies": {
49
- "@opengis/fastify-table": "^2.0.32"
50
- },
51
- "resolutions": {
52
- "rollup": "4.30.0"
53
- },
54
- "devDependencies": {
55
- "@opengis/core": "^0.0.23",
56
- "@opengis/fastify-table": "^2.0.135",
57
- "@opengis/filter": "0.1.31",
58
- "@opengis/form": "^0.0.103",
59
- "@opengis/table": "^0.0.27",
60
- "@vitejs/plugin-vue": "^5.2.4",
61
- "axios": "^1.13.5",
62
- "eslint": "^8.57.1",
63
- "eslint-config-airbnb": "19.0.4",
64
- "eslint-plugin-import": "^2.32.0",
65
- "eslint-plugin-vue": "^9.33.0",
66
- "@vue/eslint-config-typescript": "^12.0.0",
67
- "vue-eslint-parser": "^10.4.0",
68
- "lucide-vue-next": "^0.514.0",
69
- "sass-embedded": "1.86.3",
70
- "typescript": "^5.9.3",
71
- "vite": "^6.4.1",
72
- "vue": "^3.5.28",
73
- "vue-router": "4.5.1",
74
- "vuedraggable": "^4.1.0"
75
- }
76
- }
1
+ {
2
+ "name": "@opengis/gis",
3
+ "version": "0.2.88",
4
+ "type": "module",
5
+ "author": "Softpro",
6
+ "main": "./dist/index.js",
7
+ "files": [
8
+ "dist/*",
9
+ "module/*",
10
+ "server/*",
11
+ "plugin.js",
12
+ "utils.js",
13
+ "config.js",
14
+ "README.md",
15
+ "LICENSE"
16
+ ],
17
+ "scripts": {
18
+ "dump": "bun ./node_modules/@opengis/fastify-table/dist/script/dump.js",
19
+ "migrate": "MIGRATE=true bun ./node_modules/@opengis/fastify-table/dist/script/migrate.js",
20
+ "start": "bun server",
21
+ "start:kyiv-demo": "bun --env-file=.env.kyiv-demo server",
22
+ "kamyanske": "bun --env-file=.env.kamyanske server",
23
+ "start:kr": "bun --env-file=.env.kr server",
24
+ "poltava": "bun --env-file=.env.poltava --hot server",
25
+ "dev:kyiv-demo": "bun --env-file=.env.kyiv-demo --hot server",
26
+ "dev:kamyanske": "bun --env-file=.env.kamyanske --hot server",
27
+ "dev:kr": "bun --env-file=.env.kr --hot server",
28
+ "lint": "eslint src --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts",
29
+ "fix": "eslint src --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix",
30
+ "patch": "npm version patch && git push && npm publish",
31
+ "dev": "bun --hot server",
32
+ "front": "vite dev",
33
+ "build-lib": "vite build",
34
+ "build:admin": "vite build admin",
35
+ "build": "vite build",
36
+ "preview": "vite preview",
37
+ "prod": "NODE_ENV=production node server",
38
+ "docs:install": "npm install --prefix ./docs",
39
+ "docs:dev": "npm run --prefix ./docs docs:dev",
40
+ "docs:build": "npm run --prefix ./docs docs:build",
41
+ "docs:preview": "npm run --prefix ./docs docs:preview",
42
+ "prepublishOnly": "npm run build"
43
+ },
44
+ "dependencies": {
45
+ "@mapbox/sphericalmercator": "1.2.0",
46
+ "carto": "0.16.3"
47
+ },
48
+ "peerDependencies": {
49
+ "@opengis/fastify-table": "^2.0.32"
50
+ },
51
+ "resolutions": {
52
+ "rollup": "4.30.0"
53
+ },
54
+ "devDependencies": {
55
+ "@opengis/core": "^0.0.23",
56
+ "@opengis/fastify-table": "^2.0.135",
57
+ "@opengis/filter": "0.1.31",
58
+ "@opengis/form": "^0.0.103",
59
+ "@opengis/table": "^0.0.27",
60
+ "@vitejs/plugin-vue": "^5.2.4",
61
+ "axios": "^1.13.5",
62
+ "eslint": "^8.57.1",
63
+ "eslint-config-airbnb": "19.0.4",
64
+ "eslint-plugin-import": "^2.32.0",
65
+ "eslint-plugin-vue": "^9.33.0",
66
+ "@vue/eslint-config-typescript": "^12.0.0",
67
+ "vue-eslint-parser": "^10.4.0",
68
+ "lucide-vue-next": "^0.514.0",
69
+ "sass-embedded": "1.86.3",
70
+ "typescript": "^5.9.3",
71
+ "vite": "^6.4.1",
72
+ "vue": "^3.5.28",
73
+ "vue-router": "4.5.1",
74
+ "vuedraggable": "^4.1.0"
75
+ }
76
+ }
@@ -19,3 +19,7 @@ create table if not exists gis.cartocss(
19
19
 
20
20
  alter table gis.cartocss add column if not exists geom public.geometry;
21
21
  alter table gis.cartocss add column if not exists source_path text;
22
+ alter table gis.cartocss add column if not exists card_auto boolean not null default false;
23
+ alter table gis.cartocss add column if not exists card_html text;
24
+ alter table gis.cartocss add column if not exists card_table text;
25
+ alter table gis.cartocss add column if not exists card_columns text;
@@ -261,4 +261,6 @@ COMMENT ON COLUMN gis.rasters.raster_zoom IS 'Зум для відображен
261
261
  COMMENT ON COLUMN gis.rasters.srid IS 'Просторова система координат';
262
262
  COMMENT ON COLUMN gis.rasters.center IS 'Центр покриття';
263
263
  COMMENT ON COLUMN gis.rasters.bbox IS 'Область покриття сервісу';
264
- COMMENT ON COLUMN gis.rasters.group_id IS 'id групи';
264
+ COMMENT ON COLUMN gis.rasters.group_id IS 'id групи';
265
+
266
+ ALTER TABLE gis.rasters add COLUMN if not exists isadmin boolean NOT NULL default false;
@@ -206,6 +206,7 @@ message GetRasterInfoData {
206
206
  repeated string bands = 11;
207
207
  int64 color_depth = 12;
208
208
  string compression = 13;
209
+ bool xml = 14;
209
210
  }
210
211
 
211
212
  message GetRasterInfoOut {
@@ -14,6 +14,7 @@ export default async function addCartocss(req, reply) {
14
14
  }
15
15
 
16
16
  const sourcePath = body.source_path || cartocss.source_path;
17
+
17
18
  const config = body.config || cartocss.config;
18
19
  const style = body.style || cartocss.style;
19
20
 
@@ -7,6 +7,8 @@ const { RenderTile } = mapnik();
7
7
 
8
8
  const { prefix = '/api' } = config;
9
9
 
10
+ const exclude = ['created_at', 'updated_at', 'created_by', 'updated_by'];
11
+
10
12
  export default async function checkCarto({
11
13
  pg = pgClients.client, params,
12
14
  }, reply) {
@@ -15,12 +17,16 @@ export default async function checkCarto({
15
17
  return reply.status(400).send({ error: 'mapnik server address needed', code: 400 });
16
18
  }
17
19
 
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]);
20
+ // extract all columns, migrations-agnostic
21
+ const cartocss = await pg.query('select *, ARRAY[ST_XMin(geom), ST_YMin(geom), ST_XMax(geom), ST_YMax(geom)] as bounds, st_asgeojson(geom)::json as geom from gis.cartocss where cartocss_id=$1', [params.id]).then(el => el.rows?.[0]);
19
22
 
20
23
  if (!cartocss) {
21
24
  return reply.status(404).send({ error: `cartocss not found: ${params.id}`, code: 404 });
22
25
  }
23
26
 
27
+ // filter system columns
28
+ Object.keys(cartocss).filter(key => exclude.includes(key)).forEach(key => delete cartocss[key]);
29
+
24
30
  const rtile = await RenderTile({
25
31
  name: params.id,
26
32
  width: 256,
@@ -34,6 +40,7 @@ export default async function checkCarto({
34
40
  return {
35
41
  time: Date.now() - time,
36
42
  ...cartocss,
43
+ info: !!(cartocss.card_auto || (cartocss.card_html && cartocss.card_table)),
37
44
  url: `${prefix}/gis-rtile/${params.id}/{z}/{x}/{y}.png`,
38
45
  bounds,
39
46
  render: !!rtile.base64,
@@ -1,43 +1,181 @@
1
1
  import {
2
2
  pgClients, getTemplate, handlebars, metaFormat,
3
+ getMeta,
3
4
  } from '@opengis/fastify-table/utils.js';
4
5
 
5
- export default async function mapFormat(req, reply) {
6
- const { pg = pgClients.client, query = {}, user } = req;
7
- const { layer, id } = query;
8
- const time = Date.now();
6
+ const excluded = ['created_by', 'created_at', 'updated_by', 'geom', 'id', 'uid', 'updated_at', 'cdate', 'editor_date', 'editor_id'];
9
7
 
10
- if (!layer || !id) return reply.status(404).send('not enough params: layer,id,map is required');
8
+ function getLayerTableQuery({
9
+ el, id, point, srids, nogeom,
10
+ }, pg = pgClients.client) {
11
+ const {
12
+ gcol: geom = 'geom', table, pk = pg.pk[el.table], query: tableQuery, srid, columns,
13
+ } = el;
14
+ const step = srids.length && srids.includes(srid - 0) && srid !== 4326 ? 10 : 0.001;
15
+ return `SELECT
16
+ ${pk} as "id"
17
+ ,'${el.key}' as "key"
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
+ ${point ? `,st_distance(${el.srid !== 4326 ? `st_transform(${geom}, 4326)` : geom},'${point} ') as distance` : ''}
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`;
29
+ }
30
+
31
+ async function getLayersData({
32
+ id, lng, lat, cartocss, nogeom,
33
+ }, pg = pgClients.client) {
34
+ if (!(lng && lat) && !id) {
35
+ return { error: 'not enough params: lat / lng' };
36
+ }
37
+
38
+ if (!cartocss.config?.length) {
39
+ return { error: 'empty cartocss.config' };
40
+ }
41
+
42
+ const point = lng && lat ? `srid=4326;point(${lng} ${lat})`.replace(/'/g, "''") : null;
43
+
44
+ const srids = pg?.queryCache ? await pg.queryCache('select json_agg(srid) from public.spatial_ref_sys').then(el => el.rows?.[0]?.json_agg || []) : [];
45
+
46
+ const q = cartocss.card_table
47
+ ? getLayerTableQuery({
48
+ el: { key: cartocss.card_table, table: cartocss.card_table, columns: cartocss.card_columns }, id, point, srids, nogeom,
49
+ }, pg)
50
+ : 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({
51
+ el, id, point, srids, nogeom,
52
+ }, pg)).join(' union all ');
53
+
54
+ // console.time(q);
55
+ const rows = await pg.query(q).then(el => el.rows || []);
56
+ // console.timeEnd(q);
57
+
58
+ if (!rows.length) {
59
+ return { error: 'object not found', code: 404 };
60
+ }
61
+
62
+ const layerData = rows[0].key ? cartocss.config?.find(el => el.key === rows[0].key) || { table: cartocss?.card_table, columns: cartocss?.card_columns } : {};
11
63
 
12
- const service = await getTemplate('layer', layer) || (pg.tlist.includes('gis.services') ? await pg.query('SELECT * FROM gis.services WHERE service_id = $1', [layer]).then(res => res.rows[0]) : null);
64
+ if (rows[0].data && layerData.columns) {
65
+ const columnNames = layerData.columns.split(',');
66
+ const rowData = Object.keys(rows[0].data).filter(key => columnNames.includes(key)).reduce((acc, key) => ({ ...acc, [key]: rows[0].data[key] }), {});
67
+ Object.assign(rows[0], { data: undefined, ...rowData });
68
+ }
69
+
70
+ const metaColumns = cartocss?.card_table && cartocss?.card_columns
71
+ ? await getMeta({ pg, table: cartocss?.card_table }).then(el => el.columns?.map(({ name }) => ({ name, format: 'text' })) || [])
72
+ : [];
73
+
74
+ const columns = metaColumns.length && cartocss?.card_columns
75
+ ? metaColumns.filter(el => cartocss?.card_columns.includes(el.name))
76
+ : Object.keys(rows[0] || {}).map(key => ({ name: key, format: 'text' }));
77
+
78
+ return {
79
+ rows,
80
+ columns,
81
+ tname: layerData.table,
82
+ htmlTemplate: cartocss.card_html,
83
+ };
84
+ }
13
85
 
86
+ async function getTableData({
87
+ service, layer, id, user,
88
+ }, pg = pgClients.client) {
14
89
  const {
15
- source_path: tname, cardInterface, card, template,
16
- } = service;
90
+ source_path: tname, card, template,
91
+ } = service || {};
17
92
 
18
93
  const columns = (card || []).filter((col) => (user?.uid ? true : !col.is_admin));
19
- if (!tname) return reply.status(404).send('missing source_path');
94
+
95
+ if (!tname) {
96
+ return { error: 'missing source_path', code: 400 };
97
+ }
20
98
 
21
99
  const pk = pg.pk?.[tname];
22
- if (!pk) return reply.status(404).send('missing pk');
23
100
 
24
- if (!columns) return reply.status(404).send('columns setting not found');
101
+ if (!pk) {
102
+ return { error: 'missing pk', code: 400 };
103
+ }
104
+
105
+ if (!columns) {
106
+ return { error: 'columns setting not found', code: 404 };
107
+ }
25
108
 
26
109
  const columnNames = columns.map(col => col.name);
27
- const excluded = ['created_by', 'created_at', 'updated_by', 'geom', 'id', 'uid', 'updated_at', 'cdate', 'editor_date', 'editor_id'];
110
+
28
111
  const filteredColumns = columnNames.filter(name => !excluded.includes(name));
29
112
 
30
113
  const rows = await pg.query(
31
- `SELECT ${pk} as "id", geom::json, geom::box2d as box2d ${filteredColumns?.length > 0 ? ',' : ''} ${filteredColumns.map((n) => `"${n}"`).join(', ')} FROM ${tname} WHERE ${pk} = $1`,
114
+ `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`,
32
115
  [id],
33
116
  ).then(el => el.rows || []);
34
117
 
35
- if (!rows.length) return reply.status(404).send('object not found');
118
+ if (!rows.length) {
119
+ return { error: 'object not found', code: 404 };
120
+ }
36
121
 
37
122
  const classifiers = columns
38
123
  .filter(col => col.data && ['select', 'badge', 'tags'].includes(col.format))
39
124
  .reduce((acc, curr) => ({ ...acc, [curr.name]: curr.data }), {});
40
125
 
126
+ const htmlTemplate = pg?.pk?.['admin.templates'] && service?.card_mode === 'html'
127
+ ? await pg.query('select body from admin.templates where name=$1 limit 1', [template || layer]).then(el => el.rows?.[0]?.body)
128
+ : null;
129
+
130
+ return {
131
+ rows,
132
+ columns,
133
+ classifiers,
134
+ tname,
135
+ htmlTemplate,
136
+ };
137
+ }
138
+
139
+ export default async function mapFormat({ pg = pgClients.client, query = {}, user }, reply) {
140
+ const {
141
+ layer, id, lat, lng, nogeom,
142
+ } = query;
143
+
144
+ const t1 = Date.now();
145
+
146
+ if (!layer) {
147
+ return reply.status(400).send({ error: 'not enough query params: layer', code: 400 });
148
+ }
149
+
150
+ const service = await getTemplate('layer', layer) || (pg.pk?.['gis.services'] ? await pg.query('SELECT * FROM gis.services WHERE service_id = $1', [layer]).then(el => el.rows[0]) : null);
151
+ const cartocss = pg.pk?.['gis.cartocss'] ? await pg.query('SELECT * FROM gis.cartocss WHERE cartocss_id = $1', [layer]).then(el => el.rows[0]) : null;
152
+
153
+ if (!cartocss && !id) {
154
+ return reply.status(400).send({ error: 'not enough query params: id', code: 400 });
155
+ }
156
+
157
+ if (cartocss && !cartocss.config?.length) {
158
+ return reply.status(400).send({ error: 'invalid layer settings: empty config', code: 400 });
159
+ }
160
+
161
+ if (cartocss && !(lat && lng) && !id) {
162
+ return reply.status(400).send({ error: 'not enough query params: lat and lng / id', code: 400 });
163
+ }
164
+
165
+ const {
166
+ rows, columns, classifiers, tname, template, error, code = 500, htmlTemplate,
167
+ } = cartocss
168
+ ? await getLayersData({
169
+ cartocss, id, lng, lat, nogeom,
170
+ }, pg)
171
+ : await getTableData({
172
+ service, layer, id, user, nogeom,
173
+ }, pg);
174
+
175
+ if (error) {
176
+ return reply.status(code).send({ error, code });
177
+ }
178
+
41
179
  rows.forEach(row => Object.assign(row, { box2d: undefined, bounds: row.box2d ? row.box2d.replace(/[A-Z\)\(]+/g, '').split(/[ ,]+/).map(el => el - 0) : null }));
42
180
 
43
181
  await metaFormat({
@@ -51,34 +189,32 @@ export default async function mapFormat(req, reply) {
51
189
  const col = filtered[i];
52
190
 
53
191
  const name = col.label || col.ua || col.name;
54
- const value = (col.format === 'date' ? new Date(fullRow[col.name]).toLocaleDateString('uk-UA') : null) || fullRow[`${col.name}_data`]?.text
55
- || fullRow[`${col.name}_text`]
192
+ const value = (col.format === 'date' ? new Date(fullRow[col.name]).toLocaleDateString('uk-UA') : null) || fullRow[`${col.name} _data`]?.text
193
+ || fullRow[`${col.name} _text`]
56
194
  || fullRow[col.name];
57
195
 
58
- result.push(`<div class="grid grid-cols-1 gap-1 py-3 sm:grid-cols-3 sm:gap-4 even:bg-gray-50 text-[12px]">
196
+ result.push(`< div class="grid grid-cols-1 gap-1 py-3 sm:grid-cols-3 sm:gap-4 even:bg-gray-50 text-[12px]" >
59
197
  <dt class="text-gray-900">${name}</dt>
60
198
  <dd class="text-gray-700 sm:col-span-2">${value || '-'}</dd>
61
- </div>`);
199
+ </div > `);
62
200
  }
63
201
 
64
- const htmlTemplate = pg?.pk?.['admin.templates'] && service.card_mode === 'html'
65
- ? await pg.query('select body from admin.templates where name=$1 limit 1', [template || layer]).then(el => el.rows?.[0]?.body)
66
- : null;
67
-
68
202
  const html1 = htmlTemplate ? await handlebars.compile(htmlTemplate)(fullRow) : null;
69
203
 
70
- const html = html1 || `<dl class="divide-y divide-gray-100 py-[5px]">${result.join('')}</dl>`;
204
+ const auto = service ? service?.card_mode === 'list' : cartocss?.card_auto;
205
+ const html = html1 || (auto ? `< dl class="divide-y divide-gray-100 py-[5px]" > ${result.join('')}</dl > ` : undefined);
71
206
 
72
207
  const res = {
73
- time: Date.now() - time,
74
- id,
208
+ time: Date.now() - t1,
209
+ id: fullRow.id,
75
210
  rows: fullRow,
76
211
  columns,
77
212
  template,
78
213
  html,
214
+ auto,
79
215
  };
80
216
  if (service) {
81
- res.cardInterface = cardInterface;
217
+ res.cardInterface = service.cardInterface;
82
218
  }
83
219
 
84
220
  return res;
@@ -1,7 +1,7 @@
1
1
  import { pgClients } from "@opengis/fastify-table/utils.js";
2
2
 
3
3
  export default async function cartoBounds({ id, dataset }, pg = pgClients.client) {
4
- const sqlBounds = dataset.map(el => ({ tbl: el.table.split('.'), geom: el.gcol || 'geom' })).map(({ tbl, geom }) => `select ST_EstimatedExtent('${tbl[0]}','${tbl[1]}', '${geom}')`);
4
+ const sqlBounds = dataset.map(el => ({ tbl: el.table.replace(/"/g, "").split('.'), geom: el.gcol || 'geom' })).map(({ tbl, geom }) => `select ST_EstimatedExtent('${tbl[0]}','${tbl[1]}', '${geom}')`);
5
5
  // const sqlBounds = dataset.map(el => ({ srid: el.srid || 4326, tbl: el.table.split('.'), geom: el.gcol || 'geom' })).map(({ tbl, geom, srid }) => `select st_transform(st_setsrid(ST_EstimatedExtent('${tbl[0]}','${tbl[1]}', '${geom}'),${srid}),4326) as st_estimatedextent`);
6
6
 
7
7
  const geom = await pg.query(