UNPKG

geostyler

Version:
271 lines (270 loc) 9.01 kB
var g = Object.defineProperty; var F = (f, e, r) => e in f ? g(f, e, { enumerable: !0, configurable: !0, writable: !0, value: r }) : f[e] = r; var u = (f, e, r) => F(f, typeof e != "symbol" ? e + "" : e, r); import { isGeoStylerBooleanFunction as w, 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 p from "lodash-es/get.js"; import d from "lodash-es/set.js"; import P from "lodash-es/isBoolean.js"; import N from "lodash-es/uniqueId.js"; import k from "./FunctionUtil.js"; const o = class o { /** * Calculates the number of features that are covered by more than 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, s) => { const n = {}; t.forEach((i) => n[i.id] = !0), a[s] = n; }), e.forEach((t, s) => { let n = 0; a.forEach((i, c) => { s !== c && t.forEach((l) => { i[l.id] && ++n; }); }), r[s] = n; }), 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, i) => (n.id || (n.id = i), n)); const t = [], s = /* @__PURE__ */ new Set(); return e.forEach((n, i) => { let c = n.filter ? o.getMatches(n.filter, r) : r.exampleFeatures.features; n.elseRule && (c = c.filter((l) => !s.has(l.id))), c.forEach((l) => s.add(l.id)), a.counts.push(c.length), t[i] = c; }), 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 : p(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), s = parseInt(t.slice(1, 2), 10), n = r.substring(0, r.length - 3); let i = a; return n !== "" && (i = p(a, n)), i.splice(s, 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), s = a.substring(a.length - 3), n = parseInt(s.slice(1, 2), 10), i = !["&&", "||", "!"].includes(r[0]), c = structuredClone(e), l = t === "" ? c : p(c, t); return i ? c.length - 1 === n ? l.push(r) : l.splice(n, 0, r) : l.push(r), c; } /** * Handler for the add button. * Adds a filter of a given type at the given position. * */ static addFilter(e, r, a) { let t, s = structuredClone(e); switch (a) { case "and": t = ["&&", ["==", "", ""], ["==", "", ""]]; break; case "or": t = ["||", ["==", "", ""], ["==", "", ""]]; break; case "not": t = ["!", ["==", "", ""]]; break; case "comparison": default: t = ["==", "", ""]; break; } if (r === "") s = s, s.push(t); else { if (!Array.isArray(s)) throw new Error(`Cannot add filter to filter ${e}. Root filter has to be an array.`); const n = p(s, r); n.push(t), d(s, r, n); } return s; } /** * Changes a filter at a position to a given typ. * */ static changeFilter(e, r, a) { let t; const s = structuredClone(e), n = r === "" ? s : p(s, r); switch (a) { case "and": if (n && (n[0] === "&&" || n[0] === "||")) { if (t = n, !Array.isArray(t)) throw new Error("Cannot change filter. Filter is not an array."); t[0] = "&&"; } else t = ["&&", ["==", "", ""], ["==", "", ""]]; break; case "or": if (n && (n[0] === "&&" || n[0] === "||")) { if (t = n, !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(s)) throw new Error("Cannot change filter. Filter is not an array."); return d(s, r, t), s; } }; u(o, "nestingOperators", ["&&", "||", "!"]), /** * Handle nested filters. */ u(o, "handleNestedFilter", (e, r) => { let a, t; switch (e[0]) { case "&&": return a = !0, t = e.slice(1), t.forEach((s) => { o.featureMatchesFilter(s, r) || (a = !1); }), a; case "||": return a = !1, t = e.slice(1), t.forEach((s) => { o.featureMatchesFilter(s, 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. */ u(o, "handleSimpleFilter", (e, r) => { const a = p(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); case "<=x<=": return parseFloat(a) >= Number(e[2]) && parseFloat(a) <= Number(e[3]); 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. */ u(o, "featureMatchesFilter", (e, r) => { if (P(e)) return e; if (w(e)) return k.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. */ u(o, "getMatches", (e, r) => r.exampleFeatures.features.filter(((a) => o.featureMatchesFilter(e, a)))), /** * Removes a filter at a given position. * */ u(o, "removeFilter", (e, r) => { const a = r.substring(0, r.length - 3), t = o.getFilterAtPosition(e, a); let s; if (r === "") s = void 0; else { if (!Array.isArray(t)) throw new Error("Cannot remove filter. Filter is not an array."); t.length <= 2 ? s = o.removeAtPosition(e, a) : s = o.removeAtPosition(e, r); } return s; }), /** * Helper method for FilterUtil.filterToTree(). */ u(o, "filterToTreeHelper", (e) => { const r = { key: N() }; if (!Array.isArray(e)) throw new Error("Filter is not an array."); const a = structuredClone(e), t = a.shift(); return C(t) ? t === "<=x<=" ? r.title = `${a[1]} <= ${a[0]} <= ${a[2]}` : r.title = `${a[0]} ${t} ${a[1]}` : E(t) ? (r.title = t, r.children = a.map((s) => { if (h(s)) return o.filterToTreeHelper(s); })) : T(t) && (r.title = t, r.children = a.map((s) => { if (h(s)) return o.filterToTreeHelper(s); })), r; }), /** * Maps a GeoStyler filter to an antd treeData object. */ u(o, "filterToTree", (e) => [o.filterToTreeHelper(e)]); let m = o; export { m as default };