@opengis/gis 0.2.155 → 0.2.156

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.
@@ -1,9 +1,9 @@
1
1
  import { defineComponent as te, resolveDirective as We, openBlock as u, createElementBlock as m, createElementVNode as n, Fragment as W, renderList as X, toDisplayString as d, withDirectives as we, createTextVNode as Xe, normalizeClass as ae, ref as $, watch as S, computed as h, vModelText as Ke, onMounted as Ye, onBeforeUnmount as Ze, createCommentVNode as q, createVNode as B, withCtx as He, createBlock as F, resolveDynamicComponent as Je } from "vue";
2
2
  import { useRouter as et, useRoute as tt } from "vue-router";
3
3
  import { TooltipDirective as st, notify as M } from "@opengis/core";
4
- import { _ as nt, u as lt, f as rt, M as ot, i as it, j as be, F as at } from "./index-CEghyThV.js";
5
- import { _ as ut, a as ct, b as dt, c as ft } from "./HeaderActions.vue_vue_type_script_setup_true_lang-9qBoTuch.js";
6
- import { _ as he } from "./ExtentOutlineLayer.vue_vue_type_script_setup_true_lang-BqFaLaMA.js";
4
+ import { _ as nt, u as lt, f as rt, M as ot, i as it, j as be, F as at } from "./index-DUvc4hNZ.js";
5
+ import { _ as ut, a as ct, b as dt, c as ft } from "./HeaderActions.vue_vue_type_script_setup_true_lang-DMkvpe25.js";
6
+ import { _ as he } from "./ExtentOutlineLayer.vue_vue_type_script_setup_true_lang-CtT-2WgB.js";
7
7
  const mt = { class: "flex-1 overflow-y-auto p-4 sm:p-6" }, pt = { class: "space-y-3" }, gt = { class: "bg-white p-3 rounded-xl border border-gray-200 shadow-sm" }, yt = { class: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-2" }, vt = { class: "text-xs text-gray-500 mb-1" }, xt = {
8
8
  key: 0,
9
9
  class: "text-base text-md font-semibold text-gray-900"
@@ -2,9 +2,9 @@ import { defineComponent as B, mergeModels as j, useModel as S, computed as h, d
2
2
  import { useRoute as Z, useRouter as ee } from "vue-router";
3
3
  import { notify as F } from "@opengis/core";
4
4
  import { _ as te } from "./TableFormHeader.vue_vue_type_script_setup_true_lang-Mci_tseM.js";
5
- import { V as N } from "./vs-datatable-D7TR-oB2.js";
6
- import { _ as z, n as R, m as E, r as H } from "./import-utils-DEV-Lsyq.js";
7
- import { a as ae, b as le, c as se, d as oe, e as ie } from "./index-CEghyThV.js";
5
+ import { V as N } from "./vs-datatable-B9s6O_XG.js";
6
+ import { _ as z, n as R, m as E, r as H } from "./import-utils-CC4-riao.js";
7
+ import { a as ae, b as le, c as se, d as oe, e as ie } from "./index-DUvc4hNZ.js";
8
8
  import { LucideChevronRight as re } from "lucide-vue-next";
9
9
  import { _ as ne } from "./MapSettingsTabs.vue_vue_type_script_setup_true_lang-CKCK3NqY.js";
10
10
  const ue = { class: "vs-form" }, de = { class: "vs-form__body auto-rows-max container" }, ce = { class: "flex flex-wrap" }, me = { class: "h-fit w-full mb-6 bg-white border border-gray-200 rounded-lg p-6" }, ve = { class: "h-fit w-full flex flex-wrap" }, pe = { class: "w-full" }, fe = /* @__PURE__ */ B({
@@ -1,12 +1,12 @@
1
1
  import { openBlock as C, createElementBlock as D, createElementVNode as v, defineComponent as ee, ref as S, watch as I, createTextVNode as Gi, createVNode as j, createBlock as M, createCommentVNode as q, defineAsyncComponent as Qi, unref as Te, withCtx as We, withDirectives as qe, vModelText as Ke, normalizeClass as ve, Fragment as Hn, renderList as Vn, toDisplayString as le, getCurrentInstance as qn, onBeforeUnmount as Kn, toRef as Wi, computed as ue, onMounted as Ji, resolveDynamicComponent as Zi } from "vue";
2
2
  import { useRoute as Xi, useRouter as el } from "vue-router";
3
3
  import { notify as Q } from "@opengis/core";
4
- import { _ as Re, u as Ie, f as nl, M as il, g as ll, h as rl, i as tl, j as kn, k as ol, l as ul, m as al, s as Cn, n as sl } from "./index-CEghyThV.js";
5
- import { _ as cl, a as fl, b as dl, c as pl } from "./HeaderActions.vue_vue_type_script_setup_true_lang-9qBoTuch.js";
6
- import { S as ml, C as hl } from "./CardIcon-Dleu0v3g.js";
4
+ import { _ as Re, u as Ie, f as nl, M as il, g as ll, h as rl, i as tl, j as kn, k as ol, l as ul, m as al, s as Cn, n as sl } from "./index-DUvc4hNZ.js";
5
+ import { _ as cl, a as fl, b as dl, c as pl } from "./HeaderActions.vue_vue_type_script_setup_true_lang-DMkvpe25.js";
6
+ import { S as ml, C as hl } from "./CardIcon-D-1qypTS.js";
7
7
  import { _ as zn } from "./MonacoEditor.vue_vue_type_script_setup_true_lang-D3ZPeXMw.js";
8
- import { V as $e } from "./vs-datatable-D7TR-oB2.js";
9
- import { _ as ln, m as rn, r as xe } from "./import-utils-DEV-Lsyq.js";
8
+ import { V as $e } from "./vs-datatable-B9s6O_XG.js";
9
+ import { _ as ln, m as rn, r as xe } from "./import-utils-CC4-riao.js";
10
10
  /*! js-yaml 4.1.1 https://github.com/nodeca/js-yaml @license MIT */
11
11
  function Gn(e) {
12
12
  return typeof e > "u" || e === null;
@@ -1,7 +1,7 @@
1
1
  import { defineComponent as F, mergeModels as O, defineAsyncComponent as I, useModel as R, ref as y, watch as K, openBlock as o, createElementBlock as s, createElementVNode as e, createVNode as $, unref as x, withCtx as S, createStaticVNode as V, useSlots as P, computed as H, Fragment as b, createTextVNode as U, createCommentVNode as N, renderList as A, normalizeStyle as Q, toDisplayString as M, normalizeClass as z, withModifiers as X, createBlock as Y, resolveDynamicComponent as ee, withDirectives as te, renderSlot as ne } from "vue";
2
2
  import { notify as E } from "@opengis/core";
3
3
  import { Edit as le, Trash as oe } from "lucide-vue-next";
4
- import { _ as u } from "./index-CEghyThV.js";
4
+ import { _ as u } from "./index-DUvc4hNZ.js";
5
5
  const se = { class: "flex items-center justify-center col-span-3 gap-2" }, re = { class: "flex justify-end p-[20px] gap-[10px] border-t w-full" }, ie = /* @__PURE__ */ F({
6
6
  __name: "vs-datatable-controls",
7
7
  props: /* @__PURE__ */ O({
@@ -0,0 +1,7 @@
1
+ select
2
+ srid::text as id,
3
+ auth_name || ' - ' || auth_srid as text
4
+ from
5
+ public.spatial_ref_sys
6
+ order by
7
+ srid asc
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengis/gis",
3
- "version": "0.2.155",
3
+ "version": "0.2.156",
4
4
  "type": "module",
5
5
  "author": "Softpro",
6
6
  "main": "./dist/index.js",
@@ -8,6 +8,7 @@ package map;
8
8
  // Map Service
9
9
  // ----------------------------
10
10
  service MapService {
11
+ rpc PrintMap(PrintMapRequest) returns (PrintMapOut);
11
12
  rpc RenderTile(RenderTileRequest) returns (RenderTileOut);
12
13
  rpc ClearTile(ClearTileRequest) returns (ClearTileOut);
13
14
  rpc ReadDir(ReadDirRequest) returns (ReadDirOut);
@@ -17,6 +18,7 @@ service MapService {
17
18
  rpc CreateIndex(CreateIndexRequest) returns (CreateIndexOut); // create/update index.geojson for folder
18
19
  rpc ConvertLog(ConvertLogRequest) returns (ConvertLogOut); // json state for current stream tasks
19
20
  rpc ConvertCog(ConvertCogRequest) returns (stream JobProgress); // streaming COG conversion
21
+ rpc ConvertVector(ConvertVectorRequest) returns (ConvertVectorOut); // vector file/archive -> GeoJSON
20
22
  rpc ImportData(ImportDataRequest) returns (stream JobProgress); // streaming SHP -> PostGIS import
21
23
  rpc UploadXML(UploadXMLRequest) returns (UploadXMLOut);
22
24
  rpc UploadRaster(UploadRasterRequest) returns (UploadRasterOut);
@@ -30,6 +32,26 @@ service MapService {
30
32
  // ----------------------------
31
33
  // Messages for MapService
32
34
  // ----------------------------
35
+ message PrintMapRequest {
36
+ string path = 1;
37
+ string geojson = 2;
38
+ repeated double bbox = 3; // [minx, miny, maxx, maxy]
39
+ int32 width = 4;
40
+ int32 height = 5;
41
+ string ttl = 6; // "5m", "1h", "1d" or "0"
42
+ optional bool base64 = 7; // optional output mode flag: true -> base64, false -> raw bytes
43
+ int32 opacity = 8; // 0-255
44
+ repeated string colors = 9; // [ #00FF00, #0000FF]
45
+ repeated string layers = 10;
46
+ }
47
+
48
+ message PrintMapOut {
49
+ string base64 = 1;
50
+ bool cache = 2;
51
+ string err = 3;
52
+ bytes data = 7; // raw PNG bytes (used when request.base64=false)
53
+ }
54
+
33
55
  message RenderTileRequest {
34
56
  string name = 1;
35
57
  string path = 2;
@@ -42,6 +64,7 @@ message RenderTileRequest {
42
64
  optional int32 y = 9; // optional XYZ tile y
43
65
  bool meta = 10; // when true return tile metadata/path only (without base64 image payload)
44
66
  optional bool base64 = 11; // optional output mode flag: true -> base64, false -> raw bytes
67
+ optional string format = 12; // optional tile image format: png|jpg|jpeg|webp
45
68
  }
46
69
 
47
70
  message RenderTileOut {
@@ -182,10 +205,27 @@ message ConvertCogRequest {
182
205
  int32 srid = 7; // optional target SRID for reprojection before COG conversion
183
206
  }
184
207
 
208
+ message ConvertVectorRequest {
209
+ bytes data = 1; // input vector file/archive bytes
210
+ string format = 2; // optional input format hint: zip|shp|kml|gml|geojson|json
211
+ int32 srs = 3; // target EPSG code, default 4326
212
+ string filename = 4; // optional original filename for extension/layer detection
213
+ }
214
+
215
+ message ConvertVectorOut {
216
+ string geojson = 1; // converted GeoJSON payload
217
+ string err = 2; // error text when failed
218
+ int64 size = 3; // output GeoJSON byte size
219
+ }
220
+
185
221
  message ImportDataRequest {
186
222
  string path = 1; // path to .shp file or directory under vector root
187
223
  bool recursive = 2; // process nested folders when path is directory
188
224
  bool force = 3; // overwrite existing tables when true
225
+ string mode = 4; // import mode: file|type (aliases: 1|2)
226
+ string db = 5; // PostgreSQL URL: postgresql://user:pass@host:port/dbname
227
+ string schema = 6; // target schema override
228
+ string type = 7; // optional geometry type override, e.g. LineString
189
229
  }
190
230
 
191
231
  message UploadXMLRequest {
@@ -229,7 +269,7 @@ message GetStatRequest {
229
269
  }
230
270
 
231
271
  message GetStatOut {
232
- google.protobuf.Struct result = 1; // dynamic json structure, not bound by same value type like with map
272
+ google.protobuf.Struct result = 1; // dynamic stats structure
233
273
  }
234
274
 
235
275
  message GetLogsRequest {
@@ -0,0 +1,53 @@
1
+ import path from "node:path";
2
+
3
+ import mapnik from "../../../plugins/mapnik/funcs/mapnik.js";
4
+ import { downloadFile } from "@opengis/fastify-table/utils.js";
5
+
6
+ const { ConvertVector } = mapnik();
7
+
8
+ const ALLOWED_FORMAT = new Set(["zip", "shp", "kml", "gml", "geojson", "json"]);
9
+
10
+ /**
11
+ * Конвертує векторний файл на сервері у GeoJSON через mapnik ConvertVector.
12
+ *
13
+ * @method POST /gis-convert
14
+ * @body {string} filepath - шлях до файлу на сервері
15
+ * @body {number} [srid=4326] - цільовий EPSG код
16
+ */
17
+ export default async function gisConvert({ body = {} }, reply) {
18
+ const { filepath, srid = 4326 } = body;
19
+
20
+ if (!filepath || typeof filepath !== "string") {
21
+ return reply
22
+ .status(400)
23
+ .send({ error: "Потрібен параметр filepath", code: 400 });
24
+ }
25
+
26
+ const ext = path.extname(filepath).replace(".", "").toLowerCase();
27
+ if (!ALLOWED_FORMAT.has(ext)) {
28
+ return reply.status(400).send({
29
+ error: `Непідтримуване розширення: .${ext}. Підтримується: ${[...ALLOWED_FORMAT].join(", ")}`,
30
+ code: 400,
31
+ });
32
+ }
33
+
34
+ const data = await downloadFile(filepath, { buffer: true });
35
+ if (!data) {
36
+ return reply
37
+ .status(404)
38
+ .send({ error: `Файл не знайдено: ${filepath}`, code: 404 });
39
+ }
40
+
41
+ const res = await ConvertVector({
42
+ data,
43
+ format: ext,
44
+ srs: +srid,
45
+ filename: path.basename(filepath),
46
+ }).catch((err) => ({ err }));
47
+
48
+ if (res?.err) {
49
+ return reply.code(500).send(res.err);
50
+ }
51
+
52
+ return reply.send(JSON.parse(res.geojson));
53
+ }
@@ -25,6 +25,8 @@ import getWidget from './widgets/get.widget.js';
25
25
  import addWidget from './widgets/add.widget.js';
26
26
  import delWidget from './widgets/del.widget.js';
27
27
 
28
+ import gisConvert from './controllers/gis.convert.js';
29
+
28
30
  const schemaInfo = {
29
31
  type: 'object',
30
32
  properties: {
@@ -72,8 +74,16 @@ const mapFormatSchema = {
72
74
  },
73
75
  };
74
76
 
75
- const publicParams = { config: { policy: 'L0' }, schema: schemaInfo, package: 'gis' }; // * L0 === public
76
- const privilegedParams = { config: { policy: 'L1', role: 'admin' }, schema: schemaInfo, package: 'gis' }; // ? just auth or admin
77
+ const publicParams = {
78
+ config: { policy: 'L0' },
79
+ schema: schemaInfo,
80
+ package: 'gis',
81
+ }; // * L0 === public
82
+ const privilegedParams = {
83
+ config: { policy: 'L1', role: 'admin' },
84
+ schema: schemaInfo,
85
+ package: 'gis',
86
+ }; // ? just auth or admin
77
87
 
78
88
  export default async function route(app) {
79
89
  if (!app.hasRoute({ method: 'GET', url: '/gis-map/:id?' })) {
@@ -131,7 +141,9 @@ export default async function route(app) {
131
141
  app.get('/layer-vtile/:id/:z/:y/:x', publicParams, vtile);
132
142
  }
133
143
 
134
- if (!app.hasRoute({ method: 'GET', url: '/api/vtile/:layer/:lang/:z/:y/:x' })) {
144
+ if (
145
+ !app.hasRoute({ method: 'GET', url: '/api/vtile/:layer/:lang/:z/:y/:x' })
146
+ ) {
135
147
  console.log('\x1b[34m%s\x1b[0m', 'add vtile from gis');
136
148
  app.get('/vtile/:layer/:lang/:z/:y/:x', publicParams, vtile1);
137
149
  }
@@ -165,10 +177,22 @@ export default async function route(app) {
165
177
  }
166
178
 
167
179
  if (!app.hasRoute({ method: 'GET', url: '/api/map-format' })) {
168
- app.get('/map-format', { ...publicParams, schema: mapFormatSchema }, mapFormat);
180
+ app.get(
181
+ '/map-format',
182
+ { ...publicParams, schema: mapFormatSchema },
183
+ mapFormat,
184
+ );
169
185
  }
170
186
 
171
187
  if (!app.hasRoute({ method: 'POST', url: '/api/gis-parse-geo' })) {
172
188
  app.post('/gis-parse-geo', publicParams, parseGeoFile);
173
189
  }
190
+
191
+ if (!app.hasRoute({ method: 'POST', url: '/api/gis-convert' })) {
192
+ app.post(
193
+ '/gis-convert',
194
+ { config: { policy: 'L0' }, schema: {}, package: 'gis' },
195
+ gisConvert,
196
+ );
197
+ }
174
198
  }
@@ -113,6 +113,7 @@ export default async function gisRtile({
113
113
  width: 256,
114
114
  bbox,
115
115
  ttl,
116
+ format: 'webp',
116
117
  meta,
117
118
  base64: false,
118
119
  debug: query.debug,
@@ -130,7 +131,7 @@ export default async function gisRtile({
130
131
  if (meta) {
131
132
  const accelPath = result.tile_path?.startsWith('/') ? result.tile_path : `/${result.tile_path}`;
132
133
  const metaHeaders = {
133
- 'Content-Type': 'image/png',
134
+ 'Content-Type': 'image/webp',
134
135
  'Cache-Control': query.nocache || query.nottl ? 'no-store, no-cache, must-revalidate' : 'public, max-age=2592000',
135
136
  'X-Accel-Redirect': accelPath,
136
137
  };
@@ -155,7 +156,7 @@ export default async function gisRtile({
155
156
 
156
157
  const buffer = result.data || Buffer.from(result.base64, 'base64');
157
158
 
158
- return reply.headers({ 'Content-Type': 'image/png', 'Cache-Control': query.nocache || query.nottl ? 'no-store, no-cache, must-revalidate' : 'public, max-age=2592000' }).send(buffer);
159
+ return reply.headers({ 'Content-Type': 'image/webp', 'Cache-Control': query.nocache || query.nottl ? 'no-store, no-cache, must-revalidate' : 'public, max-age=2592000' }).send(buffer);
159
160
  }
160
161
  catch (err) {
161
162
  logger.file('rtile/error', {