@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
@@ -1,18 +1,19 @@
1
- import SphericalMercator from '@mapbox/sphericalmercator';
1
+ import { SphericalMercator } from '@mapbox/sphericalmercator';
2
2
 
3
3
  import {
4
- config, logger, eventStream, pgClients,
4
+ config, logger, pgClients,
5
5
  } from '@opengis/fastify-table/utils.js';
6
+ import { BadRequestError, NotFoundError } from '@opengis/fastify-table/errors.js';
6
7
 
7
- import convertBoundToTile from '../functions/convertBoundToTile.js';
8
+ import convertBoundToTile from './convertBoundToTile.js';
8
9
  import mapnik from '../../../plugins/mapnik/funcs/mapnik.js';
9
- import cartoBounds from '../functions/cartoBounds.js';
10
- import rasterInfo from './rasterInfo.js';
11
-
12
- const { RenderTile } = mapnik();
10
+ // import cartoBounds from '../functions/cartoBounds.js';
11
+ // import rasterInfo from './rasterInfo.js';
13
12
 
14
13
  const mercator = new SphericalMercator({ size: 256 });
15
14
 
15
+ const { RenderTile } = mapnik();
16
+
16
17
  const MAX_LIMIT = 100000;
17
18
 
18
19
  const CONCURRENCY = 5;
@@ -39,35 +40,31 @@ async function runPool(tasks, limit) {
39
40
  const maxBounds = [23, 44, 40, 53];
40
41
 
41
42
  export default async function pretile({
42
- pg = pgClients.client, params, query,
43
- }, reply) {
44
- const { zoom = 11, max = 15 } = query || {};
45
-
43
+ id, zoom = 11, max = 15, callback = () => { },
44
+ }, pg = pgClients.client) {
46
45
  if (zoom > max) {
47
- return reply.status(422).send({ error: 'Error: querystring/max must be > querystring/zoom', code: 422 });
46
+ throw BadRequestError('Error: querystring/max must be > querystring/zoom');
48
47
  }
49
48
 
50
- const data = await pg.query(`select *, geom::box2d as bounds, 'raster' as source_type from gis.rasters where raster_id=$1`, [params.id]).then(el => el.rows?.[0])
51
- || await pg.query(`select *, geom::box2d as bounds, 'css' as source_type from gis.cartocss where cartocss_id=$1`, [params.id]).then(el => el.rows?.[0]);
49
+ const data = await pg.query(`select *, geom::box2d as bounds, 'raster' as source_type from gis.rasters where raster_id=$1`, [id]).then(r => r.rows?.[0])
50
+ || await pg.query(`select *, geom::box2d as bounds, 'css' as source_type from gis.cartocss where cartocss_id=$1`, [id]).then(r => r.rows?.[0]);
52
51
 
53
52
  if (!data) {
54
- return reply.status(404).send({ error: 'not found', code: 404 });
53
+ throw NotFoundError('raster/css not found');
55
54
  }
56
55
 
57
56
  if (!data.bounds || data.bounds === 'BOX(-180 -85.05112877980659,180 85.05112877980659)') {
58
- return reply.status(400).send({ error: 'geom is not set', code: 400 });
57
+ throw BadRequestError('geom is not set');
59
58
  }
60
59
 
61
- const send = eventStream(reply);
62
-
63
60
  try {
64
61
  const relpath = data.source_type === 'raster' ? ['raster', config.mapnik?.folder, data.source_path].filter(Boolean).join('/') : null;
65
- const name = data.source_type === 'css' ? ['vector', config.mapnik?.folder || '', data.source_path || params.id].filter(Boolean).join('/') : null;
62
+ const name = data.source_type === 'css' ? ['vector', config.mapnik?.folder || '', data.source_path || id].filter(Boolean).join('/') : null;
66
63
 
67
64
  // refresh extent
68
65
  const bounds = data.bounds.replace(')', '').substr(4).split(/[, ]/g).map((el) => el - 0);
69
66
 
70
- send(`start: ${data.name} ${params.id} ${bounds} ${data.srid} ${data.proj4}`);
67
+ callback(`start: ${data.name} ${id} ${bounds} ${data.srid} ${data.proj4}`);
71
68
 
72
69
  bounds[0] = Math.max(bounds[0], maxBounds[0]);
73
70
  bounds[1] = Math.max(bounds[1], maxBounds[1]);
@@ -75,7 +72,7 @@ export default async function pretile({
75
72
  bounds[2] = Math.min(bounds[2], maxBounds[2]);
76
73
  bounds[3] = Math.min(bounds[3], maxBounds[3]);
77
74
 
78
- send({
75
+ callback({
79
76
  bounds, minzoom: zoom, maxzoom: max, maxBounds,
80
77
  });
81
78
 
@@ -83,12 +80,12 @@ export default async function pretile({
83
80
  bounds, minzoom: zoom, maxzoom: max, mercator,
84
81
  });
85
82
 
86
- send(tiles);
83
+ callback(tiles);
87
84
 
88
85
  const tileLen = tiles.reduce((acc, el) => acc + el.count, 0);
89
86
 
90
87
  if (tileLen > MAX_LIMIT) {
91
- send({ MAX_LIMIT });
88
+ callback({ MAX_LIMIT });
92
89
  }
93
90
 
94
91
  let tileNum = 0;
@@ -106,8 +103,8 @@ export default async function pretile({
106
103
  return ys.map((y) => async () => {
107
104
  if (tileNum > MAX_LIMIT) return;
108
105
 
109
- const tilePath = `${params.id}/${z}/${x}/${y}.png`;
110
- send(`Start ${tileNum + 1}/${tileLen} ${tilePath}`);
106
+ const tilePath = `${id}/${z}/${x}/${y}.png`;
107
+ callback(`Start ${tileNum + 1}/${tileLen} ${tilePath}`);
111
108
 
112
109
  const time = Date.now();
113
110
 
@@ -115,12 +112,12 @@ export default async function pretile({
115
112
  const render = await RenderTile({ path: relpath, name, bbox });
116
113
 
117
114
  if (render?.err) {
118
- send(render.err);
115
+ callback(render.err);
119
116
  return;
120
117
  }
121
118
 
122
- send(
123
- `${tileNum + 1}/${tileLen} ${config.local || config.debug ? render.tile_path : params.id} len:${render.base64.length} cache: ${!!render?.cache} time:${Date.now() - time}ms`,
119
+ callback(
120
+ `${tileNum + 1}/${tileLen} ${config.local || config.debug ? render.tile_path : id} len:${render.base64.length} cache: ${!!render?.cache} time:${Date.now() - time}ms`,
124
121
  );
125
122
  tileNum += 1;
126
123
  });
@@ -129,16 +126,13 @@ export default async function pretile({
129
126
 
130
127
  await runPool(tasks, CONCURRENCY);
131
128
 
132
- send('OK');
129
+ callback('OK');
133
130
  return 'OK';
134
131
  }
135
132
  catch (err) {
136
133
  const error = config.local || config.debug ? err.toString() : 'pretile error';
137
- send(error);
138
- logger.file('pretile.error', { error: err.toString(), stack: err.stack, id: params.id });
139
- return reply.status(500).send({ error, code: 500 });
140
- }
141
- finally {
142
- send('finish', true);
134
+ callback(error);
135
+ logger.file('pretile.error', { error: err.toString(), stack: err.stack, id });
136
+ throw err;
143
137
  }
144
138
  }
@@ -1,6 +1,7 @@
1
1
  import { config, pgClients } from '@opengis/fastify-table/utils.js';
2
2
 
3
3
  import mapnik from '../../../plugins/mapnik/funcs/mapnik.js';
4
+ import { BadRequestError, NotImplementedError } from '@opengis/fastify-table/errors.js';
4
5
 
5
6
  const { GetRasterInfo } = mapnik();
6
7
 
@@ -8,28 +9,36 @@ const { prefix = '/api' } = config;
8
9
 
9
10
  // example: GET /api/gis-raster/9be8f8c51746
10
11
  export default async function rasterInfo({
11
- pg = pgClients.client, params, query,
12
- }, reply) {
12
+ id, debug,
13
+ }, pg = pgClients.client) {
13
14
  const time = Date.now();
15
+
16
+ if (!id) {
17
+ throw NotImplementedError('not enough params: id');
18
+ }
19
+
14
20
  if (!config.mapnik?.server) {
15
- return reply.status(400).send({ error: 'mapnik server address needed', code: 400 });
21
+ throw NotImplementedError('mapnik server address needed');
16
22
  }
17
23
 
18
24
  const raster = pg.pk?.['gis.rasters']
19
- ? await pg.query('select raster_id, source_path, name, description, raster_key, is_active, is_public, srid, proj4, geom from gis.rasters where raster_id=$1::text', [params.id])
20
- .then(el => el.rows?.[0] || {})
25
+ ? await pg.query('select raster_id, source_path, name, description, raster_key, is_active, is_public, srid, proj4, st_asgeojson(geom)::json as geom from gis.rasters where raster_id=$1::text', [id])
26
+ .then(r => r.rows?.[0] || {})
21
27
  : {};
22
28
 
23
29
  if (raster.raster_id && !raster.source_path) {
24
- return reply.status(400).send({ error: 'empty source_path', code: 400 });
30
+ throw BadRequestError('empty source_path');
25
31
  }
26
32
 
27
33
  if (!raster.raster_id) {
28
- const decodedPath = Buffer.from(params.id, 'base64url').toString('utf-8');
34
+ const decodedPath = Buffer.from(id, 'base64url').toString('utf-8');
29
35
  Object.assign(raster, { source_path: decodedPath });
30
36
  }
31
37
 
32
- const proj4 = raster.proj4 || (raster.srid && pg.pk?.['public.spatial_ref_sys'] ? await pg.query('select proj4text from public.spatial_ref_sys where srid=$1', [raster.srid]).then(el => el.rows?.[0]?.proj4text) : undefined);
38
+ const proj4 = raster.proj4
39
+ || (raster.srid && pg.pk?.['public.spatial_ref_sys']
40
+ ? await pg.query('select proj4text from public.spatial_ref_sys where srid=$1', [raster.srid]).then(r => r.rows?.[0]?.proj4text)
41
+ : undefined);
33
42
 
34
43
  const relpath = ['raster', config.mapnik?.folder, raster.source_path].filter(Boolean).join('/');
35
44
 
@@ -38,12 +47,12 @@ export default async function rasterInfo({
38
47
  proj4,
39
48
  }).catch(err => ({ error: err.toString() }));
40
49
 
41
- if (query.debug) {
50
+ if (debug) {
42
51
  return { data, cache, raster };
43
52
  }
44
53
 
45
54
  if (!raster.geom && Array.isArray(data?.extent)) {
46
- await pg.query(`update gis.rasters set geom = ST_MakeEnvelope(${data.extent.join(',')}) where raster_id = $1`, [raster.raster_id]);
55
+ await pg.query(`update gis.rasters set geom = ST_MakeEnvelope($2,$3,$4,$5) where raster_id = $1`, [raster.raster_id, ...data.extent]);
47
56
  }
48
57
 
49
58
  return {
@@ -1,4 +1,5 @@
1
1
  import { config } from '@opengis/fastify-table/utils.js';
2
+ import { NotImplementedError } from '@opengis/fastify-table/errors.js';
2
3
 
3
4
  import mapnik from '../../../plugins/mapnik/funcs/mapnik.js';
4
5
 
@@ -6,13 +7,12 @@ const { ReadDir } = mapnik();
6
7
 
7
8
  // example: GET /api/gis-files?dir=raster/genplan
8
9
  export default async function readDir({
9
- query,
10
- }, reply) {
10
+ dir,
11
+ }) {
11
12
  if (!ReadDir) {
12
- return reply.status(400).send({ error: 'mapnik server address needed', code: 400 });
13
+ throw NotImplementedError('mapnik server address needed');
13
14
  }
14
15
 
15
- const { dir } = query;
16
16
  const relpath = `raster/${[config.mapnik?.folder, dir].filter(Boolean).join('/')}`;
17
17
 
18
18
  const {
@@ -0,0 +1,164 @@
1
+ import path from 'node:path';
2
+ import { createHash } from 'node:crypto';
3
+
4
+ import { SphericalMercator } from '@mapbox/sphericalmercator';
5
+
6
+ const mercator = new SphericalMercator({ size: 256 });
7
+
8
+ import {
9
+ config, logger, pgClients,
10
+ } from '@opengis/fastify-table/utils.js';
11
+
12
+ import { BadRequestError, ForbiddenError, NotFoundError } from '@opengis/fastify-table/errors.js';
13
+
14
+ import mapnik from '../../../plugins/mapnik/funcs/mapnik.js';
15
+
16
+ const { RenderTile } = mapnik();
17
+
18
+ const meta = !!config?.mapnik?.meta;
19
+
20
+ /**
21
+ * Формування растрового tile cartoCss
22
+ *
23
+ * @method GET
24
+ * @alias rtile
25
+ * @param {String} bbox - bbox
26
+ * @param {Number} height - висота по координатам
27
+ * @param {Number} width - ширина по координатам
28
+ * @param {String} data - стилізація
29
+ * @param {String} lang - мова
30
+ * @param {String} z - координата z
31
+ * @param {String} x - координата y
32
+ * @param {String} y - координата x
33
+ */
34
+
35
+ export default async function gisRtile({
36
+ id, z, y, x, debug, nocache, nottl, uid,
37
+ }, pg = pgClients.client) {
38
+ if (!RenderTile) {
39
+ throw BadRequestError('mapnik server address needed');
40
+ }
41
+
42
+ if (!id) {
43
+ throw BadRequestError('not enough params: id');
44
+ }
45
+
46
+ if (!x || !y || !z) {
47
+ throw BadRequestError('not enough params: xyz');
48
+ }
49
+
50
+ const decodedPath = Buffer.from(id, 'base64url').toString('utf-8');
51
+
52
+ const data = pg.pk?.['gis.rasters']
53
+ ? await pg.queryCache(`select raster_id as id, source_path, is_public, 'raster' as type from gis.rasters where raster_id=$1::text or source_path=$2::text`, { args: [id, decodedPath], table: 'gis.rasters' })
54
+ .then(r => r.rows?.[0] || {})
55
+ : {};
56
+
57
+ const carto = pg.pk?.['gis.cartocss']
58
+ ? await pg.queryCache('select cartocss_id, source_path, is_public, is_static from gis.cartocss where cartocss_id=$1::text', { args: [id], table: 'gis.cartocss' }).then(r => r.rows?.[0] || {})
59
+ : {};
60
+
61
+ if (carto.cartocss_id) {
62
+ Object.assign(data, {
63
+ id: carto.cartocss_id,
64
+ source_path: carto.source_path,
65
+ is_public: carto.is_public,
66
+ is_static: carto.is_static,
67
+ type: 'css',
68
+ });
69
+ }
70
+
71
+ if (!uid && !config.local && data.is_public === false && process.env.NODE_ENV !== 'test' && !process.env.VITEST) {
72
+ throw ForbiddenError('access restricted');
73
+ }
74
+
75
+ if (!data.id && data.type !== 'css') {
76
+ Object.assign(data, { source_path: decodedPath });
77
+ }
78
+
79
+ if (!data.source_path && data.type !== 'css') {
80
+ throw NotFoundError('raster / cartocss not found');
81
+ }
82
+
83
+ const bbox = mercator.bbox(y, x, z, false, '900913');
84
+
85
+ const ttl = (nocache ? '0' : null)
86
+ || (data.type === 'css' && !data.is_static ? '1w' : null);
87
+
88
+ const md5 = data.source_path
89
+ ? createHash('md5').update(data.source_path).digest('hex')
90
+ : undefined;
91
+ const base64 = data.source_path
92
+ ? Buffer.from(data.source_path).toString('base64url')
93
+ : undefined;
94
+
95
+ const getParams = () => {
96
+ if (data.type === 'css' && data.source_path) {
97
+ return { name: path.posix.join('vector', config.mapnik?.folder || '', data.source_path) };
98
+ }
99
+ if (data.type === 'css') {
100
+ return { name: path.posix.join('xml', config.mapnik?.folder || '', id) };
101
+ }
102
+ return { path: path.posix.join('raster', config.mapnik?.folder || '', data.source_path) };
103
+ };
104
+
105
+ const { path: rpath, name } = getParams();
106
+
107
+ const param = {
108
+ path: rpath, // for rasters only
109
+ name, // required for cartocss
110
+ width: 256,
111
+ bbox,
112
+ ttl,
113
+ format: 'webp',
114
+ meta,
115
+ base64: false,
116
+ debug,
117
+ };
118
+
119
+ const result = await RenderTile(param);
120
+
121
+ if (result.err) {
122
+ logger.file('rtile/error', {
123
+ error: result.err, x, y, z, id: data.id, type: data.type,
124
+ });
125
+ throw new Error(result.err);
126
+ }
127
+
128
+ if (meta) {
129
+ const accelPath = result.tile_path?.startsWith('/') ? result.tile_path : `/${result.tile_path}`;
130
+ const metaHeaders = {
131
+ 'Content-Type': 'image/webp',
132
+ 'Cache-Control': nocache || nottl ? 'no-store, no-cache, must-revalidate' : 'public, max-age=2592000',
133
+ 'X-Accel-Redirect': accelPath,
134
+ };
135
+ if (debug) {
136
+ return {
137
+ headers: metaHeaders,
138
+ base64: result.base64,
139
+ z,
140
+ x,
141
+ y,
142
+ };
143
+ }
144
+ return { headers: metaHeaders, code: 204 };
145
+ }
146
+
147
+ if (debug) {
148
+ return {
149
+ ...result,
150
+ name,
151
+ path: rpath,
152
+ ttl,
153
+ md5_path: md5,
154
+ base64_path: base64,
155
+ raster: !!data.id,
156
+ carto: data.type === 'css',
157
+ is_static: data.type === 'css' ? data.is_static : true,
158
+ };
159
+ }
160
+
161
+ const buffer = result.data || Buffer.from(result.base64, 'base64');
162
+
163
+ return { headers: { 'Content-Type': 'image/webp', 'Cache-Control': nocache || nottl ? 'no-store, no-cache, must-revalidate' : 'public, max-age=2592000' }, data: buffer };
164
+ }
@@ -3,9 +3,11 @@ import { ListObjectsV2Command } from '@aws-sdk/client-s3';
3
3
 
4
4
  /* eslint-disable no-await-in-loop */
5
5
  import {
6
- config, isFileExists, logger, pgClients, eventStream, downloadFile, s3Client,
6
+ config, isFileExists, logger, pgClients, downloadFile, s3Client,
7
7
  } from '@opengis/fastify-table/utils.js';
8
8
 
9
+ import { BadRequestError, NotFoundError, NotImplementedError } from '@opengis/fastify-table/errors.js';
10
+
9
11
  import mapnik from '../../../plugins/mapnik/funcs/mapnik.js';
10
12
 
11
13
  const { UploadRaster, GetRasterStatus } = mapnik();
@@ -26,7 +28,7 @@ async function uploadRasterFile({
26
28
  id, prefix, relpath: relpathOriginal, callback = () => { },
27
29
  }) {
28
30
  const metadata = await isFileExists(relpathOriginal);
29
- const relpath = relpathOriginal.replace(config.folder, '').replace(prefix, '');
31
+ const relpath = ['raster', config.mapnik?.folder || '', relpathOriginal.replace(/\/\//, '/').replace(config.folder, '')].join('/');
30
32
 
31
33
  let offset = 0;
32
34
 
@@ -95,29 +97,27 @@ async function uploadRasterFile({
95
97
  }
96
98
 
97
99
  export default async function uploadRaster({
98
- pg = pgClients.client, params,
99
- }, reply) {
100
+ id, callback = () => { },
101
+ }, pg = pgClients.client) {
100
102
  if (!UploadRaster || !GetRasterStatus) {
101
- return reply.status(400).send({ error: 'mapnik server address needed', code: 400 });
103
+ throw NotImplementedError('mapnik server address needed');
102
104
  }
103
105
 
104
- const { id } = params;
105
-
106
106
  if (!id) {
107
- return reply.status(400).send({ error: 'not enough params: id', code: 400 });
107
+ throw BadRequestError('not enough params: id');
108
108
  }
109
109
 
110
110
  const data = pg.pk?.['gis.rasters']
111
111
  ? await pg.query('select raster_id as id, source_path from gis.rasters where raster_id=$1::text', [id])
112
- .then(el => el.rows?.[0])
112
+ .then(r => r.rows?.[0])
113
113
  : null;
114
114
 
115
115
  if (!data?.id) {
116
- return reply.status(404).send({ error: 'raster not found', code: 404 });
116
+ throw NotFoundError('raster not found');
117
117
  }
118
118
 
119
119
  if (!data.source_path) {
120
- return reply.status(400).send({ error: 'raster source_path not set', code: 400 });
120
+ throw BadRequestError('raster source_path not set');
121
121
  }
122
122
 
123
123
  const prefix = '/map/raster';
@@ -129,29 +129,24 @@ export default async function uploadRaster({
129
129
  Prefix: path.join(config.folder, relpath).replace(/\\/g, '/'),
130
130
  }));
131
131
  if (!metadata.Contents?.length) {
132
- return reply.status(404).send({
133
- error: 'invalid: raster source_path: not found / empty directory',
134
- code: 404,
135
- });
132
+ throw NotFoundError('invalid: raster source_path: not found / empty directory');
136
133
  }
137
134
 
138
135
  // list rasters, skip preview subdir content, skip folders from s3 directory name of which only starts with same characters, but does not exactly match
139
136
  const files = metadata.Contents.map(file => file.Key).filter((file) => path.basename(path.dirname(file)) === path.basename(relpath) && !path.basename(path.dirname(file)).startsWith('preview') && path.extname(file).toLowerCase() === '.tif');
140
137
 
141
138
  if (!files.length) {
142
- return reply.status(400).send({
143
- error: 'invalid: raster source_path: no raster files at directory',
144
- code: 400,
145
- });
139
+ throw BadRequestError('invalid: raster source_path: no raster files at directory');
146
140
  }
147
- const callback = eventStream(reply);
141
+
148
142
  await sequence(files, { id, prefix, callback }, uploadRasterFile);
149
- return callback('finish', 1);
143
+ return 'uploaded';
150
144
  }
151
145
 
152
- const callback = eventStream(reply);
146
+
153
147
  await uploadRasterFile({
154
- id, prefix, callback, relpath,
148
+ id, prefix, callback, relpath: data.source_path,
155
149
  });
156
- return callback('finish', 1);
150
+
151
+ return 'uploaded';
157
152
  }
@@ -18,6 +18,7 @@ const getGeomColumn = (geoms, customColumn) => {
18
18
  };
19
19
 
20
20
  import cartoBounds from './cartoBounds.js';
21
+ import { NotFoundError } from '@opengis/fastify-table/errors.js';
21
22
 
22
23
  function cartoData(el, extent, pg) {
23
24
  const minzoom = el.minzoom ? (+el.minzoom || 5) : 5;
@@ -53,6 +54,32 @@ export default async function uploadXML({
53
54
  if (!id || !dataset?.length || Array.isArray(dataset) === false) {
54
55
  return null;
55
56
  }
57
+
58
+ const tlist = await pg
59
+ .query(
60
+ `SELECT
61
+ array_agg(
62
+ (
63
+ SELECT
64
+ nspname
65
+ FROM
66
+ pg_namespace
67
+ WHERE
68
+ oid = relnamespace
69
+ ) || '.' || relname
70
+ ) tlist
71
+ FROM
72
+ pg_class
73
+ WHERE
74
+ relkind IN ('r', 'v', 'm')`
75
+ )
76
+ .then((d) => d.rows[0].tlist);
77
+
78
+ const { table: missingTable } = dataset.find(el => el.active !== false && el.table && !tlist.includes(el.table)) || {};
79
+ if (missingTable) {
80
+ throw NotFoundError('table not found: ' + missingTable);
81
+ }
82
+
56
83
  await Promise.all(dataset.filter((el) => el.active !== false).map(async el => {
57
84
  const { table } = el;
58
85
 
@@ -0,0 +1,102 @@
1
+ import { eventStream } from '@opengis/fastify-table/utils.js';
2
+
3
+ import uploadRaster from './functions/uploadRaster.js';
4
+ import createXml from './functions/createXml.js';
5
+ import rtile from './functions/rtile.js';
6
+ import rasterInfo from './functions/rasterInfo.js';
7
+
8
+ import createXmlMulti from './functions/createXmlMulti.js';
9
+ import readDir from './functions/readDir.js';
10
+ import fileStat from './functions/fileStat.js';
11
+ import fileSearch from './functions/fileSearch.js';
12
+ import clearTiles from './functions/clearTiles.js';
13
+ import pretile from './functions/pretile.js';
14
+
15
+ import {
16
+ pretileSchema,
17
+ uploadRasterSchema,
18
+ gisXmlSchema,
19
+ gisRtileSchema,
20
+ gisRasterSchema,
21
+ createXmlMultiSchema,
22
+ readDirSchema,
23
+ fileStatSchema,
24
+ fileSearchSchema,
25
+ clearTilesSchema,
26
+ } from './mapnik.schema.mjs';
27
+
28
+ const publicParams = { config: { policy: 'L0' }, package: 'gis' }; // L0 === public
29
+ const adminParams = { config: { role: 'admin' }, package: 'gis' };
30
+ const privateParams = { config: { policy: 'L1' }, package: 'gis' }; // L1 === authorized only
31
+
32
+ export default function route(app) {
33
+ app.get('/gis-upload-raster/:id', { ...privateParams, schema: uploadRasterSchema }, async ({ params, pg }, reply) => {
34
+ const callback = process.env.NODE_ENV === 'test' || process.env.VITEST ? console.log : eventStream(reply);
35
+ const result = await uploadRaster({ id: params.id, callback }, pg).catch(err => ({ error: err.toString() }));
36
+ callback(result?.error || 'finish', true);
37
+ return result;
38
+ });
39
+ app.get('/gis-xml/:id', { ...publicParams, schema: gisXmlSchema }, async ({ params, query }, reply) => {
40
+ const callback = process.env.NODE_ENV === 'test' || process.env.VITEST ? console.log : eventStream(reply);
41
+ const result = await createXml({ id: params.id, vrt: query.vrt, debug: query.debug, nocache: query.nocache, callback }).catch(err => ({ error: err.toString() }));
42
+ callback(result?.error || 'finish', true);
43
+ return result;
44
+ });
45
+ app.get('/gis-rtile/:id/:z/:y/:x', { ...publicParams, schema: gisRtileSchema }, async ({ params, query, user, pg }, reply) => {
46
+ const result = await rtile({
47
+ id: params.id,
48
+ z: params.z,
49
+ y: params.y,
50
+ x: params.x.split('.')[0] - 0,
51
+ uid: user?.uid,
52
+ debug: query.debug,
53
+ nocache: query.nocache,
54
+ nottl: query.nottl,
55
+ }, pg);
56
+ if (query.debug) {
57
+ return result;
58
+ }
59
+
60
+ if (result.code === 204) {
61
+ return reply.headers(result.headers).code(204).send();
62
+ }
63
+
64
+ return reply.headers(result.headers).send(result.data);
65
+ });
66
+ app.get('/gis-raster/:id', { ...publicParams, schema: gisRasterSchema }, async ({ params, query, pg }) => {
67
+ const result = await rasterInfo({ id: params.id, debug: query.debug }, pg);
68
+ return result;
69
+ });
70
+
71
+ app.get('/gis-create-xml/:id?', { ...adminParams, schema: createXmlMultiSchema }, async ({ params, query, pg }, reply) => {
72
+ const callback = process.env.NODE_ENV === 'test' || process.env.VITEST ? console.log : eventStream(reply);
73
+ const result = await createXmlMulti({
74
+ id: params.id, nocache: query.nocache, callback
75
+ }, pg).catch(err => ({ error: err.toString() }));
76
+ callback(result?.error || 'finish', true);
77
+ return result;
78
+ });
79
+ app.get('/gis-files', { ...adminParams, schema: readDirSchema }, async ({ query }) => {
80
+ const result = await readDir({ dir: query.dir });
81
+ return result;
82
+ });
83
+ app.get('/gis-file-info', { ...adminParams, schema: fileStatSchema }, async ({ query }) => {
84
+ const result = await fileStat({ path: query.path });
85
+ return result;
86
+ });
87
+ app.get('/gis-file-search', { ...adminParams, schema: fileSearchSchema }, async ({ query }) => {
88
+ const { dir, key, period, size, page, limit } = query;
89
+ const result = await fileSearch({ dir, key, period, size, page, limit });
90
+ return result;
91
+ });
92
+ app.get('/gis-clear-rtile/:id', { ...adminParams, schema: clearTilesSchema }, async ({ params, query }) => {
93
+ const result = await clearTiles({ id: params.id, debug: query.debug });
94
+ return result;
95
+ });
96
+ app.get('/gis-pretile/:id', { ...adminParams, schema: pretileSchema }, async ({ params, query, pg }, reply) => {
97
+ const callback = process.env.NODE_ENV === 'test' || process.env.VITEST ? console.log : eventStream(reply);
98
+ const result = await pretile({ id: params.id, zoom: query.zoom, max: query.max, callback }, pg).catch(err => ({ error: err.toString() }));
99
+ callback(result?.error || 'finish', true);
100
+ return result;
101
+ });
102
+ }