@opengis/gis 0.2.52 → 0.2.53

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.
Files changed (158) hide show
  1. package/README.md +5 -5
  2. package/dist/index.css +1 -1
  3. package/dist/index.js +145 -145
  4. package/dist/index.umd.cjs +3 -3
  5. package/module/cls.json +6 -6
  6. package/module/gis/card/gis.metadata.table/index.yml +22 -22
  7. package/module/gis/card/gis.metadata.table/main_info.hbs +20 -20
  8. package/module/gis/card/gis.metadata.table/metadata_info.hbs +27 -27
  9. package/module/gis/card/gis.metadata.table/other.hbs +25 -25
  10. package/module/gis/card/gis.rasters.table/index.yml +11 -11
  11. package/module/gis/card/gis.rasters.table/main_info.hbs +27 -27
  12. package/module/gis/card/gis.registers.table/cls.hbs +36 -36
  13. package/module/gis/card/gis.registers.table/columns.hbs +89 -89
  14. package/module/gis/card/gis.registers.table/filters.hbs +80 -80
  15. package/module/gis/card/gis.registers.table/index.yml +23 -23
  16. package/module/gis/card/gis.registers.table/main_info.hbs +35 -35
  17. package/module/gis/card/gis.registers.table/source.hbs +45 -45
  18. package/module/gis/card/gis.services.table/attributes.hbs +91 -91
  19. package/module/gis/card/gis.services.table/filters.hbs +83 -83
  20. package/module/gis/card/gis.services.table/index.yml +25 -25
  21. package/module/gis/card/gis.services.table/main_info.hbs +27 -27
  22. package/module/gis/card/gis.services.table/source.hbs +25 -25
  23. package/module/gis/cls/bool.yes_no.json +12 -12
  24. package/module/gis/cls/encoding.json +14 -14
  25. package/module/gis/cls/geom_type.json +14 -14
  26. package/module/gis/cls/gis.column_type.json +34 -34
  27. package/module/gis/cls/gis.column_view_type.json +26 -26
  28. package/module/gis/cls/gis.filter_type.json +22 -22
  29. package/module/gis/cls/language.json +10 -10
  30. package/module/gis/cls/meta.service_type.json +42 -42
  31. package/module/gis/cls/ogc.service.json +21 -21
  32. package/module/gis/cls/service_type.json +42 -42
  33. package/module/gis/cls/source_type.json +10 -10
  34. package/module/gis/cls/standarts.json +6 -6
  35. package/module/gis/cls/topic_category.json +106 -106
  36. package/module/gis/cls/update_frequency.json +29 -29
  37. package/module/gis/cls/view.json +21 -21
  38. package/module/gis/form/gis.cartocss.form.json +45 -45
  39. package/module/gis/form/gis.group_list.form.json +17 -17
  40. package/module/gis/form/gis.maps.form.json +61 -61
  41. package/module/gis/form/gis.metadata.form.json +240 -240
  42. package/module/gis/form/gis.ogc_service.form.json +45 -45
  43. package/module/gis/form/gis.rasters.form.json +76 -76
  44. package/module/gis/form/gis.registers.form.json +124 -124
  45. package/module/gis/form/gis.registers_column.form.json +84 -84
  46. package/module/gis/form/gis.registers_filter.form.json +65 -65
  47. package/module/gis/form/gis.services.form.json +111 -111
  48. package/module/gis/form/gis.services_attributes.form.json +75 -75
  49. package/module/gis/form/gis.services_filter.form.json +65 -65
  50. package/module/gis/menu.json +43 -43
  51. package/module/gis/select/pg.columns.parent.sql +6 -6
  52. package/module/gis/select/pg.table_name.sql +17 -17
  53. package/module/gis/select/service_id.sql +1 -1
  54. package/module/gis/table/gis.cartocss.table.json +62 -62
  55. package/module/gis/table/gis.group_list.table.json +35 -35
  56. package/module/gis/table/gis.maps.table.json +108 -108
  57. package/module/gis/table/gis.metadata.table.json +70 -70
  58. package/module/gis/table/gis.ogc_service.table.json +98 -98
  59. package/module/gis/table/gis.rasters.table.json +101 -101
  60. package/module/gis/table/gis.registers.table.json +144 -144
  61. package/module/gis/table/gis.services.table.json +121 -121
  62. package/module/gis/table/site.gis.registers.table.json +88 -88
  63. package/module/gis/table/site.gis.services.table.json +106 -106
  64. package/module/gis/templates/ISO19136_2017_gml_template.xml +330 -330
  65. package/module/gis/tokens.yml +5 -5
  66. package/module/test/cls/bp_build_type.json +37 -37
  67. package/module/test/cls/doc_status.json +31 -31
  68. package/module/test/cls/ts.temp_status.json +18 -18
  69. package/module/test/cls/ts.temp_structure.ts_class.json +49 -49
  70. package/module/test/cls/ts.temp_type.json +9 -9
  71. package/module/test/layer/bp.json +59 -59
  72. package/module/test/layer/bp1.yml +33 -33
  73. package/module/test/layer/individual.yml +53 -53
  74. package/module/test/layer/ts.linking_passport.yml +55 -55
  75. package/module/test/layer/ts.temp_structure.yml +50 -50
  76. package/module/test/map/addr.yml +21 -21
  77. package/module/test/map/bp_myo.json +43 -43
  78. package/module/test/map/bpf.json +43 -43
  79. package/module/test/map/main.json +36 -36
  80. package/module/test/map/mbd.json +91 -91
  81. package/module/test/map/ts.json +52 -52
  82. package/module/test/select/address_id.json +2 -2
  83. package/module/test/select/address_id.sql +7 -7
  84. package/module/test/select/core.user_uid.sql +1 -1
  85. package/module/test/table/data_address.street.table.json +69 -69
  86. package/module/test/table/data_bp_myo.bp.table.json +122 -122
  87. package/package.json +75 -75
  88. package/plugin.js +45 -45
  89. package/server/migrations/cartocss.sql +20 -20
  90. package/server/migrations/maps.sql +30 -30
  91. package/server/migrations/ogc.sql +106 -106
  92. package/server/migrations/rasters.sql +263 -263
  93. package/server/migrations/services.sql +247 -247
  94. package/server/migrations/widgets.sql +20 -20
  95. package/server/plugins/crons.js +21 -21
  96. package/server/plugins/mapnik/funcs/checkRasterFile.js +92 -92
  97. package/server/plugins/mapnik/funcs/mapnik.js +146 -146
  98. package/server/plugins/mapnik/funcs/rootFolder.mjs +8 -8
  99. package/server/plugins/mapnik/map.proto +187 -188
  100. package/server/plugins/vite.js +74 -74
  101. package/server/routes/gis/cartocss/add.cartocss.js +29 -29
  102. package/server/routes/gis/cartocss/get.cartocss.js +12 -12
  103. package/server/routes/gis/dashboard.js +29 -29
  104. package/server/routes/gis/index.mjs +73 -73
  105. package/server/routes/gis/metadata/metadataXML.js +13 -13
  106. package/server/routes/gis/ogc/map.info.point.js +124 -124
  107. package/server/routes/gis/registers/add.registry.js +35 -35
  108. package/server/routes/gis/registers/del.registry.js +14 -14
  109. package/server/routes/gis/registers/funcs/classifiers.js +100 -100
  110. package/server/routes/gis/registers/funcs/columns.js +4 -4
  111. package/server/routes/gis/registers/funcs/content.type.js +9 -9
  112. package/server/routes/gis/registers/funcs/get.info.js +89 -89
  113. package/server/routes/gis/registers/funcs/handleRegistryRequest.js +145 -145
  114. package/server/routes/gis/registers/gis.export.js +148 -148
  115. package/server/routes/gis/registers/gis.registry.js +64 -64
  116. package/server/routes/gis/registers/gis.registry.list.js +59 -59
  117. package/server/routes/gis/registers/insert.columns.js +107 -107
  118. package/server/routes/gis/registers/insert.filters.js +110 -110
  119. package/server/routes/gis/registers/map.registry.js +79 -79
  120. package/server/routes/gis/services/add.service.js +64 -64
  121. package/server/routes/gis/services/del.service.js +12 -12
  122. package/server/routes/gis/services/get.layer.geom.js +27 -27
  123. package/server/routes/gis/services/get.services.col.js +33 -33
  124. package/server/routes/gis/services/get.services.js +84 -84
  125. package/server/routes/gis/services/legend.auto.js +77 -77
  126. package/server/routes/map/controllers/geojson.js +187 -187
  127. package/server/routes/map/controllers/jsonData.js +205 -205
  128. package/server/routes/map/controllers/layerList.js +60 -60
  129. package/server/routes/map/controllers/map.js +123 -123
  130. package/server/routes/map/controllers/mapCatalog.js +72 -72
  131. package/server/routes/map/controllers/mapCatalogAttribute.js +55 -55
  132. package/server/routes/map/controllers/mapFeatures.js +128 -128
  133. package/server/routes/map/controllers/mapFormat.js +85 -85
  134. package/server/routes/map/controllers/mapTiles.js +152 -152
  135. package/server/routes/map/controllers/maps.js +15 -15
  136. package/server/routes/map/controllers/marker_icon.js +43 -43
  137. package/server/routes/map/controllers/vtile.js +172 -172
  138. package/server/routes/map/index.mjs +142 -142
  139. package/server/routes/map/maps/add.map.js +43 -43
  140. package/server/routes/map/maps/del.map.js +18 -18
  141. package/server/routes/map/maps/get.map.js +80 -80
  142. package/server/routes/map/vtile1.js +170 -170
  143. package/server/routes/map/widgets/add.widget.js +38 -38
  144. package/server/routes/map/widgets/del.widget.js +22 -22
  145. package/server/routes/map/widgets/get.widget.js +40 -40
  146. package/server/routes/mapnik/controllers/checkCarto.js +40 -40
  147. package/server/routes/mapnik/controllers/createXml.js +63 -63
  148. package/server/routes/mapnik/controllers/mapnikLogger.js +23 -23
  149. package/server/routes/mapnik/controllers/mapnikStat.js +20 -20
  150. package/server/routes/mapnik/controllers/rasterInfo.js +36 -36
  151. package/server/routes/mapnik/controllers/rtile.js +96 -96
  152. package/server/routes/mapnik/controllers/rtileMBD.js +91 -91
  153. package/server/routes/mapnik/controllers/uploadRaster.js +157 -157
  154. package/server/routes/mapnik/functions/cartoBounds.js +22 -22
  155. package/server/routes/mapnik/functions/uploadXML.js +106 -106
  156. package/server/routes/mapnik/index.js +21 -21
  157. package/server/routes/root.mjs +3 -3
  158. package/utils.js +13 -13
@@ -1,101 +1,101 @@
1
- import { getSelectVal, getSelect, getTemplates } from '@opengis/fastify-table/utils.js';
2
-
3
- export async function attachClassifiers(rowOrRows, classifiers, table) {
4
- const rows = Array.isArray(rowOrRows) ? rowOrRows : [rowOrRows];
5
-
6
- const list = getTemplates(['cls', 'select']);
7
-
8
- // classifiers as object
9
- if (table) {
10
- await Promise.all(rows.map(async row => {
11
- await Promise.all(Object.keys(row).filter(key => classifiers?.[key] || list.map(el => el[0]).includes(`${table}.${key}`) || list.map(el => el[0]).includes(key)).map(async key => {
12
- const clsAsColumn = list.map(el => el[0]).includes(key);
13
- const arr = await getSelectVal({ name: classifiers?.[key] || (clsAsColumn ? key : `${table}.${key}`), values: [row[key]], ar: true });
14
- const val = arr?.find?.(el => el.id && el.id.toString() === row[key].toString());
15
- if (val?.text) { row[`${key}_data`] = val; }
16
- row[key] = val?.text || val || row[key]; // for frontend
17
- row[`${key}_text`] = val?.text || val || row[key]; // legacy?
18
- }));
19
- }));
20
- return rowOrRows;
21
- }
22
-
23
- // classifiers as array of objects
24
- await Promise.all(rows.map(async row => {
25
- (classifiers || []).filter(item => item.classifier && item.name && row[item.name]).map(async ({ name, classifier }) => {
26
- const arr = await getSelectVal({ name: classifier, values: [row[name]], ar: true });
27
- const val = arr?.find?.(el => el.id === row[name]);
28
- if (val?.text) { row[`${name}_data`] = val; }
29
- row[name] = val?.text || val || row[name]; // for frontend
30
- row[`${name}_text`] = val?.text || val || row[name]; // legacy?
31
- });
32
- }));
33
-
34
- /* for (const row of rows) {
35
- for (const { name, classifier } of classifiers) {
36
- const value = row[name];
37
- if (value != null && classifier) {
38
-
39
- const match = await getSelectVal({ name: classifier, values: [value] });
40
- const matchVal = Object.values(match)?.[0]
41
-
42
- if (typeof matchVal === 'object' && matchVal !== null) {
43
- row[`${name}_data`] = matchVal;
44
- } else if (
45
- typeof matchVal === 'string' && matchVal !== null
46
- ) {
47
- row[`${name}_text`] = matchVal;
48
- };
49
-
50
- }
51
- }
52
- } */
53
-
54
- return rowOrRows;
55
- }
56
-
57
- export async function populateFilterOptions({ pg, table, filters, columns, whereConditions }) {
58
- if (!filters?.length || !table || !columns?.length) return;
59
-
60
- const optimizedSQL = `select * from ${table} where ${whereConditions || '1=1'}`;
61
-
62
- await Promise.all(
63
- filters
64
- .filter(
65
- (el) =>
66
- el.id &&
67
- el.type !== "Autocomplete" &&
68
- !el.sql &&
69
- !el.options?.find?.((item) => item.sql)
70
- )
71
- .map(async (el) => {
72
- const cls = el.data ? await getSelect(el.data, pg) : null;
73
-
74
- if (!cls && !el.type?.includes?.("Check")) return;
75
- const { dataTypeID } = (columns || []).find((item) => item.name === el.id) || {};
76
-
77
- const q = pg.pgType[dataTypeID || '']?.includes("[]")
78
- ? `select unnest(${el.id})::text as id,count(*) from (${optimizedSQL})q group by unnest(${el.id}) limit 100`
79
- : `select ${el.id}::text as id,count(*) from (${optimizedSQL})q group by ${el.id} limit 100`;
80
-
81
- const countArr = await pg.queryCache(q, { table });
82
-
83
- if (countArr.timeout) {
84
- Object.assign(el, { timeout: countArr.timeout });
85
- console.warn("timeout filter", table, el.id);
86
- }
87
-
88
- const ids = countArr.rows.map((el1) => el1.id);
89
-
90
- const clsData = await getSelectVal({ pg, values: ids, name: el.data });
91
-
92
- const options = countArr.rows.map((cel) => {
93
- const data = cls?.arr?.find?.(
94
- (c) => c.id?.toString?.() === cel.id?.toString?.()
95
- ) || { text: clsData?.[cel.id]?.text || clsData?.[cel.id] || cel.id };
96
- return { ...cel, id: cel.id === null ? "null" : cel.id, ...data };
97
- });
98
- Object.assign(el, { options });
99
- })
100
- );
1
+ import { getSelectVal, getSelect, getTemplates } from '@opengis/fastify-table/utils.js';
2
+
3
+ export async function attachClassifiers(rowOrRows, classifiers, table) {
4
+ const rows = Array.isArray(rowOrRows) ? rowOrRows : [rowOrRows];
5
+
6
+ const list = getTemplates(['cls', 'select']);
7
+
8
+ // classifiers as object
9
+ if (table) {
10
+ await Promise.all(rows.map(async row => {
11
+ await Promise.all(Object.keys(row).filter(key => classifiers?.[key] || list.map(el => el[0]).includes(`${table}.${key}`) || list.map(el => el[0]).includes(key)).map(async key => {
12
+ const clsAsColumn = list.map(el => el[0]).includes(key);
13
+ const arr = await getSelectVal({ name: classifiers?.[key] || (clsAsColumn ? key : `${table}.${key}`), values: [row[key]], ar: true });
14
+ const val = arr?.find?.(el => el.id && el.id.toString() === row[key].toString());
15
+ if (val?.text) { row[`${key}_data`] = val; }
16
+ row[key] = val?.text || val || row[key]; // for frontend
17
+ row[`${key}_text`] = val?.text || val || row[key]; // legacy?
18
+ }));
19
+ }));
20
+ return rowOrRows;
21
+ }
22
+
23
+ // classifiers as array of objects
24
+ await Promise.all(rows.map(async row => {
25
+ (classifiers || []).filter(item => item.classifier && item.name && row[item.name]).map(async ({ name, classifier }) => {
26
+ const arr = await getSelectVal({ name: classifier, values: [row[name]], ar: true });
27
+ const val = arr?.find?.(el => el.id === row[name]);
28
+ if (val?.text) { row[`${name}_data`] = val; }
29
+ row[name] = val?.text || val || row[name]; // for frontend
30
+ row[`${name}_text`] = val?.text || val || row[name]; // legacy?
31
+ });
32
+ }));
33
+
34
+ /* for (const row of rows) {
35
+ for (const { name, classifier } of classifiers) {
36
+ const value = row[name];
37
+ if (value != null && classifier) {
38
+
39
+ const match = await getSelectVal({ name: classifier, values: [value] });
40
+ const matchVal = Object.values(match)?.[0]
41
+
42
+ if (typeof matchVal === 'object' && matchVal !== null) {
43
+ row[`${name}_data`] = matchVal;
44
+ } else if (
45
+ typeof matchVal === 'string' && matchVal !== null
46
+ ) {
47
+ row[`${name}_text`] = matchVal;
48
+ };
49
+
50
+ }
51
+ }
52
+ } */
53
+
54
+ return rowOrRows;
55
+ }
56
+
57
+ export async function populateFilterOptions({ pg, table, filters, columns, whereConditions }) {
58
+ if (!filters?.length || !table || !columns?.length) return;
59
+
60
+ const optimizedSQL = `select * from ${table} where ${whereConditions || '1=1'}`;
61
+
62
+ await Promise.all(
63
+ filters
64
+ .filter(
65
+ (el) =>
66
+ el.id &&
67
+ el.type !== "Autocomplete" &&
68
+ !el.sql &&
69
+ !el.options?.find?.((item) => item.sql)
70
+ )
71
+ .map(async (el) => {
72
+ const cls = el.data ? await getSelect(el.data, pg) : null;
73
+
74
+ if (!cls && !el.type?.includes?.("Check")) return;
75
+ const { dataTypeID } = (columns || []).find((item) => item.name === el.id) || {};
76
+
77
+ const q = pg.pgType[dataTypeID || '']?.includes("[]")
78
+ ? `select unnest(${el.id})::text as id,count(*) from (${optimizedSQL})q group by unnest(${el.id}) limit 100`
79
+ : `select ${el.id}::text as id,count(*) from (${optimizedSQL})q group by ${el.id} limit 100`;
80
+
81
+ const countArr = await pg.queryCache(q, { table });
82
+
83
+ if (countArr.timeout) {
84
+ Object.assign(el, { timeout: countArr.timeout });
85
+ console.warn("timeout filter", table, el.id);
86
+ }
87
+
88
+ const ids = countArr.rows.map((el1) => el1.id);
89
+
90
+ const clsData = await getSelectVal({ pg, values: ids, name: el.data });
91
+
92
+ const options = countArr.rows.map((cel) => {
93
+ const data = cls?.arr?.find?.(
94
+ (c) => c.id?.toString?.() === cel.id?.toString?.()
95
+ ) || { text: clsData?.[cel.id]?.text || clsData?.[cel.id] || cel.id };
96
+ return { ...cel, id: cel.id === null ? "null" : cel.id, ...data };
97
+ });
98
+ Object.assign(el, { options });
99
+ })
100
+ );
101
101
  }
@@ -1,5 +1,5 @@
1
- export function extractVisibleColumns(columns, mode = "table") {
2
- return columns.filter((col) =>
3
- mode === "card" ? col.hidden_card !== true : col.hidden_register !== true
4
- );
1
+ export function extractVisibleColumns(columns, mode = "table") {
2
+ return columns.filter((col) =>
3
+ mode === "card" ? col.hidden_card !== true : col.hidden_register !== true
4
+ );
5
5
  }
@@ -1,10 +1,10 @@
1
- const ContentType = {
2
- xml: 'application/xml',
3
- shp: 'application/zip',
4
- csv: 'text/csv',
5
- geojson: 'application/vnd.geo+json',
6
- json: 'application/json',
7
- xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
8
- };
9
-
1
+ const ContentType = {
2
+ xml: 'application/xml',
3
+ shp: 'application/zip',
4
+ csv: 'text/csv',
5
+ geojson: 'application/vnd.geo+json',
6
+ json: 'application/json',
7
+ xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
8
+ };
9
+
10
10
  export default ContentType;
@@ -1,89 +1,89 @@
1
- import { pgClients } from '@opengis/fastify-table/utils.js';
2
- import { attachClassifiers } from '../../../gis/registers/funcs/classifiers.js';
3
- const pg = pgClients.client;
4
-
5
- export default async function getInfo({ finalInfo, format }, reply) {
6
- if (!finalInfo) return { error: 'No data found' };
7
-
8
- const table = finalInfo?.table_name;
9
- const queryCondition = finalInfo?.query || '1=1';
10
- const columns = finalInfo?.columns || finalInfo?.attributes || '[]';
11
- const exportable = columns.filter(c => c.is_export);
12
- const selectNames = exportable.map(c => `"${c.name}"`);
13
- const selectSQL = `
14
- SELECT ${selectNames?.length ? selectNames.join(', ') : ''} ${format === 'geojson' || format === 'shp' ? `${selectNames?.length ? ',' : ''} ST_AsGeoJSON(geom)::json as geom` : ``}
15
- FROM ${table}
16
- WHERE ${queryCondition} ${format === 'geojson' || format === 'shp' ? `and geom is not null` : ``}
17
- `;
18
-
19
- if (format === 'shp') {
20
- const { rows: geomTypeRows } = await pg.query(`
21
- SELECT DISTINCT ST_GeometryType(geom) AS geom_type
22
- FROM ${table}
23
- WHERE geom IS NOT NULL
24
- `);
25
- const geometryTypes = geomTypeRows.map(row => row.geom_type);
26
-
27
- const sqlList = geometryTypes.map(type => {
28
- return {
29
- type,
30
- query: `
31
- SELECT ${selectNames.join(', ')} ${selectNames?.length ? ',' : ''} ST_AsGeoJSON(geom)::json as geom
32
- FROM ${table}
33
- WHERE ${queryCondition} AND ST_GeometryType(geom) = '${type}' AND geom IS NOT NULL
34
- `,
35
- };
36
- });
37
-
38
- const { rows: [{ srid }] } = await pg.query(`
39
- SELECT ST_SRID(geom) AS srid
40
- FROM ${table}
41
- WHERE geom IS NOT NULL
42
- LIMIT 1;
43
- `);
44
-
45
- return {
46
- columns: exportable,
47
- table,
48
- srid: srid || 4326,
49
- geomTypes: geometryTypes,
50
- sqlList
51
- };
52
- }
53
-
54
- const { rows } = await pg.query(selectSQL);
55
- if (!rows?.length) {
56
- return reply.status(404).send({ message: 'Немає даних, які можна експортувати', status: 404 });
57
- }
58
-
59
- const classifiers = exportable
60
- .filter(col => col.data && ["select", "badge", "tags"].includes(col.format))
61
- .map(col => ({ name: col.name, classifier: col.data }));
62
-
63
- const rowsWithClassifiers = await attachClassifiers(rows, classifiers);
64
-
65
- const simplifiedRows = rowsWithClassifiers.map(row => {
66
- const newRow = { ...row };
67
-
68
- for (const key of Object.keys(newRow)) {
69
- if (key.endsWith('_data') && typeof newRow[key]?.text === 'string') {
70
- const baseKey = key.replace(/_data$/, '');
71
- newRow[baseKey] = newRow[key].text;
72
- }
73
-
74
- if (key.endsWith('_text') && typeof newRow[key] === 'string') {
75
- const baseKey = key.replace(/_text$/, '');
76
- newRow[baseKey] = newRow[key];
77
- }
78
- }
79
-
80
- return newRow;
81
- });
82
-
83
- return {
84
- rows: simplifiedRows,
85
- data: rows,
86
- columns: exportable,
87
- table
88
- };
89
- }
1
+ import { pgClients } from '@opengis/fastify-table/utils.js';
2
+ import { attachClassifiers } from '../../../gis/registers/funcs/classifiers.js';
3
+ const pg = pgClients.client;
4
+
5
+ export default async function getInfo({ finalInfo, format }, reply) {
6
+ if (!finalInfo) return { error: 'No data found' };
7
+
8
+ const table = finalInfo?.table_name;
9
+ const queryCondition = finalInfo?.query || '1=1';
10
+ const columns = finalInfo?.columns || finalInfo?.attributes || '[]';
11
+ const exportable = columns.filter(c => c.is_export);
12
+ const selectNames = exportable.map(c => `"${c.name}"`);
13
+ const selectSQL = `
14
+ SELECT ${selectNames?.length ? selectNames.join(', ') : ''} ${format === 'geojson' || format === 'shp' ? `${selectNames?.length ? ',' : ''} ST_AsGeoJSON(geom)::json as geom` : ``}
15
+ FROM ${table}
16
+ WHERE ${queryCondition} ${format === 'geojson' || format === 'shp' ? `and geom is not null` : ``}
17
+ `;
18
+
19
+ if (format === 'shp') {
20
+ const { rows: geomTypeRows } = await pg.query(`
21
+ SELECT DISTINCT ST_GeometryType(geom) AS geom_type
22
+ FROM ${table}
23
+ WHERE geom IS NOT NULL
24
+ `);
25
+ const geometryTypes = geomTypeRows.map(row => row.geom_type);
26
+
27
+ const sqlList = geometryTypes.map(type => {
28
+ return {
29
+ type,
30
+ query: `
31
+ SELECT ${selectNames.join(', ')} ${selectNames?.length ? ',' : ''} ST_AsGeoJSON(geom)::json as geom
32
+ FROM ${table}
33
+ WHERE ${queryCondition} AND ST_GeometryType(geom) = '${type}' AND geom IS NOT NULL
34
+ `,
35
+ };
36
+ });
37
+
38
+ const { rows: [{ srid }] } = await pg.query(`
39
+ SELECT ST_SRID(geom) AS srid
40
+ FROM ${table}
41
+ WHERE geom IS NOT NULL
42
+ LIMIT 1;
43
+ `);
44
+
45
+ return {
46
+ columns: exportable,
47
+ table,
48
+ srid: srid || 4326,
49
+ geomTypes: geometryTypes,
50
+ sqlList
51
+ };
52
+ }
53
+
54
+ const { rows } = await pg.query(selectSQL);
55
+ if (!rows?.length) {
56
+ return reply.status(404).send({ message: 'Немає даних, які можна експортувати', status: 404 });
57
+ }
58
+
59
+ const classifiers = exportable
60
+ .filter(col => col.data && ["select", "badge", "tags"].includes(col.format))
61
+ .map(col => ({ name: col.name, classifier: col.data }));
62
+
63
+ const rowsWithClassifiers = await attachClassifiers(rows, classifiers);
64
+
65
+ const simplifiedRows = rowsWithClassifiers.map(row => {
66
+ const newRow = { ...row };
67
+
68
+ for (const key of Object.keys(newRow)) {
69
+ if (key.endsWith('_data') && typeof newRow[key]?.text === 'string') {
70
+ const baseKey = key.replace(/_data$/, '');
71
+ newRow[baseKey] = newRow[key].text;
72
+ }
73
+
74
+ if (key.endsWith('_text') && typeof newRow[key] === 'string') {
75
+ const baseKey = key.replace(/_text$/, '');
76
+ newRow[baseKey] = newRow[key];
77
+ }
78
+ }
79
+
80
+ return newRow;
81
+ });
82
+
83
+ return {
84
+ rows: simplifiedRows,
85
+ data: rows,
86
+ columns: exportable,
87
+ table
88
+ };
89
+ }