@opengis/gis 0.1.82 → 0.2.0
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.
- package/dist/index.css +1 -1
- package/dist/index.js +4665 -5874
- package/dist/index.umd.cjs +40 -56
- package/module/gis/table/gis.group_list.table.json +36 -0
- package/module/test/cls/doc_status.json +31 -31
- package/module/test/cls/ts.temp_structure.ts_class.json +50 -0
- package/module/test/layer/bp.json +60 -0
- package/module/test/map/address4.json +2 -42
- package/module/test/map/bp_myo.json +37 -0
- package/module/test/map/main.json +44 -0
- package/module/test/map/mbd.json +24 -176
- package/module/test/map/ts.json +20 -129
- package/module/test/select/core.user_uid.sql +1 -1
- package/package.json +61 -61
- package/server/migrations/widgets.sql +21 -0
- package/server/routes/gis/index.mjs +2 -0
- package/server/routes/gis/services/get.services.js +4 -2
- package/server/routes/gis/services/legend.auto.js +78 -0
- package/server/routes/map/controllers/mapFormat.js +4 -5
- package/server/routes/map/index.mjs +36 -17
- package/server/routes/map/maps/add.map.js +42 -0
- package/server/routes/map/maps/del.map.js +19 -0
- package/server/routes/map/maps/get.map.js +65 -0
- package/server/routes/map/vtile1.js +12 -4
- package/server/routes/map/widgets/add.widget.js +39 -0
- package/server/routes/map/widgets/del.widget.js +23 -0
- package/server/routes/map/widgets/get.widget.js +41 -0
package/module/test/map/ts.json
CHANGED
|
@@ -1,152 +1,43 @@
|
|
|
1
1
|
{
|
|
2
2
|
"history": true,
|
|
3
|
-
"height": "calc(100vh - 65px)",
|
|
4
|
-
"
|
|
3
|
+
"height": "calc(100vh - 65px)",
|
|
4
|
+
"center": [
|
|
5
|
+
34.65450,
|
|
6
|
+
48.51174
|
|
7
|
+
],
|
|
8
|
+
"zoom": 11,
|
|
9
|
+
"layers": ["ed67980cd690"],
|
|
5
10
|
"widgets": [
|
|
6
11
|
{
|
|
7
12
|
"type": "info",
|
|
8
13
|
"position": "top-left",
|
|
9
14
|
"config": {
|
|
10
15
|
"title": "Тимчасові споруди",
|
|
11
|
-
"content": "<p style='font-size: 14px; color: #34495E;'>Інформація про тимчасові споруди встановлені на території м. Кам'янське</p>"
|
|
12
|
-
"goTo": [
|
|
13
|
-
{
|
|
14
|
-
"label": "Карта адресного реєстру",
|
|
15
|
-
"url": "/map/addr"
|
|
16
|
-
},
|
|
17
|
-
{
|
|
18
|
-
"label": "Карта БП/МУО",
|
|
19
|
-
"url": "/map/bp_myo"
|
|
20
|
-
},
|
|
21
|
-
{
|
|
22
|
-
"label": "Карта містобудівної документації",
|
|
23
|
-
"url": "/map/mbd"
|
|
24
|
-
},
|
|
25
|
-
{
|
|
26
|
-
"label": "Основна карта",
|
|
27
|
-
"url": "/map/main"
|
|
28
|
-
}
|
|
29
|
-
]
|
|
16
|
+
"content": "<p style='font-size: 14px; color: #34495E;'>Інформація про тимчасові споруди встановлені на території м. Кам'янське</p>"
|
|
30
17
|
}
|
|
31
18
|
},
|
|
32
19
|
{
|
|
33
|
-
"type": "
|
|
20
|
+
"type": "dataset",
|
|
34
21
|
"position": "top-left",
|
|
35
22
|
"config": {
|
|
36
|
-
"layer":
|
|
37
|
-
|
|
38
|
-
"service": "vtile",
|
|
39
|
-
"service_key": "ts",
|
|
40
|
-
"map_key": "ts",
|
|
41
|
-
"visible": true,
|
|
42
|
-
"url": "/api/vtile/ts.temp_structure/ua/{z}/{x}/{y}.vmt",
|
|
43
|
-
"style": {
|
|
44
|
-
"type": "polygon",
|
|
45
|
-
"attrType": "icon-by-attribute",
|
|
46
|
-
"attribute": "temp_structure_status",
|
|
47
|
-
"default_icon": "pin6-l-fa-question+4767e6.png",
|
|
48
|
-
"icon_base_url": "https://data.softpro.ua/api-user/markerIcon/",
|
|
49
|
-
"icon_size": 1,
|
|
50
|
-
"iconZoom": 14,
|
|
51
|
-
"pointZoom": 14,
|
|
52
|
-
"icon_anchor": "bottom",
|
|
53
|
-
"rules": [
|
|
54
|
-
{
|
|
55
|
-
"value": "1",
|
|
56
|
-
"label": "Діючий",
|
|
57
|
-
"color": "#28a745",
|
|
58
|
-
"icon": "pin6-l-fa-check+28a745.png"
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
"value": "2",
|
|
62
|
-
"label": "Анульований",
|
|
63
|
-
"color": "#dc3545",
|
|
64
|
-
"icon": "pin6-l-fa-exclamation+dc3545.png"
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
"value": "3",
|
|
68
|
-
"label": "Призупинений",
|
|
69
|
-
"color": "#ffc107",
|
|
70
|
-
"icon": "pin6-l-ty-lock-closed-outline+ffc107.png"
|
|
71
|
-
},
|
|
72
|
-
{
|
|
73
|
-
"value": "4",
|
|
74
|
-
"label": "Завершився термін дії",
|
|
75
|
-
"color": "purple",
|
|
76
|
-
"icon": "pin6-l-fa-clock-o+800080.png"
|
|
77
|
-
}
|
|
78
|
-
],
|
|
79
|
-
"popup": {
|
|
80
|
-
"mode": "html",
|
|
81
|
-
"title": "<strong>Тимчасова споруда</strong>",
|
|
82
|
-
"fields": [
|
|
83
|
-
{
|
|
84
|
-
"label": "Назва",
|
|
85
|
-
"value": "name"
|
|
86
|
-
},
|
|
87
|
-
{
|
|
88
|
-
"label": "Кадастровий номер ЗД",
|
|
89
|
-
"value": "cad_num"
|
|
90
|
-
},
|
|
91
|
-
{
|
|
92
|
-
"label": "Площа тимчасової споруди, м. кв.",
|
|
93
|
-
"value": "area"
|
|
94
|
-
}
|
|
95
|
-
]
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}
|
|
23
|
+
"layer":"ed67980cd690",
|
|
24
|
+
"attribute":"status"
|
|
99
25
|
}
|
|
100
26
|
},
|
|
101
|
-
|
|
102
|
-
"type": "
|
|
103
|
-
"
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
27
|
+
{
|
|
28
|
+
"type": "layers",
|
|
29
|
+
"visible":false
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"type": "legend",
|
|
33
|
+
"position":"bottom-right"
|
|
107
34
|
},
|
|
108
35
|
{
|
|
109
36
|
"type": "basemaps",
|
|
110
37
|
"position": "bottom-left",
|
|
111
|
-
"title": "Базові карти"
|
|
112
|
-
"config": {
|
|
113
|
-
"default": "voyager",
|
|
114
|
-
"layers": [
|
|
115
|
-
{
|
|
116
|
-
"id": "voyager",
|
|
117
|
-
"title": "Базова карта (voyager)",
|
|
118
|
-
"url": "https://data.gki.com.ua/api-user/rtile/voyager/ua/{z}/{x}/{y}.png",
|
|
119
|
-
"service": "raster",
|
|
120
|
-
"map_key": "ts",
|
|
121
|
-
"service_key": "ts",
|
|
122
|
-
"attribution": "© <a href='http://www.openstreetmap.org/copyright'>OpenStreetMap</a>, © <a href='https://carto.com/attributions'>CARTO</a>",
|
|
123
|
-
"image": "https://data.gki.com.ua/api-user/rtile/voyager/ua/12/2422/1400.png",
|
|
124
|
-
"owner": "OSM",
|
|
125
|
-
"basemap": true
|
|
126
|
-
},
|
|
127
|
-
{
|
|
128
|
-
"id": "esri",
|
|
129
|
-
"title": "ESRI Online Imagery(2022-2023)",
|
|
130
|
-
"url": "https://server.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}.png",
|
|
131
|
-
"service": "raster",
|
|
132
|
-
"image": "https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/7/47/69.png"
|
|
133
|
-
}
|
|
134
|
-
]
|
|
135
|
-
},
|
|
136
|
-
"visible": true
|
|
137
|
-
}
|
|
138
|
-
],
|
|
139
|
-
"interactions": {
|
|
140
|
-
"hover": {
|
|
141
|
-
"enabled": true
|
|
142
|
-
},
|
|
143
|
-
"navigation": {
|
|
144
|
-
"enabled": true
|
|
145
|
-
},
|
|
146
|
-
"click": {
|
|
147
|
-
"enabled": true
|
|
38
|
+
"title": "Базові карти"
|
|
148
39
|
}
|
|
149
|
-
|
|
40
|
+
],
|
|
150
41
|
"tools": [
|
|
151
42
|
"home",
|
|
152
43
|
"geolocation",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
select uid, coalesce(coalesce(sur_name,'')||coalesce(' '||user_name,'') ||coalesce(' '||father_name,''),login) as text from admin.users
|
|
1
|
+
select uid, coalesce(coalesce(sur_name,'')||coalesce(' '||user_name,'') ||coalesce(' '||father_name,''),login) as text from admin.users
|
package/package.json
CHANGED
|
@@ -1,61 +1,61 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@opengis/gis",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"type": "module",
|
|
5
|
-
"author": "Softpro",
|
|
6
|
-
"main": "./dist/index.js",
|
|
7
|
-
"files": [
|
|
8
|
-
"dist/*",
|
|
9
|
-
"module/*",
|
|
10
|
-
"server/*",
|
|
11
|
-
"plugin.js",
|
|
12
|
-
"utils.js",
|
|
13
|
-
"config.js",
|
|
14
|
-
"README.md",
|
|
15
|
-
"LICENSE"
|
|
16
|
-
],
|
|
17
|
-
"scripts": {
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"build
|
|
23
|
-
"build": "vite build",
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"docs:
|
|
28
|
-
"docs:
|
|
29
|
-
"docs:
|
|
30
|
-
"
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
"
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
"@opengis/
|
|
45
|
-
"@opengis/
|
|
46
|
-
"@opengis/
|
|
47
|
-
"@opengis/
|
|
48
|
-
"@
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
"eslint
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
"
|
|
59
|
-
"
|
|
60
|
-
}
|
|
61
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@opengis/gis",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"author": "Softpro",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist/*",
|
|
9
|
+
"module/*",
|
|
10
|
+
"server/*",
|
|
11
|
+
"plugin.js",
|
|
12
|
+
"utils.js",
|
|
13
|
+
"config.js",
|
|
14
|
+
"README.md",
|
|
15
|
+
"LICENSE"
|
|
16
|
+
],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"start1": "bun server",
|
|
19
|
+
"patch": "npm version patch && git push && npm publish",
|
|
20
|
+
"dev": "bun --hot server",
|
|
21
|
+
"front": "vite dev",
|
|
22
|
+
"build-lib": "vite build",
|
|
23
|
+
"build:admin": "vite build admin",
|
|
24
|
+
"build": "vite build",
|
|
25
|
+
"preview": "vite preview",
|
|
26
|
+
"prod": "NODE_ENV=production node server",
|
|
27
|
+
"docs:install": "npm install --prefix ./docs",
|
|
28
|
+
"docs:dev": "npm run --prefix ./docs docs:dev",
|
|
29
|
+
"docs:build": "npm run --prefix ./docs docs:build",
|
|
30
|
+
"docs:preview": "npm run --prefix ./docs docs:preview",
|
|
31
|
+
"prepublishOnly": "npm run build"
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"@mapbox/sphericalmercator": "1.2.0",
|
|
35
|
+
"carto": "0.16.3"
|
|
36
|
+
},
|
|
37
|
+
"peerDependencies": {
|
|
38
|
+
"@opengis/fastify-table": "^2.0.13"
|
|
39
|
+
},
|
|
40
|
+
"resolutions": {
|
|
41
|
+
"rollup": "4.30.0"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@opengis/core": "^0.0.23",
|
|
45
|
+
"@opengis/fastify-table": "^2.0.13",
|
|
46
|
+
"@opengis/filter": "^0.1.7",
|
|
47
|
+
"@opengis/form": "^0.0.28",
|
|
48
|
+
"@opengis/table": "^0.0.27",
|
|
49
|
+
"@vitejs/plugin-vue": "^5.2.3",
|
|
50
|
+
"axios": "^1.11.0",
|
|
51
|
+
"eslint": "8.49.0",
|
|
52
|
+
"eslint-config-airbnb": "19.0.4",
|
|
53
|
+
"lucide-vue-next": "^0.514.0",
|
|
54
|
+
"sass-embedded": "1.86.3",
|
|
55
|
+
"typescript": "^5.9.2",
|
|
56
|
+
"vite": "^6.3.5",
|
|
57
|
+
"vue": "^3.5.13",
|
|
58
|
+
"vue-router": "4.5.1",
|
|
59
|
+
"vuedraggable": "^4.1.0"
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
create schema if not exists gis;
|
|
2
|
+
|
|
3
|
+
CREATE TABLE if not exists gis.widgets
|
|
4
|
+
(
|
|
5
|
+
widget_id text NOT NULL DEFAULT next_id(),
|
|
6
|
+
map_id text NOT NULL,
|
|
7
|
+
name text,
|
|
8
|
+
type text NOT NULL,
|
|
9
|
+
title text,
|
|
10
|
+
position text,
|
|
11
|
+
config jsonb,
|
|
12
|
+
created_by text NOT NULL,
|
|
13
|
+
updated_by text,
|
|
14
|
+
updated_at timestamp without time zone,
|
|
15
|
+
created_at timestamp without time zone NOT NULL DEFAULT now(),
|
|
16
|
+
CONSTRAINT widgets_pkey PRIMARY KEY (widget_id),
|
|
17
|
+
CONSTRAINT widgets_map_id_fkey FOREIGN KEY (map_id)
|
|
18
|
+
REFERENCES gis.maps (map_id)
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
COMMENT ON TABLE gis.widgets IS 'Map widgets';
|
|
@@ -15,6 +15,7 @@ import addService from './services/add.service.js';
|
|
|
15
15
|
import addGisRegistry from './registers/add.registry.js';
|
|
16
16
|
import deleteGisRegistry from './registers/del.registry.js';
|
|
17
17
|
import getServicesCol from './services/get.services.col.js';
|
|
18
|
+
import legendAuto from './services/legend.auto.js';
|
|
18
19
|
|
|
19
20
|
async function route(app) {
|
|
20
21
|
app.put('/insert-columns/:token', insertColumns);
|
|
@@ -38,6 +39,7 @@ async function route(app) {
|
|
|
38
39
|
app.post('/gis-service/:id?', { config: { policy: ['public'] } }, addService);
|
|
39
40
|
app.put('/gis-service/:id', { config: { policy: ['public'] } }, addService);
|
|
40
41
|
app.delete('/gis-service/:id', { config: { policy: ['public'] } }, deleteService);
|
|
42
|
+
app.get('/legend-auto/:id', { config: { policy: ['public'] } }, legendAuto);
|
|
41
43
|
}
|
|
42
44
|
|
|
43
45
|
export default route;
|
|
@@ -13,9 +13,7 @@ const columnType = {
|
|
|
13
13
|
};
|
|
14
14
|
|
|
15
15
|
export default async function getServices({ params = {}, pg = pgClients.client }, reply) {
|
|
16
|
-
const { columns = [] } = await getMeta({ pg, table }) || {};
|
|
17
16
|
|
|
18
|
-
const fields = columns.map(({ name, dataTypeID, title }) => ({ name, type: columnType[pg.pgType?.[dataTypeID] || 'text'], label: title || name }));
|
|
19
17
|
|
|
20
18
|
const rows = await pg.query(`
|
|
21
19
|
SELECT
|
|
@@ -31,6 +29,10 @@ export default async function getServices({ params = {}, pg = pgClients.client }
|
|
|
31
29
|
Object.assign(rows[0], { html });
|
|
32
30
|
}
|
|
33
31
|
|
|
32
|
+
const { columns = [] } = await getMeta({ pg, table: rows[0].source_path }) || {};
|
|
33
|
+
|
|
34
|
+
const fields = columns.map(({ name, dataTypeID, title }) => ({ name, type: columnType[pg.pgType?.[dataTypeID] || 'text'], label: title || name }));
|
|
35
|
+
|
|
34
36
|
const noCenterIds = rows.filter(row => !row.center && row.bbox).map(row => row.service_id);
|
|
35
37
|
|
|
36
38
|
const centers = noCenterIds.length ? await pg.query(`SELECT json_object_agg(service_id, st_pointonsurface(bbox)::json) FROM gis.services where service_id=any($1)`, [noCenterIds].filter(Boolean)).then(el => el.rows?.[0]?.json_object_agg || {}) : {};
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { dataUpdate, getMeta, getSelectVal, yml2json } from "@opengis/fastify-table/utils.js";
|
|
2
|
+
|
|
3
|
+
export default async function legendAuto({ params = {}, query = {}, user = {}, pg = pgClients.client }, reply) {
|
|
4
|
+
if (!params.id) {
|
|
5
|
+
return reply.status(400).send({ error: "not enough params: id", code: 400 });
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const service = await pg.query(`SELECT source_path as table, style, legend as dblegend FROM gis.services where service_id=$1`, [params.id]).then(el => el.rows?.[0]);
|
|
9
|
+
|
|
10
|
+
if (!service) {
|
|
11
|
+
return reply.status(404).send({ error: "Service not found", code: 404 });
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const { style, dblegend, table } = service;
|
|
15
|
+
|
|
16
|
+
if (!table) {
|
|
17
|
+
return reply.status(400).send({ error: "service table not specified", code: 400 });
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (dblegend && !query.nocache) {
|
|
21
|
+
return reply.status(400).send({ error: "legend already exists", code: 400 });
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (!style) {
|
|
25
|
+
return reply.status(400).send({ error: "empty service style", code: 400 });
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const { colorAttr, iconAttr } = yml2json(style);
|
|
29
|
+
|
|
30
|
+
if (!colorAttr && !iconAttr) {
|
|
31
|
+
return reply.status(400).send({ error: "colorAttr / iconAttr not specified", code: 400 });
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const { columns = [] } = await getMeta({ pg, table });
|
|
35
|
+
|
|
36
|
+
const attr = columns.find(col => col.name === (colorAttr || iconAttr));
|
|
37
|
+
|
|
38
|
+
if (!attr?.name) {
|
|
39
|
+
return reply.status(404).send({ error: "attribute column not found", code: 404 });
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const values = await pg.query(`select array_agg(distinct "${attr.name}") from ${table}`).then(el => el.rows?.[0]?.array_agg || []);
|
|
43
|
+
const arr = await getSelectVal({ pg, name: `${table}.${attr.name}`, table, values, ar: true });
|
|
44
|
+
|
|
45
|
+
const colors = {
|
|
46
|
+
1: "#FFCF1F1F",
|
|
47
|
+
2: "#FF1FCF2D",
|
|
48
|
+
3: "#FF1F77CF"
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const colorKeys = Object.keys(colors).map(Number);
|
|
52
|
+
|
|
53
|
+
const legend = arr
|
|
54
|
+
? arr.map((el, idx) => ({
|
|
55
|
+
name: el.id,
|
|
56
|
+
label: el.text,
|
|
57
|
+
icon: iconAttr ? el.icon : undefined,
|
|
58
|
+
color: colorAttr ? (el.color || colors[colorKeys[idx % colorKeys.length]]) : undefined,
|
|
59
|
+
}))
|
|
60
|
+
: values.map((el, idx) => ({
|
|
61
|
+
name: el,
|
|
62
|
+
label: el,
|
|
63
|
+
icon: undefined,
|
|
64
|
+
color: colorAttr ? (colors[colorKeys[idx % colorKeys.length]]) : undefined,
|
|
65
|
+
}));
|
|
66
|
+
|
|
67
|
+
const res = await dataUpdate({
|
|
68
|
+
pg,
|
|
69
|
+
table: 'gis.services',
|
|
70
|
+
id: params.id,
|
|
71
|
+
data: {
|
|
72
|
+
legend
|
|
73
|
+
},
|
|
74
|
+
uid: user.uid,
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
return reply.status(200).send(res);
|
|
78
|
+
}
|
|
@@ -84,22 +84,21 @@ export default async function mapFormat(req, reply) {
|
|
|
84
84
|
if (excluded.includes(col.name)) continue;
|
|
85
85
|
if (col.hidden_card === true) continue;
|
|
86
86
|
|
|
87
|
-
const name = col.ua || col.name;
|
|
87
|
+
const name = col.label || col.ua || col.name;
|
|
88
88
|
let value;
|
|
89
89
|
value = fullRow[`${col.name}_data`]?.text
|
|
90
90
|
|| fullRow[`${col.name}_text`]
|
|
91
|
-
|| fullRow[col.name]
|
|
92
|
-
|| '-';
|
|
91
|
+
|| fullRow[col.name] ;
|
|
93
92
|
|
|
94
93
|
if (col.format === 'date' && fullRow[col.name]) {
|
|
95
94
|
// const dt = formatDate(fullRow[col.name], { hash: { format: 'dd.mm.yy' } });
|
|
96
95
|
const dt = await handlebars.compile(`{{formatDate "${fullRow[col.name]}"}}`)({ format: 'dd.mm.yy' });
|
|
97
96
|
value = dt;
|
|
98
97
|
}
|
|
99
|
-
|
|
98
|
+
if (!value) continue;
|
|
100
99
|
result.push(`<div class="grid grid-cols-1 gap-1 py-3 sm:grid-cols-3 sm:gap-4 even:bg-gray-50 text-[12px]">
|
|
101
100
|
<dt class="text-gray-900">${name}</dt>
|
|
102
|
-
<dd class="text-gray-700 sm:col-span-2">${value}</dd>
|
|
101
|
+
<dd class="text-gray-700 sm:col-span-2">${value|| '-'}</dd>
|
|
103
102
|
</div>`);
|
|
104
103
|
}
|
|
105
104
|
|
|
@@ -13,10 +13,18 @@ import mapFormat from './controllers/mapFormat.js';
|
|
|
13
13
|
import maps from './controllers/maps.js';
|
|
14
14
|
import markerIconApi from './controllers/marker_icon.js';
|
|
15
15
|
|
|
16
|
+
import getMap from './maps/get.map.js';
|
|
17
|
+
import addMap from './maps/add.map.js';
|
|
18
|
+
import delMap from './maps/del.map.js';
|
|
19
|
+
|
|
20
|
+
import getWidget from './widgets/get.widget.js';
|
|
21
|
+
import addWidget from './widgets/add.widget.js';
|
|
22
|
+
import delWidget from './widgets/del.widget.js';
|
|
23
|
+
|
|
16
24
|
const schemaInfo = {
|
|
17
25
|
type: 'object',
|
|
18
26
|
properties: {
|
|
19
|
-
|
|
27
|
+
publicParams: {
|
|
20
28
|
slug: {
|
|
21
29
|
type: 'string',
|
|
22
30
|
},
|
|
@@ -37,31 +45,42 @@ const schemaInfo = {
|
|
|
37
45
|
},
|
|
38
46
|
};
|
|
39
47
|
|
|
40
|
-
const
|
|
48
|
+
const publicParams = { config: { policy: 'L0' }, schema: schemaInfo }; // * L0 === public
|
|
49
|
+
const privilegedParams = { config: { policy: 'L1', role: 'admin' }, schema: schemaInfo }; // ? just auth or admin
|
|
41
50
|
|
|
42
51
|
export default async function route(app) {
|
|
43
|
-
app.get('/
|
|
44
|
-
app.
|
|
45
|
-
app.
|
|
46
|
-
app.
|
|
47
|
-
|
|
52
|
+
app.get('/gis-map/:id?', publicParams, getMap);
|
|
53
|
+
app.post('/gis-map/:id?', privilegedParams, addMap);
|
|
54
|
+
app.put('/gis-map/:id', privilegedParams, addMap);
|
|
55
|
+
app.delete('/gis-map/:id', privilegedParams, delMap);
|
|
56
|
+
|
|
57
|
+
app.get('/gis-widget/:map/:id?', publicParams, getWidget);
|
|
58
|
+
app.post('/gis-widget/:map/:id?', privilegedParams, addWidget);
|
|
59
|
+
app.put('/gis-widget/:map/:id', privilegedParams, addWidget);
|
|
60
|
+
app.delete('/gis-widget/:map/:id', privilegedParams, delWidget);
|
|
61
|
+
|
|
62
|
+
app.get('/maps', publicParams, maps);
|
|
63
|
+
app.get('/map/:slug', publicParams, map);
|
|
64
|
+
app.get('/map-tiles/:slug/:z/:y/:x', publicParams, mapTiles);
|
|
65
|
+
app.get('/map-features/:slug/:id', publicParams, mapFeatures);
|
|
66
|
+
app.get('/map-features-point/:slug', publicParams, mapFeatures);
|
|
48
67
|
|
|
49
|
-
app.get('/map-catalog',
|
|
50
|
-
app.get('/map-catalog/:service/:attr',
|
|
51
|
-
app.get('/layer-rtile/:id/:z/:y/:x',
|
|
52
|
-
app.get('/layer-vtile/:id/:z/:y/:x',
|
|
68
|
+
app.get('/map-catalog', publicParams, mapCatalog);
|
|
69
|
+
app.get('/map-catalog/:service/:attr', publicParams, mapCatalogAttribute);
|
|
70
|
+
app.get('/layer-rtile/:id/:z/:y/:x', publicParams, rtile);
|
|
71
|
+
app.get('/layer-vtile/:id/:z/:y/:x', publicParams, vtile);
|
|
53
72
|
|
|
54
73
|
if (!app.hasRoute({ method: 'GET', url: '/api/vtile/:layer/:lang/:z/:y/:x', })) {
|
|
55
74
|
console.log("\x1b[34m%s\x1b[0m", 'add vtile from gis');
|
|
56
|
-
app.get('/vtile/:layer/:lang/:z/:y/:x',
|
|
75
|
+
app.get('/vtile/:layer/:lang/:z/:y/:x', publicParams, vtile1);
|
|
57
76
|
}
|
|
58
77
|
if (!app.hasRoute({ method: 'GET', url: '/api/gis-layer-list', })) {
|
|
59
78
|
console.log("\x1b[34m%s\x1b[0m", 'add gis-layer-list from gis');
|
|
60
|
-
app.get('/gis-layer-list',
|
|
79
|
+
app.get('/gis-layer-list', publicParams, layerList);
|
|
61
80
|
}
|
|
62
81
|
|
|
63
|
-
app.get('/gis-icon/*',
|
|
64
|
-
app.get('/icon/*',
|
|
65
|
-
app.get('/marker-icon/*',
|
|
66
|
-
app.get('/map-format',
|
|
82
|
+
app.get('/gis-icon/*', publicParams, markerIconApi);
|
|
83
|
+
app.get('/icon/*', publicParams, markerIconApi);
|
|
84
|
+
app.get('/marker-icon/*', publicParams, markerIconApi);
|
|
85
|
+
app.get('/map-format', publicParams, mapFormat);
|
|
67
86
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { dataInsert, dataUpdate, pgClients } from "@opengis/fastify-table/utils.js";
|
|
2
|
+
export default async function addMap({
|
|
3
|
+
method, params = {}, body, pg = pgClients.client, user = {},
|
|
4
|
+
}, reply) {
|
|
5
|
+
const { uid } = user;
|
|
6
|
+
|
|
7
|
+
if (!uid) {
|
|
8
|
+
return reply.status(401).send('unauthorized');
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
if (method === 'POST') {
|
|
12
|
+
if (!body?.name) {
|
|
13
|
+
return reply.status(400).send('not enough body params: name');
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (!body?.map_key) {
|
|
17
|
+
return reply.status(400).send('not enough body params: map_key');
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const { rows = [] } = await dataInsert({
|
|
21
|
+
pg,
|
|
22
|
+
id: params.id,
|
|
23
|
+
table: 'gis.maps',
|
|
24
|
+
data: body,
|
|
25
|
+
uid,
|
|
26
|
+
});
|
|
27
|
+
return reply.status(200).send(rows[0]);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (!params.id) {
|
|
31
|
+
return reply.status(400).send('not enough params: id');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const row = await dataUpdate({
|
|
35
|
+
pg,
|
|
36
|
+
id: params.id,
|
|
37
|
+
table: 'gis.maps',
|
|
38
|
+
data: body,
|
|
39
|
+
uid,
|
|
40
|
+
});
|
|
41
|
+
return reply.status(200).send(row);
|
|
42
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { dataDelete, pgClients } from "@opengis/fastify-table/utils.js";
|
|
2
|
+
|
|
3
|
+
export default async function delMap({
|
|
4
|
+
params = {}, pg = pgClients.client, user = {},
|
|
5
|
+
}, reply) {
|
|
6
|
+
const { uid } = user;
|
|
7
|
+
|
|
8
|
+
if (!uid) {
|
|
9
|
+
return reply.status(401).send('unauthorized');
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const row = await dataDelete({
|
|
13
|
+
pg,
|
|
14
|
+
id: params.id,
|
|
15
|
+
table: 'gis.maps',
|
|
16
|
+
uid,
|
|
17
|
+
});
|
|
18
|
+
return reply.status(200).send(row);
|
|
19
|
+
}
|