import { Filter, StyleParser, Style, Rule, ScaleDenominator, PointSymbolizer, Symbolizer, IconSymbolizer, LineSymbolizer, MarkSymbolizer, FillSymbolizer, TextSymbolizer, WriteStyleResult, ReadStyleResult, isGeoStylerFunction, DistanceUnit } from 'geostyler-style'; import { CqlParser } from 'geostyler-cql-parser'; import Color from 'color'; import { XMLBuilder, XMLParser, XMLValidator } from 'fast-xml-parser'; // Constants for mapping QML-units const DEF_RESOLUTION = 96.0; const PT_PER_INCH = 72.0; const MM_PER_INCH = 25.4; const xmlParser = new XMLParser({ ignoreAttributes: false, attributeNamePrefix: '', attributesGroupName: '$', parseAttributeValue: false, parseTagValue: false, trimValues: false, isArray: (_tagName, path, _isLeafNode, isAttribute) => !isAttribute && typeof path === 'string' && path.includes('.') }); const xmlBuilder = new XMLBuilder({ ignoreAttributes: false, attributeNamePrefix: '', attributesGroupName: '$', format: true, indentBy: ' ', suppressEmptyNode: true }); const get = (obj: any, path: any, defaultValue = undefined) => { const travel = (regexp: RegExp) => String.prototype.split .call(path, regexp) .filter(Boolean) .reduce((res: any, key: any) => (res !== null && res !== undefined ? res[key] : res), obj); const result = travel(/[,[\]]+?/) || travel(/[,[\].]+?/); return result === undefined || result === obj ? defaultValue : result; }; export type ConstructorParams = { qgisVersion?: string; }; type SymbolizerMap = { [key: string]: Symbolizer[]; }; type QmlProp = { $: { k: any; v: any; }; }; type QmlMapOption = { $: { type: string; }; Option: QmlOption[]; }; type QmlOption = { $: { name: string; value: string; type: string; }; }; type QmlRule = { $: { filter?: string; scalemaxdenom?: number; scalemindenom?: number; symbol: string; key: string; label: string; }; }; type QmlCategory = { $: { label: string; render: string; symbol: string; value: string; }; }; type QmlRange = { $: { upper: string; lower: string; label: string; symbol: string; render: string; }; }; const dot = [2, 2]; const dash = [10, 2]; const lineStyleDashArrays: { [key: string]: number[] | undefined } = { solid: undefined, dot: dot, dash: dash, 'dash dot': [...dash, ...dot], 'dash dot dot': [...dash, ...dot, ...dot] }; const AnchorMap = { left: 'L', right: 'R', top: 'T', bottom: 'B', 'top-left': 'TL', 'top-right': 'TR', 'bottom-left': 'BL', 'bottom-right': 'BR' }; /** * This parser can be used with the GeoStyler. * It implements the GeoStyler-Style StyleParser interface. * * @class QGISStyleParser * @implements StyleParser */ export class QGISStyleParser implements StyleParser { cqlParser = new CqlParser(); /** * The name of the QGIS Style Parser. */ public static title = 'QGIS Style Parser'; title = 'QGIS Style Parser'; qgisVersion: string; // QGIS 3.28 and later use