Source: map/filters/FilterBuilder.js

  1. import { TimeDimension } from "./builders/TimeDimension.js";
  2. import { CQLEsri } from "./builders/CQLEsri.js";
  3. import { CQLGeoserver } from "./builders/CQLGeoserver.js";
  4. import { OGCGeoserver } from "./builders/OGCGeoserver.js";
  5. import { SQLEsri } from "./builders/SQLEsri.js";
  6. export { FilterBuilder };
  7. /**
  8. * Helper class for creating filter query strings for different software and service types.
  9. * @memberof vef.map.filters
  10. */
  11. class FilterBuilder {
  12. static FILTER_CASES = {
  13. "geoserver": {
  14. "wms": {
  15. "dimension": TimeDimension,
  16. "cql": CQLGeoserver,
  17. "ogc": OGCGeoserver
  18. },
  19. "wfs": {
  20. "cql": CQLGeoserver,
  21. "ogc": OGCGeoserver
  22. }
  23. },
  24. "esri": {
  25. "wms": {
  26. "dimension": TimeDimension,
  27. "cql_imageserver": SQLEsri,
  28. "sql": SQLEsri,
  29. "cql": CQLEsri
  30. }
  31. },
  32. "thredds": {
  33. "wms": {
  34. "dimension": TimeDimension
  35. }
  36. },
  37. "rasdaman": {
  38. "wms": {
  39. "dimension": TimeDimension
  40. }
  41. }
  42. }
  43. /**
  44. * Get the filter query for a service based on the filter config for a specific layer
  45. *
  46. * @param {Layer} layer
  47. * @param {object[]} filters
  48. *
  49. * @returns {string}
  50. */
  51. static getFilterParams(filters, software, service, type, layerName) {
  52. const filterCase = this.FILTER_CASES?.[software.toLowerCase()]?.[service.toLowerCase()]?.[type.toLowerCase()] || undefined;
  53. return (filterCase) ? filterCase.getFilterParams(this.harmonizeFilter(filters), layerName) : {};
  54. }
  55. /**
  56. * Group all columns by attribute in an object
  57. *
  58. * @param {object[]} filters
  59. * @returns {object} mapped filters to an object grouped by column
  60. */
  61. static harmonizeFilter(filters) {
  62. const harmonizedFilter = {};
  63. const add = (column, values) => {
  64. if (!column) return;
  65. if (!(column in harmonizedFilter)) harmonizedFilter[column] = [];
  66. harmonizedFilter[column].push(values)
  67. };
  68. for (let i = 0; i < filters.length; ++i) {
  69. const filter = filters[i];
  70. if (Array.isArray(filter.values)) for (let j = 0; j < filter.values.length; ++j) {
  71. const value = filter.values[j];
  72. const operator = value[0].toLowerCase();
  73. switch (operator) {
  74. case "bt":
  75. if (value.length == 4) {
  76. add(value[1], [operator, value[2], value[3]]);
  77. } else if (value.length == 3) {
  78. add(filter.column, [operator, value[1], value[2]]);
  79. }
  80. break;
  81. case "null":
  82. if (value.length == 2) {
  83. add(value[1], [operator]);
  84. } else if (value.length == 1) {
  85. add(filter.column, [operator]);
  86. }
  87. break;
  88. case "eq":
  89. case "like":
  90. case "gt":
  91. case "gteq":
  92. case "lt":
  93. case "lteq":
  94. if (value.length == 3) {
  95. add(value[1], [operator, value[2]]);
  96. } else if (value.length == 2) {
  97. add(filter.column, [operator, value[1]]);
  98. }
  99. break;
  100. case "bbox":
  101. if (value.length == 6) {
  102. add(value[1], [operator, value[2], value[3], value[4], value[5]]);
  103. } else if (value.length == 5) {
  104. add(filter.column, [operator, value[1], value[2], value[3], value[4]]);
  105. }
  106. }
  107. }
  108. }
  109. return harmonizedFilter;
  110. }
  111. }