@opengis/gis 0.0.17 → 0.0.19

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 (101) hide show
  1. package/dist/import-file.cjs +845 -0
  2. package/dist/{index.css → import-file.css} +1 -1
  3. package/dist/{index.js → import-file.js} +13002 -11703
  4. package/module/gis/card/gis.maps.table/index.yml +11 -0
  5. package/module/gis/card/gis.maps.table/main_info.hbs +25 -0
  6. package/module/gis/card/gis.maps.table/maps_layers.hbs +19 -0
  7. package/module/gis/card/gis.metadata.table/index.yml +19 -0
  8. package/module/gis/card/gis.metadata.table/main_info.hbs +21 -0
  9. package/module/gis/card/gis.metadata.table/metadata_info.hbs +28 -0
  10. package/module/gis/card/gis.metadata.table/other.hbs +26 -0
  11. package/module/gis/card/gis.rasters.table/index.yml +8 -0
  12. package/module/gis/card/gis.rasters.table/main_info.hbs +27 -0
  13. package/module/gis/card/gis.registers.table/cls.hbs +36 -0
  14. package/module/gis/card/gis.registers.table/columns.hbs +83 -0
  15. package/module/gis/card/gis.registers.table/filters.hbs +80 -0
  16. package/module/gis/card/gis.registers.table/index.yml +21 -0
  17. package/module/gis/card/gis.registers.table/main_info.hbs +35 -0
  18. package/module/gis/card/gis.registers.table/source.hbs +45 -0
  19. package/module/gis/card/gis.services.table/attributes.hbs +85 -0
  20. package/module/gis/card/gis.services.table/filters.hbs +83 -0
  21. package/module/gis/card/gis.services.table/index.yml +20 -0
  22. package/module/gis/card/gis.services.table/main_info.hbs +27 -0
  23. package/module/gis/card/gis.services.table/source.hbs +25 -0
  24. package/module/gis/cls/bool.yes_no.json +12 -0
  25. package/module/gis/cls/encoding.json +14 -0
  26. package/module/gis/cls/geom_type.json +14 -0
  27. package/module/gis/cls/gis.column_type.json +34 -0
  28. package/module/gis/cls/gis.column_view_type.json +18 -0
  29. package/module/gis/cls/gis.filter_type.json +22 -0
  30. package/module/gis/cls/language.json +10 -0
  31. package/module/gis/cls/meta.service_type.json +43 -0
  32. package/module/gis/cls/ogc.service.json +22 -0
  33. package/module/gis/cls/service_type.json +42 -0
  34. package/module/gis/cls/source_type.json +10 -0
  35. package/module/gis/cls/standarts.json +6 -0
  36. package/module/gis/cls/topic_category.json +107 -0
  37. package/module/gis/cls/update_frequency.json +30 -0
  38. package/module/gis/form/gis.group_list.form.json +17 -0
  39. package/module/gis/form/gis.maps.form.json +67 -0
  40. package/module/gis/form/gis.metadata.form.json +240 -0
  41. package/module/gis/form/gis.ogc_service.form.json +36 -0
  42. package/module/gis/form/gis.rasters.form.json +100 -0
  43. package/module/gis/form/gis.registers.form.json +264 -0
  44. package/module/gis/form/gis.registers_column.form.json +77 -0
  45. package/module/gis/form/gis.registers_filter.form.json +65 -0
  46. package/module/gis/form/gis.services.form.json +300 -0
  47. package/module/gis/form/gis.services_attributes.form.json +68 -0
  48. package/module/gis/form/gis.services_filter.form.json +65 -0
  49. package/module/gis/menu.json +43 -0
  50. package/module/gis/select/gis.group_list.sql +1 -0
  51. package/module/gis/select/pg.columns.parent.sql +6 -0
  52. package/module/gis/select/pg.table_name.sql +17 -0
  53. package/module/gis/select/service_id.sql +1 -0
  54. package/module/gis/table/gis.maps.table.json +78 -0
  55. package/module/gis/table/gis.metadata.table.json +71 -0
  56. package/module/gis/table/gis.ogc_service.table.json +81 -0
  57. package/module/gis/table/gis.rasters.table.json +98 -0
  58. package/module/gis/table/gis.registers.table.json +79 -0
  59. package/module/gis/table/gis.services.table.json +105 -0
  60. package/module/gis/table/site.gis.registers.table.json +75 -0
  61. package/module/gis/table/site.gis.services.table.json +104 -0
  62. package/module/gis/templates/ISO19136_2017_gml_template.xml +331 -0
  63. package/module/gis/tokens.yml +5 -0
  64. package/package.json +11 -5
  65. package/plugin.js +12 -0
  66. package/server/plugins/mapnik/funcs/createXML.js +72 -0
  67. package/server/plugins/mapnik/funcs/gdalWrapper.js +72 -0
  68. package/server/plugins/mapnik/funcs/mapnik.js +101 -0
  69. package/server/plugins/mapnik/funcs/rasterConfig.js +11 -0
  70. package/server/plugins/mapnik/funcs/rasterExists.js +21 -0
  71. package/server/plugins/mapnik/funcs/rasterInfo.js +109 -0
  72. package/server/plugins/mapnik/funcs/rasterVrt.js +56 -0
  73. package/server/plugins/mapnik/funcs/rasterXML.js +65 -0
  74. package/server/plugins/mapnik/funcs/rootFolder.mjs +8 -0
  75. package/server/plugins/mapnik/index.mjs +12 -0
  76. package/server/plugins/mapnik/utils/map.proto +241 -0
  77. package/server/routes/gis/index.mjs +19 -0
  78. package/server/routes/gis/metadata/metadataXML.js +13 -0
  79. package/server/routes/gis/registers/funcs/classifiers.js +26 -0
  80. package/server/routes/gis/registers/funcs/columns.js +5 -0
  81. package/server/routes/gis/registers/funcs/handleRegistryRequest.js +100 -0
  82. package/server/routes/gis/registers/gis.registry.js +32 -0
  83. package/server/routes/gis/registers/gis.registry.list.js +59 -0
  84. package/server/routes/gis/registers/insert.columns.js +107 -0
  85. package/server/routes/gis/registers/insert.filters.js +110 -0
  86. package/server/routes/gis/registers/map.registry.js +79 -0
  87. package/server/routes/gis/services/get.layer.geom.js +27 -0
  88. package/server/routes/map/controllers/map.js +123 -0
  89. package/server/routes/map/controllers/mapCatalog.js +55 -0
  90. package/server/routes/map/controllers/mapCatalogAttribute.js +56 -0
  91. package/server/routes/map/controllers/mapFeatures.js +120 -0
  92. package/server/routes/map/controllers/mapFormat.js +111 -0
  93. package/server/routes/map/controllers/mapTiles.js +148 -0
  94. package/server/routes/map/controllers/maps.js +16 -0
  95. package/server/routes/map/controllers/marker_icon.js +42 -0
  96. package/server/routes/map/controllers/rtile.js +133 -0
  97. package/server/routes/map/controllers/vtile.js +146 -0
  98. package/server/routes/map/index.mjs +51 -0
  99. package/server/routes/root.mjs +3 -0
  100. package/utils.js +9 -0
  101. package/dist/index.umd.cjs +0 -845
@@ -0,0 +1,109 @@
1
+ import path from 'node:path';
2
+ import { createHash } from 'node:crypto';
3
+ import { existsSync } from 'node:fs';
4
+ import { writeFile, mkdir, readFile } from 'node:fs/promises';
5
+
6
+ import { getRedis, logger, getPG } from '@opengis/fastify-table/utils.js';
7
+
8
+ import mapnik from './mapnik.js';
9
+ import rasterVrt from './rasterVrt.js';
10
+ import rasterExists from './rasterExists.js';
11
+ import rootFolder from './rootFolder.mjs';
12
+
13
+ const { gdal } = mapnik();
14
+
15
+ const pg = getPG();
16
+ const rclient = getRedis();
17
+
18
+ export default async function rasterInfo(fullPath, send = () => { }, proj4text, nocache = 0) {
19
+ const time = [Date.now()];
20
+
21
+ const key = `raster-stat:${fullPath}`;
22
+ const cache = await rclient.get(key).then(el => (el ? JSON.parse(el) : null));
23
+
24
+ if (cache?.fullPath && cache.size && cache.extent && !nocache) {
25
+ return { type: 'redis', ...cache };
26
+ }
27
+
28
+ // console.log(fullPath)
29
+ if (fullPath.includes('.vrt')) {
30
+ await rasterVrt(fullPath, send)
31
+ }
32
+
33
+ // file cache
34
+ const hash = createHash('md5').update(fullPath).digest("hex");
35
+
36
+ const statPath = path.join(rootFolder, `stat/${hash}.json`);
37
+ if (existsSync(statPath) && !nocache) {
38
+ send('stat:' + statPath);
39
+ const fileData = await readFile(statPath, 'utf-8');
40
+
41
+ await rclient.set(key, fileData);
42
+ const parse = JSON.parse(fileData)
43
+
44
+ if (parse.fullPath && parse.extent) return parse;
45
+ }
46
+ // console.log(fullPath);
47
+
48
+ // size
49
+ const exists = fullPath.includes('.vrt') ? 1 : await rasterExists(fullPath)
50
+ //console.log(fullPath, exists)
51
+ send('exists:' + fullPath + ' - ' + (exists ? 'yes' : 'no'));
52
+ if (!exists) return { error: 'file not exists info ' + fullPath }
53
+
54
+ const { result: stat, error: err1 = '' } = await gdal({ name: 'ls -lah ', path: fullPath })
55
+ .then(el => (el.result ? { result: el.result.replace(/\n/g, '') } : el));
56
+ time.push(Date.now());
57
+
58
+ const size = stat.split(' ')[4]
59
+
60
+ // srs
61
+ // send('srs:' + (proj4text || '') + fullPath)
62
+ const { result: srs, err: error1 } = proj4text ? { result: proj4text } : await gdal({ name: 'gdalsrsinfo', path: fullPath, params: '-o proj4 ' })
63
+ .then(el => (el.result ? { result: el.result.replace(/\n/g, '') } : el));
64
+
65
+ if (error1) return { error: error1 }
66
+ time.push(Date.now());
67
+
68
+ // gdalinfo
69
+ // send('info:' + fullPath)
70
+ const { result, err: error } = await gdal({ name: 'gdalinfo', path: fullPath, params: '-json' });
71
+
72
+ if (error) return { error }
73
+ const gdalInfo = JSON.parse(result);
74
+
75
+ time.push(Date.now());
76
+ send('wgs84:' + JSON.stringify(gdalInfo?.wgs84Extent) + ' coors:' + JSON.stringify(gdalInfo?.cornerCoordinates));
77
+
78
+ console.log(proj4text, gdalInfo?.cornerCoordinates)
79
+ if (proj4text && gdalInfo?.cornerCoordinates) {
80
+ const { lowerLeft, upperRight } = gdalInfo.cornerCoordinates;
81
+ //send(gdalInfo.cornerCoordinates);
82
+ const { geom, extent } = await pg.query(`select st_asgeojson(geom)::json as geom, geom::box2d as extent from
83
+ (select st_transform('box(${lowerLeft[0]} ${lowerLeft[1]}, ${upperRight[0]} ${upperRight[1]})'::box2d,'${proj4text}','+proj=longlat +datum=WGS84 +no_defs') as geom )q`)
84
+ .then(el => el.rows[0]);
85
+ //send(extent)
86
+ gdalInfo.wgs84Extent = geom;
87
+ gdalInfo.extent = extent.substring(4, extent.length - 1).replace(/ /g, ',').split(',')
88
+ }
89
+
90
+ // extent
91
+ const geom = gdalInfo?.wgs84Extent;
92
+ const extent = gdalInfo.extent || (geom?.coordinates?.[0]?.[0] ? geom.coordinates[0][0].concat(geom.coordinates[0][2]) : undefined);
93
+ // send(extent);
94
+
95
+ const data = {
96
+ time: { total: Date.now() - time[0], size: time[1] - time[0], srs: time[2] - time[1], info: time[3] - time[2] }, srs, gdalInfo, fullPath, size, extent, error
97
+ };
98
+
99
+ await rclient.setex(key, 8000, JSON.stringify(data));
100
+
101
+ // file cache
102
+ await mkdir(path.dirname(statPath), { recursive: true });
103
+
104
+ logger.file('editor', { time: Date.now() - time[0], srs, statPath, })
105
+
106
+ await writeFile(statPath, JSON.stringify(data, null, 2));
107
+
108
+ return data;
109
+ }
@@ -0,0 +1,56 @@
1
+ import path from 'node:path';
2
+
3
+ import mapnik from './mapnik.js';
4
+ import rasterConfig from './rasterConfig.js';
5
+
6
+ const { gdal, uploadFile, downloadFile } = mapnik();
7
+
8
+ export default async function rasterVrt(rasterPath, send = () => { }) {
9
+ if (rasterPath.includes('.tif')) {
10
+ return null;
11
+ }
12
+
13
+ const folderPath = path.posix.dirname(rasterPath);
14
+
15
+ // vrt config
16
+ const configFilePath = rasterPath.replace('/preview1', '').replace('mosaic.vrt', 'config.yml')
17
+ const configData = await rasterConfig(configFilePath);
18
+
19
+ // -b 1 -b 2 -b 3 -overwrite
20
+ // -b 1 -b 2 -b 3 -hidenodata -srcnodata "0 0 0" -addalpha -overwrite
21
+ const vrt = configData?.vrt || ' -b 1 -b 2 -b 3 -hidenodata -srcnodata "0 0 0" -vrtnodata "256 256 256" -addalpha -overwrite';
22
+
23
+
24
+ const paramsVrt = `${vrt} -input_file_list ${folderPath}/files.txt `; // ${folderPath}/mosaic.vrt ${folderPath}/*.tif
25
+ send(paramsVrt)
26
+ const obj = {
27
+ name: 'gdalbuildvrt', out: ` -o ${folderPath}/mosaic.vrt `, params: paramsVrt,
28
+ };
29
+
30
+ // check mosaic.vrt exists
31
+ const time1 = Date.now()
32
+ const fullPath = rasterPath;
33
+
34
+ send('vrt:' + rasterPath)
35
+ const { result: resStat } = await gdal({ name: `ls "${fullPath}"` });
36
+
37
+ if (resStat) return { obj, resStat };
38
+
39
+ const { result: files } = await gdal({ name: `ls "${folderPath}"` });
40
+ const fileList = files.split('\n').filter(el => el.toLowerCase().endsWith('.tif') && !el.includes('mosaic')).map(el => path.posix.join(folderPath, el) || `"${path.posix.join(folderPath, el)}"`);
41
+ send({ folderPath, files: fileList.length, time: Date.now() - time1 })
42
+
43
+ if (!fileList.length) return { err: 'fileList is empty' };
44
+
45
+ await gdal({ name: `rm -rf "${folderPath}/files.txt"` });
46
+
47
+ await uploadFile({ fileBytes: Buffer.from(fileList.join('\n')), relativeFilepath: path.posix.join(folderPath, 'files.txt') });
48
+
49
+ const time = Date.now()
50
+ send(obj);
51
+ const { result, err } = await gdal(obj);
52
+ send(err || result);
53
+ await downloadFile({ filePath: fullPath });
54
+ send({ rasterPath, time: Date.now() - time })
55
+ return { result, err, obj };
56
+ }
@@ -0,0 +1,65 @@
1
+ import path from 'node:path';
2
+ import { mkdir, writeFile } from 'node:fs/promises';
3
+
4
+ import { config, pgClients } from '@opengis/fastify-table/utils.js';
5
+
6
+ import rasterInfo from './rasterInfo.js';
7
+ import createXML from './createXML.js';
8
+ import mapnik from './mapnik.js';
9
+ import rootFolder from './rootFolder.mjs';
10
+
11
+ const { loadXML } = mapnik();
12
+
13
+ export default async function rasterXML({ id, pg = pgClients.client, send = () => { } }) {
14
+ if (!id) {
15
+ send('not enough params: id', true);
16
+ return { error: 'not enough params: id' };
17
+ }
18
+
19
+ const db = pg.options?.database;
20
+
21
+ const { source_path: rasterPath, srid, proj4 } = await pg.query(
22
+ 'SELECT source_path, srid, proj4 from gis.rasters where raster_id=$1',
23
+ [id]
24
+ ).then(el => el.rows?.[0] || {});
25
+
26
+ const proj4text = srid ? await pg.query('select proj4text from spatial_ref_sys where srid::text=$1', [srid]).then(el => el.rows?.[0]?.proj4text) : null;
27
+ const fullPath = rasterPath ? path.posix.join(config.mapServerRoot || '', config.folder, '/map/raster/', rasterPath, (rasterPath?.toLowerCase().includes('.tif') ? '' : 'mosaic.vrt')) : null;
28
+
29
+ if (!fullPath) {
30
+ send('file not found ' + fullPath, true);
31
+ return { error: 'file not found ' + fullPath };
32
+ }
33
+
34
+ const { error, srs = proj4, extent, size, gdalInfo } = await rasterInfo(fullPath);
35
+
36
+ send(`xml srs: ${proj4text || proj4 || '-'} file:${fullPath} size:${size}`);
37
+
38
+ if (error) {
39
+ send(error.toString(), true);
40
+ return { error: error.toString() };
41
+ }
42
+
43
+ const xmlFileText = await createXML({
44
+ fullPath,
45
+ srs: proj4 || proj4text || srs,
46
+ extent,
47
+ send,
48
+ size,
49
+ });
50
+
51
+ if (srs && proj4 && gdalInfo?.wgs84Extent && id) {
52
+ const wgs = '+proj=longlat +datum=WGS84 +no_defs';
53
+ await pg.query(
54
+ 'update gis.rasters set bbox=st_transform(st_transform($2,$5,$3),$4,$5) where raster_id=$1 returning bbox::box2d',
55
+ [id, gdalInfo.wgs84Extent, srs, proj4, wgs],
56
+ ).then(el => el.rows?.[0]) || {};
57
+ }
58
+
59
+ send(xmlFileText);
60
+ await loadXML({ xml: xmlFileText, name: id, reload: true });
61
+ const localPath = path.join(rootFolder, `mapnik/${db}_${id}.xml`);
62
+ await mkdir(path.dirname(localPath), { recursive: true });
63
+ await writeFile(localPath, xmlFileText);
64
+ return localPath;
65
+ }
@@ -0,0 +1,8 @@
1
+ import path from 'node:path';
2
+ import { existsSync } from 'node:fs';
3
+
4
+ import { config } from '@opengis/fastify-table/utils.js';
5
+
6
+ const root = config.temp || (existsSync('/data/local') ? '/data/local/kamianske' : process.cwd());
7
+
8
+ export default path.join(root, 'log/map').replace(/\\/g, '/');
@@ -0,0 +1,12 @@
1
+ import fp from 'fastify-plugin';
2
+ // import config from '../config.js';
3
+
4
+ import mapnik from './funcs/mapnik.js';
5
+ import gdalWrapper from './funcs/gdalWrapper.js';
6
+
7
+ async function plugin(fastify, opts) {
8
+ // fastify.decorate('mapnik', mapnik);
9
+ // fastify.decorate('gdalWrapper', gdalWrapper);
10
+ }
11
+
12
+ export default fp(plugin);
@@ -0,0 +1,241 @@
1
+ syntax = "proto3";
2
+
3
+
4
+ message render_in {
5
+ string path = 1;
6
+ string name = 2;
7
+ repeated double bbox = 3 [packed=true];
8
+ string tile = 4;
9
+ string xml = 5;
10
+ int32 width = 6;
11
+ int32 height = 7;
12
+ }
13
+
14
+
15
+ message render_out {
16
+ string err = 1;
17
+ string base64 = 2;
18
+ string tile = 3;
19
+ }
20
+
21
+ message xml_in {
22
+ string path = 1;
23
+ string name = 2;
24
+ string xml = 3;
25
+ bool reload = 4;
26
+ }
27
+
28
+ message xml_out {
29
+ string err = 1;
30
+ bool is_ok = 2;
31
+ }
32
+
33
+ message cmd_in {
34
+ string cmd = 1;
35
+ string svg = 2;
36
+ string filename = 3;
37
+ }
38
+
39
+ message cmd_out {
40
+ string err = 1;
41
+ string base64 = 2;
42
+ }
43
+
44
+ message gdal_in {
45
+ string name = 1;
46
+ string path = 2;
47
+ string out = 3;
48
+ string params = 4;
49
+ }
50
+ message gdal_out {
51
+ string result = 1;
52
+ string err = 2;
53
+ }
54
+
55
+ message clear_tiles_in {
56
+ string path = 1;
57
+ }
58
+
59
+ message clear_tiles_out {
60
+ oneof clear_message {
61
+ bool ok = 1;
62
+ string err = 2;
63
+ }
64
+ }
65
+
66
+ message empty {}
67
+
68
+ message statusRenderInfo {
69
+ string name = 1;
70
+ bool isActive = 2;
71
+ float workTime = 3;
72
+ }
73
+
74
+ message statusInfo {
75
+ repeated statusRenderInfo info = 1;
76
+ }
77
+
78
+ message printMapOut {
79
+ string map = 1;
80
+ string err = 2;
81
+ }
82
+
83
+ message xyz {
84
+ float x = 1;
85
+ float y = 2;
86
+ float z = 3;
87
+ }
88
+
89
+ message printMapIn {
90
+ string baseurl = 1;
91
+ string baseImg = 2;
92
+ repeated string xml = 3;
93
+ string overlayXml = 4;
94
+ string overlay = 5;
95
+ int32 width = 6;
96
+ int32 height = 7;
97
+ repeated double bbox = 8;
98
+ xyz pos = 9;
99
+ string geojsonSettings = 10;
100
+ }
101
+
102
+ message log_in {
103
+ uint32 rows = 1;
104
+ string level = 2;
105
+ }
106
+
107
+ message log_out {
108
+ repeated string logs = 1;
109
+ }
110
+
111
+ message sqlToShpIn {
112
+ string db = 1;
113
+ string host = 2;
114
+ string port = 3;
115
+ string sql = 4;
116
+ string savePath = 5;
117
+ string shpName = 6;
118
+ }
119
+
120
+ message shapeOut {
121
+ string zipPath = 1;
122
+ }
123
+
124
+ message fileIn {
125
+ bytes fileBytes = 1;
126
+ string relativeFilepath = 2;
127
+ }
128
+
129
+ message deleteFileIn {
130
+ string dir = 1;
131
+ repeated string objectList = 2;
132
+ }
133
+
134
+ message fileManagerOut {
135
+ bool status = 1;
136
+ string operation = 2;
137
+ }
138
+
139
+ message checkFilesDir {
140
+ string dir = 1;
141
+ repeated string filesSearch = 2;
142
+ }
143
+
144
+ enum status {
145
+ LOADING = 0;
146
+ OK = 1;
147
+ }
148
+
149
+ message filesStatus {
150
+ status fileLoadingStatus = 1;
151
+ }
152
+
153
+ message fileListIn {
154
+ string dir = 1;
155
+ }
156
+
157
+ message fileInfo {
158
+ repeated fileInfoL fileInfoList = 1;
159
+ }
160
+
161
+ message fileInfoL {
162
+ oneof fileInfo {
163
+ fileInfoObj file = 1;
164
+ dirInfoObj dir = 2;
165
+ }
166
+ }
167
+
168
+ message fileInfoObj {
169
+ string type = 1;
170
+ string birthtime = 2;
171
+ string name = 3;
172
+ uint64 size = 4;
173
+ string ext = 5;
174
+ string server = 6;
175
+ }
176
+
177
+ message dirInfoObj {
178
+ string type = 1;
179
+ string birthtime = 2;
180
+ string name = 3;
181
+ uint64 size = 4;
182
+ uint64 count = 5;
183
+ string server = 6;
184
+ }
185
+
186
+ message deleteOut {
187
+ repeated deleteObjSuccess success = 1;
188
+ repeated deleteObjError error = 2;
189
+
190
+ }
191
+
192
+ message deleteObjSuccess {
193
+ string object = 1;
194
+ string type = 2;
195
+ string status = 3;
196
+ }
197
+
198
+ message deleteObjError {
199
+ string object = 1;
200
+ string fullPath = 2;
201
+ string result = 3;
202
+ }
203
+
204
+ message readDirIn {
205
+ string dir = 1;
206
+ repeated string filter = 2;
207
+ string fullPath = 3;
208
+ }
209
+
210
+ message readDirOut {
211
+ repeated string res = 1;
212
+
213
+ }
214
+
215
+ message downloadFileIn {
216
+ string filePath = 1;
217
+ }
218
+
219
+ message downloadFileOut {
220
+ bytes chunk_data = 1;
221
+ }
222
+
223
+
224
+ service Map {
225
+ rpc Render(render_in) returns (render_out) {}
226
+ rpc RenderXML(render_in) returns (render_out) {}
227
+ rpc LoadXML(xml_in) returns (xml_out) {}
228
+ rpc MarkerIcon(cmd_in) returns (cmd_out) {}
229
+ rpc Gdal(gdal_in) returns (gdal_out) {}
230
+ rpc ClearTiles(clear_tiles_in) returns (clear_tiles_out) {}
231
+ rpc RenderStatus(empty) returns (statusInfo) {}
232
+ rpc PrintMap(printMapIn) returns (printMapOut) {}
233
+ rpc Log(log_in) returns (log_out) {}
234
+ rpc SqlToShp(sqlToShpIn) returns (shapeOut) {}
235
+ rpc uploadFile(fileIn) returns (fileManagerOut) {}
236
+ rpc deleteFiles(deleteFileIn) returns (deleteOut) {}
237
+ rpc checkFiles(checkFilesDir) returns (filesStatus) {}
238
+ rpc fileList(fileListIn) returns (fileInfo) {}
239
+ rpc readDir(readDirIn) returns (readDirOut) {}
240
+ rpc downloadFile(downloadFileIn) returns (stream downloadFileOut) {}
241
+ }
@@ -0,0 +1,19 @@
1
+ import insertColumns from './registers/insert.columns.js';
2
+ import insertFilters from './registers/insert.filters.js';
3
+ import metadataXML from './metadata/metadataXML.js';
4
+ import getLayerGeom from './services/get.layer.geom.js';
5
+ import gisRegistry from './registers/gis.registry.js';
6
+ import gisRegistryList from './registers/gis.registry.list.js';
7
+ import mapRegistry from './registers/map.registry.js';
8
+
9
+ export default async function route(app) {
10
+ app.put('/insert-columns/:token', insertColumns);
11
+ app.put('/insert-filters/:token', insertFilters);
12
+ app.get('/gis-registry/:slug', { config: { policy: ['public'] } }, gisRegistry);
13
+ app.get('/gis-registry-list', { config: { policy: ['public'] } }, gisRegistryList);
14
+ app.get('/map-registry/:slug/:id', { config: { policy: ['public'] } }, mapRegistry);
15
+
16
+ app.get('/xml/:id', { config: { policy: ['public'] } }, metadataXML);
17
+
18
+ app.get('/get-layer-geom/:id', { config: { policy: ['public'] } }, getLayerGeom);
19
+ }
@@ -0,0 +1,13 @@
1
+ import { handlebars, getTemplate } from "@opengis/fastify-table/utils.js";
2
+
3
+ export default async function insertColumns(req,reply) {
4
+ const { params} = req;
5
+ const { id } = params;
6
+
7
+ const pt = await getTemplate('templates','ISO19136_2017_gml_template');
8
+ const data = await handlebars.compile(pt)({ id: id });
9
+
10
+ return reply
11
+ .header('Content-Type', 'text/xml; charset=utf-8')
12
+ .send(data);
13
+ }
@@ -0,0 +1,26 @@
1
+ import { getSelectVal } from '@opengis/fastify-table/utils.js';
2
+
3
+ export async function attachClassifiers(rowOrRows, classifiers) {
4
+ const rows = Array.isArray(rowOrRows) ? rowOrRows : [rowOrRows];
5
+
6
+ for (const row of rows) {
7
+ for (const { name, classifier } of classifiers) {
8
+ const value = row[name];
9
+ if (value != null && classifier) {
10
+
11
+ const match = await getSelectVal({ name: classifier, values: [value] });
12
+ const matchVal = Object.values(match)?.[0]
13
+
14
+ if (typeof matchVal === 'object' && matchVal !== null) {
15
+ row[`${name}_data`] = matchVal;
16
+ } else if (
17
+ typeof matchVal === 'string' && matchVal !== null
18
+ ) {
19
+ row[`${name}_text`] = matchVal;
20
+ };
21
+ }
22
+ }
23
+ }
24
+
25
+ return rowOrRows;
26
+ }
@@ -0,0 +1,5 @@
1
+ export function extractVisibleColumns(columns, mode = "table") {
2
+ return columns.filter((col) =>
3
+ mode === "card" ? col.hidden_card !== true : col.hidden_register !== true
4
+ );
5
+ }
@@ -0,0 +1,100 @@
1
+ import { attachClassifiers } from './classifiers.js';
2
+ import { extractVisibleColumns } from './columns.js';
3
+ import { getMeta, getFilterSQL } from "@opengis/fastify-table/utils.js";
4
+
5
+ export async function handleRegistryRequest({ settings, query, object_id, offset, limit, page, pg }) {
6
+ const { name, table_name, columns, filters, query: whereQuery, order, pk, register_id, is_files } = settings;
7
+ const parsedColumns = Array.isArray(columns) ? columns : JSON.parse(columns);
8
+ const filtersParsed = Array.isArray(filters) ? filters : JSON.parse(filters);
9
+ const activeFilters = filtersParsed.filter((f) => f.disabled !== true);
10
+ const { geom } = await getMeta({ pg, table: table_name });
11
+
12
+ const mode = object_id ? "card" : "table";
13
+ const visibleColumns = extractVisibleColumns(parsedColumns, mode);
14
+ const selectColumns = visibleColumns.map((col) => col.name);
15
+ const columnsInfo = visibleColumns.map((col) => ({
16
+ name: col.name,
17
+ ua: col.ua,
18
+ format: col.format,
19
+ data: col.data,
20
+ view_type: col.view_type
21
+ }));
22
+
23
+ const classifiers = visibleColumns
24
+ .filter((col) => col.data && ["select", "badge", "tags"].includes(col.format))
25
+ .map((col) => ({ name: col.name, classifier: col.data }));
26
+
27
+ if (object_id) {
28
+ const sql = `
29
+ SELECT "${pk}" as id, ${selectColumns.join(", ")} ${geom ? `, st_asgeojson(${geom})::json as geom` : ''}
30
+ FROM ${table_name}
31
+ WHERE ${pk} = $1
32
+ `;
33
+ const {
34
+ rows: [row],
35
+ } = await pg.query(sql, [object_id]);
36
+
37
+ //if (!row) return reply.code(404).send({ message: 'Object not found', status: 404 });
38
+ if (!row) throw new Error('Object not found');
39
+
40
+ await attachClassifiers(row, classifiers);
41
+
42
+ return {
43
+ row,
44
+ columns: columnsInfo,
45
+ register_id,
46
+ name,
47
+ is_files,
48
+ };
49
+ }
50
+
51
+ const { search, filter } = query || {};
52
+ const { q: sqlFilter } = (filter || search)
53
+ ? await getFilterSQL({
54
+ table: table_name,
55
+ search: search,
56
+ filter: filter,
57
+ filterList: filters,
58
+ json: 1
59
+ })
60
+ : { q: '1=1' };
61
+
62
+ const whereConditions = [whereQuery, sqlFilter].filter(Boolean).join(' AND ');
63
+ const whereClause = whereConditions ? `WHERE ${whereConditions}` : '';
64
+
65
+ const sqlBase = `FROM ${table_name} ${whereClause}`;
66
+ const sqlOrder = order ? `ORDER BY ${order}` : "";
67
+ const sqlLimit = `LIMIT $1 OFFSET $2`;
68
+
69
+ const sqlSelect = `SELECT "${pk}" as id, ${selectColumns.join(", ")} ${geom ? `, st_asgeojson(${geom})::json as geom` : ''} ${sqlBase}`;
70
+ const dataQuery = `${sqlSelect} ${sqlOrder} ${sqlLimit}`;
71
+ const totalQuery = `SELECT COUNT(*) ${sqlBase}`;
72
+
73
+ const [dataRes, countRes] = await Promise.all([
74
+ pg.query(dataQuery, [limit, offset]),
75
+ pg.query(totalQuery),
76
+ ]);
77
+
78
+ const rows = await attachClassifiers(dataRes.rows, classifiers);
79
+ const total = parseInt(countRes.rows[0]?.count || 0, 10);
80
+
81
+ const listConfig = {};
82
+ for (const col of parsedColumns) {
83
+ if (col.view_type === 'title') listConfig.title = col.name;
84
+ if (col.view_type === 'subtitle') listConfig.subtitle = col.name;
85
+ }
86
+
87
+ return {
88
+ register_id,
89
+ name,
90
+ rows,
91
+ total,
92
+ columns: columnsInfo,
93
+ filters: activeFilters,
94
+ limit,
95
+ page,
96
+ config: {
97
+ listConfig
98
+ }
99
+ };
100
+ }
@@ -0,0 +1,32 @@
1
+ import { pgClients, getTemplate } from "@opengis/fastify-table/utils.js";
2
+ import { handleRegistryRequest } from './funcs/handleRegistryRequest.js';
3
+ const pg = pgClients.client;
4
+
5
+ export default async function gisRegistry(req = {}) {
6
+ const { params = {}, query = {} } = req;
7
+ const { slug } = params;
8
+ const { page = 1, limit = 9, object_id } = query;
9
+ const offset = limit * (page - 1);
10
+
11
+ //if (!slug) return reply.code(404).send({ message: 'Params slug is required', status: 404 });
12
+ if (!slug) throw new Error('Params slug is required');
13
+
14
+ const {
15
+ rows: [registry],
16
+ } = await pg.query(
17
+ `SELECT register_id, name, table_name, columns, filters, query, "order", pk, register_key, is_files
18
+ FROM gis.registers
19
+ WHERE register_key = $1`,
20
+ [slug]
21
+ );
22
+
23
+ if (registry) {
24
+ return await handleRegistryRequest({ settings: registry, query, object_id, offset, limit, page, pg });
25
+ }
26
+
27
+ const registryTemplate = await getTemplate('registry', slug);
28
+ //if (!registryTemplate) return reply.code(404).send({ message: 'Template not found', status: 404 });
29
+ if (!registryTemplate) throw new Error('Template not found');
30
+
31
+ return await handleRegistryRequest({ settings: registryTemplate, query, object_id, offset, limit, page, pg });
32
+ }