@opengis/gis 0.2.118 → 0.2.120

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 (200) hide show
  1. package/README.md +148 -148
  2. package/dist/{CardIcon-FxpK90rl.js → CardIcon-Dx_myDwM.js} +1 -1
  3. package/dist/{EntityCreatePage-Da8XgBKU.js → EntityCreatePage-Ch8NU_Yw.js} +14 -14
  4. package/dist/{EntityEditPage-QktKEAxz.js → EntityEditPage-CRRcW7FL.js} +27 -27
  5. package/dist/EntityTablePage-DY9v1aWL.js +282 -0
  6. package/dist/{ExtentOutlineLayer.vue_vue_type_script_setup_true_lang-Bl5ZwNQX.js → ExtentOutlineLayer.vue_vue_type_script_setup_true_lang-DgQHLSak.js} +1 -1
  7. package/dist/{HeaderActions.vue_vue_type_script_setup_true_lang-CKEep8BL.js → HeaderActions.vue_vue_type_script_setup_true_lang-BQ32ioLC.js} +30 -30
  8. package/dist/{MapSettings-CjJ7WWkn.js → MapSettings-CaGPr5uG.js} +34 -34
  9. package/dist/{MonacoEditor.vue_vue_type_script_setup_true_lang-Bs7gz6Lt.js → MonacoEditor.vue_vue_type_script_setup_true_lang-D3ZPeXMw.js} +92 -73
  10. package/dist/RastersTablePage-CJyO2DoI.js +247 -0
  11. package/dist/{cartocss-C_O8qG3h.js → cartocss-Bhat1m61.js} +297 -295
  12. package/dist/{import-utils-BbZ1gVp-.js → import-utils-BxeYqcn7.js} +33 -33
  13. package/dist/index-Ba6SE4TN.js +10203 -0
  14. package/dist/index.css +1 -1
  15. package/dist/index.js +1 -1
  16. package/dist/index.umd.cjs +41 -41
  17. package/dist/{raster-Du8ZMtjf.js → raster-Cbs1xR5Y.js} +120 -121
  18. package/dist/{register-B2gF-GzA.js → register-D0AsH83v.js} +8 -8
  19. package/dist/{service-BnPCDVwm.js → service-C4nt_DBO.js} +11 -11
  20. package/dist/{vs-datatable-QKks38xL.js → vs-datatable-QG5b0CCL.js} +28 -28
  21. package/module/cls.json +6 -6
  22. package/module/gis/card/gis.metadata.table/index.yml +22 -22
  23. package/module/gis/card/gis.metadata.table/main_info.hbs +20 -20
  24. package/module/gis/card/gis.metadata.table/metadata_info.hbs +27 -27
  25. package/module/gis/card/gis.metadata.table/other.hbs +25 -25
  26. package/module/gis/card/gis.rasters.table/index.yml +11 -11
  27. package/module/gis/card/gis.rasters.table/main_info.hbs +27 -27
  28. package/module/gis/card/gis.registers.table/cls.hbs +36 -36
  29. package/module/gis/card/gis.registers.table/columns.hbs +89 -89
  30. package/module/gis/card/gis.registers.table/filters.hbs +80 -80
  31. package/module/gis/card/gis.registers.table/index.yml +23 -23
  32. package/module/gis/card/gis.registers.table/main_info.hbs +35 -35
  33. package/module/gis/card/gis.registers.table/source.hbs +45 -45
  34. package/module/gis/card/gis.services.table/attributes.hbs +91 -91
  35. package/module/gis/card/gis.services.table/filters.hbs +83 -83
  36. package/module/gis/card/gis.services.table/index.yml +25 -25
  37. package/module/gis/card/gis.services.table/main_info.hbs +27 -27
  38. package/module/gis/card/gis.services.table/source.hbs +25 -25
  39. package/module/gis/cls/bool.yes_no.json +12 -12
  40. package/module/gis/cls/encoding.json +14 -14
  41. package/module/gis/cls/geom_type.json +14 -14
  42. package/module/gis/cls/gis.column_type.json +34 -34
  43. package/module/gis/cls/gis.column_view_type.json +26 -26
  44. package/module/gis/cls/gis.filter_type.json +22 -22
  45. package/module/gis/cls/language.json +10 -10
  46. package/module/gis/cls/meta.service_type.json +42 -42
  47. package/module/gis/cls/ogc.service.json +21 -21
  48. package/module/gis/cls/service_type.json +42 -42
  49. package/module/gis/cls/source_type.json +10 -10
  50. package/module/gis/cls/standarts.json +6 -6
  51. package/module/gis/cls/topic_category.json +106 -106
  52. package/module/gis/cls/update_frequency.json +29 -29
  53. package/module/gis/cls/view.json +21 -21
  54. package/module/gis/form/feedback.answer.form.json +10 -10
  55. package/module/gis/form/gis.cartocss.form.json +54 -54
  56. package/module/gis/form/gis.group_list.form.json +17 -17
  57. package/module/gis/form/gis.maps.form.json +61 -61
  58. package/module/gis/form/gis.metadata.form.json +240 -240
  59. package/module/gis/form/gis.metadata_new.form.json +195 -195
  60. package/module/gis/form/gis.ogc_service.form.json +51 -51
  61. package/module/gis/form/gis.rasters.form.json +76 -76
  62. package/module/gis/form/gis.registers.form.json +124 -124
  63. package/module/gis/form/gis.registers_column.form.json +84 -84
  64. package/module/gis/form/gis.registers_filter.form.json +65 -65
  65. package/module/gis/form/gis.services.form.json +111 -111
  66. package/module/gis/form/gis.services_attributes.form.json +75 -75
  67. package/module/gis/form/gis.services_filter.form.json +65 -65
  68. package/module/gis/menu.json +43 -43
  69. package/module/gis/select/admin.cls.name.sql +2 -2
  70. package/module/gis/select/layer_list.sql +7 -7
  71. package/module/gis/select/layer_list_text.sql +7 -7
  72. package/module/gis/select/pg.column_name.geometry.sql +12 -12
  73. package/module/gis/select/pg.columns.parent.sql +6 -6
  74. package/module/gis/select/pg.table_name.sql +17 -17
  75. package/module/gis/select/service_id.sql +1 -1
  76. package/module/gis/table/gis.cartocss.table.json +74 -74
  77. package/module/gis/table/gis.group_list.table.json +58 -58
  78. package/module/gis/table/gis.maps.table.json +110 -110
  79. package/module/gis/table/gis.metadata.table.json +70 -70
  80. package/module/gis/table/gis.metadata_new.table.json +137 -137
  81. package/module/gis/table/gis.ogc_service.table.json +100 -100
  82. package/module/gis/table/gis.rasters.table.json +101 -101
  83. package/module/gis/table/gis.registers.table.json +143 -143
  84. package/module/gis/table/gis.services.table.json +120 -120
  85. package/module/gis/table/site.gis.registers.table.json +88 -88
  86. package/module/gis/table/site.gis.services.table.json +106 -106
  87. package/module/gis/templates/ISO19136_2017_gml_template.xml +330 -330
  88. package/module/gis/tokens.yml +5 -5
  89. package/module/permissions/form/permissions.users.form.json +151 -151
  90. package/module/permissions/table/gis.permissions.table.json +97 -97
  91. package/module/test/cls/bp_build_type.json +37 -37
  92. package/module/test/cls/ts.temp_status.json +18 -18
  93. package/module/test/cls/ts.temp_structure.ts_class.json +49 -49
  94. package/module/test/cls/ts.temp_type.json +9 -9
  95. package/module/test/layer/bp.json +59 -59
  96. package/module/test/layer/bp1.yml +33 -33
  97. package/module/test/layer/individual.yml +53 -53
  98. package/module/test/layer/ts.linking_passport.yml +55 -55
  99. package/module/test/layer/ts.temp_structure.yml +50 -50
  100. package/module/test/map/addr.yml +21 -21
  101. package/module/test/map/bp_myo.json +43 -43
  102. package/module/test/map/bpf.json +43 -43
  103. package/module/test/map/main.json +37 -37
  104. package/module/test/map/mbd.json +92 -92
  105. package/module/test/map/ts.json +53 -53
  106. package/module/test/select/address_id.json +2 -2
  107. package/module/test/select/address_id.sql +7 -7
  108. package/module/test/table/data_address.street.table.json +69 -69
  109. package/module/test/table/data_bp_myo.bp.table.json +122 -122
  110. package/package.json +75 -75
  111. package/plugin.js +55 -55
  112. package/server/migrations/array_intersect.sql +13 -13
  113. package/server/migrations/cartocss.sql +27 -27
  114. package/server/migrations/group_list.sql +74 -74
  115. package/server/migrations/maps.sql +30 -30
  116. package/server/migrations/metadata.sql +415 -415
  117. package/server/migrations/ogc.sql +106 -106
  118. package/server/migrations/rasters.sql +265 -265
  119. package/server/migrations/services.sql +247 -247
  120. package/server/migrations/services_users_rel.sql +22 -22
  121. package/server/migrations/widgets.sql +20 -20
  122. package/server/plugins/crons.js +21 -21
  123. package/server/plugins/mapnik/funcs/checkRasterFile.js +109 -108
  124. package/server/plugins/mapnik/funcs/mapnik.js +146 -146
  125. package/server/plugins/mapnik/funcs/rootFolder.mjs +8 -8
  126. package/server/plugins/mapnik/map.proto +234 -234
  127. package/server/plugins/vite.js +74 -74
  128. package/server/routes/gis/cartocss/add.cartocss.js +42 -42
  129. package/server/routes/gis/cartocss/get.cartocss.js +50 -50
  130. package/server/routes/gis/checkXML.js +118 -118
  131. package/server/routes/gis/dashboard.js +29 -29
  132. package/server/routes/gis/index.mjs +87 -87
  133. package/server/routes/gis/metadata/editMetadata.js +34 -34
  134. package/server/routes/gis/metadata/metadataXML.js +13 -13
  135. package/server/routes/gis/ogc/map.info.point.js +124 -124
  136. package/server/routes/gis/registers/add.registry.js +35 -35
  137. package/server/routes/gis/registers/del.registry.js +14 -14
  138. package/server/routes/gis/registers/funcs/classifiers.js +100 -100
  139. package/server/routes/gis/registers/funcs/columns.js +4 -4
  140. package/server/routes/gis/registers/funcs/content.type.js +9 -9
  141. package/server/routes/gis/registers/funcs/get.info.js +89 -89
  142. package/server/routes/gis/registers/funcs/handleRegistryRequest.js +146 -146
  143. package/server/routes/gis/registers/gis.export.js +153 -153
  144. package/server/routes/gis/registers/gis.registry.js +64 -64
  145. package/server/routes/gis/registers/gis.registry.list.js +59 -59
  146. package/server/routes/gis/registers/insert.columns.js +107 -107
  147. package/server/routes/gis/registers/insert.filters.js +110 -110
  148. package/server/routes/gis/registers/map.registry.js +79 -79
  149. package/server/routes/gis/services/add.service.js +64 -64
  150. package/server/routes/gis/services/del.service.js +12 -12
  151. package/server/routes/gis/services/get.layer.geom.js +27 -27
  152. package/server/routes/gis/services/get.services.col.js +33 -33
  153. package/server/routes/gis/services/get.services.js +84 -84
  154. package/server/routes/gis/services/legend.auto.js +77 -77
  155. package/server/routes/map/controllers/clearTiles.js +34 -34
  156. package/server/routes/map/controllers/geojson.js +187 -187
  157. package/server/routes/map/controllers/jsonData.js +205 -205
  158. package/server/routes/map/controllers/layerList.js +102 -102
  159. package/server/routes/map/controllers/map.js +123 -123
  160. package/server/routes/map/controllers/mapCatalog.js +72 -72
  161. package/server/routes/map/controllers/mapCatalogAttribute.js +55 -55
  162. package/server/routes/map/controllers/mapFeatures.js +128 -128
  163. package/server/routes/map/controllers/mapFormat.js +222 -222
  164. package/server/routes/map/controllers/mapTiles.js +152 -152
  165. package/server/routes/map/controllers/maps.js +15 -15
  166. package/server/routes/map/controllers/marker_icon.js +43 -43
  167. package/server/routes/map/controllers/vtile.js +172 -172
  168. package/server/routes/map/index.mjs +169 -169
  169. package/server/routes/map/maps/add.map.js +43 -43
  170. package/server/routes/map/maps/del.map.js +18 -18
  171. package/server/routes/map/maps/get.map.js +112 -112
  172. package/server/routes/map/vtile1.js +179 -179
  173. package/server/routes/map/widgets/add.widget.js +38 -38
  174. package/server/routes/map/widgets/del.widget.js +22 -22
  175. package/server/routes/map/widgets/get.widget.js +40 -40
  176. package/server/routes/mapnik/controllers/clearTiles.js +106 -98
  177. package/server/routes/mapnik/controllers/createXml.js +67 -66
  178. package/server/routes/mapnik/controllers/createXmlMulti.js +76 -75
  179. package/server/routes/mapnik/controllers/fileSearch.js +38 -38
  180. package/server/routes/mapnik/controllers/fileStat.js +28 -28
  181. package/server/routes/mapnik/controllers/mapnikLogger.js +29 -29
  182. package/server/routes/mapnik/controllers/mapnikStat.js +20 -20
  183. package/server/routes/mapnik/controllers/rasterInfo.js +54 -53
  184. package/server/routes/mapnik/controllers/readDir.js +22 -22
  185. package/server/routes/mapnik/controllers/rtile.js +150 -150
  186. package/server/routes/mapnik/controllers/uploadRaster.js +157 -157
  187. package/server/routes/mapnik/functions/cartoBounds.js +28 -28
  188. package/server/routes/mapnik/functions/uploadXML.js +110 -110
  189. package/server/routes/mapnik/index.js +27 -27
  190. package/server/routes/permissions/controllers/catalog.permissions.edit.js +22 -22
  191. package/server/routes/permissions/controllers/catalog.permissions.js +7 -7
  192. package/server/routes/permissions/controllers/gis.catalog.js +80 -80
  193. package/server/routes/permissions/controllers/utils/get.permissions.js +59 -59
  194. package/server/routes/permissions/index.mjs +18 -18
  195. package/server/routes/root.mjs +3 -3
  196. package/utils.js +13 -13
  197. package/dist/EntityTablePage-ii-Wz0YZ.js +0 -286
  198. package/dist/FileEdit-C7tteUeG.js +0 -37
  199. package/dist/RastersTablePage-DpKkFOyo.js +0 -359
  200. package/dist/index-4aSsUBB8.js +0 -10020
@@ -1,222 +1,222 @@
1
- import {
2
- pgClients, getTemplate, handlebars, metaFormat,
3
- getMeta,
4
- } from '@opengis/fastify-table/utils.js';
5
-
6
- const excluded = ['created_by', 'created_at', 'updated_by', 'geom', 'id', 'uid', 'updated_at', 'cdate', 'editor_date', 'editor_id'];
7
-
8
- function getLayerTableQuery({
9
- el, id, point, nogeom, radius,
10
- }, pg = pgClients.client) {
11
- const {
12
- gcol: geom = 'geom', table, pk = pg.pk[el.table], query: tableQuery, srid, columns,
13
- } = el;
14
- const buffer = `ST_Buffer('${point}'::geography, ${radius || 50})::geometry`;
15
- const q = `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
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`;
26
- return q;
27
- }
28
-
29
- async function getLayersData({
30
- id, lng, lat, cartocss, nogeom, radius,
31
- }, pg = pgClients.client) {
32
- if (!(lng && lat) && !id) {
33
- return { error: 'not enough params: lat / lng' };
34
- }
35
-
36
- if (!cartocss.config?.length && !cartocss.card_table) {
37
- return { error: 'empty cartocss.config' };
38
- }
39
-
40
- const point = lng && lat ? `srid=4326;point(${lng} ${lat})`.replace(/'/g, "''") : null;
41
-
42
- const q = cartocss.card_table
43
- ? getLayerTableQuery({
44
- el: { key: cartocss.card_table, table: cartocss.card_table, columns: cartocss.card_columns }, id, point, nogeom, radius,
45
- }, pg)
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({
47
- el, id, point, nogeom, radius,
48
- }, pg)).join(' union all ');
49
-
50
- // console.time(q);
51
- const rows = await pg.query(q).then(el => el.rows || []);
52
- // console.timeEnd(q);
53
-
54
- if (!rows.length) {
55
- return { error: 'object not found', code: 404 };
56
- }
57
-
58
- const layerData = rows[0].key ? cartocss.config?.find(el => el.key === rows[0].key) || { table: cartocss?.card_table, columns: cartocss?.card_columns } : {};
59
-
60
- const { data } = rows[0] || {};
61
-
62
- if (rows[0].data && layerData.columns) {
63
- const columnNames = layerData.columns.split(',');
64
- const rowData = Object.keys(rows[0].data).filter(key => columnNames.includes(key)).reduce((acc, key) => ({ ...acc, [key]: rows[0].data[key] }), {});
65
- Object.assign(rows[0], { data: undefined, ...rowData });
66
- }
67
-
68
- const metaColumns = cartocss?.card_table
69
- ? await getMeta({ pg, table: cartocss?.card_table }).then(el => el.columns?.map(({ name }) => ({ name, format: 'text' })) || [])
70
- : [];
71
-
72
- const columns = metaColumns.length && cartocss?.card_columns
73
- ? metaColumns.filter(el => cartocss?.card_columns.includes(el.name))
74
- : Object.keys(rows[0] || {}).map(key => ({ name: key, format: 'text' }));
75
-
76
- return {
77
- ids: rows.map(row => row.id),
78
- rows,
79
- data,
80
- columns,
81
- tname: layerData.table,
82
- htmlTemplate: cartocss.card_html,
83
- };
84
- }
85
-
86
- async function getTableData({
87
- service, layer, id, user, nogeom,
88
- }, pg = pgClients.client) {
89
- const {
90
- source_path: tname, card, template,
91
- } = service || {};
92
-
93
- const columns = (card || []).filter((col) => (user?.uid ? true : !col.is_admin));
94
-
95
- if (!tname) {
96
- return { error: 'missing source_path', code: 400 };
97
- }
98
-
99
- const pk = pg.pk?.[tname];
100
-
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
- }
108
-
109
- const columnNames = columns.map(col => col.name);
110
-
111
- const filteredColumns = columnNames.filter(name => !excluded.includes(name));
112
-
113
- const rows = await pg.query(
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`,
115
- [id],
116
- ).then(el => el.rows || []);
117
-
118
- if (!rows.length) {
119
- return { error: 'object not found', code: 404 };
120
- }
121
-
122
- const classifiers = columns
123
- .filter(col => col.data && ['select', 'badge', 'tags'].includes(col.format))
124
- .reduce((acc, curr) => ({ ...acc, [curr.name]: curr.data }), {});
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, radius = 50,
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 || cartocss.card_table)) {
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
- ids, rows, data, columns, classifiers, tname, template, error, code = 500, htmlTemplate,
167
- } = cartocss
168
- ? await getLayersData({
169
- cartocss, id, lng, lat, radius, 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
-
179
- rows.forEach(row => Object.assign(row, { box2d: undefined, bounds: row.box2d ? row.box2d.replace(/[A-Z\)\(]+/g, '').split(/[ ,]+/).map(el => el - 0) : null }));
180
-
181
- await metaFormat({
182
- rows, table: tname, cls: classifiers, sufix: false,
183
- });
184
- const fullRow = rows[0];
185
-
186
- const result = [];
187
- const filtered = columns.filter(col => !excluded.includes(col.name));
188
- for (let i = 0; i < filtered.length; i += 1) {
189
- const col = filtered[i];
190
-
191
- const name = col.label || col.ua || col.name;
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`]
194
- || fullRow[col.name];
195
-
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]" >
197
- <dt class="text-gray-900">${name}</dt>
198
- <dd class="text-gray-700 sm:col-span-2">${value || '-'}</dd>
199
- </div > `);
200
- }
201
-
202
- const html1 = htmlTemplate ? await handlebars.compile(htmlTemplate)(data || fullRow) : null;
203
-
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);
206
-
207
- const res = {
208
- time: Date.now() - t1,
209
- ids,
210
- id: fullRow.id,
211
- data: fullRow,
212
- columns,
213
- template,
214
- html,
215
- auto,
216
- };
217
- if (service) {
218
- res.cardInterface = service.cardInterface;
219
- }
220
-
221
- return res;
222
- }
1
+ import {
2
+ pgClients, getTemplate, handlebars, metaFormat,
3
+ getMeta,
4
+ } from '@opengis/fastify-table/utils.js';
5
+
6
+ const excluded = ['created_by', 'created_at', 'updated_by', 'geom', 'id', 'uid', 'updated_at', 'cdate', 'editor_date', 'editor_id'];
7
+
8
+ function getLayerTableQuery({
9
+ el, id, point, nogeom, radius,
10
+ }, pg = pgClients.client) {
11
+ const {
12
+ gcol: geom = 'geom', table, pk = pg.pk[el.table], query: tableQuery, srid, columns,
13
+ } = el;
14
+ const buffer = `ST_Buffer('${point}'::geography, ${radius || 50})::geometry`;
15
+ const q = `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
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`;
26
+ return q;
27
+ }
28
+
29
+ async function getLayersData({
30
+ id, lng, lat, cartocss, nogeom, radius,
31
+ }, pg = pgClients.client) {
32
+ if (!(lng && lat) && !id) {
33
+ return { error: 'not enough params: lat / lng' };
34
+ }
35
+
36
+ if (!cartocss.config?.length && !cartocss.card_table) {
37
+ return { error: 'empty cartocss.config' };
38
+ }
39
+
40
+ const point = lng && lat ? `srid=4326;point(${lng} ${lat})`.replace(/'/g, "''") : null;
41
+
42
+ const q = cartocss.card_table
43
+ ? getLayerTableQuery({
44
+ el: { key: cartocss.card_table, table: cartocss.card_table, columns: cartocss.card_columns }, id, point, nogeom, radius,
45
+ }, pg)
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({
47
+ el, id, point, nogeom, radius,
48
+ }, pg)).join(' union all ');
49
+
50
+ // console.time(q);
51
+ const rows = await pg.query(q).then(el => el.rows || []);
52
+ // console.timeEnd(q);
53
+
54
+ if (!rows.length) {
55
+ return { error: 'object not found', code: 404 };
56
+ }
57
+
58
+ const layerData = rows[0].key ? cartocss.config?.find(el => el.key === rows[0].key) || { table: cartocss?.card_table, columns: cartocss?.card_columns } : {};
59
+
60
+ const { data } = rows[0] || {};
61
+
62
+ if (rows[0].data && layerData.columns) {
63
+ const columnNames = layerData.columns.split(',');
64
+ const rowData = Object.keys(rows[0].data).filter(key => columnNames.includes(key)).reduce((acc, key) => ({ ...acc, [key]: rows[0].data[key] }), {});
65
+ Object.assign(rows[0], { data: undefined, ...rowData });
66
+ }
67
+
68
+ const metaColumns = cartocss?.card_table
69
+ ? await getMeta({ pg, table: cartocss?.card_table }).then(el => el.columns?.map(({ name }) => ({ name, format: 'text' })) || [])
70
+ : [];
71
+
72
+ const columns = metaColumns.length && cartocss?.card_columns
73
+ ? metaColumns.filter(el => cartocss?.card_columns.includes(el.name))
74
+ : Object.keys(rows[0] || {}).map(key => ({ name: key, format: 'text' }));
75
+
76
+ return {
77
+ ids: rows.map(row => row.id),
78
+ rows,
79
+ data,
80
+ columns,
81
+ tname: layerData.table,
82
+ htmlTemplate: cartocss.card_html,
83
+ };
84
+ }
85
+
86
+ async function getTableData({
87
+ service, layer, id, user, nogeom,
88
+ }, pg = pgClients.client) {
89
+ const {
90
+ source_path: tname, card, template,
91
+ } = service || {};
92
+
93
+ const columns = (card || []).filter((col) => (user?.uid ? true : !col.is_admin));
94
+
95
+ if (!tname) {
96
+ return { error: 'missing source_path', code: 400 };
97
+ }
98
+
99
+ const pk = pg.pk?.[tname];
100
+
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
+ }
108
+
109
+ const columnNames = columns.map(col => col.name);
110
+
111
+ const filteredColumns = columnNames.filter(name => !excluded.includes(name));
112
+
113
+ const rows = await pg.query(
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`,
115
+ [id],
116
+ ).then(el => el.rows || []);
117
+
118
+ if (!rows.length) {
119
+ return { error: 'object not found', code: 404 };
120
+ }
121
+
122
+ const classifiers = columns
123
+ .filter(col => col.data && ['select', 'badge', 'tags'].includes(col.format))
124
+ .reduce((acc, curr) => ({ ...acc, [curr.name]: curr.data }), {});
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, radius = 50,
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 || cartocss.card_table)) {
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
+ ids, rows, data, columns, classifiers, tname, template, error, code = 500, htmlTemplate,
167
+ } = cartocss
168
+ ? await getLayersData({
169
+ cartocss, id, lng, lat, radius, 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
+
179
+ rows.forEach(row => Object.assign(row, { box2d: undefined, bounds: row.box2d ? row.box2d.replace(/[A-Z\)\(]+/g, '').split(/[ ,]+/).map(el => el - 0) : null }));
180
+
181
+ await metaFormat({
182
+ rows, table: tname, cls: classifiers, sufix: false,
183
+ });
184
+ const fullRow = rows[0];
185
+
186
+ const result = [];
187
+ const filtered = columns.filter(col => !excluded.includes(col.name));
188
+ for (let i = 0; i < filtered.length; i += 1) {
189
+ const col = filtered[i];
190
+
191
+ const name = col.label || col.ua || col.name;
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`]
194
+ || fullRow[col.name];
195
+
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]" >
197
+ <dt class="text-gray-900">${name}</dt>
198
+ <dd class="text-gray-700 sm:col-span-2">${value || '-'}</dd>
199
+ </div > `);
200
+ }
201
+
202
+ const html1 = htmlTemplate ? await handlebars.compile(htmlTemplate)(data || fullRow) : null;
203
+
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);
206
+
207
+ const res = {
208
+ time: Date.now() - t1,
209
+ ids,
210
+ id: fullRow.id,
211
+ data: fullRow,
212
+ columns,
213
+ template,
214
+ html,
215
+ auto,
216
+ };
217
+ if (service) {
218
+ res.cardInterface = service.cardInterface;
219
+ }
220
+
221
+ return res;
222
+ }