@lbdudc/gp-gis-dsl 0.2.6 → 0.3.1

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.
@@ -58,7 +58,66 @@ createWmsLayer: WMS_SYMBOL LAYER_SYMBOL identifier (AS_SYMBOL text)? OPAR_SYMBOL
58
58
  wmsSubLayer (COMMA_SYMBOL wmsSubLayer)*
59
59
  CPAR_SYMBOL SCOL_SYMBOL;
60
60
 
61
- wmsSubLayer: identifier identifier;
61
+ wmsSubLayer:
62
+ identifier identifier
63
+ | (wmsUrl wmsLayerName wmsFormatName? wmsCrs? wmsStyles? wmsQueryable? wmsAttribution? wmsBboxGroup? wmsVersion?)
64
+ ;
65
+
66
+ wmsUrl:
67
+ URL_WMS_SYMBOL text
68
+ ;
69
+
70
+ wmsLayerName:
71
+ COMMA_SYMBOL LAYERNAME_SYMBOL text
72
+ ;
73
+
74
+ wmsFormatName:
75
+ COMMA_SYMBOL FORMAT_SYMBOL text
76
+ ;
77
+
78
+ wmsCrs:
79
+ COMMA_SYMBOL CRS_SYMBOL text
80
+ ;
81
+
82
+ wmsBboxCrs:
83
+ COMMA_SYMBOL BBOX_CRS_SYMBOL text
84
+ ;
85
+
86
+ wmsMinX:
87
+ COMMA_SYMBOL MINX_SYMBOL floatNumber
88
+ ;
89
+
90
+ wmsMinY:
91
+ COMMA_SYMBOL MINY_SYMBOL floatNumber
92
+ ;
93
+
94
+ wmsMaxX:
95
+ COMMA_SYMBOL MAXX_SYMBOL floatNumber
96
+ ;
97
+
98
+ wmsMaxY:
99
+ COMMA_SYMBOL MAXY_SYMBOL floatNumber
100
+ ;
101
+
102
+ wmsBboxGroup:
103
+ wmsBboxCrs wmsMinX wmsMinY wmsMaxX wmsMaxY
104
+ ;
105
+
106
+ wmsStyles:
107
+ COMMA_SYMBOL STYLE_SYMBOL text
108
+ ;
109
+
110
+ wmsQueryable:
111
+ COMMA_SYMBOL QUERYABLE_SYMBOL text
112
+ ;
113
+
114
+ wmsAttribution:
115
+ COMMA_SYMBOL ATTRIBUTION_SYMBOL text
116
+ ;
117
+
118
+ wmsVersion:
119
+ COMMA_SYMBOL VERSION_SYMBOL text
120
+ ;
62
121
 
63
122
  createSortableMap: SORTABLE_SYMBOL createMap;
64
123
 
@@ -159,6 +218,7 @@ fragment LETTER_WITHOUT_FLOAT_PART: [a-df-zA-DF-Z_$\u0080-\uffff];
159
218
 
160
219
  fragment UNDERLINE_SYMBOL: '_';
161
220
  fragment QUOTE_SYMBOL: '"';
221
+ fragment MINUS_SYMBOL: '-';
162
222
 
163
223
  CREATE_SYMBOL: C R E A T E;
164
224
  GIS_SYMBOL: G I S;
@@ -194,6 +254,19 @@ MAP_SYMBOL: M A P;
194
254
  SET_SYMBOL: S E T;
195
255
  DEPLOYMENT_SYMBOL: D E P L O Y M E N T;
196
256
 
257
+ URL_WMS_SYMBOL: U R L W M S;
258
+ LAYERNAME_SYMBOL: L A Y E R N A M E;
259
+ FORMAT_SYMBOL: F O R M A T;
260
+ CRS_SYMBOL: C R S;
261
+ BBOX_CRS_SYMBOL: B B O X C R S;
262
+ MINX_SYMBOL: M I N X;
263
+ MINY_SYMBOL: M I N Y;
264
+ MAXX_SYMBOL: M A X X;
265
+ MAXY_SYMBOL: M A X Y;
266
+ QUERYABLE_SYMBOL: Q U E R Y A B L E;
267
+ ATTRIBUTION_SYMBOL: A T T R I B U T I O N;
268
+ VERSION_SYMBOL: V E R S I O N;
269
+
197
270
  ZERO_ONE_SYMBOL: '0..1';
198
271
  ONE_ONE_SYMBOL: '1..1';
199
272
  ZERO_MANY_SYMBOL: '0..*';
@@ -224,7 +297,7 @@ SCOL_SYMBOL : ';';
224
297
 
225
298
  HEX_COLOR: POUND_SYMBOL HEXDIGIT HEXDIGIT HEXDIGIT HEXDIGIT HEXDIGIT HEXDIGIT;
226
299
  INT_NUMBER: DIGITS;
227
- FLOAT_NUMBER: (DIGITS? DOT_SYMBOL)? DIGITS;
300
+ FLOAT_NUMBER: MINUS_SYMBOL? (DIGITS? DOT_SYMBOL)? DIGITS;
228
301
 
229
302
  COMMENT: '//' ~[\r\n]* -> skip;
230
303
  //SPACE: [ \t]+ -> skip;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lbdudc/gp-gis-dsl",
3
- "version": "0.2.6",
3
+ "version": "0.3.1",
4
4
  "homepage": "https://github.com/lbdudc/gis-dsl#readme",
5
5
  "repository": {
6
6
  "type": "git",
package/src/GISVisitor.js CHANGED
@@ -8,6 +8,7 @@ import {
8
8
  Map,
9
9
  GeoJSONLayerStyle,
10
10
  WMSStyleCustom,
11
+ WMSServiceLayer,
11
12
  } from "./spl/Map.js";
12
13
  import { transformation, getPropertyParams } from "./GISVisitorHelper.js";
13
14
  // import { generateProduct } from "./project-generator.js";
@@ -256,8 +257,75 @@ class Visitor extends GISGrammarVisitor {
256
257
 
257
258
  visitCreateWmsLayer(ctx) {
258
259
  const id = ctx.getChild(2).getText();
259
- let label = id,
260
- from = 4,
260
+ let label = id;
261
+
262
+ const isWmsService = ctx
263
+ .getChild(6)
264
+ .getText()
265
+ .toLowerCase()
266
+ .startsWith("urlwms");
267
+
268
+ const layer = isWmsService
269
+ ? this._createWmsServiceLayer(ctx, id, label)
270
+ : this._createStandardLayer(ctx, id, label);
271
+
272
+ this.log(`visitCreateWmsLayer ${id} - ${label}`);
273
+
274
+ this.store.getCurrentProduct().addLayer(layer);
275
+ }
276
+
277
+ _getCleanText = (node) => node?.text()?.getText().replace(/"/g, "") || null;
278
+
279
+ _createWmsServiceLayer(ctx, id, label) {
280
+ const sub = ctx.wmsSubLayer(0);
281
+ const clean = this._getCleanText;
282
+
283
+ const url = clean(sub.wmsUrl());
284
+ const layerName = clean(sub.wmsLayerName());
285
+ const format = clean(sub.wmsFormatName());
286
+ const crs = clean(sub.wmsCrs());
287
+ const version = clean(sub.wmsVersion());
288
+ const attribution = clean(sub.wmsAttribution());
289
+
290
+ const styles = sub.wmsStyles()
291
+ ? clean(sub.wmsStyles())
292
+ .split(",")
293
+ .map((s) => s.trim())
294
+ : [];
295
+
296
+ const queryable = sub.wmsQueryable()
297
+ ? clean(sub.wmsQueryable()).toLowerCase() === "true"
298
+ : false;
299
+
300
+ let bbox = null;
301
+ const bboxNode = sub.wmsBboxGroup();
302
+ if (bboxNode) {
303
+ bbox = {
304
+ crs: clean(bboxNode.wmsBboxCrs()),
305
+ minx: parseFloat(bboxNode.wmsMinX().floatNumber().getText()),
306
+ miny: parseFloat(bboxNode.wmsMinY().floatNumber().getText()),
307
+ maxx: parseFloat(bboxNode.wmsMaxX().floatNumber().getText()),
308
+ maxy: parseFloat(bboxNode.wmsMaxY().floatNumber().getText()),
309
+ };
310
+ }
311
+
312
+ return new WMSServiceLayer({
313
+ id,
314
+ label,
315
+ url,
316
+ layerName,
317
+ format,
318
+ crs,
319
+ bbox,
320
+ styles,
321
+ queryable,
322
+ attribution,
323
+ version,
324
+ });
325
+ }
326
+
327
+ _createStandardLayer(ctx, id, label) {
328
+ let from = 4,
261
329
  i,
262
330
  aux,
263
331
  entity,
@@ -269,10 +337,9 @@ class Visitor extends GISGrammarVisitor {
269
337
  label = ctx.getChild(4).getText().slice(1, -1);
270
338
  from = 6;
271
339
  }
272
-
273
340
  const layer = new WMSLayer(id, label);
274
341
 
275
- for (i = from; i < ctx.getChildCount() - 2; i = i + 2) {
342
+ for (i = from; i < ctx.getChildCount() - 2; i += 2) {
276
343
  aux = ctx.getChild(i);
277
344
  auxEntityName = aux.getChild(0).getText();
278
345
  entity = this.store.getCurrentProduct().getEntity(auxEntityName);
@@ -282,7 +349,7 @@ class Visitor extends GISGrammarVisitor {
282
349
  if (entity) {
283
350
  layer.addSubLayer(entity.name, styleName);
284
351
  } else {
285
- // GeoTIFF case: no associated entity exists
352
+ // GeoTIFF: no entity
286
353
  const normalizedId = id
287
354
  .replace(/Layer$/, "")
288
355
  .replace(/^(\d+)([A-Z][a-z]+)/, "$1_$2")
@@ -291,9 +358,7 @@ class Visitor extends GISGrammarVisitor {
291
358
  }
292
359
  }
293
360
 
294
- this.log(`visitCreateWmsLayer ${id} - ${label}`);
295
-
296
- this.store.getCurrentProduct().addLayer(layer);
361
+ return layer;
297
362
  }
298
363
 
299
364
  visitCreateMap(ctx, sortable) {
@@ -1,93 +1,93 @@
1
- import features from "./features.js";
2
-
3
- function transformation(spec) {
4
- _relationships(spec);
5
- const newSpec = {
6
- features: features,
7
- basicData: {
8
- name: spec.name,
9
- },
10
- data: {
11
- dataModel: {
12
- entities: spec.entities,
13
- enums: [],
14
- },
15
- },
16
- mapViewer: {
17
- maps: spec.maps,
18
- layers: spec.layers,
19
- styles: spec.styles,
20
- },
21
- };
22
-
23
- if (spec.extra) {
24
- newSpec.basicData.extra = spec.extra;
25
- }
26
-
27
- return newSpec;
28
- }
29
-
30
- function _relationships(spec) {
31
- let source, target;
32
-
33
- spec.relationships.forEach((r) => {
34
- source = spec.getEntity(r.source);
35
- target = spec.getEntity(r.target);
36
- let sourceOwner = false;
37
- let targetOwner = false;
38
- let sourceMultiple = _multiple(r.sourceOpts.multiplicity);
39
- let targetMultiple = _multiple(r.targetOpts.multiplicity);
40
- if (sourceMultiple && !targetMultiple) {
41
- targetOwner = true;
42
- } else {
43
- sourceOwner = true;
44
- }
45
-
46
- source.properties.push({
47
- name: r.sourceOpts.label,
48
- class: target.name,
49
- owner: sourceOwner,
50
- bidirectional: r.targetOpts.label,
51
- multiple: sourceMultiple,
52
- required: _required(r.sourceOpts.multiplicity),
53
- });
54
-
55
- target.properties.push({
56
- name: r.targetOpts.label,
57
- class: source.name,
58
- owner: targetOwner,
59
- bidirectional: r.sourceOpts.label,
60
- multiple: targetMultiple,
61
- required: _required(r.targetOpts.multiplicity),
62
- });
63
- });
64
- }
65
-
66
- function _multiple(multiplicity) {
67
- return ["1..1", "0..1"].find((a) => a == multiplicity) == null;
68
- }
69
-
70
- function _required(multiplicity) {
71
- return ["1..1", "1..*"].find((a) => a == multiplicity) != null;
72
- }
73
-
74
- function getPropertyParams(symbols) {
75
- if (!symbols.length) return null;
76
-
77
- const ret = {};
78
- if (symbols.includes("identifier")) {
79
- ret.pk = true;
80
- }
81
- if (symbols.includes("required")) {
82
- ret.required = true;
83
- }
84
- if (symbols.includes("unique")) {
85
- ret.unique = true;
86
- }
87
- if (symbols.includes("display_string")) {
88
- ret.displayString = true;
89
- }
90
- return ret;
91
- }
92
-
93
- export { transformation, getPropertyParams };
1
+ import features from "./features.js";
2
+
3
+ function transformation(spec) {
4
+ _relationships(spec);
5
+ const newSpec = {
6
+ features: features,
7
+ basicData: {
8
+ name: spec.name,
9
+ },
10
+ data: {
11
+ dataModel: {
12
+ entities: spec.entities,
13
+ enums: [],
14
+ },
15
+ },
16
+ mapViewer: {
17
+ maps: spec.maps,
18
+ layers: spec.layers,
19
+ styles: spec.styles,
20
+ },
21
+ };
22
+
23
+ if (spec.extra) {
24
+ newSpec.basicData.extra = spec.extra;
25
+ }
26
+
27
+ return newSpec;
28
+ }
29
+
30
+ function _relationships(spec) {
31
+ let source, target;
32
+
33
+ spec.relationships.forEach((r) => {
34
+ source = spec.getEntity(r.source);
35
+ target = spec.getEntity(r.target);
36
+ let sourceOwner = false;
37
+ let targetOwner = false;
38
+ let sourceMultiple = _multiple(r.sourceOpts.multiplicity);
39
+ let targetMultiple = _multiple(r.targetOpts.multiplicity);
40
+ if (sourceMultiple && !targetMultiple) {
41
+ targetOwner = true;
42
+ } else {
43
+ sourceOwner = true;
44
+ }
45
+
46
+ source.properties.push({
47
+ name: r.sourceOpts.label,
48
+ class: target.name,
49
+ owner: sourceOwner,
50
+ bidirectional: r.targetOpts.label,
51
+ multiple: sourceMultiple,
52
+ required: _required(r.sourceOpts.multiplicity),
53
+ });
54
+
55
+ target.properties.push({
56
+ name: r.targetOpts.label,
57
+ class: source.name,
58
+ owner: targetOwner,
59
+ bidirectional: r.sourceOpts.label,
60
+ multiple: targetMultiple,
61
+ required: _required(r.targetOpts.multiplicity),
62
+ });
63
+ });
64
+ }
65
+
66
+ function _multiple(multiplicity) {
67
+ return ["1..1", "0..1"].find((a) => a == multiplicity) == null;
68
+ }
69
+
70
+ function _required(multiplicity) {
71
+ return ["1..1", "1..*"].find((a) => a == multiplicity) != null;
72
+ }
73
+
74
+ function getPropertyParams(symbols) {
75
+ if (!symbols.length) return null;
76
+
77
+ const ret = {};
78
+ if (symbols.includes("identifier")) {
79
+ ret.pk = true;
80
+ }
81
+ if (symbols.includes("required")) {
82
+ ret.required = true;
83
+ }
84
+ if (symbols.includes("unique")) {
85
+ ret.unique = true;
86
+ }
87
+ if (symbols.includes("display_string")) {
88
+ ret.displayString = true;
89
+ }
90
+ return ret;
91
+ }
92
+
93
+ export { transformation, getPropertyParams };
package/src/cli.js CHANGED
@@ -1,34 +1,34 @@
1
- #!/usr/bin/env node
2
-
3
- import meow from "meow";
4
- import fs from "fs";
5
- import gisdslParser from "./index.js";
6
- import path from "path";
7
-
8
- const usage = "Usage: gisdsl input output";
9
-
10
- const cli = meow(usage, {
11
- importMeta: import.meta,
12
- flags: {
13
- debug: {
14
- type: "boolean",
15
- default: false,
16
- },
17
- },
18
- });
19
-
20
- if (cli.input.length < 2) {
21
- cli.showHelp();
22
- }
23
-
24
- const inputPath = path.resolve(process.cwd(), cli.input.at(0));
25
- const input = fs.readFileSync(inputPath, {
26
- encoding: "utf-8",
27
- });
28
-
29
- const spec = gisdslParser(input, cli.flags.debug);
30
-
31
- const outputPath = path.resolve(process.cwd(), cli.input.at(1));
32
- fs.writeFileSync(outputPath, JSON.stringify(spec, null, 2), "utf8");
33
-
34
- console.log(`File ${cli.input.at(1)} generated`);
1
+ #!/usr/bin/env node
2
+
3
+ import meow from "meow";
4
+ import fs from "fs";
5
+ import gisdslParser from "./index.js";
6
+ import path from "path";
7
+
8
+ const usage = "Usage: gisdsl input output";
9
+
10
+ const cli = meow(usage, {
11
+ importMeta: import.meta,
12
+ flags: {
13
+ debug: {
14
+ type: "boolean",
15
+ default: false,
16
+ },
17
+ },
18
+ });
19
+
20
+ if (cli.input.length < 2) {
21
+ cli.showHelp();
22
+ }
23
+
24
+ const inputPath = path.resolve(process.cwd(), cli.input.at(0));
25
+ const input = fs.readFileSync(inputPath, {
26
+ encoding: "utf-8",
27
+ });
28
+
29
+ const spec = gisdslParser(input, cli.flags.debug);
30
+
31
+ const outputPath = path.resolve(process.cwd(), cli.input.at(1));
32
+ fs.writeFileSync(outputPath, JSON.stringify(spec, null, 2), "utf8");
33
+
34
+ console.log(`File ${cli.input.at(1)} generated`);
@@ -1,26 +1,26 @@
1
- import antlr4 from "antlr4";
2
-
3
- import SyntaxGenericError from "./SyntaxGenericError.js";
4
-
5
- /**
6
- * Custom Error Listener
7
- *
8
- * @returns {object}
9
- */
10
- class ErrorListener extends antlr4.error.ErrorListener {
11
- /**
12
- * Checks syntax error
13
- *
14
- * @param {object} recognizer The parsing support code essentially. Most of it is error recovery stuff
15
- * @param {object} symbol Offending symbol
16
- * @param {int} line Line of offending symbol
17
- * @param {int} column Position in line of offending symbol
18
- * @param {string} message Error message
19
- * @param {string} payload Stack trace
20
- */
21
- syntaxError(recognizer, symbol, line, column, message) {
22
- throw new SyntaxGenericError({ line, column, message });
23
- }
24
- }
25
-
26
- export default ErrorListener;
1
+ import antlr4 from "antlr4";
2
+
3
+ import SyntaxGenericError from "./SyntaxGenericError.js";
4
+
5
+ /**
6
+ * Custom Error Listener
7
+ *
8
+ * @returns {object}
9
+ */
10
+ class ErrorListener extends antlr4.error.ErrorListener {
11
+ /**
12
+ * Checks syntax error
13
+ *
14
+ * @param {object} recognizer The parsing support code essentially. Most of it is error recovery stuff
15
+ * @param {object} symbol Offending symbol
16
+ * @param {int} line Line of offending symbol
17
+ * @param {int} column Position in line of offending symbol
18
+ * @param {string} message Error message
19
+ * @param {string} payload Stack trace
20
+ */
21
+ syntaxError(recognizer, symbol, line, column, message) {
22
+ throw new SyntaxGenericError({ line, column, message });
23
+ }
24
+ }
25
+
26
+ export default ErrorListener;
@@ -1,18 +1,18 @@
1
- export default class SyntaxGenericError extends Error {
2
- constructor(payload) {
3
- super(payload);
4
-
5
- this.code = "E_SYNTAX_GENERIC";
6
- this.message = "Something went wrong";
7
-
8
- if (typeof payload !== "undefined") {
9
- this.message = payload.message || this.message;
10
- this.payload = payload;
11
- }
12
-
13
- console.error(
14
- `line ${this.payload.line}, col ${this.payload.column}: ${this.payload.message}`,
15
- );
16
- Error.captureStackTrace(this, SyntaxGenericError);
17
- }
18
- }
1
+ export default class SyntaxGenericError extends Error {
2
+ constructor(payload) {
3
+ super(payload);
4
+
5
+ this.code = "E_SYNTAX_GENERIC";
6
+ this.message = "Something went wrong";
7
+
8
+ if (typeof payload !== "undefined") {
9
+ this.message = payload.message || this.message;
10
+ this.payload = payload;
11
+ }
12
+
13
+ console.error(
14
+ `line ${this.payload.line}, col ${this.payload.column}: ${this.payload.message}`,
15
+ );
16
+ Error.captureStackTrace(this, SyntaxGenericError);
17
+ }
18
+ }
package/src/features.js CHANGED
@@ -1,5 +1,6 @@
1
1
  export default [
2
2
  "MapViewer",
3
+ "ChartViewer",
3
4
  "Tools",
4
5
  "DM_SpatialDatabase",
5
6
  "DM_GenerationType",
package/src/index.js CHANGED
@@ -1,26 +1,26 @@
1
- import antlr4 from "antlr4";
2
- import GISGrammarLexer from "./lib/GISGrammarLexer.js";
3
- import GISGrammarParser from "./lib/GISGrammarParser.js";
4
- import ErrorListener from "./error/ErrorListener.js";
5
- import GISVisitor from "./GISVisitor.js";
6
- import store from "./store.js";
7
-
8
- export default function parse(inputStr, debug = false) {
9
- const chars = new antlr4.InputStream(inputStr);
10
- const lexer = new GISGrammarLexer(chars);
11
- lexer.strictMode = false; // do not use js strictMode
12
-
13
- const tokens = new antlr4.CommonTokenStream(lexer);
14
- const parser = new GISGrammarParser(tokens);
15
-
16
- const errorListener = new ErrorListener();
17
- // Do this after creating the parser and before running it
18
- parser.removeErrorListeners(); // Remove default ConsoleErrorListener
19
- parser.addErrorListener(errorListener); // Add custom error listener
20
-
21
- const visitor = new GISVisitor(store, debug);
22
- const tree = parser.parse();
23
- visitor.start(tree);
24
-
25
- return store.getLastGeneratedProduct();
26
- }
1
+ import antlr4 from "antlr4";
2
+ import GISGrammarLexer from "./lib/GISGrammarLexer.js";
3
+ import GISGrammarParser from "./lib/GISGrammarParser.js";
4
+ import ErrorListener from "./error/ErrorListener.js";
5
+ import GISVisitor from "./GISVisitor.js";
6
+ import store from "./store.js";
7
+
8
+ export default function parse(inputStr, debug = false) {
9
+ const chars = new antlr4.InputStream(inputStr);
10
+ const lexer = new GISGrammarLexer(chars);
11
+ lexer.strictMode = false; // do not use js strictMode
12
+
13
+ const tokens = new antlr4.CommonTokenStream(lexer);
14
+ const parser = new GISGrammarParser(tokens);
15
+
16
+ const errorListener = new ErrorListener();
17
+ // Do this after creating the parser and before running it
18
+ parser.removeErrorListeners(); // Remove default ConsoleErrorListener
19
+ parser.addErrorListener(errorListener); // Add custom error listener
20
+
21
+ const visitor = new GISVisitor(store, debug);
22
+ const tree = parser.parse();
23
+ visitor.start(tree);
24
+
25
+ return store.getLastGeneratedProduct();
26
+ }