@mwater/visualization 5.6.0 → 5.6.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.
Files changed (92) hide show
  1. package/lib/ColorComponent.js +2 -2
  2. package/lib/TranslationsTabComponent.d.ts +34 -0
  3. package/lib/TranslationsTabComponent.js +256 -0
  4. package/lib/dashboards/DashboardComponent.js +1 -1
  5. package/lib/dashboards/ServerDashboardDataSource.d.ts +0 -1
  6. package/lib/dashboards/ServerDashboardDataSource.js +0 -15
  7. package/lib/dashboards/SettingsModalComponent.js +9 -233
  8. package/lib/datagrids/DatagridComponent.js +5 -0
  9. package/lib/datagrids/DatagridViewComponent.js +30 -4
  10. package/lib/maps/BufferLayer.d.ts +0 -13
  11. package/lib/maps/BufferLayer.js +12 -237
  12. package/lib/maps/BufferLayerDesignerComponent.d.ts +1 -1
  13. package/lib/maps/BufferLayerDesignerComponent.js +0 -5
  14. package/lib/maps/ChoroplethLayer.d.ts +1 -16
  15. package/lib/maps/ChoroplethLayer.js +13 -358
  16. package/lib/maps/ClusterLayer.d.ts +0 -9
  17. package/lib/maps/ClusterLayer.js +0 -250
  18. package/lib/maps/DirectMapDataSource.js +1 -38
  19. package/lib/maps/GridLayer.d.ts +0 -15
  20. package/lib/maps/GridLayer.js +0 -212
  21. package/lib/maps/Layer.d.ts +1 -26
  22. package/lib/maps/Layer.js +0 -13
  23. package/lib/maps/MapComponent.d.ts +19 -35
  24. package/lib/maps/MapComponent.js +135 -76
  25. package/lib/maps/MapControlComponent.d.ts +4 -5
  26. package/lib/maps/MapControlComponent.js +5 -12
  27. package/lib/maps/MapDesign.d.ts +8 -0
  28. package/lib/maps/MapDesignerComponent.d.ts +2 -0
  29. package/lib/maps/MapDesignerComponent.js +7 -2
  30. package/lib/maps/MapLayerDataSource.d.ts +0 -4
  31. package/lib/maps/MapLayerViewDesignerComponent.d.ts +3 -1
  32. package/lib/maps/MapLayerViewDesignerComponent.js +5 -1
  33. package/lib/maps/MapLayersDesignerComponent.d.ts +2 -0
  34. package/lib/maps/MapLayersDesignerComponent.js +2 -1
  35. package/lib/maps/MapTranslationsTab.d.ts +15 -0
  36. package/lib/maps/MapTranslationsTab.js +47 -0
  37. package/lib/maps/MapUtils.d.ts +11 -0
  38. package/lib/maps/MapUtils.js +47 -0
  39. package/lib/maps/MapViewComponent.d.ts +1 -1
  40. package/lib/maps/MapViewComponent.js +1 -8
  41. package/lib/maps/MarkersLayer.d.ts +1 -14
  42. package/lib/maps/MarkersLayer.js +71 -252
  43. package/lib/maps/MarkersLayerDesign.d.ts +4 -0
  44. package/lib/maps/MarkersLayerDesignerComponent.d.ts +20 -16
  45. package/lib/maps/MarkersLayerDesignerComponent.js +77 -23
  46. package/lib/maps/ServerMapDataSource.d.ts +0 -1
  47. package/lib/maps/ServerMapDataSource.js +0 -15
  48. package/lib/maps/SwitchableTileUrlLayer.d.ts +0 -2
  49. package/lib/maps/SwitchableTileUrlLayer.js +0 -9
  50. package/lib/maps/TileUrlLayer.d.ts +0 -1
  51. package/lib/maps/TileUrlLayer.js +0 -5
  52. package/lib/maps/VectorMapViewComponent.js +12 -1
  53. package/lib/maps/vectorMaps.d.ts +5 -6
  54. package/lib/maps/vectorMaps.js +13 -9
  55. package/lib/widgets/MapWidget.js +2 -1
  56. package/package.json +2 -2
  57. package/src/ColorComponent.tsx +2 -2
  58. package/src/TranslationsTabComponent.tsx +429 -0
  59. package/src/dashboards/DashboardComponent.tsx +1 -1
  60. package/src/dashboards/ServerDashboardDataSource.ts +0 -19
  61. package/src/dashboards/SettingsModalComponent.tsx +27 -383
  62. package/src/datagrids/DatagridComponent.tsx +6 -0
  63. package/src/datagrids/DatagridViewComponent.tsx +41 -5
  64. package/src/maps/BufferLayer.ts +16 -262
  65. package/src/maps/BufferLayerDesignerComponent.tsx +0 -6
  66. package/src/maps/ChoroplethLayer.ts +16 -393
  67. package/src/maps/ClusterLayer.ts +0 -274
  68. package/src/maps/DirectMapDataSource.ts +2 -49
  69. package/src/maps/GridLayer.ts +0 -224
  70. package/src/maps/Layer.ts +1 -35
  71. package/src/maps/MapComponent.tsx +448 -0
  72. package/src/maps/MapControlComponent.tsx +41 -0
  73. package/src/maps/MapDesign.ts +6 -0
  74. package/src/maps/MapDesignerComponent.tsx +18 -1
  75. package/src/maps/MapLayerDataSource.ts +0 -5
  76. package/src/maps/MapLayerViewDesignerComponent.ts +9 -2
  77. package/src/maps/MapLayersDesignerComponent.ts +4 -1
  78. package/src/maps/MapTranslationsTab.tsx +53 -0
  79. package/src/maps/MapUtils.ts +48 -0
  80. package/src/maps/MapViewComponent.tsx +2 -8
  81. package/src/maps/MarkersLayer.ts +79 -270
  82. package/src/maps/MarkersLayerDesign.ts +6 -0
  83. package/src/maps/MarkersLayerDesignerComponent.tsx +114 -38
  84. package/src/maps/ServerMapDataSource.ts +0 -19
  85. package/src/maps/SwitchableTileUrlLayer.tsx +0 -11
  86. package/src/maps/TileUrlLayer.tsx +0 -6
  87. package/src/maps/VectorMapViewComponent.tsx +13 -2
  88. package/src/maps/vectorMaps.tsx +12 -9
  89. package/src/widgets/MapWidget.tsx +2 -0
  90. package/src/maps/MapComponent.ts +0 -311
  91. package/src/maps/MapControlComponent.ts +0 -46
  92. package/src/maps/RasterMapViewComponent.ts +0 -345
@@ -305,280 +305,6 @@ export default class ClusterLayer extends Layer<ClusterLayerDesign> {
305
305
  return query
306
306
  }
307
307
 
308
- // Gets the layer definition as JsonQL + CSS in format:
309
- // {
310
- // layers: array of { id: layer id, jsonql: jsonql that includes "the_webmercator_geom" as a column }
311
- // css: carto css
312
- // interactivity: (optional) { layer: id of layer, fields: array of field names }
313
- // }
314
- // arguments:
315
- // design: design of layer
316
- // schema: schema to use
317
- // filters: array of filters to apply. Each is { table: table id, jsonql: jsonql condition with {alias} for tableAlias. Use injectAlias to put in table alias
318
- getJsonQLCss(design: ClusterLayerDesign, schema: Schema, filters: JsonQLFilter[]) {
319
- // Create design
320
- const layerDef = {
321
- layers: [{ id: "layer0", jsonql: this.createMapnikJsonQL(design, schema, filters) }],
322
- css: this.createCss(design, schema)
323
- // interactivity: {
324
- // layer: "layer0"
325
- // fields: ["id"]
326
- // }
327
- }
328
-
329
- return layerDef
330
- }
331
-
332
- createMapnikJsonQL(design: ClusterLayerDesign, schema: Schema, filters: JsonQLFilter[]): JsonQLQuery {
333
- const axisBuilder = new AxisBuilder({ schema })
334
- const exprCompiler = new ExprCompiler(schema)
335
-
336
- /*
337
- Query:
338
- Works by first snapping to grid and then clustering the clusters with slower DBSCAN method
339
-
340
- select
341
- ST_Centroid(ST_Collect(center)) as the_geom_webmercator,
342
- sum(cnt) as cnt,
343
- log(sum(cnt)) * 6 + 14 as size from
344
- (
345
- select
346
- ST_ClusterDBSCAN(center, (!pixel_width!*30 + !pixel_height!*30)/2, 1) over () as clust,
347
- sub1.center as center,
348
- cnt as cnt
349
- from
350
- (
351
- select
352
- count(*) as cnt,
353
- ST_Centroid(ST_Collect(<geometry axis>)) as center,
354
- round(ST_XMin(<geometry axis>) / (!pixel_width!*40)) as gridx,
355
- round(ST_YMin(<geometry axis>) / (!pixel_width!*40)) as gridy,
356
- from <table> as main
357
- where <geometry axis> && !bbox!
358
- and <geometry axis> is not null
359
- and <other filters>
360
- group by 3, 4
361
- ) as sub1
362
- ) as sub2
363
- group by sub2.clust
364
-
365
- */
366
-
367
- // Compile geometry axis
368
- let geometryExpr = axisBuilder.compileAxis({ axis: design.axes.geometry!, tableAlias: "main" })
369
-
370
- // ST_Centroid(ST_Collect(<geometry axis>))
371
- let centerExpr: JsonQLExpr = {
372
- type: "op",
373
- op: "ST_Centroid",
374
- exprs: [
375
- {
376
- type: "op",
377
- op: "ST_Collect",
378
- exprs: [geometryExpr]
379
- }
380
- ]
381
- }
382
-
383
- const gridXExpr: JsonQLExpr = {
384
- type: "op",
385
- op: "round",
386
- exprs: [
387
- {
388
- type: "op",
389
- op: "/",
390
- exprs: [
391
- { type: "op", op: "ST_XMin", exprs: [geometryExpr] },
392
- { type: "op", op: "*", exprs: [{ type: "token", token: "!pixel_width!" }, 40] }
393
- ]
394
- }
395
- ]
396
- }
397
-
398
- const gridYExpr: JsonQLExpr = {
399
- type: "op",
400
- op: "round",
401
- exprs: [
402
- {
403
- type: "op",
404
- op: "/",
405
- exprs: [
406
- { type: "op", op: "ST_YMin", exprs: [geometryExpr] },
407
- { type: "op", op: "*", exprs: [{ type: "token", token: "!pixel_height!" }, 5] }
408
- ]
409
- }
410
- ]
411
- }
412
-
413
- // Create inner query
414
- const innerQuery: JsonQLQuery = {
415
- type: "query",
416
- selects: [
417
- { type: "select", expr: { type: "op", op: "count", exprs: [] }, alias: "cnt" },
418
- { type: "select", expr: centerExpr, alias: "center" },
419
- { type: "select", expr: gridXExpr, alias: "gridx" },
420
- { type: "select", expr: gridYExpr, alias: "gridy" }
421
- ],
422
- from: exprCompiler.compileTable(design.table, "main"),
423
- groupBy: [3, 4]
424
- }
425
-
426
- // Create filters. First ensure geometry and limit to bounding box
427
- let whereClauses: JsonQLExpr[] = [
428
- {
429
- type: "op",
430
- op: "&&",
431
- exprs: [geometryExpr, { type: "token", token: "!bbox!" }]
432
- }
433
- ]
434
-
435
- // Then add filters baked into layer
436
- if (design.filter) {
437
- whereClauses.push(exprCompiler.compileExpr({ expr: design.filter || null, tableAlias: "main" }))
438
- }
439
-
440
- // Then add extra filters passed in, if relevant
441
- // Get relevant filters
442
- const relevantFilters = _.where(filters, { table: design.table })
443
- for (let filter of relevantFilters) {
444
- whereClauses.push(injectTableAlias(filter.jsonql, "main"))
445
- }
446
-
447
- whereClauses = _.compact(whereClauses)
448
-
449
- // Wrap if multiple
450
- if (whereClauses.length > 1) {
451
- innerQuery.where = { type: "op", op: "and", exprs: whereClauses }
452
- } else {
453
- innerQuery.where = whereClauses[0]
454
- }
455
-
456
- // Create next level
457
- // select
458
- // ST_ClusterDBSCAN(center, (!pixel_width!*30 + !pixel_height!*30)/2, 1) over () as clust,
459
- // sub1.center as center,
460
- // cnt as cnt from () as innerquery
461
- const clustExpr: JsonQLExpr = {
462
- type: "op",
463
- op: "ST_ClusterDBSCAN",
464
- exprs: [
465
- { type: "field", tableAlias: "innerquery", column: "center" },
466
- {
467
- type: "op",
468
- op: "/",
469
- exprs: [
470
- {
471
- type: "op",
472
- op: "+",
473
- exprs: [
474
- { type: "op", op: "*", exprs: [{ type: "token", token: "!pixel_width!" }, 30] },
475
- { type: "op", op: "*", exprs: [{ type: "token", token: "!pixel_height!" }, 30] }
476
- ]
477
- },
478
- 2
479
- ]
480
- },
481
- 1
482
- ],
483
- over: {}
484
- }
485
-
486
- const inner2Query: JsonQLQuery = {
487
- type: "query",
488
- selects: [
489
- { type: "select", expr: clustExpr, alias: "clust" },
490
- { type: "select", expr: { type: "field", tableAlias: "innerquery", column: "center" }, alias: "center" },
491
- { type: "select", expr: { type: "field", tableAlias: "innerquery", column: "cnt" }, alias: "cnt" }
492
- ],
493
- from: { type: "subquery", query: innerQuery, alias: "innerquery" }
494
- }
495
-
496
- // Create final level
497
- // ST_Centroid(ST_Collect(center)) as the_geom_webmercator,
498
- // sum(cnt) as cnt,
499
- // log(sum(cnt)) * 6 + 14 as size from
500
-
501
- // ST_Centroid(ST_Collect(center))
502
- centerExpr = {
503
- type: "op",
504
- op: "ST_Centroid",
505
- exprs: [
506
- {
507
- type: "op",
508
- op: "ST_Collect",
509
- exprs: [{ type: "field", tableAlias: "inner2query", column: "center" }]
510
- }
511
- ]
512
- }
513
-
514
- const cntExpr: JsonQLExpr = {
515
- type: "op",
516
- op: "sum",
517
- exprs: [{ type: "field", tableAlias: "inner2query", column: "cnt" }]
518
- }
519
-
520
- const sizeExpr: JsonQLExpr = {
521
- type: "op",
522
- op: "+",
523
- exprs: [{ type: "op", op: "*", exprs: [{ type: "op", op: "log", exprs: [cntExpr] }, 6] }, 14]
524
- }
525
-
526
- const query: JsonQLQuery = {
527
- type: "query",
528
- selects: [
529
- { type: "select", expr: centerExpr, alias: "the_geom_webmercator" },
530
- { type: "select", expr: cntExpr, alias: "cnt" },
531
- { type: "select", expr: sizeExpr, alias: "size" }
532
- ],
533
- from: { type: "subquery", query: inner2Query, alias: "inner2query" },
534
- groupBy: [{ type: "field", tableAlias: "inner2query", column: "clust" }]
535
- }
536
-
537
- return query
538
- }
539
-
540
- createCss(design: ClusterLayerDesign, schema: Schema) {
541
- const css =
542
- `\
543
- #layer0 [cnt>1] {
544
- marker-width: [size];
545
- marker-line-color: white;
546
- marker-line-width: 4;
547
- marker-line-opacity: 0.6;
548
- marker-placement: point;
549
- marker-type: ellipse;
550
- marker-allow-overlap: true;
551
- marker-fill: ` +
552
- (design.fillColor || "#337ab7") +
553
- `;
554
- }
555
-
556
- #layer0::l1 [cnt>1] {
557
- text-name: [cnt];
558
- text-face-name: 'Arial Bold';
559
- text-allow-overlap: true;
560
- text-fill: ` +
561
- (design.textColor || "white") +
562
- `;
563
- }
564
-
565
- #layer0 [cnt=1] {
566
- marker-width: 10;
567
- marker-line-color: white;
568
- marker-line-width: 2;
569
- marker-line-opacity: 0.6;
570
- marker-placement: point;
571
- marker-type: ellipse;
572
- marker-allow-overlap: true;
573
- marker-fill: ` +
574
- (design.fillColor || "#337ab7") +
575
- `;
576
- }\
577
- `
578
-
579
- return css
580
- }
581
-
582
308
  // # Called when the interactivity grid is clicked.
583
309
  // # arguments:
584
310
  // # ev: { data: interactivty data e.g. `{ id: 123 }` }
@@ -8,7 +8,7 @@ import MapBoundsCalculator from "./MapBoundsCalculator"
8
8
  import { MapDesign, MapLayerView } from "./MapDesign"
9
9
  import { MapDataSource } from "./MapDataSource"
10
10
  import DirectWidgetDataSource from "../widgets/DirectWidgetDataSource"
11
- import { JsonQLCssLayerDefinition, VectorTileCTE, VectorTileDef, VectorTileSourceLayer } from "./Layer"
11
+ import { VectorTileCTE, VectorTileDef, VectorTileSourceLayer } from "./Layer"
12
12
  import compressJson from "../compressJson"
13
13
  import querystring from "querystring"
14
14
  import { MapLayerDataSource } from "./MapLayerDataSource"
@@ -282,32 +282,7 @@ class DirectLayerDataSource implements MapLayerDataSource {
282
282
  return (layer as TileUrlLayer).getTileUrl(design, filters)
283
283
  }
284
284
 
285
- // Get JsonQLCss
286
- const jsonqlCss = layer.getJsonQLCss(design, this.options.schema, filters)
287
-
288
- return this.createUrl("png", jsonqlCss)
289
- }
290
-
291
- // Get the url for the interactivity tiles with the specified filters applied
292
- // Called with (design, filters) where design is the design of the layer and filters are filters to apply. Returns URL
293
- getUtfGridUrl(design: any, filters: JsonQLFilter[]) {
294
- // Create layer
295
- const layer = LayerFactory.createLayer(this.options.layerView.type)
296
-
297
- // Handle special cases
298
- if (this.options.layerView.type === "MWaterServer") {
299
- return this.createLegacyUrl(design, "grid.json", filters)
300
- }
301
-
302
- // If layer has tiles url directly available
303
- if (layer.getLayerDefinitionType() === "TileUrl") {
304
- return layer.getUtfGridUrl(design, filters)
305
- }
306
-
307
- // Get JsonQLCss
308
- const jsonqlCss = layer.getJsonQLCss(design, this.options.schema, filters)
309
-
310
- return this.createUrl("grid.json", jsonqlCss)
285
+ throw new Error("Layer type not supported: " + this.options.layerView.type)
311
286
  }
312
287
 
313
288
  // Gets widget data source for a popup widget
@@ -331,28 +306,6 @@ class DirectLayerDataSource implements MapLayerDataSource {
331
306
  })
332
307
  }
333
308
 
334
- // Create query string
335
- createUrl(extension: string, jsonqlCss: JsonQLCssLayerDefinition) {
336
- const query: any = {
337
- type: "jsonql",
338
- design: compressJson(jsonqlCss)
339
- }
340
-
341
- if (this.options.client) {
342
- query.client = this.options.client
343
- }
344
-
345
- // Make URL change when cache expired
346
- const cacheExpiry = this.options.dataSource.getCacheExpiry()
347
- if (cacheExpiry) {
348
- query.cacheExpiry = cacheExpiry
349
- }
350
-
351
- let url = `${this.options.apiUrl}maps/tiles/{z}/{x}/{y}.${extension}?` + querystring.stringify(query)
352
-
353
- return url
354
- }
355
-
356
309
  // Create query string
357
310
  createLegacyUrl(design: any, extension: string, filters: JsonQLFilter[]) {
358
311
  let where
@@ -254,230 +254,6 @@ export default class GridLayer extends Layer<GridLayerDesign> {
254
254
  return query
255
255
  }
256
256
 
257
- /** Gets the layer definition as JsonQL + CSS in format:
258
- * {
259
- * layers: array of { id: layer id, jsonql: jsonql that includes "the_webmercator_geom" as a column }
260
- * css: carto css
261
- * interactivity: (optional) { layer: id of layer, fields: array of field names }
262
- * }
263
- * arguments:
264
- * design: design of layer
265
- * schema: schema to use
266
- * filters: array of filters to apply
267
- */
268
- getJsonQLCss(design: GridLayerDesign, schema: Schema, filters: JsonQLFilter[]): LayerDefinition {
269
- // Create design
270
- const layerDef = {
271
- layers: [{ id: "layer0", jsonql: this.createMapnikJsonQL(design, schema, filters) }],
272
- css: this.createCss(design, schema, filters),
273
- interactivity: {
274
- layer: "layer0",
275
- fields: ["id", "name"]
276
- }
277
- }
278
-
279
- return layerDef
280
- }
281
-
282
- createMapnikJsonQL(design: GridLayerDesign, schema: Schema, filters: JsonQLFilter[]): JsonQLQuery {
283
- const axisBuilder = new AxisBuilder({ schema })
284
- const exprCompiler = new ExprCompiler(schema)
285
-
286
- /* Compile to a query like this:
287
- select mwater_hex_make(grid.q, grid.r, !pixel_width!*SIZE) as the_geom_webmercator, data.color as color from
288
- mwater_hex_grid(!bbox!, !pixel_width!*SIZE) as grid
289
- left outer join
290
- (select qr.q as q, qr.r as r, COLOREXPR as color from TABLE as innerquery
291
- inner join mwater_hex_xy_to_qr(st_xmin(innerquery.LOCATIONEXPR), st_ymin(innerquery.LOCATIONEXPR), !pixel_width!*10) as qr
292
- on true
293
- where innerquery.LOCATIONEXPR && ST_Expand(!bbox!, SIZE)
294
- group by 1, 2) as data
295
- on data.q = grid.q and data.r = grid.r
296
- */
297
- const compiledGeometryExpr = exprCompiler.compileExpr({ expr: design.geometryExpr, tableAlias: "innerquery" })
298
- const colorExpr = axisBuilder.compileAxis({ axis: design.colorAxis, tableAlias: "innerquery" })
299
- let compiledSizeExpr: JsonQLExpr
300
-
301
- if (design.shape == "hex") {
302
- // Hex needs distance from center to points
303
- compiledSizeExpr =
304
- design.sizeUnits == "pixels"
305
- ? { type: "op", op: "*", exprs: [{ type: "token", token: "!pixel_width!" }, design.size! / 1.73205] }
306
- : { type: "literal", value: design.size! / 1.73205 }
307
- } else if (design.shape == "square") {
308
- // Square needs distance from center to center
309
- compiledSizeExpr =
310
- design.sizeUnits == "pixels"
311
- ? { type: "op", op: "*", exprs: [{ type: "token", token: "!pixel_width!" }, design.size!] }
312
- : { type: "literal", value: design.size! }
313
- } else {
314
- throw new Error("Unknown shape")
315
- }
316
-
317
- // Create inner query
318
- const innerQuery: JsonQLQuery = {
319
- type: "query",
320
- selects: [
321
- { type: "select", expr: { type: "field", tableAlias: "qr", column: "q" }, alias: "q" },
322
- { type: "select", expr: { type: "field", tableAlias: "qr", column: "r" }, alias: "r" },
323
- { type: "select", expr: colorExpr, alias: "color" }
324
- ],
325
- from: {
326
- type: "join",
327
- kind: "inner",
328
- left: { type: "table", table: design.table!, alias: "innerquery" },
329
- right: {
330
- type: "subexpr",
331
- expr: {
332
- type: "op",
333
- op: `mwater_${design.shape}_xy_to_qr`,
334
- exprs: [
335
- { type: "op", op: "ST_XMin", exprs: [compiledGeometryExpr] },
336
- { type: "op", op: "ST_YMin", exprs: [compiledGeometryExpr] },
337
- compiledSizeExpr
338
- ]
339
- },
340
- alias: "qr"
341
- },
342
- on: { type: "literal", value: true }
343
- },
344
- groupBy: [1, 2]
345
- }
346
-
347
- // Filter by bounding box
348
- let whereClauses: JsonQLExpr[] = [
349
- {
350
- type: "op",
351
- op: "&&",
352
- exprs: [
353
- compiledGeometryExpr,
354
- { type: "op", op: "ST_Expand", exprs: [{ type: "token", token: "!bbox!" }, compiledSizeExpr] }
355
- ]
356
- }
357
- ]
358
-
359
- // Then add filters
360
- if (design.filter) {
361
- whereClauses.push(exprCompiler.compileExpr({ expr: design.filter, tableAlias: "innerquery" }))
362
- }
363
-
364
- // Then add extra filters passed in, if relevant
365
- const relevantFilters = _.where(filters, { table: design.table })
366
- for (let filter of relevantFilters) {
367
- whereClauses.push(injectTableAlias(filter.jsonql, "innerquery"))
368
- }
369
-
370
- whereClauses = _.compact(whereClauses)
371
- if (whereClauses.length > 0) {
372
- innerQuery.where = { type: "op", op: "and", exprs: whereClauses }
373
- }
374
-
375
- // Now create outer query
376
- const query: JsonQLQuery = {
377
- type: "query",
378
- selects: [
379
- {
380
- type: "select",
381
- expr: {
382
- type: "op",
383
- op: `mwater_${design.shape}_make`,
384
- exprs: [
385
- { type: "field", tableAlias: "grid", column: "q" },
386
- { type: "field", tableAlias: "grid", column: "r" },
387
- compiledSizeExpr
388
- ]
389
- },
390
- alias: "the_geom_webmercator"
391
- },
392
- { type: "select", expr: { type: "field", tableAlias: "data", column: "color" }, alias: "color" }
393
- ],
394
- from: {
395
- type: "join",
396
- kind: "left",
397
- left: {
398
- type: "subexpr",
399
- expr: {
400
- type: "op",
401
- op: `mwater_${design.shape}_grid`,
402
- exprs: [{ type: "token", token: "!bbox!" }, compiledSizeExpr]
403
- },
404
- alias: "grid"
405
- },
406
- right: { type: "subquery", query: innerQuery, alias: "data" },
407
- // on data.q = grid.q and data.r = grid.r
408
- on: {
409
- type: "op",
410
- op: "and",
411
- exprs: [
412
- {
413
- type: "op",
414
- op: "=",
415
- exprs: [
416
- { type: "field", tableAlias: "data", column: "q" },
417
- { type: "field", tableAlias: "grid", column: "q" }
418
- ]
419
- },
420
- {
421
- type: "op",
422
- op: "=",
423
- exprs: [
424
- { type: "field", tableAlias: "data", column: "r" },
425
- { type: "field", tableAlias: "grid", column: "r" }
426
- ]
427
- }
428
- ]
429
- }
430
- }
431
- }
432
-
433
- return query
434
- }
435
-
436
- createCss(design: GridLayerDesign, schema: Schema, filters: JsonQLFilter[]): string {
437
- let css =
438
- `
439
- #layer0 {
440
- polygon-opacity: ` +
441
- design.fillOpacity +
442
- `;
443
- ` +
444
- (design.borderStyle == "color"
445
- ? `line-opacity: ` + (1 - (1 - design.fillOpacity!) / 2) + `; `
446
- : `line-width: 0;`) +
447
- `
448
- polygon-fill: transparent;
449
- }
450
- \
451
- `
452
- if (!design.colorAxis) {
453
- throw new Error("Color axis not set")
454
- }
455
- // If color axes, add color conditions
456
- if (design.colorAxis.colorMap) {
457
- for (let item of design.colorAxis.colorMap) {
458
- // If invisible
459
- if (design.colorAxis.excludedValues && _.any(design.colorAxis.excludedValues, (ev) => ev === item.value)) {
460
- css += `#layer0 [color=${JSON.stringify(item.value)}] {
461
- line-color: transparent;
462
- line-opacity: 0;
463
- polygon-opacity: 0;
464
- polygon-fill: transparent;
465
- }\n`
466
- } else {
467
- css +=
468
- `#layer0 [color=${JSON.stringify(item.value)}] {
469
- ` +
470
- (design.borderStyle == "color" ? `line-color: ${item.color};` : "") +
471
- `
472
- polygon-fill: ${item.color};
473
- }\n`
474
- }
475
- }
476
- }
477
-
478
- return css
479
- }
480
-
481
257
  // TODO
482
258
  // /**
483
259
  // * Called when the interactivity grid is clicked.
package/src/maps/Layer.ts CHANGED
@@ -11,25 +11,6 @@ import { JsonQLExpr, JsonQLQuery, JsonQLSelectQuery } from "@mwater/jsonql"
11
11
  import { LayerSpecification } from "maplibre-gl"
12
12
  import { MapLayerDataSource } from "./MapLayerDataSource"
13
13
 
14
- export interface JsonQLCssLayerDefinition {
15
- layers: Array<{
16
- /** Layer id */
17
- id: string
18
- /** jsonql that includes "the_webmercator_geom" as a column */
19
- jsonql: JsonQLQuery
20
- }>
21
-
22
- /** carto css */
23
- css: string
24
-
25
- interactivity?: {
26
- /** id of layer */
27
- layer: string
28
- /** array of field names */
29
- fields: string[]
30
- }
31
- }
32
-
33
14
  export interface OnGridClickOptions<LayerDesign> {
34
15
  /** design of layer */
35
16
  design: LayerDesign
@@ -112,22 +93,7 @@ export interface VectorTileCTE {
112
93
  /** Defines a layer for a map which has all the logic for rendering the specific data to be viewed */
113
94
  export default class Layer<LayerDesign> {
114
95
  /** Gets the type of layer definition */
115
- getLayerDefinitionType(): "JsonQLCss" | "TileUrl" | "VectorTile" {
116
- return "JsonQLCss"
117
- }
118
-
119
- /** Gets the layer definition as JsonQL + CSS for type "JsonQLCss"
120
- arguments:
121
- design: design of layer
122
- schema: schema to use
123
- filters: array of filters to apply. Each is { table: table id, jsonql: jsonql condition with {alias} for tableAlias. Use injectAlias to put in table alias
124
- */
125
- getJsonQLCss(design: LayerDesign, schema: Schema, filters: JsonQLFilter[]): JsonQLCssLayerDefinition {
126
- throw new Error("Not implemented")
127
- }
128
-
129
- /** Gets the utf grid url for definition type "TileUrl" */
130
- getUtfGridUrl(design: LayerDesign, filters: JsonQLFilter[]): string | null {
96
+ getLayerDefinitionType(): "TileUrl" | "VectorTile" {
131
97
  throw new Error("Not implemented")
132
98
  }
133
99