@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,503 @@
1
+ import { describe, test, beforeAll, expect } from 'vitest';
2
+
3
+ import { getTemplate, getPGAsync, uploadFile, isFileExists } from '@opengis/fastify-table/utils.js';
4
+
5
+ import { build, injectWithHeaders } from '../../../test/helper.js';
6
+
7
+ const user = { id: '1', type: 'admin' };
8
+
9
+ let pg;
10
+ let addr = {};
11
+
12
+ // base64 from ziped shapefile for /gis-convert api
13
+ const base64 = `UEsDBBQAAAAAAMVDBV2t8XCrgwAAAIMAAAAJAAAAcG9pbnQucHJqR0VPR0NTWyJXR1MgODQiLERBVFVNWyJXR1NfMTk4NCIsU1BIRVJPSURbIldHUyA4NCIsNjM3ODEzNywyOTguMjU3MjIzNTYzXV0sUFJJTUVNWyJHcmVlbndpY2giLDBdLFVOSVRbImRlZ3JlZSIsMC4wMTc0NTMyOTI1MTk5NDMzXV1QSwMEFAAAAAAAxUMFXeUBOGx0AAAAdAAAAAkAAABwb2ludC5kYmYDfggFAQAAAEEAMwAAAAAAAAAAAAAAAAAAAAAAAAAAAGlkAAAAAAAAAAAATgAAAAAyAAAAAAAAAAAAAAAAAAAADSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMVBLAwQUAAAAAADFQwVdjfPd44AAAACAAAAACQAAAHBvaW50LnNocAAAJwoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEDoAwAAAQAAAPW52or9hT5A/fZ14Jw5SUD1udqK/YU+QP32deCcOUlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAACgEAAAD1udqK/YU+QP32deCcOUlAUEsDBBQAAAAAAMVDBV0HI9CqbAAAAGwAAAAJAAAAcG9pbnQuc2h4AAAnCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANugDAAABAAAA9bnaiv2FPkD99nXgnDlJQPW52or9hT5A/fZ14Jw5SUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADIAAAAKUEsBAhQDFAAAAAAAxUMFXa3xcKuDAAAAgwAAAAkAAAAAAAAAAAAAAKSBAAAAAHBvaW50LnByalBLAQIUAxQAAAAAAMVDBV3lAThsdAAAAHQAAAAJAAAAAAAAAAAAAACkgaoAAABwb2ludC5kYmZQSwECFAMUAAAAAADFQwVdjfPd44AAAACAAAAACQAAAAAAAAAAAAAApIFFAQAAcG9pbnQuc2hwUEsBAhQDFAAAAAAAxUMFXQcj0KpsAAAAbAAAAAkAAAAAAAAAAAAAAKSB7AEAAHBvaW50LnNoeFBLBQYAAAAABAAEANwAAAB/AgAAAAA=`;
14
+
15
+ describe('map api test', () => {
16
+ beforeAll(async () => {
17
+ await build();
18
+ pg = await getPGAsync();
19
+
20
+ // preload an address row for map-feature tests
21
+ if (pg.pk?.['data_address.address']) {
22
+ addr = await pg
23
+ .query('select addr_id, st_x(geom), st_y(geom) from data_address.address where geom is not null limit 1')
24
+ .then(r => r.rows?.[0] || {});
25
+ expect(!!addr.addr_id).toBeTruthy();
26
+ }
27
+ });
28
+
29
+ test('GET /map-catalog', async () => {
30
+ const res = await injectWithHeaders({ method: 'GET', url: '/api/map-catalog' });
31
+ expect(res.statusCode).toBe(200);
32
+ const rep = res.json();
33
+ expect(Array.isArray(rep.rasters)).toBeTruthy();
34
+ expect(Array.isArray(rep.services)).toBeTruthy();
35
+ });
36
+
37
+ test('GET /marker-icon/*', async () => {
38
+ // latest changes break local icon generation
39
+ const res = await injectWithHeaders({
40
+ method: 'GET',
41
+ // url: `/api/marker-icon/pin6-m-fa-space-shuttle+teal.png`,
42
+ url: '/api/marker-icon/icon-l-fa-location-dot+ff0000.svg',
43
+ headers: { uid: user.id, user_type: user.type }
44
+ });
45
+ if (res.statusCode === 200) {
46
+ expect(res.statusCode).toBe(200);
47
+ expect(res.body.includes('PNG')).toBeTruthy();
48
+ expect(res.rawPayload?.length).toBeTruthy();
49
+ } else {
50
+ expect(res.statusCode).toBe(404);
51
+ expect(res.body.message).toMatch('icon not found');
52
+ }
53
+ }, 15000);
54
+
55
+ test('GET /gis-icon/*', async () => {
56
+ const res = await injectWithHeaders({
57
+ method: 'GET',
58
+ url: `/api/gis-icon/pin6-m-fa-plus-square+7ed957.png`,
59
+ headers: { uid: user.id, user_type: user.type }
60
+ });
61
+ expect(res.statusCode).toBe(200);
62
+ expect(res.headers['content-type']).toBe('image/png');
63
+ expect(res.body.includes('PNG')).toBeTruthy();
64
+ });
65
+
66
+ test('GET /icon/*', async () => {
67
+ const res = await injectWithHeaders({
68
+ method: 'GET',
69
+ url: `/api/icon/pin6-m-fa-plus-square+7ed957.png`,
70
+ headers: { uid: user.id, user_type: user.type }
71
+ });
72
+ expect(res.statusCode).toBe(200);
73
+ expect(res.headers['content-type']).toBe('image/png');
74
+ expect(res.body.includes('PNG')).toBeTruthy();
75
+ });
76
+
77
+ test('GET /gis-icon/*.svg', async () => {
78
+ const res = await injectWithHeaders({
79
+ method: 'GET',
80
+ url: `/api/gis-icon/pin6-m-fa-plus-square+7ed957.svg`,
81
+ headers: { uid: user.id, user_type: user.type }
82
+ });
83
+ expect(res.statusCode).toBe(200);
84
+ expect(res.headers['content-type']).toBe('image/svg+xml');
85
+ expect(res.body).toContain('<svg');
86
+ expect(res.body).toContain('viewBox="0 0 446 518"');
87
+ });
88
+
89
+ test('GET /gis-icon/ar-* renders a symbol', async () => {
90
+ const res = await injectWithHeaders({
91
+ method: 'GET',
92
+ url: `/api/gis-icon/pin6-m-ar-E+ff4500.svg`,
93
+ headers: { uid: user.id, user_type: user.type }
94
+ });
95
+ expect(res.statusCode).toBe(200);
96
+ expect(res.headers['content-type']).toBe('image/svg+xml');
97
+ expect(res.body).toContain('>E</text>');
98
+ expect(res.body).toContain('fill="#ff4500"');
99
+ expect(res.body).not.toContain('#ff0000');
100
+ });
101
+
102
+ test.each(['pin2', 'pin3', 'pin4', 'pin5', 'pin6', 'pin7'])(
103
+ 'GET /gis-icon/%s recolors the background',
104
+ async (pin) => {
105
+ const res = await injectWithHeaders({
106
+ method: 'GET',
107
+ url: `/api/gis-icon/${pin}-m-fa-plus-square+7ed957.svg`,
108
+ headers: { uid: user.id, user_type: user.type }
109
+ });
110
+ expect(res.statusCode).toBe(200);
111
+ expect(res.body).not.toContain('#ff0000');
112
+ expect(res.body).toContain('fill="#7ed957"');
113
+ expect(res.body.lastIndexOf('data-gis-icon-layer="foreground"'))
114
+ .toBeGreaterThan(res.body.lastIndexOf('<use'));
115
+ },
116
+ );
117
+
118
+ test.each([
119
+ ['pin', '#ff0000'],
120
+ ['pin1', '#ff0000'],
121
+ ['circle1', '#176e1c'],
122
+ ['circle2', '#ff0000'],
123
+ ['none', 'fill="red"'],
124
+ ])(
125
+ 'GET /gis-icon/%s keeps the original background',
126
+ async (pin, backgroundColor) => {
127
+ const res = await injectWithHeaders({
128
+ method: 'GET',
129
+ url: `/api/gis-icon/${pin}-m-fa-plus-square+7ed957.svg`,
130
+ headers: { uid: user.id, user_type: user.type }
131
+ });
132
+ expect(res.statusCode).toBe(200);
133
+ expect(res.body).toContain(backgroundColor);
134
+ expect(res.body).toContain('fill="#7ed957"');
135
+ expect(res.body.lastIndexOf('data-gis-icon-layer="foreground"'))
136
+ .toBeGreaterThan(res.body.lastIndexOf('<use'));
137
+ },
138
+ );
139
+
140
+ test('GET /maps', async () => {
141
+ const res = await injectWithHeaders({
142
+ method: 'GET', url: `/api/maps`,
143
+ headers: { uid: user.id, user_type: user.type }
144
+ });
145
+ expect(res.statusCode).toBe(200);
146
+ const rep = res.json();
147
+ expect(rep).toBeInstanceOf(Array);
148
+ if (rep?.length) {
149
+ expect(rep?.[0]?.name).toBeTruthy();
150
+ expect(rep?.[0]?.slug).toBeTruthy();
151
+ }
152
+ });
153
+
154
+ test(`GET /map/:name`, async () => {
155
+ const slug = 'addr';
156
+ const body = await getTemplate('map', slug);
157
+ expect(body).toBeTruthy();
158
+
159
+ const res = await injectWithHeaders({
160
+ method: 'GET', url: `/api/map/${slug}`,
161
+ headers: { uid: user.id, user_type: user.type }
162
+ });
163
+ expect(res.statusCode).toBe(200);
164
+ // expect(res.body).toHaveProperty('name');
165
+ // expect(res.body.name).toBe('Адресний реєстр');
166
+ expect(res.body).toHaveProperty('source_path');
167
+ expect(res.body.source_path).toBe('data_address.street');
168
+ expect(res.body).toHaveProperty('layers');
169
+ expect(res.body.layers.length).toBe(3);
170
+ expect(res.body).toHaveProperty('maps');
171
+ expect(res.body.maps.length).toBeGreaterThan(0);
172
+ });
173
+
174
+ test(`GET /map-features/:slug/:id`, async () => {
175
+ const slug = 'addr';
176
+ const res = await injectWithHeaders({
177
+ method: 'GET',
178
+ url: `/api/map-features/${slug}/${addr.addr_id}`,
179
+ });
180
+ expect(res.statusCode).toBe(200);
181
+ const rep = res.json();
182
+ expect(rep.data).toBeTruthy();
183
+ expect(rep.meta).toBeTruthy();
184
+ expect(rep.data.addr_id).toBe(addr.addr_id);
185
+ });
186
+
187
+ test(`GET /map-features-point/:slug?x=&y=`, async () => {
188
+ const slug = 'addr';
189
+ const res = await injectWithHeaders({
190
+ method: 'GET',
191
+ url: `/api/map-features-point/${slug}?x=${addr.st_x}&y=${addr.st_y}`,
192
+ headers: { uid: user.id, user_type: user.type }
193
+ });
194
+ expect(res.statusCode).toBe(200);
195
+ const rep = res.json();
196
+ expect(rep.data).toBeTruthy();
197
+ expect(rep.meta).toBeTruthy();
198
+ expect(rep.data.addr_id).toBe(addr.addr_id);
199
+ });
200
+
201
+ test(`GET /map-tiles/:slug/:z/:y/:x.pbf`, async () => {
202
+ const slug = 'addr';
203
+ const res = await injectWithHeaders({
204
+ method: 'GET',
205
+ url: `/api/map-tiles/${slug}/14/9767/5659.pbf`,
206
+ headers: { uid: user.id, user_type: user.type }
207
+ });
208
+ expect(res.statusCode).toBe(200);
209
+ expect(res.headers['content-type']).toBe('application/x-protobuf');
210
+ expect(res.body.length).toBeGreaterThan(0);
211
+ expect(res.body).toMatch('\u001a�8\n\u0006street');
212
+ });
213
+
214
+ test(`GET /api/map-catalog/:service/:attr`, async () => {
215
+ const { id, columns } = await pg.query('select service_id as id, coalesce(filters::jsonb,attributes::jsonb,card::jsonb,popup::jsonb) as columns from gis.services where source_path is not null and is_active and is_public limit 1').then(r => r.rows?.[0] || {});
216
+ expect(id).toBeTypeOf('string');
217
+ expect(columns).toBeInstanceOf(Array);
218
+ expect(columns.length).toBeGreaterThan(0);
219
+ const { name: attr, data } = columns.find(col => col.data) || {};
220
+ expect(attr).toBeTypeOf('string');
221
+ expect(data).toBeTypeOf('string');
222
+ const res = await injectWithHeaders({
223
+ method: 'GET',
224
+ url: `/api/map-catalog/${id}/${attr}`,
225
+ headers: { uid: user.id, user_type: user.type }
226
+ });
227
+ expect(res.statusCode).toBe(200);
228
+ expect(res.body).toHaveProperty('legend');
229
+ expect(res.body.legend).toBeInstanceOf(Array);
230
+ if (res.body.legend.length) {
231
+ expect(res.body.legend[0]).toHaveProperty('id');
232
+ expect(res.body.legend[0]).toHaveProperty('count');
233
+ expect(res.body.legend[0].count).toMatch(/\d+/);
234
+ expect(+res.body.legend[0].count).toBeGreaterThanOrEqual(0);
235
+ }
236
+ expect(res.body).toHaveProperty('min');
237
+ expect(res.body).toHaveProperty('max');
238
+ });
239
+
240
+ test(`GET /api/map-catalog/:service/:attr?cls=`, async () => {
241
+ const { id, columns } = await pg.query('select service_id as id, coalesce(filters::jsonb,attributes::jsonb,card::jsonb,popup::jsonb) as columns from gis.services where source_path is not null and is_active and is_public limit 1').then(r => r.rows?.[0] || {});
242
+ expect(id).toBeTypeOf('string');
243
+ expect(columns).toBeInstanceOf(Array);
244
+ expect(columns.length).toBeGreaterThan(0);
245
+ const { name: attr, data } = columns.find(col => col.data) || {};
246
+ expect(attr).toBeTypeOf('string');
247
+ expect(data).toBeTypeOf('string');
248
+ const res = await injectWithHeaders({
249
+ method: 'GET',
250
+ url: `/api/map-catalog/${id}/${attr}`,
251
+ query: { cls: data },
252
+ headers: { uid: user.id, user_type: user.type }
253
+ });
254
+ expect(res.statusCode).toBe(200);
255
+ expect(res.body).toHaveProperty('legend');
256
+ expect(res.body.legend).toBeInstanceOf(Array);
257
+ if (res.body.legend.length) {
258
+ expect(res.body.legend[0]).toHaveProperty('id');
259
+ expect(res.body.legend[0]).toHaveProperty('count');
260
+ expect(res.body.legend[0].count).toMatch(/\d+/);
261
+ expect(+res.body.legend[0].count).toBeGreaterThanOrEqual(0);
262
+ expect(res.body.legend[0]).toHaveProperty('text');
263
+ expect(res.body.legend[0].text).toBeTypeOf('string');
264
+ }
265
+ expect(res.body).toHaveProperty('min');
266
+ expect(res.body).toHaveProperty('max');
267
+ });
268
+
269
+ test(`GET /api/vtile/:layer/:lang/:z/:y/:x`, async () => {
270
+ const layer = await pg.query('select service_id from gis.services where source_path is not null and is_active and is_public limit 1').then(r => r.rows?.[0]?.service_id);
271
+ expect(layer).toBeTypeOf('string');
272
+ const res = await injectWithHeaders({
273
+ method: 'GET',
274
+ url: `/api/vtile/${layer}/ua/1/1/1.pbf`,
275
+ // headers: { uid: user.id, user_type: user.type }
276
+ });
277
+ expect(res.statusCode).toBe(200);
278
+ expect(res.headers).toHaveProperty('cache-control');
279
+ expect(res.headers).toHaveProperty('content-type');
280
+ expect(res.headers['content-type']).toBe("application/x-protobuf");
281
+ expect(res.headers).toHaveProperty('content-length');
282
+ });
283
+
284
+ test(`GET /api/gis-clear-vtile/:id`, async () => {
285
+ const layer = await pg.query('select service_id from gis.services where source_path is not null and is_active and is_public limit 1').then(r => r.rows?.[0]?.service_id);
286
+ expect(layer).toBeTypeOf('string');
287
+ const res = await injectWithHeaders({
288
+ method: 'GET',
289
+ url: `/api/gis-clear-vtile/${layer}`,
290
+ headers: { uid: user.id, user_type: user.type }
291
+ });
292
+ expect(res.statusCode).toBe(200);
293
+ expect(res.body).toHaveProperty('message');
294
+ expect(res.body.message).toBe('Тайли очищено');
295
+ });
296
+ test(`GET /api/geojson/:layer`, async () => {
297
+ const layer = await pg.query('select service_id from gis.services where source_path is not null and is_active and is_public limit 1').then(r => r.rows?.[0]?.service_id);
298
+ expect(layer).toBeTypeOf('string');
299
+ const res = await injectWithHeaders({
300
+ method: 'GET',
301
+ url: `/api/geojson/${layer}`,
302
+ // headers: { uid: user.id, user_type: user.type }
303
+ });
304
+ expect(res.statusCode).toBe(200);
305
+ expect(res.body).toHaveProperty('type');
306
+ expect(res.body.type).toBe('FeatureCollection');
307
+ expect(res.body).toHaveProperty('features');
308
+ expect(res.body.features).toBeInstanceOf(Array);
309
+ expect(res.body.features.length).toBeGreaterThan(0);
310
+ expect(res.body.features[0]).toHaveProperty('type');
311
+ expect(res.body.features[0].type).toBe('Feature');
312
+ expect(res.body.features[0]).toHaveProperty('geometry');
313
+ expect(res.body.features[0].geometry).toHaveProperty('type');
314
+ expect(res.body.features[0].geometry.type).toBeOneOf(['Point', 'LineString', 'Polygon']);
315
+ expect(res.body.features[0].geometry).toHaveProperty('coordinates');
316
+ expect(res.body.features[0].geometry.coordinates).toBeInstanceOf(Array);
317
+ expect(res.body.features[0]).toHaveProperty('properties');
318
+ expect(Object.keys(res.body.features[0].properties).length).toBeGreaterThan(0);
319
+ });
320
+ test(`GET /api/json/:layer`, async () => {
321
+ const layer = await pg.query('select register_id from gis.registers where 1=1 and is_active and is_public limit 1').then(r => r.rows?.[0]?.register_id);
322
+ expect(layer).toBeTypeOf('string');
323
+ const res = await injectWithHeaders({
324
+ method: 'GET',
325
+ url: `/api/json/${layer}`,
326
+ // headers: { uid: user.id, user_type: user.type }
327
+ });
328
+ expect(res.statusCode).toBe(200);
329
+ expect(res.body).toHaveProperty('register_id');
330
+ expect(res.body).toHaveProperty('total');
331
+ expect(res.body).toHaveProperty('limit');
332
+ expect(res.body).toHaveProperty('page');
333
+ expect(res.body).toHaveProperty('data');
334
+ expect(res.body.data).toBeInstanceOf(Array);
335
+ expect(res.body.data.length).toBeGreaterThan(0);
336
+ expect(res.body.data[0]).toHaveProperty('id');
337
+ });
338
+ test(`GET /api/gis-layer-list`, async () => {
339
+ const res = await injectWithHeaders({
340
+ method: 'GET',
341
+ url: `/api/gis-layer-list`,
342
+ // headers: { uid: user.id, user_type: user.type }
343
+ });
344
+ expect(res.statusCode).toBe(200);
345
+ });
346
+
347
+ test(`GET /api/map-format?layer=&id=`, async () => {
348
+ const { service_id: layer, source_path: table } = await pg.query('select service_id, source_path from gis.services where source_path is not null and is_active and is_public limit 1').then(r => r.rows?.[0] || {});
349
+ expect(layer).toBeTypeOf('string');
350
+ expect(pg.pk?.[table]).toBeTypeOf('string');
351
+
352
+ const id = await pg.query(`select ${pg.pk?.[table]} as id from ${table} limit 1`).then(r => r.rows?.[0]?.id);
353
+ expect(id).toBeTypeOf('string');
354
+
355
+ const res = await injectWithHeaders({
356
+ method: 'GET',
357
+ url: `/api/map-format`,
358
+ query: {
359
+ layer,
360
+ id
361
+ },
362
+ headers: { uid: user.id, user_type: user.type }
363
+ });
364
+ expect(res.statusCode).toBe(200);
365
+ expect(res.body).toHaveProperty('id');
366
+ expect(res.body).toHaveProperty('data');
367
+ expect(res.body).toHaveProperty('columns');
368
+ expect(res.body.columns).toBeInstanceOf(Array);
369
+ expect(res.body.data).toHaveProperty('id');
370
+ expect(res.body.data).toHaveProperty('geom');
371
+ });
372
+ test(`GET /api/map-format?layer=&lng=&lat=`, async () => {
373
+ const { cartocss_id: layer, card_table: table } = await pg.query('select cartocss_id, card_table from gis.cartocss where card_table is not null and enabled and is_public limit 1').then(r => r.rows?.[0] || {});
374
+ expect(layer).toBeTypeOf('string');
375
+ expect(pg.pk?.[table]).toBeTypeOf('string');
376
+
377
+ const { st_x: lng, st_y: lat } = await pg.query(`select st_x(st_pointonsurface(st_transform(geom,4326))), st_y(st_pointonsurface(st_transform(geom,4326))) from ${table} where geom is not null limit 1`).then(r => r.rows[0]);
378
+ expect(lat).toBeTypeOf('number');
379
+ const res = await injectWithHeaders({
380
+ method: 'GET',
381
+ url: `/api/map-format`,
382
+ query: {
383
+ layer,
384
+ lng,
385
+ lat
386
+ },
387
+ headers: { uid: user.id, user_type: user.type }
388
+ });
389
+ expect(res.statusCode).toBe(200);
390
+ expect(res.body).toHaveProperty('id');
391
+ expect(res.body).toHaveProperty('ids');
392
+ expect(res.body.ids).toBeInstanceOf(Array);
393
+ expect(res.body).toHaveProperty('data');
394
+ expect(res.body).toHaveProperty('columns');
395
+ expect(res.body.columns).toBeInstanceOf(Array);
396
+ expect(res.body.data).toHaveProperty('id');
397
+ expect(res.body.data).toHaveProperty('geom');
398
+ expect(res.body.data).toHaveProperty('distance'); // self-explanatory
399
+ expect(res.body.data).toHaveProperty('key'); // cartocss layer key
400
+ });
401
+ test(`GET /api/coords/height?lat=&lng=`, async () => {
402
+ const res = await injectWithHeaders({
403
+ method: 'GET',
404
+ url: `/api/coords/height`,
405
+ query: { lat: 50, lng: 30 },
406
+ headers: { uid: user.id, user_type: user.type }
407
+ });
408
+ expect(res.statusCode).toBe(200);
409
+ expect(res.body).toHaveProperty('height');
410
+ expect(res.body.height).toBeTypeOf('number');
411
+ expect(res.body.height).toBe(201);
412
+ expect(res.body).toHaveProperty('lat');
413
+ expect(res.body).toHaveProperty('lng');
414
+ });
415
+ test(`POST /api/gis-parse-geo`, async () => {
416
+ const res = await injectWithHeaders({
417
+ method: 'POST',
418
+ url: `/api/gis-parse-geo`,
419
+ payload: {
420
+ content: `{ "type":"Feature", "geometry": { "type": "Point", "coordinates": [30.523,50.4501] }, "properties": {} }`
421
+ },
422
+ headers: { uid: user.id, user_type: user.type }
423
+ });
424
+ expect(res.statusCode).toBe(200);
425
+ expect(res.body).toHaveProperty('type');
426
+ expect(res.body.type).toBe('FeatureCollection');
427
+ expect(res.body).toHaveProperty('features');
428
+ expect(res.body.features).toBeInstanceOf(Array);
429
+ expect(res.body.features.length).toBeGreaterThan(0);
430
+ expect(res.body.features[0]).toHaveProperty('type');
431
+ expect(res.body.features[0].type).toBe('Feature');
432
+ expect(res.body.features[0]).toHaveProperty('geometry');
433
+ expect(res.body.features[0].geometry).toHaveProperty('type');
434
+ expect(res.body.features[0].geometry.type).toBeOneOf(['Point', 'LineString', 'Polygon']);
435
+ expect(res.body.features[0].geometry).toHaveProperty('coordinates');
436
+ expect(res.body.features[0].geometry.coordinates).toBeInstanceOf(Array);
437
+ expect(res.body.features[0]).toHaveProperty('properties');
438
+ });
439
+ test(`POST /api/gis-convert (file as base64 + filename)`, async () => {
440
+ const res = await injectWithHeaders({
441
+ method: 'POST',
442
+ url: `/api/gis-convert`,
443
+ payload: {
444
+ file: base64,
445
+ filename: 'shapefile.zip',
446
+ },
447
+ headers: { uid: user.id, user_type: user.type }
448
+ });
449
+ expect(res.statusCode).toBe(200);
450
+ expect(res.body).toHaveProperty('type');
451
+ expect(res.body.type).toBe('FeatureCollection');
452
+ expect(res.body).toHaveProperty('features');
453
+ expect(res.body.features).toBeInstanceOf(Array);
454
+ expect(res.body.features.length).toBeGreaterThan(0);
455
+ expect(res.body.features[0]).toHaveProperty('type');
456
+ expect(res.body.features[0].type).toBe('Feature');
457
+ expect(res.body.features[0]).toHaveProperty('geometry');
458
+ expect(res.body.features[0].geometry).toHaveProperty('type');
459
+ expect(res.body.features[0].geometry.type).toBe('Point');
460
+ expect(res.body.features[0].geometry).toHaveProperty('coordinates');
461
+ expect(res.body.features[0].geometry.coordinates).toBeInstanceOf(Array);
462
+ expect(res.body.features[0].geometry.coordinates[0]).toBe(30.5234);
463
+ expect(res.body.features[0].geometry.coordinates[1]).toBe(50.4501);
464
+ expect(res.body.features[0]).toHaveProperty('properties');
465
+ expect(res.body.features[0].properties).toHaveProperty('id');
466
+ expect(res.body.features[0].properties.id).toBe(1);
467
+ });
468
+
469
+ test(`POST /api/gis-convert (filepath)`, async () => {
470
+ const relpath = '/files/test/shapefile.zip';
471
+ const exists = await isFileExists(relpath);
472
+ if (!exists) {
473
+ await uploadFile(relpath, Buffer.from(base64, 'base64'));
474
+ }
475
+
476
+ const res = await injectWithHeaders({
477
+ method: 'POST',
478
+ url: `/api/gis-convert`,
479
+ payload: {
480
+ filepath: relpath
481
+ },
482
+ headers: { uid: user.id, user_type: user.type }
483
+ });
484
+ expect(res.statusCode).toBe(200);
485
+ expect(res.body).toHaveProperty('type');
486
+ expect(res.body.type).toBe('FeatureCollection');
487
+ expect(res.body).toHaveProperty('features');
488
+ expect(res.body.features).toBeInstanceOf(Array);
489
+ expect(res.body.features.length).toBeGreaterThan(0);
490
+ expect(res.body.features[0]).toHaveProperty('type');
491
+ expect(res.body.features[0].type).toBe('Feature');
492
+ expect(res.body.features[0]).toHaveProperty('geometry');
493
+ expect(res.body.features[0].geometry).toHaveProperty('type');
494
+ expect(res.body.features[0].geometry.type).toBe('Point');
495
+ expect(res.body.features[0].geometry).toHaveProperty('coordinates');
496
+ expect(res.body.features[0].geometry.coordinates).toBeInstanceOf(Array);
497
+ expect(res.body.features[0].geometry.coordinates[0]).toBe(30.5234);
498
+ expect(res.body.features[0].geometry.coordinates[1]).toBe(50.4501);
499
+ expect(res.body.features[0]).toHaveProperty('properties');
500
+ expect(res.body.features[0].properties).toHaveProperty('id');
501
+ expect(res.body.features[0].properties.id).toBe(1);
502
+ });
503
+ });