@opengis/gis 0.2.167 → 0.2.169

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 (249) hide show
  1. package/dist/{CardIcon-golqfa-Y.js → CardIcon-xkRDr3_E.js} +1 -1
  2. package/dist/{EntityTablePage-BhmxePgR.js → EntityTablePage-D1IR5Bmq.js} +1 -1
  3. package/dist/{ExtentOutlineLayer.vue_vue_type_script_setup_true_lang-BFa27smR.js → ExtentOutlineLayer.vue_vue_type_script_setup_true_lang-BJKIgAkD.js} +1 -1
  4. package/dist/{HeaderActions.vue_vue_type_script_setup_true_lang-Dp0MjgnU.js → HeaderActions.vue_vue_type_script_setup_true_lang-BU8__ouG.js} +1 -1
  5. package/dist/{MapSettings-F_DT3xKl.js → MapSettings-DIOlNpt6.js} +1 -1
  6. package/dist/{RastersTablePage-3rXQ0baG.js → RastersTablePage-OD1VqHP8.js} +1 -1
  7. package/dist/{cartocss-CN-UrS7V.js → cartocss-BiamDcNB.js} +5 -5
  8. package/dist/{import-utils-F5ErbNz1.js → import-utils-CvUG1jV0.js} +1 -1
  9. package/dist/{index-CdB0VXro.js → index-C6W8IkTm.js} +1224 -1221
  10. package/dist/index.css +1 -1
  11. package/dist/index.js +1 -1
  12. package/dist/index.umd.cjs +53 -40
  13. package/dist/{raster-DWmiWlf7.js → raster-BbIiZGoX.js} +3 -3
  14. package/dist/{register-D1jLD0hK.js → register-Dt2QoLZ3.js} +3 -3
  15. package/dist/service-CdUYntMi.js +3472 -0
  16. package/dist/{vs-datatable-BWItxbtK.js → vs-datatable-BELnJrfM.js} +2 -3
  17. package/module/gis/card/gis.metadata.table/index.yml +22 -22
  18. package/module/gis/card/gis.rasters.table/index.yml +11 -11
  19. package/module/gis/card/gis.registers.table/index.yml +23 -23
  20. package/module/gis/card/gis.services.table/index.yml +25 -25
  21. package/module/gis/cls/bool.yes_no.json +12 -12
  22. package/module/gis/cls/encoding.json +14 -14
  23. package/module/gis/cls/geom_type.json +14 -14
  24. package/module/gis/cls/gis.column_type.json +34 -34
  25. package/module/gis/cls/gis.column_view_type.json +26 -26
  26. package/module/gis/cls/gis.filter_type.json +22 -22
  27. package/module/gis/cls/language.json +10 -10
  28. package/module/gis/cls/meta.service_type.json +42 -42
  29. package/module/gis/cls/ogc.service.json +21 -21
  30. package/module/gis/cls/source_type.json +10 -10
  31. package/module/gis/cls/standarts.json +6 -6
  32. package/module/gis/cls/topic_category.json +106 -106
  33. package/module/gis/cls/update_frequency.json +29 -29
  34. package/module/gis/cls/view.json +21 -21
  35. package/module/gis/form/feedback.answer.form.json +10 -10
  36. package/module/gis/form/gis.cartocss.form.json +64 -64
  37. package/module/gis/form/gis.group_list.form.json +17 -17
  38. package/module/gis/form/gis.maps.form.json +61 -61
  39. package/module/gis/form/gis.metadata.form.json +240 -240
  40. package/module/gis/form/gis.metadata_new.form.json +195 -195
  41. package/module/gis/form/gis.ogc_service.form.json +51 -51
  42. package/module/gis/form/gis.rasters.form.json +76 -76
  43. package/module/gis/form/gis.registers.form.json +124 -124
  44. package/module/gis/form/gis.registers_column.form.json +84 -84
  45. package/module/gis/form/gis.registers_filter.form.json +65 -65
  46. package/module/gis/form/gis.services.form.json +111 -111
  47. package/module/gis/form/gis.services_attributes.form.json +75 -75
  48. package/module/gis/form/gis.services_filter.form.json +65 -65
  49. package/module/gis/menu.json +43 -43
  50. package/module/gis/select/admin.cls.name.sql +9 -9
  51. package/module/gis/select/layer_list.sql +7 -7
  52. package/module/gis/select/layer_list_text.sql +7 -7
  53. package/module/gis/select/pg.column_name.geometry.sql +12 -12
  54. package/module/gis/select/pg.columns.parent.sql +6 -6
  55. package/module/gis/select/pg.table_name.sql +17 -17
  56. package/module/gis/select/service_id.sql +1 -1
  57. package/module/gis/select/srid.sql +7 -7
  58. package/module/gis/table/gis.cartocss.table.json +74 -74
  59. package/module/gis/table/gis.group_list.table.json +58 -58
  60. package/module/gis/table/gis.maps.table.json +110 -110
  61. package/module/gis/table/gis.metadata.table.json +70 -70
  62. package/module/gis/table/gis.metadata_new.table.json +137 -137
  63. package/module/gis/table/gis.ogc_service.table.json +100 -100
  64. package/module/gis/table/gis.rasters.table.json +113 -113
  65. package/module/gis/table/gis.registers.table.json +143 -143
  66. package/module/gis/table/gis.services.table.json +120 -120
  67. package/module/gis/table/site.gis.registers.table.json +88 -88
  68. package/module/gis/table/site.gis.services.table.json +106 -106
  69. package/module/gis/templates/ISO19136_2017_gml_template.xml +330 -330
  70. package/module/gis/tokens.yml +5 -5
  71. package/module/permissions/form/permissions.users.form.json +151 -151
  72. package/module/permissions/table/gis.permissions.table.json +97 -97
  73. package/module/test/map/addr.json +303 -0
  74. package/module/test/map/{addr.yml → addr1.yml} +3 -1
  75. package/module/test/select/address.str_id.sql +3 -0
  76. package/package.json +10 -10
  77. package/plugin.js +21 -12
  78. package/server/plugins/mapnik/funcs/checkRasterFile.js +1 -3
  79. package/server/routes/cartocss/cartocss.route.js +31 -0
  80. package/server/routes/cartocss/cartocss.route.test.js +79 -0
  81. package/server/routes/cartocss/cartocss.schema.js +73 -0
  82. package/server/routes/{gis/cartocss → cartocss/functions}/add.cartocss.js +8 -11
  83. package/server/routes/{gis/cartocss → cartocss/functions}/get.cartocss.js +11 -13
  84. package/server/routes/gis/functions/checkXML.js +107 -0
  85. package/server/routes/gis/functions/dashboard.js +24 -0
  86. package/server/routes/gis/gis.route.js +26 -0
  87. package/server/routes/gis/gis.route.test.js +34 -0
  88. package/server/routes/gis/gis.schema.js +1 -0
  89. package/server/routes/map/{controllers → functions}/clearTiles.js +9 -8
  90. package/server/routes/map/{controllers → functions}/geojson.js +43 -43
  91. package/server/routes/map/{controllers → functions}/gis.convert.js +15 -23
  92. package/server/routes/map/{controllers → functions}/gis.icon.js +23 -10
  93. package/server/routes/map/{controllers → functions}/jsonData.js +72 -71
  94. package/server/routes/map/{controllers → functions}/layerList.js +17 -17
  95. package/server/routes/map/{controllers → functions}/map.js +8 -9
  96. package/server/routes/map/{controllers → functions}/mapCatalog.js +7 -7
  97. package/server/routes/map/functions/mapCatalogAttribute.js +54 -0
  98. package/server/routes/map/{controllers → functions}/mapFeatures.js +22 -18
  99. package/server/routes/map/{controllers → functions}/mapFormat.js +25 -28
  100. package/server/routes/map/{controllers → functions}/mapTiles.js +39 -30
  101. package/server/routes/map/{controllers → functions}/maps.js +3 -3
  102. package/server/routes/map/{controllers → functions}/marker_icon.js +1 -1
  103. package/server/routes/map/{controllers → functions}/parseGeoFile.js +10 -11
  104. package/server/routes/map/{controllers → functions}/pointHeight.js +3 -7
  105. package/server/routes/map/{controllers → functions}/vtile.js +5 -3
  106. package/server/routes/map/{vtile1.js → functions/vtile1.js} +39 -33
  107. package/server/routes/map/map.route.js +280 -0
  108. package/server/routes/map/map.route.test.js +503 -0
  109. package/server/routes/map/map.schema.js +356 -0
  110. package/server/routes/mapnik/{controllers → functions}/clearTiles.js +26 -29
  111. package/server/routes/mapnik/{controllers → functions}/createXml.js +17 -20
  112. package/server/routes/mapnik/{controllers → functions}/createXmlMulti.js +11 -15
  113. package/server/routes/mapnik/{controllers → functions}/fileSearch.js +6 -9
  114. package/server/routes/mapnik/functions/fileStat.js +28 -0
  115. package/server/routes/mapnik/{controllers → functions}/pretile.js +29 -35
  116. package/server/routes/mapnik/{controllers → functions}/rasterInfo.js +19 -10
  117. package/server/routes/mapnik/{controllers → functions}/readDir.js +4 -4
  118. package/server/routes/mapnik/functions/rtile.js +164 -0
  119. package/server/routes/mapnik/{controllers → functions}/uploadRaster.js +19 -24
  120. package/server/routes/mapnik/functions/uploadXML.js +27 -0
  121. package/server/routes/mapnik/mapnik.route.js +102 -0
  122. package/server/routes/mapnik/mapnik.route.test.js +371 -0
  123. package/server/routes/mapnik/mapnik.schema.mjs +190 -0
  124. package/server/routes/mapnik.prefixless/functions/mapnikLogger.js +31 -0
  125. package/server/routes/{mapnik/controllers → mapnik.prefixless/functions}/mapnikStat.js +7 -5
  126. package/server/routes/mapnik.prefixless/mapnik.prefixless.route.js +20 -0
  127. package/server/routes/mapnik.prefixless/mapnik.prefixless.route.test.js +91 -0
  128. package/server/routes/mapnik.prefixless/mapnik.prefixless.schema.mjs +27 -0
  129. package/server/routes/maps/functions/add.map.js +42 -0
  130. package/server/routes/{map/maps → maps/functions}/del.map.js +6 -7
  131. package/server/routes/{map/maps → maps/functions}/get.map.js +12 -11
  132. package/server/routes/maps/maps.route.js +58 -0
  133. package/server/routes/maps/maps.route.test.js +231 -0
  134. package/server/routes/maps/maps.schema.js +10 -0
  135. package/server/routes/metadata/functions/editMetadata.js +35 -0
  136. package/server/routes/metadata/functions/metadataXML.js +19 -0
  137. package/server/routes/metadata/metadata.route.js +26 -0
  138. package/server/routes/metadata/metadata.route.test.js +47 -0
  139. package/server/routes/metadata/metadata.schema.js +53 -0
  140. package/server/routes/{gis/ogc → ogc/functions}/map.info.point.js +22 -29
  141. package/server/routes/ogc/ogc.route.js +21 -0
  142. package/server/routes/ogc/ogc.route.test.js +54 -0
  143. package/server/routes/ogc/ogc.schema.js +16 -0
  144. package/server/routes/permissions/functions/catalog.permissions.edit.js +20 -0
  145. package/server/routes/permissions/functions/catalog.permissions.js +13 -0
  146. package/server/routes/permissions/{controllers → functions}/gis.catalog.js +10 -10
  147. package/server/routes/permissions/permissions.route.js +35 -0
  148. package/server/routes/permissions/permissions.route.test.js +35 -0
  149. package/server/routes/permissions/permissions.schema.js +44 -0
  150. package/server/routes/registers/functions/add.registry.js +37 -0
  151. package/server/routes/{gis/registers/funcs → registers/functions}/classifiers.js +2 -2
  152. package/server/routes/{gis/registers → registers/functions}/del.registry.js +5 -5
  153. package/server/routes/{gis/registers/funcs → registers/functions}/get.info.js +9 -5
  154. package/server/routes/{gis/registers → registers/functions}/gis.export.js +27 -21
  155. package/server/routes/{gis/registers → registers/functions}/gis.registry.js +22 -15
  156. package/server/routes/{gis/registers → registers/functions}/gis.registry.list.js +12 -10
  157. package/server/routes/{gis/registers/funcs → registers/functions}/handleRegistryRequest.js +12 -11
  158. package/server/routes/registers/registers.route.js +80 -0
  159. package/server/routes/registers/registers.route.test.js +145 -0
  160. package/server/routes/registers/registers.schema.js +246 -0
  161. package/server/routes/{gis/services → services/functions}/add.service.js +14 -16
  162. package/server/routes/services/functions/create.route.js +93 -0
  163. package/server/routes/{gis/services → services/functions}/del.service.js +5 -5
  164. package/server/routes/{gis/services → services/functions}/get.service.users.js +15 -13
  165. package/server/routes/services/functions/get.services.col.js +34 -0
  166. package/server/routes/{gis/services → services/functions}/get.services.js +21 -16
  167. package/server/routes/services/services.route.js +76 -0
  168. package/server/routes/services/services.route.test.js +168 -0
  169. package/server/routes/services/services.schema.js +278 -0
  170. package/server/routes/widgets/functions/add.widget.js +39 -0
  171. package/server/routes/widgets/functions/del.widget.js +18 -0
  172. package/server/routes/{map/widgets → widgets/functions}/get.widget.js +12 -11
  173. package/server/routes/widgets/widgets.route.js +61 -0
  174. package/server/routes/widgets/widgets.route.test.js +144 -0
  175. package/server/routes/widgets/widgets.schema.js +25 -0
  176. package/dist/service-JGNtth-y.js +0 -2593
  177. package/module/cls.json +0 -7
  178. package/module/gis/card/gis.metadata.table/main_info.hbs +0 -21
  179. package/module/gis/card/gis.metadata.table/metadata_info.hbs +0 -28
  180. package/module/gis/card/gis.metadata.table/other.hbs +0 -26
  181. package/module/gis/card/gis.rasters.table/main_info.hbs +0 -27
  182. package/module/gis/card/gis.registers.table/cls.hbs +0 -36
  183. package/module/gis/card/gis.registers.table/columns.hbs +0 -89
  184. package/module/gis/card/gis.registers.table/filters.hbs +0 -80
  185. package/module/gis/card/gis.registers.table/main_info.hbs +0 -35
  186. package/module/gis/card/gis.registers.table/source.hbs +0 -45
  187. package/module/gis/card/gis.services.table/attributes.hbs +0 -91
  188. package/module/gis/card/gis.services.table/filters.hbs +0 -83
  189. package/module/gis/card/gis.services.table/main_info.hbs +0 -27
  190. package/module/gis/card/gis.services.table/source.hbs +0 -26
  191. package/module/test/cls/bp_build_type.json +0 -37
  192. package/module/test/cls/doc_status.json +0 -32
  193. package/module/test/cls/ts.temp_status.json +0 -18
  194. package/module/test/cls/ts.temp_structure.ts_class.json +0 -50
  195. package/module/test/cls/ts.temp_type.json +0 -10
  196. package/module/test/layer/bp.json +0 -60
  197. package/module/test/layer/bp1.yml +0 -33
  198. package/module/test/layer/individual.yml +0 -54
  199. package/module/test/layer/ts.linking_passport.yml +0 -56
  200. package/module/test/layer/ts.temp_structure.yml +0 -51
  201. package/module/test/map/bp_myo.json +0 -44
  202. package/module/test/map/bpf.json +0 -44
  203. package/module/test/map/main.json +0 -39
  204. package/module/test/map/mbd.json +0 -92
  205. package/module/test/map/ts.json +0 -53
  206. package/module/test/select/address_id.json +0 -3
  207. package/module/test/select/address_id.sql +0 -8
  208. package/module/test/select/core.user_uid.sql +0 -1
  209. package/module/test/table/data_address.street.table.json +0 -70
  210. package/module/test/table/data_bp_myo.bp.table.json +0 -123
  211. package/server/routes/gis/checkXML.js +0 -117
  212. package/server/routes/gis/dashboard.js +0 -29
  213. package/server/routes/gis/index.mjs +0 -92
  214. package/server/routes/gis/metadata/editMetadata.js +0 -34
  215. package/server/routes/gis/metadata/metadataXML.js +0 -13
  216. package/server/routes/gis/registers/add.registry.js +0 -35
  217. package/server/routes/gis/registers/insert.columns.js +0 -107
  218. package/server/routes/gis/registers/insert.filters.js +0 -110
  219. package/server/routes/gis/services/create.route.js +0 -96
  220. package/server/routes/gis/services/get.services.col.js +0 -33
  221. package/server/routes/map/controllers/mapCatalogAttribute.js +0 -56
  222. package/server/routes/map/index.mjs +0 -259
  223. package/server/routes/map/maps/add.map.js +0 -43
  224. package/server/routes/map/widgets/add.widget.js +0 -39
  225. package/server/routes/map/widgets/del.widget.js +0 -23
  226. package/server/routes/mapnik/controllers/fileStat.js +0 -28
  227. package/server/routes/mapnik/controllers/mapnikLogger.js +0 -29
  228. package/server/routes/mapnik/controllers/rtile.js +0 -167
  229. package/server/routes/mapnik/index.js +0 -40
  230. package/server/routes/permissions/controllers/catalog.permissions.edit.js +0 -22
  231. package/server/routes/permissions/controllers/catalog.permissions.js +0 -8
  232. package/server/routes/permissions/index.mjs +0 -18
  233. /package/server/routes/map/{controllers/pin → pin}/circle1.svg +0 -0
  234. /package/server/routes/map/{controllers/pin → pin}/circle2.svg +0 -0
  235. /package/server/routes/map/{controllers/pin → pin}/none.svg +0 -0
  236. /package/server/routes/map/{controllers/pin → pin}/pin.svg +0 -0
  237. /package/server/routes/map/{controllers/pin → pin}/pin1.svg +0 -0
  238. /package/server/routes/map/{controllers/pin → pin}/pin2.svg +0 -0
  239. /package/server/routes/map/{controllers/pin → pin}/pin3.svg +0 -0
  240. /package/server/routes/map/{controllers/pin → pin}/pin4.svg +0 -0
  241. /package/server/routes/map/{controllers/pin → pin}/pin5.svg +0 -0
  242. /package/server/routes/map/{controllers/pin → pin}/pin6.svg +0 -0
  243. /package/server/routes/map/{controllers/pin → pin}/pin7.svg +0 -0
  244. /package/server/routes/permissions/{controllers/utils → functions}/get.permissions.js +0 -0
  245. /package/server/routes/{gis/registers/funcs → registers/functions}/columns.js +0 -0
  246. /package/server/routes/{gis/registers/funcs → registers/functions}/content.type.js +0 -0
  247. /package/server/routes/{gis/registers → registers/functions}/map.registry.js +0 -0
  248. /package/server/routes/{gis/services → services/functions}/get.layer.geom.js +0 -0
  249. /package/server/routes/{gis/services → services/functions}/legend.auto.js +0 -0
@@ -0,0 +1,53 @@
1
+ export const editMetadataSchema = {
2
+ params: {
3
+ type: 'object',
4
+ required: ['type', 'id'],
5
+ properties: {
6
+ type: { type: 'string', enum: ['raster', 'css', 'dataset', 'service'] },
7
+ id: { type: 'string', pattern: '^([\\d\\w]+)$' },
8
+ },
9
+ },
10
+ body: {
11
+ type: 'object',
12
+ // additionalProperties: false,
13
+ properties: {
14
+ geom: {
15
+ type: 'object',
16
+ properties: {
17
+ type: { type: 'string', enum: ['Point', 'LineString', 'Polygon'] },
18
+ coordinates: { type: 'array' },
19
+ },
20
+ required: ['type', 'coordinates'],
21
+ },
22
+ description: { type: 'string' },
23
+ group_id: { type: 'string' },
24
+ keywords: {
25
+ type: 'array',
26
+ items: { type: 'string' },
27
+ },
28
+ is_public: { type: 'boolean' },
29
+ is_active: { type: 'boolean' },
30
+ service_key: { type: 'string' },
31
+ producer: { type: 'string' },
32
+ category: { type: 'string' },
33
+ license: { type: 'string' },
34
+ year: { type: 'string' },
35
+ service_url: { type: 'string' },
36
+ metadata_url: { type: 'string' },
37
+ thumbnail_url: { type: 'string' },
38
+ query: { type: 'string' },
39
+ },
40
+ },
41
+ };
42
+
43
+ export const metadataXMLSchema = {
44
+ params: {
45
+ type: 'object',
46
+ required: ['id'],
47
+ properties: {
48
+ id: { type: 'string', pattern: '^([\\d\\w]+)$' },
49
+ },
50
+ },
51
+ };
52
+
53
+ export default null;
@@ -1,3 +1,4 @@
1
+ import { BadRequestError, NotFoundError } from '@opengis/fastify-table/errors.js';
1
2
  import {
2
3
  pgClients, handlebars, getMeta, getTemplate, getFilterSQL,
3
4
  } from '@opengis/fastify-table/utils.js';
@@ -12,26 +13,26 @@ const columnType = {
12
13
  'timestamp with time zone': 'date',
13
14
  };
14
15
 
15
- export default async function mapInfoPoint(req, reply) {
16
- const { pg = pgClients.client, query = {} } = req;
17
- const {
18
- x, y, layers, index = 0,
19
- } = query;
16
+ export default async function mapInfoPoint({ x, y, layers, index = 0, sql }, pg = pgClients.client) {
20
17
  const time = Date.now();
21
18
 
22
19
  if (!x || !y || !layers) {
23
- return reply.status(400).send('not enough query params: x, y, layers are required');
20
+ throw BadRequestError('not enough query params: x, y, layers are required');
24
21
  }
25
22
 
26
- const rows = pg?.pk?.['gis.ogc_service'] ? await pg.query('select * from gis.ogc_service WHERE enabled and table_name is not null and ogc_service_id = any($1)', [layers.split(',')]).then(el => el.rows || []) : [];
23
+ const rows = pg?.pk?.['gis.ogc_service'] ? await pg.query('select * from gis.ogc_service WHERE enabled and table_name is not null and ogc_service_id = any($1)', [layers.split(',')]).then(r => r.rows || []) : [];
27
24
 
28
25
  if (!rows.length) {
29
- return reply.status(404).send('layers not found');
26
+ throw NotFoundError('layers not found');
30
27
  }
31
28
 
32
- const point = `srid=4326;point(${x} ${y})`; // 30, 50
29
+ const args = [];
33
30
 
34
- const srids = pg.queryCache ? await pg.queryCache('select json_agg(srid) as srids from spatial_ref_sys').then(el => el.rows?.[0]?.srids || {}) : {};
31
+ // 30, 50
32
+ args.push(x);
33
+ args.push(y);
34
+
35
+ const srids = pg.queryCache ? await pg.queryCache('select json_agg(srid) as srids from spatial_ref_sys').then(r => r.rows?.[0]?.srids || {}) : {};
35
36
 
36
37
  await Promise.all(rows.map(async (layer, idx) => {
37
38
  const { table_name: source, ogc_service_id: layerId } = layer;
@@ -39,7 +40,7 @@ export default async function mapInfoPoint(req, reply) {
39
40
  const meta = await getMeta({ pg, table: loadTable?.table || source });
40
41
  const { geom = 'geom' } = meta || {};
41
42
  const { table = source, columns = meta?.columns } = loadTable || {};
42
- const { srid, x } = await pg.query(`select st_srid(${geom}) as srid, st_x(st_pointonsurface(${geom})) as x from ${table} where geom is not null limit 1`).then(el => el.rows?.[0] || {});
43
+ const { srid, x } = await pg.query(`select st_srid(${geom}) as srid, st_x(st_pointonsurface(${geom})) as x from ${table} where geom is not null limit 1`).then(r => r.rows?.[0] || {});
43
44
 
44
45
  const cls = columns
45
46
  ?.filter(el => el.name && el.data)
@@ -66,41 +67,33 @@ export default async function mapInfoPoint(req, reply) {
66
67
  const qList = unique.map((el) => ({
67
68
  query: `select ${el.pk}::text as pk, '${el.layer}' as layer, '${el.table}' as table,
68
69
  row_to_json(t) as data,
69
- st_distance(${el.geomColumn},'${point.replace(/'/g, "''")}') as distance,
70
+ st_distance(${el.geomColumn}, st_setsrid(st_makepoint($1,$2),4326)) as distance,
70
71
  st_asgeojson(${el.geomColumn})::json as geom from (${el.optimizedSQL}) t
71
72
  where 1=1`,
72
73
  queryCount: `select 1 from (${el.optimizedSQL})t where 1=1`,
73
- /* where: `case
74
- when ST_GeometryType(${el.geomColumn}) in ('ST_Polygon','ST_MultiPolygon')
75
- then st_intersects(${el.geomColumn},st_buffer('${point.replace(/'/g, "''")}',${el.step}))
76
-
77
- when ST_GeometryType(${el.geomColumn}) in ('ST_Line','ST_MultiLineString', 'ST_MultiPoint', 'ST_Point')
78
- then st_distance(${el.geomColumn},'${point.replace(/'/g, "''")}') < ${el.step}
79
- else false
80
- end`, */
81
- where: `${el.geomColumn} && '${point.replace(/'/g, "''")}'`,
74
+ where: `${el.geomColumn} && st_setsrid(st_makepoint($1,$2),4326)`,
82
75
  }));
83
76
 
84
- const q = qList.map(el => `${el.query} and ${el.where}`).join(' union all ').concat(` order by distance limit 1 offset ${Math.max(+index || 0, 0)}`);
77
+ const q = qList.map(el => `${el.query} and ${el.where}`).join(' union all ').concat(` order by distance limit 1 offset $3::bigint`);
85
78
 
86
79
  const qCount = qList.map(el => `${el.queryCount} and ${el.where}`).join(' union all ');
87
80
 
88
- if (query.sql === '1') return q;
89
- if (query.sql === '2') return qCount;
81
+ if (sql === 1 && process.platform === 'win32') return q;
82
+ if (sql === 2 && process.platform === 'win32') return qCount;
90
83
 
91
- const count = await pg.query(qCount).then(el => el.rowCount);
84
+ const count = await pg.query(qCount, args).then(el => el.rowCount);
92
85
 
93
- const row = await pg.query(q).then(el => el.rows?.[0]);
86
+ const row = await pg.query(q, args.concat([Math.max(+index || 0, 0)])).then(r => r.rows?.[0]);
94
87
 
95
88
  if (!row) {
96
- return reply.status(404).send('object not found');
89
+ throw NotFoundError('object not found');
97
90
  }
98
91
 
99
- const { columns = [] } = await getMeta({ pg, table: row.table }) || {};
92
+ const columns = row.table ? await getMeta({ pg, table: row.table }).then(r => r.columns || []) : [];
100
93
  const fields = columns.map(({ name, dataTypeID, title }) => ({ name, type: columnType[pg.pgType?.[dataTypeID] || 'text'], label: title || name }));
101
94
 
102
95
  const htmlTemplate = pg?.pk?.['admin.templates'] && row.layer && false
103
- ? await pg.query('select body from admin.templates where name=$1 limit 1', [row.layer]).then(el => el.rows?.[0]?.body)
96
+ ? await pg.query('select body from admin.templates where name=$1 limit 1', [row.layer]).then(r => r.rows?.[0]?.body)
104
97
  : rows.find(el => el.ogc_service_id === row.layer)?.html;
105
98
 
106
99
  const html = await handlebars.compile(htmlTemplate || 'template not found')(row.data);
@@ -0,0 +1,21 @@
1
+ import mapInfoPoint from './functions/map.info.point.js';
2
+
3
+ import {
4
+ mapInfoPointSchema,
5
+ } from './ogc.schema.js';
6
+
7
+ const publicParams = { config: { policy: 'L0', package: 'gis' } };
8
+
9
+ async function route(app) {
10
+ app.get('/map-info-point', { ...publicParams, schema: mapInfoPointSchema }, async ({ query, pg }) => {
11
+ const result = await mapInfoPoint({
12
+ x: query.x,
13
+ y: query.y,
14
+ layers: query.layers,
15
+ index: query.index,
16
+ sql: query.sql
17
+ }, pg);
18
+ return result;
19
+ });
20
+ }
21
+ export default route;
@@ -0,0 +1,54 @@
1
+ import { beforeAll, describe, expect, test } from 'vitest';
2
+
3
+ import { getPGAsync } from '@opengis/fastify-table/utils.js';
4
+
5
+ import { build, injectWithHeaders } from '../../../test/helper.js';
6
+
7
+ let pg;
8
+
9
+ describe('OGC routes', () => {
10
+ beforeAll(async () => {
11
+ await build();
12
+
13
+ pg = await getPGAsync();
14
+ });
15
+
16
+ test('GET /map-info-point validates query', async () => {
17
+ const { id, table } = await pg.query('select ogc_service_id as id, table_name as table from gis.ogc_service WHERE enabled and table_name is not null limit 1').then(r => r.rows[0]) || {};
18
+ expect(table).toBeDefined();
19
+ const { x, y } = await pg.query(`select st_x(st_pointonsurface(geom)) as x, st_y(st_pointonsurface(geom)) as y from ${table} where geom is not null limit 1`).then(r => r.rows[0]) || {};
20
+ expect(x).toBeDefined();
21
+ expect(y).toBeDefined();
22
+ const res = await injectWithHeaders({
23
+ url: '/api/map-info-point',
24
+ query: {
25
+ x,
26
+ y,
27
+ layers: id,
28
+ // index: 0,
29
+ },
30
+ });
31
+
32
+ expect(res.statusCode).toBe(200);
33
+ expect(res.body).toHaveProperty('time');
34
+ expect(res.body).toHaveProperty('index');
35
+ expect(res.body.index).toBeTypeOf('number');
36
+ expect(res.body).toHaveProperty('count');
37
+ expect(res.body.count).toBeTypeOf('number');
38
+ expect(res.body.count).toBeGreaterThan(0);
39
+ expect(res.body).toHaveProperty('data');
40
+ expect(res.body).toHaveProperty('fields');
41
+ expect(res.body.data).toHaveProperty('layer');
42
+ expect(res.body.data).toHaveProperty('geom');
43
+ expect(res.body.data).toHaveProperty('id');
44
+ expect(res.body.data).toHaveProperty('distance');
45
+ expect(res.body.data).toHaveProperty('data');
46
+ expect(res.body.data.data).toHaveProperty('geom');
47
+ expect(res.body.fields).toBeInstanceOf(Array);
48
+ expect(res.body.fields.length).toBeGreaterThan(0);
49
+ expect(res.body.fields[0]).toHaveProperty('name');
50
+ expect(res.body.fields[0]).toHaveProperty('type');
51
+ expect(res.body.fields[0]).toHaveProperty('label');
52
+ expect(res.body).toHaveProperty('html');
53
+ });
54
+ });
@@ -0,0 +1,16 @@
1
+ export const mapInfoPointSchema = {
2
+ querystring: {
3
+ type: 'object',
4
+ additionalProperties: false,
5
+ properties: {
6
+ sql: { type: 'number', enum: [1, 2] },
7
+ x: { type: 'number', minimum: -180, maximum: 180 }, // longitude
8
+ y: { type: 'number', minimum: -90, maximum: 90 }, // latitude
9
+ layers: { type: 'string' },
10
+ index: { type: 'number', minimum: 0 },
11
+ },
12
+ required: ['x', 'y', 'layers'],
13
+ },
14
+ };
15
+
16
+ export default null;
@@ -0,0 +1,20 @@
1
+ import { BadRequestError } from "@opengis/fastify-table/errors.js";
2
+ import { pgClients } from "@opengis/fastify-table/utils.js";
3
+
4
+ export default async function catalogPermissionsEdit({ uid, body }, pg = pgClients.client) {
5
+ if (!uid) {
6
+ throw BadRequestError('not enough params: id');
7
+ }
8
+
9
+ if (!body?.length) {
10
+ throw BadRequestError('body is empty');
11
+ }
12
+
13
+ await pg.query(`delete from gis.services_users_rel where user_id = $1`, [uid]);
14
+
15
+ const promises = body.map(el => pg.query(`insert into gis.services_users_rel (service_id,user_id,created_by,actions) values ($1,$2,$2,$3)`, [el.service_id, uid, el.actions]));
16
+
17
+ await Promise.all(promises);
18
+
19
+ return { status: 201, message: `Inserted ${body?.length} permissions` };
20
+ }
@@ -0,0 +1,13 @@
1
+ import { BadRequestError } from "@opengis/fastify-table/errors.js";
2
+ import { pgClients } from "@opengis/fastify-table/utils.js";
3
+
4
+ export default async function catalogPermissions({ uid }, pg = pgClients.client) {
5
+ if (!uid) {
6
+ throw BadRequestError('not enough params: id');
7
+ }
8
+
9
+ const { total, layer_list } = await pg.query(
10
+ `select count(*)::int as total, array_agg(json_build_object('service_id',service_id,'actions',actions)) as layer_list from gis.services_users_rel where user_id=$1`, [uid]).then(r => r.rows?.[0] || {});
11
+
12
+ return { total, layer_list };
13
+ }
@@ -1,16 +1,15 @@
1
- import getPermissions from './utils/get.permissions.js';
1
+ import { pgClients } from '@opengis/fastify-table/utils.js';
2
2
 
3
- export default async function gisCatalog(req, reply) {
4
- const { pg, user } = req;
5
-
6
- if (!user?.uid) return reply.status(403).send({ status: 403, message: 'access restricted' });
3
+ import getPermissions from './get.permissions.js';
7
4
 
5
+ export default async function gisCatalog({ uid }, pg = pgClients.client) {
8
6
  // permissions
9
- const { all_layers, group_list, layer_list } = await getPermissions({ pg, uid: user.uid });
7
+ const { all_layers, group_list, layer_list } = await getPermissions({ pg, uid });
8
+
10
9
  if (!all_layers && !group_list?.length && !layer_list?.length) {
11
- return reply.status(200).send({
10
+ return {
12
11
  status: 204, categoriesCount: 0, layersCount: 0, servicesCount: 0, rastersCount: 0, categories: [], layers: [],
13
- });
12
+ };
14
13
  }
15
14
 
16
15
  // groups
@@ -74,7 +73,8 @@ export default async function gisCatalog(req, reply) {
74
73
  layers,
75
74
 
76
75
  };
77
- const statusCode = (!layersCount && !categoriesCount) ? 204 : 200;
78
76
 
79
- return reply.status(statusCode).send(res);
77
+ // const statusCode = (!layersCount && !categoriesCount) ? 204 : 200;
78
+
79
+ return res;
80
80
  }
@@ -0,0 +1,35 @@
1
+ import catalogPermissions from './functions/catalog.permissions.js';
2
+ import catalogPermissionsEdit from './functions/catalog.permissions.edit.js';
3
+ import gisCatalog from './functions/gis.catalog.js';
4
+
5
+ const privateParams = { config: { policy: 'L1' } };
6
+
7
+ import { getCatalogPermissionsSchema, editCatalogPermissionsSchema } from './permissions.schema.js';
8
+
9
+ export default function route(fastify) {
10
+ if (!fastify.hasRoute({ method: 'GET', url: '/api/catalog' })) {
11
+ console.log('\x1b[34m%s\x1b[0m', 'add catalog from gis');
12
+ // does not use any parameters - schema is not neccessary
13
+ fastify.get('/catalog', { ...privateParams, schema: {} }, async ({ user, pg }) => {
14
+ const result = await gisCatalog({ uid: user?.uid }, pg);
15
+ return result;
16
+ });
17
+ }
18
+ if (!fastify.hasRoute({ method: 'GET', url: '/api/catalog-permissions/:uid' })) {
19
+ console.log('\x1b[34m%s\x1b[0m', 'add catalog-permissions from gis');
20
+ fastify.get('/catalog-permissions/:uid', { ...privateParams, schema: getCatalogPermissionsSchema }, async ({ params, pg }) => {
21
+ const result = await catalogPermissions({ uid: params.uid }, pg);
22
+ return result;
23
+ });
24
+ }
25
+ if (!fastify.hasRoute({ method: 'POST', url: '/api/catalog-permissions/:uid' })) {
26
+ console.log('\x1b[34m%s\x1b[0m', 'add catalog-permissions-edit from gis');
27
+ fastify.post('/catalog-permissions/:uid', { ...privateParams, schema: editCatalogPermissionsSchema }, async ({ params, body, pg }) => {
28
+ const result = await catalogPermissionsEdit({
29
+ uid: params.uid,
30
+ body,
31
+ }, pg);
32
+ return result;
33
+ });
34
+ }
35
+ }
@@ -0,0 +1,35 @@
1
+ import {
2
+ describe, test, expect, beforeAll, afterAll,
3
+ } from 'vitest';
4
+
5
+ import {
6
+ getPGAsync,
7
+ } from '@opengis/fastify-table/utils.js';
8
+
9
+ import { build, injectWithHeaders } from '../../../test/helper.js';
10
+
11
+ const user = { uid: '1', user_type: 'admin' };
12
+
13
+ let pg;
14
+
15
+ describe('permissions api test', () => {
16
+ beforeAll(async () => {
17
+ await build();
18
+ pg = await getPGAsync();
19
+ });
20
+
21
+ afterAll(async () => {
22
+ });
23
+
24
+ test('GET /catalog', async () => {
25
+
26
+ });
27
+
28
+ test('POST /catalog-permissions/:uid', async () => {
29
+
30
+ });
31
+
32
+ test('GET /catalog-permissions/:uid', async () => {
33
+
34
+ });
35
+ });
@@ -0,0 +1,44 @@
1
+ export const getCatalogPermissionsSchema = {
2
+ params: {
3
+ type: 'object',
4
+ required: ['uid'],
5
+ properties: {
6
+ uid: {
7
+ type: 'string', pattern: '^([\\d\\w]+)$'
8
+ },
9
+ },
10
+ },
11
+ };
12
+
13
+ export const editCatalogPermissionsSchema = {
14
+ params: {
15
+ type: 'object',
16
+ required: ['uid'],
17
+ properties: {
18
+ uid: {
19
+ type: 'string', pattern: '^([\\d\\w]+)$'
20
+ },
21
+ },
22
+ },
23
+ body: {
24
+ type: 'array',
25
+ items: {
26
+ type: 'object',
27
+ required: ['service_id', 'actions'],
28
+ properties: {
29
+ service_id: {
30
+ type: 'string', pattern: '^([\\d\\w]+)$'
31
+ },
32
+ actions: {
33
+ type: 'array',
34
+ items: {
35
+ type: 'string',
36
+ enum: ['view', 'edit', 'add', 'del']
37
+ }
38
+ }
39
+ }
40
+ }
41
+ }
42
+ };
43
+
44
+ export default null;
@@ -0,0 +1,37 @@
1
+ import { dataInsert, dataUpdate, pgClients } from "@opengis/fastify-table/utils.js";
2
+ import { BadRequestError } from "@opengis/fastify-table/errors.js";
3
+
4
+ export default async function addGisRegistry({
5
+ method, body, slug, uid,
6
+ }, pg = pgClients.client) {
7
+ if (method === 'POST' && !body?.register_key) {
8
+ throw BadRequestError('not enough body params: register_key');
9
+ }
10
+
11
+ if (method === 'POST') {
12
+ const res = await dataInsert({
13
+ pg,
14
+ id: slug,
15
+ table: 'gis.registers',
16
+ data: body,
17
+ uid,
18
+ });
19
+ return res.data;
20
+ }
21
+
22
+ if (!slug) {
23
+ throw BadRequestError('not enough params: slug');
24
+ }
25
+
26
+ const id = await pg.query('select register_id from gis.registers where register_key=$1', [slug]).then(r => r.rows?.[0]?.register_id) || slug;
27
+
28
+ const row = await dataUpdate({
29
+ pg,
30
+ id,
31
+ table: 'gis.registers',
32
+ data: body,
33
+ uid,
34
+ });
35
+
36
+ return row;
37
+ }
@@ -54,7 +54,7 @@ export async function attachClassifiers(rowOrRows, classifiers, table) {
54
54
  return rowOrRows;
55
55
  }
56
56
 
57
- export async function populateFilterOptions({ pg, table, filters, columns, whereConditions }) {
57
+ export async function populateFilterOptions({ pg, table, filters, columns, whereConditions, args = [] }) {
58
58
  if (!filters?.length || !table || !columns?.length) return;
59
59
 
60
60
  const optimizedSQL = `select * from ${table} where ${whereConditions || '1=1'}`;
@@ -78,7 +78,7 @@ export async function populateFilterOptions({ pg, table, filters, columns, where
78
78
  ? `select unnest(${el.id})::text as id,count(*) from (${optimizedSQL})q group by unnest(${el.id}) limit 100`
79
79
  : `select ${el.id}::text as id,count(*) from (${optimizedSQL})q group by ${el.id} limit 100`;
80
80
 
81
- const countArr = await pg.queryCache(q, { table });
81
+ const countArr = await pg.queryCache(q, { args, table });
82
82
 
83
83
  if (countArr.timeout) {
84
84
  Object.assign(el, { timeout: countArr.timeout });
@@ -1,15 +1,15 @@
1
1
  import { dataDelete, pgClients } from "@opengis/fastify-table/utils.js";
2
2
 
3
3
  export default async function deleteGisRegistry({
4
- params = {}, pg = pgClients.client, user = {},
5
- }, reply) {
6
- const id = await pg.query('select register_id from gis.registers where register_key=$1', [params.slug]).then(el => el.rows?.[0]?.register_id) || params.slug;
4
+ slug, uid,
5
+ }, pg = pgClients.client) {
6
+ const id = await pg.query('select register_id from gis.registers where register_key=$1', [slug]).then(el => el.rows?.[0]?.register_id) || slug;
7
7
 
8
8
  const row = await dataDelete({
9
9
  pg,
10
10
  id,
11
11
  table: 'gis.registers',
12
- uid: user?.uid,
12
+ uid,
13
13
  });
14
- return reply.status(200).send(row);
14
+ return row;
15
15
  }
@@ -1,13 +1,16 @@
1
1
  import { pgClients } from '@opengis/fastify-table/utils.js';
2
- import { attachClassifiers } from '../../../gis/registers/funcs/classifiers.js';
2
+ import { NotFoundError } from '@opengis/fastify-table/errors.js';
3
+
4
+ import { attachClassifiers } from '../../registers/functions/classifiers.js';
5
+
3
6
  const pg = pgClients.client;
4
7
 
5
- export default async function getInfo({ finalInfo, format }, reply) {
8
+ export default async function getInfo({ finalInfo, format }) {
6
9
  if (!finalInfo) return { error: 'No data found' };
7
10
 
8
11
  const table = finalInfo?.table_name;
9
12
  const queryCondition = finalInfo?.query || '1=1';
10
- const columns = finalInfo?.columns || finalInfo?.attributes || '[]';
13
+ const columns = finalInfo?.columns || finalInfo?.attributes || [];
11
14
  const exportable = columns.filter(c => c.is_export);
12
15
  const selectNames = exportable.map(c => `"${c.name}"`);
13
16
  const selectSQL = `
@@ -51,9 +54,10 @@ export default async function getInfo({ finalInfo, format }, reply) {
51
54
  };
52
55
  }
53
56
 
54
- const { rows } = await pg.query(selectSQL);
57
+ const rows = await pg.query(selectSQL).then(r => r.rows || []);
58
+
55
59
  if (!rows?.length) {
56
- return reply.status(404).send({ message: 'Немає даних, які можна експортувати', status: 404 });
60
+ throw NotFoundError('Немає даних, які можна експортувати');
57
61
  }
58
62
 
59
63
  const classifiers = exportable
@@ -1,12 +1,16 @@
1
1
  import { createReadStream } from 'node:fs';
2
2
  import { mkdir, writeFile } from 'node:fs/promises';
3
3
  import path from 'node:path';
4
+
4
5
  import {
5
- grpc, config, getMeta, getFolder, jsonToCsv,
6
+ grpc, config, getMeta, getFolder, jsonToCsv,
7
+ pgClients,
6
8
  } from '@opengis/fastify-table/utils.js';
7
9
 
8
- import getInfo from './funcs/get.info.js';
9
- import ContentType from './funcs/content.type.js';
10
+ import { BadRequestError, NotImplementedError } from '@opengis/fastify-table/errors.js';
11
+
12
+ import getInfo from './get.info.js';
13
+ import ContentType from './content.type.js';
10
14
 
11
15
  const { jsonToXls, geojsonToShp } = grpc();
12
16
  const rootDir = getFolder(config, 'local');
@@ -19,14 +23,18 @@ const rootDir = getFolder(config, 'local');
19
23
  * @returns {boolean} File
20
24
  */
21
25
 
22
- export default async function gisExport({ pg, query = {}, params = {} }, reply) {
23
- const { format } = query;
24
- const { slug, type } = params;
26
+ export default async function gisExport({ slug, type, format }, pg = pgClients.client) {
25
27
  if (!['csv', 'xlsx', 'shp', 'geojson'].includes(format)) {
26
- return reply.code(401).send({ message: 'Param format is invalid. Allowed: csv, xlsx, shp, geojson', status: 404 });
28
+ throw BadRequestError('invalid params: format. Allowed: csv, xlsx, shp, geojson');
29
+ }
30
+
31
+ if (!slug) {
32
+ throw BadRequestError('not enough params: slug');
33
+ }
34
+
35
+ if (!type) {
36
+ throw BadRequestError('not enough params: type');
27
37
  }
28
- if (!slug) return reply.code(401).send({ message: 'slug is not defined', status: 404 });
29
- if (!type) return reply.code(401).send({ message: 'type is not defined', status: 404 });
30
38
 
31
39
  let registerInfo;
32
40
  let serviceInfo;
@@ -50,13 +58,13 @@ export default async function gisExport({ pg, query = {}, params = {} }, reply)
50
58
  const finalInfo = registerInfo?.rows[0] || serviceInfo?.rows[0];
51
59
 
52
60
  const exportable = finalInfo?.columns?.filter(c => c.is_export);
53
- const colmodel = exportable.map(col => ({
61
+ const colmodel = (exportable || []).map(col => ({
54
62
  name: col.name,
55
63
  title: col.ua || col.name,
56
64
  }));
57
65
  const {
58
- rows, table, srid, sqlList,
59
- } = await getInfo({ finalInfo, format }, reply);
66
+ rows, table, srid, sqlList,
67
+ } = await getInfo({ finalInfo, format });
60
68
  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`);
61
69
  const ext = path.extname(filePath);
62
70
  const filePathJSON = ['csv', 'geojson', 'shp'].includes(format) ? filePath.replace(ext, '.json') : filePath;
@@ -64,16 +72,12 @@ export default async function gisExport({ pg, query = {}, params = {} }, reply)
64
72
 
65
73
  const meta = await getMeta({ pg, table });
66
74
  if ((format === 'geojson' || format === 'shp') && !meta?.geom) {
67
- return reply.status(400).send('Ця таблиця не містить полів геометрії. Виберіть тип, який не потребує геометрії для вивантаження');
75
+ throw BadRequestError('Ця таблиця не містить полів геометрії. Виберіть тип, який не потребує геометрії для вивантаження');
68
76
  }
69
77
 
70
78
  if (format === 'xlsx') {
71
79
  if (!jsonToXls) {
72
- const message = 'Сервіс конвертації jsonToXls тимчасово недоступний. Спробуйте експортувати дані у іншому форматі...';
73
- const error = new Error(message);
74
- error.status = 503;
75
-
76
- throw error;
80
+ throw NotImplementedError('Сервіс конвертації jsonToXls тимчасово недоступний. Спробуйте експортувати дані у іншому форматі...');
77
81
  }
78
82
  const { result } = await jsonToXls({
79
83
  json: JSON.stringify(rows),
@@ -145,9 +149,11 @@ export default async function gisExport({ pg, query = {}, params = {} }, reply)
145
149
  exportFilePath = exportedZipPaths[0];
146
150
  }
147
151
 
148
- reply.header('Content-Disposition', `attachment; filename=${encodeURIComponent(path.basename(exportFilePath))}`);
149
- reply.header('Content-Type', ContentType[format]);
152
+ const headers = {
153
+ 'Content-Disposition': `attachment; filename=${encodeURIComponent(path.basename(exportFilePath))}`,
154
+ 'Content-Type': ContentType[format]
155
+ };
150
156
 
151
157
  const fileStream = createReadStream(exportFilePath);
152
- return reply.send(fileStream);
158
+ return { headers, data: fileStream };
153
159
  }