UNPKG

geostyler

Version:
269 lines (268 loc) 8.74 kB
var g = Object.defineProperty; var w = (p, e, r) => e in p ? g(p, e, { enumerable: !0, configurable: !0, writable: !0, value: r }) : p[e] = r; var c = (p, e, r) => w(p, typeof e != "symbol" ? e + "" : e, r); import { isGeoStylerBooleanFunction as F, isComparisonFilter as y, isCombinationFilter as A, isNegationFilter as b, isComparisonOperator as C, isCombinationOperator as E, isFilter as h, isNegationOperator as T } from "geostyler-style"; import u from "lodash-es/get.js"; import d from "lodash-es/set.js"; import P from "lodash-es/isBoolean.js"; import k from "lodash-es/uniqueId.js"; import N from "./FunctionUtil.js"; const o = class o { /** * Calculates the number of features that are covered by more then one rule per * rule. * * @param {object} matches An object containing the count of matches for every * filter. Separated by scales. * @returns {number[]} An array containing the number of duplicates for each * rule. */ static calculateDuplicates(e) { const r = [], a = []; return e.forEach((t, n) => { const s = {}; t.forEach((i) => s[i.id] = !0), a[n] = s; }), e.forEach((t, n) => { let s = 0; a.forEach((i, l) => { n !== l && t.forEach((f) => { i[f.id] && ++s; }); }), r[n] = s; }), r; } /** * Calculates the amount of matched and duplicate matched features for the rules. * * @param {Rule[]} rules An array of GeoStyler rule objects. * @param {VectorData} data A geostyler data object. * @returns {CountResult} An object containing array with the amount of matched * and duplicate matched features reachable through keys'counts' and 'duplicates'. */ static calculateCountAndDuplicates(e, r) { if (!e || !r) return {}; const a = { counts: [], duplicates: [] }; r.exampleFeatures.features = r.exampleFeatures.features.map((n, s) => (n.id || (n.id = s), n)); const t = []; return e.forEach((n, s) => { const i = n.filter ? o.getMatches(n.filter, r) : r.exampleFeatures.features; a.counts.push(i.length), t[s] = i; }), a.duplicates = o.calculateDuplicates(t), a; } /** * Transforms a position String like '[2][3]' to an positionArray like [2, 3]. */ static positionStringAsArray(e) { return e.replace(/\]\[/g, ",").replace(/\]/g, "").replace(/\[/g, "").split(",").map((r) => parseInt(r, 10)); } /** * Transforms am positionArray like [2, 3] to a string like '[2][3]'. */ static positionArrayAsString(e) { return `[${e.toString().replace(/,/g, "][")}]`; } /** * Returns the filter at a specific position. */ static getFilterAtPosition(e, r) { return r === "" ? e : u(e, r); } /** * Removes a subfilter from a given filter at the given position. */ static removeAtPosition(e, r) { if (!Array.isArray(e)) throw new Error(`Passed filter is not an array: ${e}`); const a = structuredClone(e), t = r.substr(r.length - 3), n = parseInt(t.slice(1, 2), 10), s = r.substring(0, r.length - 3); let i = a; return s !== "" && (i = u(a, s)), i.splice(n, 1), a; } /** * Inserts a given subfilter to a given parentfilter by its position and its * dropPosition. */ static insertAtPosition(e, r, a) { if (!Array.isArray(e) || !Array.isArray(r)) throw new Error(`Can not insert Filter ${r} into ${e}. Arrays are required.`); const t = a.substring(0, a.length - 3), n = a.substring(a.length - 3), s = parseInt(n.slice(1, 2), 10), i = !["&&", "||", "!"].includes(r[0]), l = structuredClone(e), f = t === "" ? l : u(l, t); return i ? l.length - 1 === s ? f.push(r) : f.splice(s, 0, r) : f.push(r), l; } /** * Handler for the add button. * Adds a filter of a given type at the given position. * */ static addFilter(e, r, a) { let t, n = structuredClone(e); switch (a) { case "and": t = ["&&", ["==", "", ""], ["==", "", ""]]; break; case "or": t = ["||", ["==", "", ""], ["==", "", ""]]; break; case "not": t = ["!", ["==", "", ""]]; break; case "comparison": default: t = ["==", "", ""]; break; } if (r === "") n = n, n.push(t); else { if (!Array.isArray(n)) throw new Error(`Cannot add filter to filter ${e}. Root filter has to be an array.`); const s = u(n, r); s.push(t), d(n, r, s); } return n; } /** * Changes a filter at a position to a given typ. * */ static changeFilter(e, r, a) { let t; const n = structuredClone(e), s = r === "" ? n : u(n, r); switch (a) { case "and": if (s && (s[0] === "&&" || s[0] === "||")) { if (t = s, !Array.isArray(t)) throw new Error("Cannot change filter. Filter is not an array."); t[0] = "&&"; } else t = ["&&", ["==", "", ""], ["==", "", ""]]; break; case "or": if (s && (s[0] === "&&" || s[0] === "||")) { if (t = s, !Array.isArray(t)) throw new Error("Cannot change filter. Filter is not an array."); t[0] = "||"; } else t = ["||", ["==", "", ""], ["==", "", ""]]; break; case "not": t = ["!", ["==", "", ""]]; break; case "comparison": default: t = ["==", "", ""]; break; } if (r === "") return t; if (!Array.isArray(n)) throw new Error("Cannot change filter. Filter is not an array."); return d(n, r, t), n; } }; c(o, "nestingOperators", ["&&", "||", "!"]), /** * Handle nested filters. */ c(o, "handleNestedFilter", (e, r) => { let a, t; switch (e[0]) { case "&&": return a = !0, t = e.slice(1), t.forEach((n) => { o.featureMatchesFilter(n, r) || (a = !1); }), a; case "||": return a = !1, t = e.slice(1), t.forEach((n) => { o.featureMatchesFilter(n, r) && (a = !0); }), a; case "!": return !o.featureMatchesFilter(e[1], r); default: throw new Error("Cannot parse Filter. Unknown combination or negation operator."); } }), /** * Handle simple filters, i.e. non-nested filters. */ c(o, "handleSimpleFilter", (e, r) => { const a = u(r, "properties[" + e[1] + "]"); let t = e[2]; switch (e[0]) { case "==": return "" + a == "" + t; case "*=": return t = t, a && t.length > a.length ? !1 : a ? a.indexOf(t) !== -1 : !1; case "!=": return "" + a != "" + t; case "<": return parseFloat(a) < Number(t); case "<=": return parseFloat(a) <= Number(t); case ">": return parseFloat(a) > Number(t); case ">=": return parseFloat(a) >= Number(t); default: throw new Error("Cannot parse Filter. Unknown comparison operator."); } }), /** * Checks if a feature matches the specified filter. * Returns true if it matches, otherwise returns false. */ c(o, "featureMatchesFilter", (e, r) => { if (P(e)) return e; if (F(e)) return N.evaluateFunction(e, r); if ((e == null ? void 0 : e.length) === 0) return !0; let a = !0; return y(e) ? a = o.handleSimpleFilter(e, r) : (A(e) || b(e)) && (a = o.handleNestedFilter(e, r)), a; }), /** * Returns those features that match a given filter. * If no feature matches, returns an empty array. * * @param {Filter} filter A geostyler filter object. * @param {VectorData} data A geostyler data object. * @return {Feature[]} An Array of geojson feature objects. */ c(o, "getMatches", (e, r) => r.exampleFeatures.features.filter((a) => o.featureMatchesFilter(e, a))), /** * Removes a filter at a given position. * */ c(o, "removeFilter", (e, r) => { const a = r.substring(0, r.length - 3), t = o.getFilterAtPosition(e, a); let n; if (r === "") n = void 0; else { if (!Array.isArray(t)) throw new Error("Cannot remove filter. Filter is not an array."); t.length <= 2 ? n = o.removeAtPosition(e, a) : n = o.removeAtPosition(e, r); } return n; }), /** * Helper method for FilterUtil.filterToTree(). */ c(o, "filterToTreeHelper", (e) => { const r = { key: k() }; if (!Array.isArray(e)) throw new Error("Filter is not an array."); const a = structuredClone(e), t = a.shift(); return C(t) ? r.title = `${a[0]} ${t} ${a[1]}` : E(t) ? (r.title = t, r.children = a.map((n) => { if (h(n)) return o.filterToTreeHelper(n); })) : T(t) && (r.title = t, r.children = a.map((n) => { if (h(n)) return o.filterToTreeHelper(n); })), r; }), /** * Maps a GeoStyler filter to an antd treeData object. */ c(o, "filterToTree", (e) => [o.filterToTreeHelper(e)]); let m = o; export { m as default };