diff --git a/.gitignore b/.gitignore index 976069c8..45c70e6a 100644 --- a/.gitignore +++ b/.gitignore @@ -9,7 +9,7 @@ # production /build /browser -/dist +# /dist # history /.history diff --git a/dist/SldStyleParser.d.ts b/dist/SldStyleParser.d.ts new file mode 100644 index 00000000..f95c0b50 --- /dev/null +++ b/dist/SldStyleParser.d.ts @@ -0,0 +1,449 @@ +import { Channel, ChannelSelection, ColorMap, ColorMapType, ComparisonFilter, ContrastEnhancement, Expression, FillSymbolizer, Filter, IconSymbolizer, LineSymbolizer, MarkSymbolizer, PointSymbolizer, RasterSymbolizer, ReadStyleResult, Rule, ScaleDenominator, Style, StyleParser, Symbolizer, TextSymbolizer, UnsupportedProperties, WriteStyleResult } from 'geostyler-style/dist/style'; +import { X2jOptions, XMLBuilder, XmlBuilderOptions, XMLParser } from 'fast-xml-parser'; +declare const SLD_VERSIONS: readonly ["1.0.0", "1.1.0"]; +export type SldVersion = (typeof SLD_VERSIONS)[number]; +export type ParserOptions = Omit; +export type BuilderOptions = Omit; +export type ConstructorParams = { + numericFilterFields?: string[]; + boolFilterFields?: string[]; + sldVersion?: SldVersion; + symbolizerUnits?: string; + parserOptions?: ParserOptions; + builderOptions?: XmlBuilderOptions; + translations?: SldStyleParserTranslations; + locale?: string; +}; +declare const COMPARISON_MAP: { + PropertyIsEqualTo: string; + PropertyIsNotEqualTo: string; + PropertyIsLike: string; + PropertyIsLessThan: string; + PropertyIsLessThanOrEqualTo: string; + PropertyIsGreaterThan: string; + PropertyIsGreaterThanOrEqualTo: string; + PropertyIsNull: string; + PropertyIsBetween: string; +}; +type ComparisonType = keyof typeof COMPARISON_MAP; +export type SldStyleParserTranslationKeys = { + marksymbolizerParseFailedUnknownWellknownName?: (params: { + wellKnownName: string; + }) => string; + noFilterDetected?: string; + symbolizerKindParseFailed?: (params: { + sldSymbolizerName: string; + }) => string; + colorMapEntriesParseFailedColorUndefined?: string; + contrastEnhancParseFailedHistoAndNormalizeMutuallyExclusive?: string; + channelSelectionParseFailedRGBAndGrayscaleMutuallyExclusive?: string; + channelSelectionParseFailedRGBChannelsUndefined?: string; +}; +export type SldStyleParserTranslations = Record; +export declare const defaultTranslations: SldStyleParserTranslations; +/** + * This parser can be used with the GeoStyler. + * It implements the geostyler-style StyleParser interface. + * + * @class SldStyleParser + * @implements StyleParser + */ +export declare class SldStyleParser implements StyleParser { + /** + * The name of the SLD Style Parser. + */ + static title: string; + title: string; + unsupportedProperties: UnsupportedProperties; + translations: SldStyleParserTranslations; + locale: string; + constructor(opts?: ConstructorParams); + translate(key: keyof SldStyleParserTranslationKeys, params?: any): string; + private _parser; + get parser(): XMLParser; + set parser(parser: XMLParser); + private _builder; + get builder(): XMLBuilder; + set builder(builder: XMLBuilder); + /** + * Array of field / property names in a filter, which are casted to numerics + * while parsing a SLD. + */ + private _numericFilterFields; + /** + * Getter for _numericFilterFields + * @return The numericFilterFields + */ + get numericFilterFields(): string[]; + /** + * Setter for _numericFilterFields + * @param numericFilterFields The numericFilterFields to set + */ + set numericFilterFields(numericFilterFields: string[]); + /** + * Array of field / property names in a filter, which are casted to boolean + * while parsing a SLD. + */ + private _boolFilterFields; + /** + * Getter for _boolFilterFields + * @return The boolFilterFields + */ + get boolFilterFields(): string[]; + /** + * Setter for _boolFilterFields + * @param boolFilterFields The boolFilterFields to set + */ + set boolFilterFields(boolFilterFields: string[]); + /** + * String indicating the SLD version to use. 1.1.0 will make use of + * Symbology Encoding. + */ + private _sldVersion; + /** + * Getter for _sldVersion + * @return + */ + get sldVersion(): SldVersion; + /** + * Setter for _sldVersion + * @param sldVersion The _sldVersion value to set + */ + set sldVersion(sldVersion: SldVersion); + /** + * String indicating the SLD version used in reading mode + */ + private _readingSldVersion; + /** + * Getter for _readingSldVersion + * @return + */ + get readingSldVersion(): SldVersion; + /** + * Setter for _readingSldVersion + * @param sldVersion The _readingSldVersion value to set + */ + set readingSldVersion(sldVersion: SldVersion); + /** + * Used to add a `uom` attribute to the symbolizer tag. Can be one of + * `metre`, `foot` or `pixel`. Defaults to pixel. + */ + private _symbolizerUnits; + /** + * Getter for _symbolizerUnits + * @return {string} + */ + get symbolizerUnits(): string; + /** + * Setter for _symbolizerUnits + * @param {string} symbolizerUnits The _symbolizerUnits value to set + */ + set symbolizerUnits(symbolizerUnits: string); + /** + * The readStyle implementation of the geostyler-style StyleParser interface. + * It reads a SLD as a string and returns a Promise. + * The Promise itself resolves with an object containing the geostyler-style. + * + * @param sldString A SLD as a string. + * @return The Promise resolving with an object containing the geostyler-style. + */ + readStyle(sldString: string): Promise; + /** + * Get the geostyler-style from a SLD Object (created with fast-xml-parser). + * + * @param sldObject The SLD object representation (created with fast-xml-parser) + * @return The geostyler-style + */ + sldObjectToGeoStylerStyle(sldObject: any): Style; + /** + * Get the geostyler-style rules from a SLD Object (created with fast-xml-parser). + * + * @param sldObject The SLD object representation (created with fast-xml-parser) + * @return The geostyler-style rules + */ + getRulesFromSldObject(sldObject: any): Rule[]; + /** + * Get the name for the Style from the SLD Object. Returns the Title of the UserStyle + * if defined or the Name of the NamedLayer if defined or an empty string. + * + * @param sldObject The SLD object representation (created with fast-xml-parser) + * @return The name to be used for the GeoStyler Style Style + */ + getStyleNameFromSldObject(sldObject: any): string; + /** + * Get the geostyler-style Filter from a SLD Rule. + * + * Currently only supports one Filter per Rule. + * + * @param sldRule The SLD Rule + * @return The geostyler-style Filter + */ + getFilterFromRule(sldRule: any[]): Filter | undefined; + /** + * Get the geostyler-style ScaleDenominator from a SLD Rule. + * + * @param sldRule The SLD Rule + * @return The geostyler-style ScaleDenominator + */ + getScaleDenominatorFromRule(sldRule: any[]): ScaleDenominator | undefined; + /** + * Get the geostyler-style Symbolizers from a SLD Rule. + * + * @param sldRule The SLD Rule + * @return The geostyler-style Symbolizer array + */ + getSymbolizersFromRule(sldRule: any[]): Symbolizer[]; + /** + * Creates a geostyler-style Filter from a given operator name and the js + * SLD object representation (created with fast-xml-parser) of the SLD Filter. + * + * @param sldOperatorName The Name of the SLD Filter Operator + * @param sldFilter The SLD Filter + * @return The geostyler-style Filter + */ + getFilterFromOperatorAndComparison(sldOperatorName: ComparisonType | 'Function', sldFilter: any): Filter; + /** + * Get the geostyler-style PointSymbolizer from a SLD Symbolizer. + * + * The opacity of the Symbolizer is taken from the . + * + * @param sldSymbolizer The SLD Symbolizer + * @return The geostyler-style PointSymbolizer + */ + getPointSymbolizerFromSldSymbolizer(sldSymbolizer: any): PointSymbolizer; + /** + * Get the geostyler-style LineSymbolizer from a SLD Symbolizer. + * + * Currently only the CssParameters are available. + * + * @param sldSymbolizer The SLD Symbolizer + * @return The geostyler-style LineSymbolizer + */ + getLineSymbolizerFromSldSymbolizer(sldSymbolizer: any): LineSymbolizer; + /** + * Get the geostyler-style TextSymbolizer from a SLD Symbolizer. + * + * @param sldSymbolizer The SLD Symbolizer + * @return The geostyler-style TextSymbolizer + */ + getTextSymbolizerFromSldSymbolizer(sldSymbolizer: any): TextSymbolizer; + /** + * Create a template string from a TextSymbolizer Label element. + * The ordering of the elemments inside the Label element is preserved. + * + * Examples: + * + * --> "foo{{bar}}" + * + * + * --> "{{bar}}foo" + * + * + * --> "{{bar}}foo{{john}}" + * + * + * --> "{{bar}}{{john}}foo" + * + * + * --> "{{bar}}{{john}}foo{{doe}}" + * + * @param sldLabel + */ + getTextSymbolizerLabelFromSldSymbolizer: (sldLabel: any) => string; + /** + * Get the geostyler-style FillSymbolizer from a SLD Symbolizer. + * + * PolygonSymbolizer Stroke is just partially supported. + * + * @param sldSymbolizer The SLD Symbolizer + * @return The geostyler-style FillSymbolizer + */ + getFillSymbolizerFromSldSymbolizer(sldSymbolizer: any): FillSymbolizer; + /** + * Get the geostyler-style RasterSymbolizer from a SLD Symbolizer. + * + * @param sldSymbolizer The SLD Symbolizer + */ + getRasterSymbolizerFromSldSymbolizer(sldSymbolizer: any): RasterSymbolizer; + /** + * Get the geostyler-style MarkSymbolizer from a SLD Symbolizer + * + * @param sldSymbolizer The SLD Symbolizer + * @return The geostyler-style MarkSymbolizer + */ + getMarkSymbolizerFromSldSymbolizer(sldSymbolizer: any): MarkSymbolizer; + /** + * Get the geostyler-style IconSymbolizer from a SLD Symbolizer + * + * @param sldSymbolizer The SLD Symbolizer + * @return The geostyler-style IconSymbolizer + */ + getIconSymbolizerFromSldSymbolizer(sldSymbolizer: any): IconSymbolizer; + /** + * Get the geostyler-style ColorMap from a SLD ColorMap. + * + * @param sldColorMap The SLD ColorMap + */ + getColorMapFromSldColorMap(sldColorMap: any, type?: ColorMapType, extended?: string): ColorMap; + /** + * Get the geostyler-style ContrastEnhancement from a SLD ContrastEnhancement. + * + * @param sldContrastEnhancement The SLD ContrastEnhancement + */ + getContrastEnhancementFromSldContrastEnhancement(sldContrastEnhancement: any): ContrastEnhancement; + /** + * Get the geostyler-style Channel from a SLD Channel. + * + * @param sldChannel The SLD Channel + */ + getChannelFromSldChannel(sldChannel: any): Channel; + /** + * Get the geostyler-style ChannelSelection from a SLD ChannelSelection. + * + * @param sldChannelSelection The SLD ChannelSelection + */ + getChannelSelectionFromSldChannelSelection(sldChannelSelection: any): ChannelSelection; + /** + * The writeStyle implementation of the geostyler-style StyleParser interface. + * It reads a geostyler-style and returns a Promise. + * The Promise itself resolves with a SLD string. + * + * @param geoStylerStyle A geostyler-style. + * @return The Promise resolving with the SLD as a string. + */ + writeStyle(geoStylerStyle: Style): Promise>; + /** + * Get the correct tagName in dependency to the configured sldVersion. + * + * @param tagName + * @returns The tagName as used by the configured sldVersion + */ + getTagName(tagName: string): string; + /** + * Get the SLD Object (readable with fast-xml-parser) from a geostyler-style + * + * @param geoStylerStyle A geostyler-style. + * @return The object representation of a SLD Style (readable with fast-xml-parser) + */ + geoStylerStyleToSldObject(geoStylerStyle: Style): any; + /** + * Get the SLD Object (readable with fast-xml-parser) from a geostyler-style Rule. + * + * @param rules An array of geostyler-style Rules. + * @return The object representation of a SLD Rule (readable with fast-xml-parser) + */ + getSldRulesFromRules(rules: Rule[]): any[]; + /** + * Get the SLD Object (readable with fast-xml-parser) from a geostyler-style ComparisonFilter. + * + * @param comparisonFilter A geostyler-style ComparisonFilter. + * @return The object representation of a SLD Filter Expression with a + * comparison operator (readable with fast-xml-parser) + */ + getSldComparisonFilterFromComparisonFilter(comparisonFilter: ComparisonFilter): any[]; + /** + * Get the SLD Object (readable with fast-xml-parser) from a geostyler-style Filter. + * + * @param filter A geostyler-style Filter. + * @return The object representation of a SLD Filter Expression (readable with fast-xml-parser) + */ + getSldFilterFromFilter(filter: Filter): any[]; + /** + * Get the SLD Object (readable with fast-xml-parser) from geostyler-style Symbolizers. + * + * @param symbolizers A geostyler-style Symbolizer array. + * @return The object representation of a SLD Symbolizer (readable with fast-xml-parser) + */ + getSldSymbolizersFromSymbolizers(symbolizers: Symbolizer[]): any; + /** + * Get the SLD Object (readable with fast-xml-parser) from a geostyler-style MarkSymbolizer. + * + * @param markSymbolizer A geostyler-style MarkSymbolizer. + * @return The object representation of a SLD PointSymbolizer with a Mark + */ + getSldPointSymbolizerFromMarkSymbolizer(markSymbolizer: MarkSymbolizer): any; + /** + * Get the SLD Object (readable with fast-xml-parser) from a geostyler-style IconSymbolizer. + * + * @param iconSymbolizer A geostyler-style IconSymbolizer. + * @return The object representation of a SLD PointSymbolizer with + * an "ExternalGraphic" (readable with fast-xml-parser) + */ + getSldPointSymbolizerFromIconSymbolizer(iconSymbolizer: IconSymbolizer): any; + /** + * Get the SLD Object (readable with fast-xml-parser) from a geostyler-style TextSymbolizer. + * + * @param textSymbolizer A geostyler-style TextSymbolizer. + * @return The object representation of a SLD TextSymbolizer (readable with fast-xml-parser) + */ + getSldTextSymbolizerFromTextSymbolizer(textSymbolizer: TextSymbolizer): any; + /** + * Get the Label from a TextSymbolizer + * + * @param template The Expression representing the label + */ + getSldLabelFromTextSymbolizer: (template: Expression) => any; + /** + * Get the SLD Object (readable with fast-xml-parser) from a geostyler-style LineSymbolizer. + * + * @param lineSymbolizer A geostyler-style LineSymbolizer. + * @return The object representation of a SLD LineSymbolizer (readable with fast-xml-parser) + */ + getSldLineSymbolizerFromLineSymbolizer(lineSymbolizer: LineSymbolizer): any[]; + /** + * Get the SLD Object (readable with fast-xml-parser) from a geostyler-style FillSymbolizer. + * + * @param fillSymbolizer A geostyler-style FillSymbolizer. + * @return The object representation of a SLD PolygonSymbolizer (readable with fast-xml-parser) + */ + getSldPolygonSymbolizerFromFillSymbolizer(fillSymbolizer: FillSymbolizer): any; + /** + * Get the SLD Object (readable with fast-xml-parser) from a geostyler-style RasterSymbolizer. + * + * @param rasterSymbolizer A geostyler-style RasterSymbolizer. + * @return The object representation of a SLD RasterSymbolizer (readable with fast-xml-parser) + */ + getSldRasterSymbolizerFromRasterSymbolizer(rasterSymbolizer: RasterSymbolizer): any; + /** + * Get the SLD Object (readable with fast-xml-parser) from a geostyler-style ColorMap. + * + * @param colorMap A geostyler-style ColorMap. + * @return The object representation of a SLD ColorMap (readable with fast-xml-parser) + */ + getSldColorMapFromColorMap(colorMap: ColorMap): any; + /** + * Get the SLD Object (readable with fast-xml-parser) from a geostyler-style ChannelSelection. + * + * @param channelSelection A geostyler-style ChannelSelection. + * @return The object representation of a SLD ChannelSelection (readable with fast-xml-parser) + */ + getSldChannelSelectionFromChannelSelection(channelSelection: ChannelSelection): any; + /** + * Get the SLD Object (readable with fast-xml-parser) from a geostyler-style ContrastEnhancement. + * + * @param contrastEnhancement A geostyler-style ContrastEnhancement. + * @return The object representation of a SLD ContrastEnhancement (readable with fast-xml-parser) + */ + getSldContrastEnhancementFromContrastEnhancement(contrastEnhancement: ContrastEnhancement): any; + checkForUnsupportedProperties(geoStylerStyle: Style): UnsupportedProperties | undefined; +} +export default SldStyleParser; diff --git a/dist/SldStyleParser.js b/dist/SldStyleParser.js new file mode 100644 index 00000000..fad61e0f --- /dev/null +++ b/dist/SldStyleParser.js @@ -0,0 +1,2458 @@ +import { XMLBuilder, XMLParser } from 'fast-xml-parser'; +import { merge } from 'lodash'; +import { geoStylerFunctionToSldFunction, get, getAttribute, getChildren, getParameterValue, isSymbolizer, keysByValue, numberExpression } from './Util/SldUtil'; +import { isCombinationFilter, isComparisonFilter, isGeoStylerFunction, isGeoStylerNumberFunction, isNegationFilter } from 'geostyler-style/dist/typeguards'; +const SLD_VERSIONS = ['1.0.0', '1.1.0']; +const WELLKNOWNNAME_TTF_REGEXP = /^ttf:\/\/(.+)#(.+)$/; +const COMPARISON_MAP = { + PropertyIsEqualTo: '==', + PropertyIsNotEqualTo: '!=', + PropertyIsLike: '*=', + PropertyIsLessThan: '<', + PropertyIsLessThanOrEqualTo: '<=', + PropertyIsGreaterThan: '>', + PropertyIsGreaterThanOrEqualTo: '>=', + PropertyIsNull: '==', + PropertyIsBetween: '<=x<=' +}; +const NEGATION_OPERATOR_MAP = { + Not: '!' +}; +const COMBINATION_MAP = { + And: '&&', + Or: '||', + PropertyIsBetween: '&&' +}; +export const defaultTranslations = { + en: { + marksymbolizerParseFailedUnknownWellknownName: ({ wellKnownName }) => `MarkSymbolizer cannot be parsed. WellKnownName ${wellKnownName} is not supported.`, + noFilterDetected: 'No Filter detected.', + symbolizerKindParseFailed: ({ sldSymbolizerName }) => `Failed to parse SymbolizerKind ${sldSymbolizerName} from SldRule.`, + colorMapEntriesParseFailedColorUndefined: 'Cannot parse ColorMapEntries. color is undefined.', + contrastEnhancParseFailedHistoAndNormalizeMutuallyExclusive: 'Cannot parse ContrastEnhancement. Histogram and Normalize are mutually exclusive.', + channelSelectionParseFailedRGBAndGrayscaleMutuallyExclusive: 'Cannot parse ChannelSelection. RGB and Grayscale are mutually exclusive.', + channelSelectionParseFailedRGBChannelsUndefined: 'Cannot parse ChannelSelection. Red, Green and Blue channels must be defined.' + }, + de: {}, + fr: { + marksymbolizerParseFailedUnknownWellknownName: ({ wellKnownName }) => `Échec de lecture du symbole de type MarkSymbolizer. Le WellKnownName ${wellKnownName} n'est pas supporté.`, + noFilterDetected: 'Aucun filtre détecté.', + symbolizerKindParseFailed: ({ sldSymbolizerName }) => `Échec de lecture du type de symbole ${sldSymbolizerName} à partir de SldRule.`, + colorMapEntriesParseFailedColorUndefined: 'Lecture de ColorMapEntries échoué. color n\'est pas défini.', + contrastEnhancParseFailedHistoAndNormalizeMutuallyExclusive: 'Échec de lecture des propriétés de contraste ContrastEnhancement échoué. ' + + 'Histogram et Normalize sont mutuellement exclusifs.', + channelSelectionParseFailedRGBAndGrayscaleMutuallyExclusive: 'Échec de lecture de la sélection de canaux ChannelSelection. ' + + 'RGB et Grayscale sont mutuellement exclusifs.', + channelSelectionParseFailedRGBChannelsUndefined: 'Échec de lecture de la sélection de canaux ChannelSelection. ' + + 'Les canaux Rouge, Vert et Bleu doivent être définis.', + }, +}; +/** + * @returns true if the provided value is null or undefined. Returns false otherwise. + */ +const isNil = (val) => val === undefined || val === null; +/** + * This parser can be used with the GeoStyler. + * It implements the geostyler-style StyleParser interface. + * + * @class SldStyleParser + * @implements StyleParser + */ +export class SldStyleParser { + /** + * The name of the SLD Style Parser. + */ + static title = 'SLD Style Parser'; + title = 'SLD Style Parser'; + unsupportedProperties = { + Symbolizer: { + MarkSymbolizer: { + avoidEdges: 'none', + blur: 'none', + offset: { + support: 'partial', + info: 'Only supported for SLD Version 1.1.0' + }, + offsetAnchor: 'none', + pitchAlignment: 'none', + pitchScale: 'none', + visibility: 'none' + }, + FillSymbolizer: { + antialias: 'none', + opacity: { + support: 'none', + info: 'General opacity is not supported. Use fillOpacity and strokeOpacity instead.' + }, + visibility: 'none' + }, + IconSymbolizer: { + allowOverlap: 'none', + anchor: 'none', + avoidEdges: 'none', + color: 'none', + haloBlur: 'none', + haloColor: 'none', + haloOpacity: 'none', + haloWidth: 'none', + keepUpright: 'none', + offset: { + support: 'partial', + info: 'Only supported for SLD Version 1.1.0' + }, + offsetAnchor: 'none', + optional: 'none', + padding: 'none', + pitchAlignment: 'none', + rotationAlignment: 'none', + textFit: 'none', + image: { + support: 'partial', + info: 'Sprites are not supported' + }, + textFitPadding: 'none', + visibility: 'none' + }, + LineSymbolizer: { + blur: 'none', + gapWidth: 'none', + gradient: 'none', + miterLimit: 'none', + roundLimit: 'none', + spacing: 'none', + visibility: 'none' + }, + RasterSymbolizer: { + brightnessMax: 'none', + brightnessMin: 'none', + contrast: 'none', + fadeDuration: 'none', + hueRotate: 'none', + resampling: 'none', + saturation: 'none', + visibility: 'none' + }, + TextSymbolizer: { + placement: { + support: 'partial', + info: 'Only "line" and "point" are currently supported' + } + } + } + }; + translations = defaultTranslations; + locale = 'en'; + constructor(opts) { + this.parser = new XMLParser({ + ...opts?.parserOptions, + // Fixed attributes + ignoreDeclaration: true, + removeNSPrefix: true, + ignoreAttributes: false, + preserveOrder: true, + trimValues: true + }); + this.builder = new XMLBuilder({ + ...opts?.builderOptions, + // Fixed attributes + cdataPropName: '#cdata', + ignoreAttributes: false, + suppressEmptyNode: true, + preserveOrder: true + }); + if (opts?.sldVersion) { + this.sldVersion = opts?.sldVersion; + } + if (opts?.locale) { + this.locale = opts.locale; + } + if (opts?.translations) { + this.translations = merge(this.translations, opts.translations); + } + Object.assign(this, opts); + } + translate(key, params) { + const trans = this.translations?.[this.locale]?.[key] ?? key; + if (typeof trans === 'function') { + return trans(params); + } + return trans; + } + _parser; + get parser() { + return this._parser; + } + set parser(parser) { + this._parser = parser; + } + _builder; + get builder() { + return this._builder; + } + set builder(builder) { + this._builder = builder; + } + /** + * Array of field / property names in a filter, which are casted to numerics + * while parsing a SLD. + */ + _numericFilterFields = []; + /** + * Getter for _numericFilterFields + * @return The numericFilterFields + */ + get numericFilterFields() { + return this._numericFilterFields; + } + /** + * Setter for _numericFilterFields + * @param numericFilterFields The numericFilterFields to set + */ + set numericFilterFields(numericFilterFields) { + this._numericFilterFields = numericFilterFields; + } + /** + * Array of field / property names in a filter, which are casted to boolean + * while parsing a SLD. + */ + _boolFilterFields = []; + /** + * Getter for _boolFilterFields + * @return The boolFilterFields + */ + get boolFilterFields() { + return this._boolFilterFields; + } + /** + * Setter for _boolFilterFields + * @param boolFilterFields The boolFilterFields to set + */ + set boolFilterFields(boolFilterFields) { + this._boolFilterFields = boolFilterFields; + } + /** + * String indicating the SLD version to use. 1.1.0 will make use of + * Symbology Encoding. + */ + _sldVersion = '1.0.0'; + /** + * Getter for _sldVersion + * @return + */ + get sldVersion() { + return this._sldVersion; + } + /** + * Setter for _sldVersion + * @param sldVersion The _sldVersion value to set + */ + set sldVersion(sldVersion) { + this._sldVersion = sldVersion; + } + /** + * String indicating the SLD version used in reading mode + */ + _readingSldVersion = '1.0.0'; + /** + * Getter for _readingSldVersion + * @return + */ + get readingSldVersion() { + return this._readingSldVersion; + } + /** + * Setter for _readingSldVersion + * @param sldVersion The _readingSldVersion value to set + */ + set readingSldVersion(sldVersion) { + this._readingSldVersion = sldVersion; + } + /** + * Used to add a `uom` attribute to the symbolizer tag. Can be one of + * `metre`, `foot` or `pixel`. Defaults to pixel. + */ + _symbolizerUnits = 'pixel'; + /** + * Getter for _symbolizerUnits + * @return {string} + */ + get symbolizerUnits() { + return this._symbolizerUnits; + } + /** + * Setter for _symbolizerUnits + * @param {string} symbolizerUnits The _symbolizerUnits value to set + */ + set symbolizerUnits(symbolizerUnits) { + this._symbolizerUnits = symbolizerUnits; + } + /** + * The readStyle implementation of the geostyler-style StyleParser interface. + * It reads a SLD as a string and returns a Promise. + * The Promise itself resolves with an object containing the geostyler-style. + * + * @param sldString A SLD as a string. + * @return The Promise resolving with an object containing the geostyler-style. + */ + readStyle(sldString) { + return new Promise((resolve) => { + try { + const sldObject = this.parser.parse(sldString); + const version = getAttribute(sldObject[0], 'version'); + if (!SLD_VERSIONS.includes(version)) { + throw new Error(`SLD version must be ${SLD_VERSIONS.toString()}`); + } + this._readingSldVersion = version; + const geoStylerStyle = this.sldObjectToGeoStylerStyle(sldObject); + resolve({ + output: geoStylerStyle + }); + } + catch (error) { + resolve({ + errors: [error] + }); + } + }); + } + /** + * Get the geostyler-style from a SLD Object (created with fast-xml-parser). + * + * @param sldObject The SLD object representation (created with fast-xml-parser) + * @return The geostyler-style + */ + sldObjectToGeoStylerStyle(sldObject) { + const rules = this.getRulesFromSldObject(sldObject); + const name = this.getStyleNameFromSldObject(sldObject); + return { + name, + rules + }; + } + /** + * Get the geostyler-style rules from a SLD Object (created with fast-xml-parser). + * + * @param sldObject The SLD object representation (created with fast-xml-parser) + * @return The geostyler-style rules + */ + getRulesFromSldObject(sldObject) { + const layers = getChildren(sldObject[0].StyledLayerDescriptor, 'NamedLayer'); + const rules = []; + layers.forEach(({ NamedLayer: layer }) => { + getChildren(layer, 'UserStyle').forEach(({ UserStyle: userStyle }) => { + getChildren(userStyle, 'FeatureTypeStyle').forEach(({ FeatureTypeStyle: featureTypeStyle }) => { + getChildren(featureTypeStyle, 'Rule').forEach(({ Rule: sldRule }) => { + const filter = this.getFilterFromRule(sldRule); + const scaleDenominator = this.getScaleDenominatorFromRule(sldRule); + const symbolizers = this.getSymbolizersFromRule(sldRule); + const ruleTitle = get(sldRule, 'Title.#text'); + const ruleName = get(sldRule, 'Name.#text'); + const name = ruleTitle !== undefined + ? ruleTitle + : (ruleName !== undefined ? ruleName : ''); + const rule = { + name + }; + if (filter) { + rule.filter = filter; + } + if (scaleDenominator) { + rule.scaleDenominator = scaleDenominator; + } + if (symbolizers) { + rule.symbolizers = symbolizers; + } + rules.push(rule); + }); + }); + }); + }); + return rules; + } + /** + * Get the name for the Style from the SLD Object. Returns the Title of the UserStyle + * if defined or the Name of the NamedLayer if defined or an empty string. + * + * @param sldObject The SLD object representation (created with fast-xml-parser) + * @return The name to be used for the GeoStyler Style Style + */ + getStyleNameFromSldObject(sldObject) { + const userStyleTitle = get(sldObject, 'StyledLayerDescriptor.NamedLayer[0].UserStyle.Name.#text'); + const namedLayerName = get(sldObject, 'StyledLayerDescriptor.NamedLayer.Name.#text'); + return userStyleTitle ? userStyleTitle + : namedLayerName ? namedLayerName : ''; + } + /** + * Get the geostyler-style Filter from a SLD Rule. + * + * Currently only supports one Filter per Rule. + * + * @param sldRule The SLD Rule + * @return The geostyler-style Filter + */ + getFilterFromRule(sldRule) { + const sldFilter = get(sldRule, 'Filter'); + if (!sldFilter || sldFilter.length === 0) { + return; + } + const operator = Object.keys(sldFilter[0])?.[0]; + if (!operator) { + return; + } + const filter = this.getFilterFromOperatorAndComparison(operator, sldFilter); + return filter; + } + /** + * Get the geostyler-style ScaleDenominator from a SLD Rule. + * + * @param sldRule The SLD Rule + * @return The geostyler-style ScaleDenominator + */ + getScaleDenominatorFromRule(sldRule) { + const scaleDenominator = {}; + const min = get(sldRule, 'MinScaleDenominator.#text'); + if (min) { + scaleDenominator.min = Number(min); + } + const max = get(sldRule, 'MaxScaleDenominator.#text'); + if (max) { + scaleDenominator.max = Number(max); + } + return (Number.isFinite(scaleDenominator.min) || Number.isFinite(scaleDenominator.max)) + ? scaleDenominator + : undefined; + } + /** + * Get the geostyler-style Symbolizers from a SLD Rule. + * + * @param sldRule The SLD Rule + * @return The geostyler-style Symbolizer array + */ + getSymbolizersFromRule(sldRule) { + const symbolizers = sldRule + .filter(isSymbolizer) + .map((sldSymbolizer) => { + const sldSymbolizerName = Object.keys(sldSymbolizer)[0]; + switch (sldSymbolizerName) { + case 'PointSymbolizer': + return this.getPointSymbolizerFromSldSymbolizer(sldSymbolizer.PointSymbolizer); + case 'LineSymbolizer': + return this.getLineSymbolizerFromSldSymbolizer(sldSymbolizer.LineSymbolizer); + case 'TextSymbolizer': + return this.getTextSymbolizerFromSldSymbolizer(sldSymbolizer.TextSymbolizer); + case 'PolygonSymbolizer': + return this.getFillSymbolizerFromSldSymbolizer(sldSymbolizer.PolygonSymbolizer); + case 'RasterSymbolizer': + return this.getRasterSymbolizerFromSldSymbolizer(sldSymbolizer.RasterSymbolizer); + default: + throw new Error(this.translate('symbolizerKindParseFailed', { sldSymbolizerName: sldSymbolizerName })); + } + }); + return symbolizers; + } + /** + * Creates a geostyler-style Filter from a given operator name and the js + * SLD object representation (created with fast-xml-parser) of the SLD Filter. + * + * @param sldOperatorName The Name of the SLD Filter Operator + * @param sldFilter The SLD Filter + * @return The geostyler-style Filter + */ + getFilterFromOperatorAndComparison(sldOperatorName, sldFilter) { + let filter; + if (sldOperatorName === 'Function') { + const functionName = sldFilter[0][':@']['@_name']; + const tempFunctionName = functionName.charAt(0).toUpperCase() + functionName.slice(1); + sldOperatorName = `PropertyIs${tempFunctionName}`; + } + // we have to first check for PropertyIsBetween, + // since it is also a comparisonOperator. But it + // needs to be treated differently. + if (sldOperatorName === 'PropertyIsBetween') { + // TODO: PropertyIsBetween spec allows more than just a PropertyName as its first argument. + const propertyName = get(sldFilter, 'PropertyIsBetween.PropertyName.#text'); + const lower = Number(get(sldFilter, 'PropertyIsBetween.LowerBoundary.Literal.#text')); + const upper = Number(get(sldFilter, 'PropertyIsBetween.UpperBoundary.Literal.#text')); + filter = ['<=x<=', propertyName, lower, upper]; + } + else if (Object.keys(COMPARISON_MAP).includes(sldOperatorName)) { + const comparisonOperator = COMPARISON_MAP[sldOperatorName]; + const filterIsFunction = !!get(sldFilter, 'Function'); + let args = []; + const childrenToArgs = (child) => { + if (get([child], '#text') !== undefined) { + return get([child], '#text'); + } + else { + return get([child], 'PropertyName.#text'); + } + }; + const children = get(sldFilter, filterIsFunction ? 'Function' : sldOperatorName) || []; + args = children.map(childrenToArgs); + if (sldOperatorName === 'PropertyIsNull') { + args[1] = null; + } + filter = [ + comparisonOperator, + ...args + ]; + } + else if (Object.keys(COMBINATION_MAP).includes(sldOperatorName)) { + const combinationOperator = COMBINATION_MAP[sldOperatorName]; + const filters = get(sldFilter, sldOperatorName)?.map((op) => { + const operatorName = Object.keys(op)?.[0]; + return this.getFilterFromOperatorAndComparison(operatorName, op); + }); + filter = [ + combinationOperator, + ...filters + ]; + } + else if (Object.keys(NEGATION_OPERATOR_MAP).includes(sldOperatorName)) { + const negationOperator = NEGATION_OPERATOR_MAP[sldOperatorName]; + const negatedOperator = Object.keys(sldFilter[sldOperatorName][0])[0]; + const negatedComparison = sldFilter[sldOperatorName][0]; + const negatedFilter = this.getFilterFromOperatorAndComparison(negatedOperator, negatedComparison); + filter = [ + negationOperator, + negatedFilter + ]; + } + else { + throw new Error(this.translate('noFilterDetected')); + } + return filter; + } + /** + * Get the geostyler-style PointSymbolizer from a SLD Symbolizer. + * + * The opacity of the Symbolizer is taken from the . + * + * @param sldSymbolizer The SLD Symbolizer + * @return The geostyler-style PointSymbolizer + */ + getPointSymbolizerFromSldSymbolizer(sldSymbolizer) { + let pointSymbolizer; + const wellKnownName = get(sldSymbolizer, 'Graphic.Mark.WellKnownName.#text'); + const externalGraphic = get(sldSymbolizer, 'Graphic.ExternalGraphic'); + if (externalGraphic) { + pointSymbolizer = this.getIconSymbolizerFromSldSymbolizer(sldSymbolizer); + } + else { + // geoserver does not set a wellKnownName for square explicitly since it is the default value. + // Therefore, we have to set the wellKnownName to square if no wellKownName is given. + if (!wellKnownName) { + // TODO: Fix this. Idealy without lodash + // _set(sldSymbolizer, 'Graphic[0].Mark[0].WellKnownName[0]._', 'square'); + } + pointSymbolizer = this.getMarkSymbolizerFromSldSymbolizer(sldSymbolizer); + } + return pointSymbolizer; + } + /** + * Get the geostyler-style LineSymbolizer from a SLD Symbolizer. + * + * Currently only the CssParameters are available. + * + * @param sldSymbolizer The SLD Symbolizer + * @return The geostyler-style LineSymbolizer + */ + getLineSymbolizerFromSldSymbolizer(sldSymbolizer) { + const lineSymbolizer = { + kind: 'Line' + }; + const strokeEl = get(sldSymbolizer, 'Stroke', this.readingSldVersion); + const color = getParameterValue(strokeEl, 'stroke', this.readingSldVersion); + const width = getParameterValue(strokeEl, 'stroke-width', this.readingSldVersion); + const opacity = getParameterValue(strokeEl, 'stroke-opacity', this.readingSldVersion); + const lineJoin = getParameterValue(strokeEl, 'stroke-linejoin', this.readingSldVersion); + const lineCap = getParameterValue(strokeEl, 'stroke-linecap', this.readingSldVersion); + const dashArray = getParameterValue(strokeEl, 'stroke-dasharray', this.readingSldVersion); + const dashOffset = getParameterValue(strokeEl, 'stroke-dashoffset', this.readingSldVersion); + if (!isNil(color)) { + lineSymbolizer.color = color; + } + if (!isNil(width)) { + lineSymbolizer.width = numberExpression(width); + } + if (!isNil(opacity)) { + lineSymbolizer.opacity = numberExpression(opacity); + } + if (!isNil(lineJoin)) { + // geostyler-style and ol use 'miter' whereas sld uses 'mitre' + if (lineJoin === 'mitre') { + lineSymbolizer.join = 'miter'; + } + else { + lineSymbolizer.join = lineJoin; + } + } + if (!isNil(lineCap)) { + lineSymbolizer.cap = lineCap; + } + if (!isNil(dashArray)) { + const dashStringAsArray = dashArray.split(' ').map(numberExpression); + lineSymbolizer.dasharray = dashStringAsArray; + } + if (!isNil(dashOffset)) { + lineSymbolizer.dashOffset = numberExpression(dashOffset); + } + const graphicStroke = get(strokeEl, 'GraphicStroke'); + if (!isNil(graphicStroke)) { + lineSymbolizer.graphicStroke = this.getPointSymbolizerFromSldSymbolizer(graphicStroke); + } + const graphicFill = get(strokeEl, 'GraphicFill'); + if (!isNil(graphicFill)) { + lineSymbolizer.graphicFill = this.getPointSymbolizerFromSldSymbolizer(graphicFill); + } + const perpendicularOffset = get(sldSymbolizer, 'PerpendicularOffset.#text'); + if (!isNil(perpendicularOffset)) { + lineSymbolizer.perpendicularOffset = numberExpression(perpendicularOffset); + } + return lineSymbolizer; + } + /** + * Get the geostyler-style TextSymbolizer from a SLD Symbolizer. + * + * @param sldSymbolizer The SLD Symbolizer + * @return The geostyler-style TextSymbolizer + */ + getTextSymbolizerFromSldSymbolizer(sldSymbolizer) { + const textSymbolizer = { + kind: 'Text' + }; + const fontEl = get(sldSymbolizer, 'Font'); + const fillEl = get(sldSymbolizer, 'Fill'); + const labelEl = get(sldSymbolizer, 'Label'); + const haloEl = get(sldSymbolizer, 'Halo'); + const haloFillEl = get(haloEl, 'Fill'); + const color = getParameterValue(fillEl, 'fill', this.readingSldVersion); + const opacity = getParameterValue(fillEl, 'fill-opacity', this.readingSldVersion); + const fontFamily = getParameterValue(fontEl, 'font-family', this.readingSldVersion); + const fontStyle = getParameterValue(fontEl, 'font-style', this.readingSldVersion); + const fontSize = getParameterValue(fontEl, 'font-size', this.readingSldVersion); + const fontWeight = getParameterValue(fontEl, 'font-weight', this.readingSldVersion); + const haloColor = getParameterValue(haloFillEl, 'fill', this.readingSldVersion); + if (!isNil(labelEl)) { + textSymbolizer.label = this.getTextSymbolizerLabelFromSldSymbolizer(labelEl); + } + textSymbolizer.color = color ? color : '#000000'; + if (!isNil(opacity)) { + textSymbolizer.opacity = numberExpression(opacity); + } + const haloRadius = get(sldSymbolizer, 'Halo.Radius.#text'); + if (!isNil(haloRadius)) { + textSymbolizer.haloWidth = numberExpression(haloRadius); + } + const haloOpacity = getParameterValue(haloFillEl, 'fill-opacity', this.readingSldVersion); + if (!isNil(haloOpacity)) { + textSymbolizer.haloOpacity = numberExpression(haloOpacity); + } + if (!isNil(haloColor)) { + textSymbolizer.haloColor = haloColor; + } + const placement = get(sldSymbolizer, 'LabelPlacement'); + if (!isNil(placement)) { + const pointPlacement = get(placement, 'PointPlacement'); + const linePlacement = get(placement, 'LinePlacement'); + if (!isNil(pointPlacement)) { + textSymbolizer.placement = 'point'; + const displacement = get(pointPlacement, 'Displacement'); + if (!isNil(displacement)) { + const x = get(displacement, 'DisplacementX.#text'); + const y = get(displacement, 'DisplacementY.#text'); + textSymbolizer.offset = [ + Number.isFinite(x) ? numberExpression(x) : 0, + Number.isFinite(y) ? -numberExpression(y) : 0, + ]; + } + const rotation = get(pointPlacement, 'Rotation.#text'); + if (!isNil(rotation)) { + textSymbolizer.rotate = numberExpression(rotation); + } + } + else if (!isNil(linePlacement)) { + textSymbolizer.placement = 'line'; + } + } + if (!isNil(fontFamily)) { + textSymbolizer.font = [fontFamily]; + } + if (!isNil(fontStyle)) { + textSymbolizer.fontStyle = fontStyle.toLowerCase(); + } + if (!isNil(fontWeight)) { + textSymbolizer.fontWeight = fontWeight.toLowerCase(); + } + if (!isNil(fontSize)) { + textSymbolizer.size = numberExpression(fontSize); + } + return textSymbolizer; + } + /** + * Create a template string from a TextSymbolizer Label element. + * The ordering of the elemments inside the Label element is preserved. + * + * Examples: + * + * --> "foo{{bar}}" + * + * + * --> "{{bar}}foo" + * + * + * --> "{{bar}}foo{{john}}" + * + * + * --> "{{bar}}{{john}}foo" + * + * + * --> "{{bar}}{{john}}foo{{doe}}" + * + * @param sldLabel + */ + getTextSymbolizerLabelFromSldSymbolizer = (sldLabel) => { + const label = sldLabel + .map((labelEl) => { + const labelName = Object.keys(labelEl)[0]; + switch (labelName.replace('ogc:', '')) { + case '#text': + return labelEl['#text']; + case 'Literal': + return labelEl?.[labelName]?.[0]?.['#text'] || labelEl?.[labelName]?.[0]?.['#cdata']?.[0]?.['#text']; + case 'PropertyName': + const propName = labelEl[labelName][0]['#text']; + return `{{${propName}}}`; + default: + return ''; + } + }) + .join(''); + return label; + }; + /** + * Get the geostyler-style FillSymbolizer from a SLD Symbolizer. + * + * PolygonSymbolizer Stroke is just partially supported. + * + * @param sldSymbolizer The SLD Symbolizer + * @return The geostyler-style FillSymbolizer + */ + getFillSymbolizerFromSldSymbolizer(sldSymbolizer) { + const fillSymbolizer = { + kind: 'Fill' + }; + const strokeEl = get(sldSymbolizer, 'Stroke'); + const fillEl = get(sldSymbolizer, 'Fill'); + const fillOpacity = getParameterValue(fillEl, 'fill-opacity', this.readingSldVersion); + const color = getParameterValue(fillEl, 'fill', this.readingSldVersion); + const outlineColor = getParameterValue(strokeEl, 'stroke', this.readingSldVersion); + const outlineWidth = getParameterValue(strokeEl, 'stroke-width', this.readingSldVersion); + const outlineOpacity = getParameterValue(strokeEl, 'stroke-opacity', this.readingSldVersion); + const outlineDashArray = getParameterValue(strokeEl, 'stroke-dasharray', this.readingSldVersion); + const outlineCap = getParameterValue(strokeEl, 'stroke-linecap', this.readingSldVersion); + const outlineJoin = getParameterValue(strokeEl, 'stroke-linejoin', this.readingSldVersion); + // const outlineDashOffset = getParameterValue(strokeEl, 'stroke-dashoffset', this.readingSldVersion); + const graphicFill = get(sldSymbolizer, 'Fill.GraphicFill'); + if (!isNil(graphicFill)) { + fillSymbolizer.graphicFill = this.getPointSymbolizerFromSldSymbolizer(graphicFill); + } + if (!isNil(color)) { + fillSymbolizer.color = color; + } + if (!isNil(fillOpacity)) { + fillSymbolizer.fillOpacity = numberExpression(fillOpacity); + } + if (!isNil(outlineColor)) { + fillSymbolizer.outlineColor = outlineColor; + } + if (!isNil(outlineWidth)) { + fillSymbolizer.outlineWidth = numberExpression(outlineWidth); + } + if (!isNil(outlineOpacity)) { + fillSymbolizer.outlineOpacity = numberExpression(outlineOpacity); + } + if (!isNil(outlineDashArray)) { + fillSymbolizer.outlineDasharray = outlineDashArray.split(' ').map(numberExpression); + } + if (!isNil(outlineCap)) { + fillSymbolizer.outlineCap = outlineCap; + } + if (!isNil(outlineJoin)) { + fillSymbolizer.outlineJoin = outlineJoin; + } + // TODO: seems like this is missing in the geostyer-stlye + // if (outlineDashOffset) { + // fillSymbolizer.outlineDashOffset = Number(outlineDashOffset); + // } + return fillSymbolizer; + } + /** + * Get the geostyler-style RasterSymbolizer from a SLD Symbolizer. + * + * @param sldSymbolizer The SLD Symbolizer + */ + getRasterSymbolizerFromSldSymbolizer(sldSymbolizer) { + const rasterSymbolizer = { + kind: 'Raster' + }; + // parse Opacity + let opacity = get(sldSymbolizer, 'Opacity.#text'); + if (!isNil(opacity)) { + opacity = numberExpression(opacity); + rasterSymbolizer.opacity = opacity; + } + // parse ColorMap + const sldColorMap = get(sldSymbolizer, 'ColorMap'); + const sldColorMapType = get(sldSymbolizer, 'ColorMap.@type'); + const extended = get(sldSymbolizer, 'ColorMap.@extended'); + if (!isNil(sldColorMap)) { + const colormap = this.getColorMapFromSldColorMap(sldColorMap, sldColorMapType, extended); + rasterSymbolizer.colorMap = colormap; + } + // parse ChannelSelection + const sldChannelSelection = get(sldSymbolizer, 'ChannelSelection'); + if (!isNil(sldChannelSelection)) { + const channelSelection = this.getChannelSelectionFromSldChannelSelection(sldChannelSelection); + rasterSymbolizer.channelSelection = channelSelection; + } + // parse ContrastEnhancement + const sldContrastEnhancement = get(sldSymbolizer, 'ContrastEnhancement'); + if (!isNil(sldContrastEnhancement)) { + const contrastEnhancement = this.getContrastEnhancementFromSldContrastEnhancement(sldContrastEnhancement); + rasterSymbolizer.contrastEnhancement = contrastEnhancement; + } + return rasterSymbolizer; + } + /** + * Get the geostyler-style MarkSymbolizer from a SLD Symbolizer + * + * @param sldSymbolizer The SLD Symbolizer + * @return The geostyler-style MarkSymbolizer + */ + getMarkSymbolizerFromSldSymbolizer(sldSymbolizer) { + const wellKnownName = get(sldSymbolizer, 'Graphic.Mark.WellKnownName.#text'); + const strokeEl = get(sldSymbolizer, 'Graphic.Mark.Stroke'); + const fillEl = get(sldSymbolizer, 'Graphic.Mark.Fill'); + const opacity = get(sldSymbolizer, 'Graphic.Opacity.#text'); + const size = get(sldSymbolizer, 'Graphic.Size.#text'); + const rotation = get(sldSymbolizer, 'Graphic.Rotation.#text'); + const fillOpacity = getParameterValue(fillEl, 'fill-opacity', this.readingSldVersion); + const color = getParameterValue(fillEl, 'fill', this.readingSldVersion); + const displacement = get(sldSymbolizer, 'Graphic.Displacement'); + const markSymbolizer = { + kind: 'Mark', + wellKnownName: 'circle' + }; + if (!isNil(opacity)) { + markSymbolizer.opacity = numberExpression(opacity); + } + if (!isNil(fillOpacity)) { + markSymbolizer.fillOpacity = numberExpression(fillOpacity); + } + if (!isNil(color)) { + markSymbolizer.color = color; + } + if (!isNil(rotation)) { + markSymbolizer.rotate = numberExpression(rotation); + } + if (!isNil(size)) { + // edge case where the value has to be divided by 2 which has to be considered in the function + markSymbolizer.radius = isGeoStylerNumberFunction(size) ? size : Number(size) / 2; + } + if (displacement) { + const x = get(displacement, 'DisplacementX.#text'); + const y = get(displacement, 'DisplacementY.#text'); + markSymbolizer.offset = [ + Number.isFinite(x) ? numberExpression(x) : 0, + Number.isFinite(y) ? numberExpression(y) : 0, + ]; + } + switch (wellKnownName) { + case 'arrow': + case 'arrowhead': + case 'asterisk_fill': + case 'circle': + case 'cross': + case 'cross2': + case 'cross_fill': + case 'decagon': + case 'diagonal_half_square': + case 'diamond': + case 'equilateral_triangle': + case 'filled_arrowhead': + case 'half_arc': + case 'half_square': + case 'heart': + case 'hexagon': + case 'horline': + case 'left_half_triangle': + case 'line': + case 'octagon': + case 'parallelogram_left': + case 'parallelogram_right': + case 'pentagon': + case 'quarter_arc': + case 'quarter_circle': + case 'quarter_square': + case 'right_half_triangle': + case 'rounded_square': + case 'semi_circle': + case 'shield': + case 'square': + case 'square_with_corners': + case 'star': + case 'star_diamond': + case 'third_arc': + case 'third_circle': + case 'trapezoid': + case 'triangle': + case 'x': + case 'shape://vertline': + case 'shape://horline': + case 'shape://slash': + case 'shape://backslash': + case 'shape://dot': + case 'shape://plus': + case 'shape://times': + case 'shape://oarrow': + case 'shape://carrow': + markSymbolizer.wellKnownName = wellKnownName; + break; + default: + if (WELLKNOWNNAME_TTF_REGEXP.test(wellKnownName)) { + markSymbolizer.wellKnownName = wellKnownName; + break; + } + throw new Error(this.translate('marksymbolizerParseFailedUnknownWellknownName', { wellKnownName: wellKnownName })); + } + const strokeColor = getParameterValue(strokeEl, 'stroke', this.readingSldVersion); + if (!isNil(strokeColor)) { + markSymbolizer.strokeColor = strokeColor; + } + const strokeWidth = getParameterValue(strokeEl, 'stroke-width', this.readingSldVersion); + if (!isNil(strokeWidth)) { + markSymbolizer.strokeWidth = numberExpression(strokeWidth); + } + const strokeOpacity = getParameterValue(strokeEl, 'stroke-opacity', this.readingSldVersion); + if (!isNil(strokeOpacity)) { + markSymbolizer.strokeOpacity = numberExpression(strokeOpacity); + } + return markSymbolizer; + } + /** + * Get the geostyler-style IconSymbolizer from a SLD Symbolizer + * + * @param sldSymbolizer The SLD Symbolizer + * @return The geostyler-style IconSymbolizer + */ + getIconSymbolizerFromSldSymbolizer(sldSymbolizer) { + const image = get(sldSymbolizer, 'Graphic.ExternalGraphic.OnlineResource.@href'); + const iconSymbolizer = { + kind: 'Icon', + image + }; + const opacity = get(sldSymbolizer, 'Graphic.Opacity.#text'); + const size = get(sldSymbolizer, 'Graphic.Size.#text'); + const rotation = get(sldSymbolizer, 'Graphic.Rotation.#text'); + const displacement = get(sldSymbolizer, 'Graphic.Displacement'); + if (!isNil(opacity)) { + iconSymbolizer.opacity = numberExpression(opacity); + } + if (!isNil(size)) { + iconSymbolizer.size = numberExpression(size); + } + if (!isNil(rotation)) { + iconSymbolizer.rotate = numberExpression(rotation); + } + if (displacement) { + const x = get(displacement, 'DisplacementX.#text'); + const y = get(displacement, 'DisplacementY.#text'); + iconSymbolizer.offset = [ + Number.isFinite(x) ? numberExpression(x) : 0, + Number.isFinite(y) ? numberExpression(y) : 0, + ]; + } + return iconSymbolizer; + } + /** + * Get the geostyler-style ColorMap from a SLD ColorMap. + * + * @param sldColorMap The SLD ColorMap + */ + getColorMapFromSldColorMap(sldColorMap, type = 'ramp', extended) { + const colorMap = { + type + }; + if (extended) { + if (extended === 'true') { + colorMap.extended = true; + } + else { + colorMap.extended = false; + } + } + const colorMapEntries = getChildren(sldColorMap, 'ColorMapEntry'); + if (Array.isArray(colorMapEntries)) { + const cmEntries = colorMapEntries.map((cm) => { + const color = getAttribute(cm, 'color'); + if (!color) { + throw new Error(this.translate('colorMapEntriesParseFailedColorUndefined')); + } + let quantity = getAttribute(cm, 'quantity'); + if (quantity) { + quantity = numberExpression(quantity); + } + const label = getAttribute(cm, 'label'); + let opacity = getAttribute(cm, 'opacity'); + if (!isNil(opacity)) { + opacity = numberExpression(opacity); + } + return { + color, + quantity, + label, + opacity + }; + }); + colorMap.colorMapEntries = cmEntries; + } + return colorMap; + } + /** + * Get the geostyler-style ContrastEnhancement from a SLD ContrastEnhancement. + * + * @param sldContrastEnhancement The SLD ContrastEnhancement + */ + getContrastEnhancementFromSldContrastEnhancement(sldContrastEnhancement) { + const contrastEnhancement = {}; + // parse enhancementType + const hasHistogram = !!get(sldContrastEnhancement, 'Histogram'); + const hasNormalize = !!get(sldContrastEnhancement, 'Normalize'); + if (hasHistogram && hasNormalize) { + throw new Error(this.translate('contrastEnhancParseFailedHistoAndNormalizeMutuallyExclusive')); + } + else if (hasHistogram) { + contrastEnhancement.enhancementType = 'histogram'; + } + else if (hasNormalize) { + contrastEnhancement.enhancementType = 'normalize'; + } + // parse gammavalue + let gammaValue = get(sldContrastEnhancement, 'GammaValue.#text'); + if (gammaValue) { + gammaValue = numberExpression(gammaValue); + } + contrastEnhancement.gammaValue = gammaValue; + return contrastEnhancement; + } + /** + * Get the geostyler-style Channel from a SLD Channel. + * + * @param sldChannel The SLD Channel + */ + getChannelFromSldChannel(sldChannel) { + const sourceChannelName = get(sldChannel, 'SourceChannelName.#text')?.toString(); + const channel = { + sourceChannelName + }; + const contrastEnhancement = get(sldChannel, 'ContrastEnhancement'); + if (contrastEnhancement) { + channel.contrastEnhancement = this.getContrastEnhancementFromSldContrastEnhancement(contrastEnhancement); + } + return channel; + } + /** + * Get the geostyler-style ChannelSelection from a SLD ChannelSelection. + * + * @param sldChannelSelection The SLD ChannelSelection + */ + getChannelSelectionFromSldChannelSelection(sldChannelSelection) { + let channelSelection; + const red = get(sldChannelSelection, 'RedChannel'); + const blue = get(sldChannelSelection, 'BlueChannel'); + const green = get(sldChannelSelection, 'GreenChannel'); + const gray = get(sldChannelSelection, 'GrayChannel'); + if (gray && red && blue && green) { + throw new Error(this.translate('channelSelectionParseFailedRGBAndGrayscaleMutuallyExclusive')); + } + if (gray) { + const grayChannel = this.getChannelFromSldChannel(gray); + channelSelection = { + grayChannel + }; + } + else if (red && green && blue) { + const redChannel = this.getChannelFromSldChannel(red); + const blueChannel = this.getChannelFromSldChannel(blue); + const greenChannel = this.getChannelFromSldChannel(green); + channelSelection = { + redChannel, + blueChannel, + greenChannel + }; + } + else { + throw new Error(this.translate('channelSelectionParseFailedRGBChannelsUndefined')); + } + return channelSelection; + } + /** + * The writeStyle implementation of the geostyler-style StyleParser interface. + * It reads a geostyler-style and returns a Promise. + * The Promise itself resolves with a SLD string. + * + * @param geoStylerStyle A geostyler-style. + * @return The Promise resolving with the SLD as a string. + */ + writeStyle(geoStylerStyle) { + return new Promise(resolve => { + const unsupportedProperties = this.checkForUnsupportedProperties(geoStylerStyle); + try { + const sldObject = this.geoStylerStyleToSldObject(geoStylerStyle); + const sldString = this.builder.build(sldObject); + resolve({ + output: sldString, + unsupportedProperties, + warnings: unsupportedProperties && ['Your style contains unsupportedProperties!'] + }); + } + catch (error) { + resolve({ + errors: [error] + }); + } + }); + } + /** + * Get the correct tagName in dependency to the configured sldVersion. + * + * @param tagName + * @returns The tagName as used by the configured sldVersion + */ + getTagName(tagName) { + const ogcList = ['Filter']; + if (ogcList.includes(tagName)) { + return tagName; + } + if (tagName === 'CssParameter') { + return this.sldVersion === '1.1.0' ? 'se:SvgParameter' : 'CssParameter'; + } + return this.sldVersion === '1.1.0' ? `se:${tagName}` : tagName; + } + /** + * Get the SLD Object (readable with fast-xml-parser) from a geostyler-style + * + * @param geoStylerStyle A geostyler-style. + * @return The object representation of a SLD Style (readable with fast-xml-parser) + */ + geoStylerStyleToSldObject(geoStylerStyle) { + const rules = this.getSldRulesFromRules(geoStylerStyle.rules); + // add the ogc namespace to the filter element, if a filter is present + rules.forEach(rule => { + const ruleEl = get(rule, this.getTagName('Rule')); + const filter = getChildren(ruleEl, 'Filter').at(0); + if (filter) { + filter[':@'] = { + '@_xmlns': 'http://www.opengis.net/ogc' + }; + } + }); + const featureTypeStyle = [ + ...rules + ]; + const Name = this.getTagName('Name'); + const Title = this.getTagName('Title'); + const FeatureTypeStyle = this.getTagName('FeatureTypeStyle'); + const attributes = { + '@_version': this.sldVersion, + '@_xsi:schemaLocation': 'http://www.opengis.net/sld StyledLayerDescriptor.xsd', + '@_xmlns': 'http://www.opengis.net/sld', + '@_xmlns:ogc': 'http://www.opengis.net/ogc', + '@_xmlns:xlink': 'http://www.w3.org/1999/xlink', + '@_xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance', + '@_xmlns:se': 'http://www.opengis.net/se' + }; + const userStyle = []; + userStyle.push({ + [Name]: [{ '#text': geoStylerStyle.name || '' }] + }); + if (this.sldVersion === '1.0.0') { + userStyle.push({ + [Title]: [{ '#text': geoStylerStyle.name || '' }] + }); + } + userStyle.push({ + [FeatureTypeStyle]: featureTypeStyle + }); + return [{ + '?xml': [{ '#text': '' }], + ':@': { + '@_version': '1.0', + '@_encoding': 'UTF-8', + '@_standalone': 'yes' + }, + }, { + StyledLayerDescriptor: [{ + NamedLayer: [{ + [Name]: [{ '#text': geoStylerStyle.name || '' }] + }, { + UserStyle: userStyle + }] + }], + ':@': attributes + }]; + } + /** + * Get the SLD Object (readable with fast-xml-parser) from a geostyler-style Rule. + * + * @param rules An array of geostyler-style Rules. + * @return The object representation of a SLD Rule (readable with fast-xml-parser) + */ + getSldRulesFromRules(rules) { + const Name = this.getTagName('Name'); + const filterTag = this.getTagName('Filter'); + const ruleTag = this.getTagName('Rule'); + const MinScaleDenominator = this.getTagName('MinScaleDenominator'); + const MaxScaleDenominator = this.getTagName('MaxScaleDenominator'); + return rules.map((rule) => { + const sldRule = { + [ruleTag]: [] + }; + if (rule.name) { + sldRule[ruleTag].push({ + [Name]: [{ + '#text': rule.name + }] + }); + } + if (rule.filter) { + const filter = this.getSldFilterFromFilter(rule.filter); + sldRule[ruleTag].push({ + [filterTag]: filter + }); + } + if (rule.scaleDenominator) { + const { min, max } = rule.scaleDenominator; + if (min && Number.isFinite(min)) { + sldRule[ruleTag].push({ + [MinScaleDenominator]: [{ + '#text': min + }] + }); + } + if (max && Number.isFinite(max)) { + sldRule[ruleTag].push({ + [MaxScaleDenominator]: [{ + '#text': max + }] + }); + } + } + // Remove empty Symbolizers and check if there is at least 1 symbolizer + const symbolizers = this.getSldSymbolizersFromSymbolizers(rule.symbolizers); + let symbolizerKeys = []; + if (symbolizers.length > 0) { + symbolizerKeys = Object.keys(symbolizers[0]); + } + symbolizerKeys.forEach((key) => { + if (symbolizers[0][key].length === 0) { + delete symbolizers[0][key]; + } + }); + if (symbolizers.length > 0 && symbolizerKeys.length !== 0) { + sldRule[ruleTag] = [ + ...sldRule[ruleTag], + ...symbolizers + ]; + } + return sldRule; + }); + } + /** + * Get the SLD Object (readable with fast-xml-parser) from a geostyler-style ComparisonFilter. + * + * @param comparisonFilter A geostyler-style ComparisonFilter. + * @return The object representation of a SLD Filter Expression with a + * comparison operator (readable with fast-xml-parser) + */ + getSldComparisonFilterFromComparisonFilter(comparisonFilter) { + const sldComparisonFilter = []; + const operator = comparisonFilter[0]; + const key = comparisonFilter[1]; + const value = comparisonFilter[2]; + const sldOperators = keysByValue(COMPARISON_MAP, operator); + const sldOperator = (sldOperators.length > 1 && value === null) + ? sldOperators[1] : sldOperators[0]; + const propertyKey = 'PropertyName'; + if (isGeoStylerFunction(key) || isGeoStylerFunction(value)) { + const tempOperator = sldOperator.replace('PropertyIs', ''); + const sldFunctionOperator = tempOperator.charAt(0).toLowerCase() + tempOperator.slice(1); + const keyResult = isGeoStylerFunction(key) ? geoStylerFunctionToSldFunction(key) : key; + const valueResult = isGeoStylerFunction(value) ? geoStylerFunctionToSldFunction(value) : value; + const functionChildren = []; + if (isGeoStylerFunction(key)) { + functionChildren.unshift(keyResult?.[0]); + } + else { + functionChildren.unshift({ + Literal: [{ + '#text': keyResult + }] + }); + } + if (isGeoStylerFunction(value)) { + functionChildren.push(valueResult?.[0]); + } + else { + functionChildren.push({ + Literal: [{ + '#text': valueResult + }] + }); + } + return [{ + Function: functionChildren, + ':@': { + '@_name': sldFunctionOperator + } + }]; + } + if (sldOperator === 'PropertyIsNull') { + // empty, selfclosing Literals are not valid in a propertyIsNull filter + sldComparisonFilter.push({ + [sldOperator]: [{ + [propertyKey]: [{ + '#text': key + }] + }] + }); + } + else if (sldOperator === 'PropertyIsLike') { + sldComparisonFilter.push({ + [sldOperator]: [{ + [propertyKey]: [{ + '#text': key + }] + }, { + Literal: [{ + '#text': value + }] + }], + [':@']: { + '@_wildCard': '*', + '@_singleChar': '.', + '@_escape': '!', + } + }); + } + else if (sldOperator === 'PropertyIsBetween') { + // Currently we only support Literals as values. + const betweenFilter = comparisonFilter; + sldComparisonFilter.push({ + [sldOperator]: [{ + [propertyKey]: [{ + '#text': key + }] + }, { + LowerBoundary: [{ + Literal: [{ + '#text': betweenFilter[2] + }] + }] + }, { + UpperBoundary: [{ + Literal: [{ + '#text': betweenFilter[3] + }] + }] + }] + }); + } + else { + sldComparisonFilter.push({ + [sldOperator]: [{ + [propertyKey]: [{ + '#text': key + }] + }, { + Literal: [{ + '#text': value + }] + }] + }); + } + return sldComparisonFilter; + } + /** + * Get the SLD Object (readable with fast-xml-parser) from a geostyler-style Filter. + * + * @param filter A geostyler-style Filter. + * @return The object representation of a SLD Filter Expression (readable with fast-xml-parser) + */ + getSldFilterFromFilter(filter) { + let sldFilter = []; + if (isComparisonFilter(filter)) { + sldFilter = this.getSldComparisonFilterFromComparisonFilter(filter); + } + else if (isNegationFilter(filter)) { + sldFilter.push({ + Not: this.getSldFilterFromFilter(filter[1]) + }); + } + else if (isCombinationFilter(filter)) { + const [operator, ...args] = filter; + const sldOperators = keysByValue(COMBINATION_MAP, operator); + const combinator = sldOperators[0]; + const sldSubFilters = args.map(subFilter => this.getSldFilterFromFilter(subFilter)[0]); + sldFilter.push({ + [combinator]: sldSubFilters + }); + } + return sldFilter; + } + /** + * Get the SLD Object (readable with fast-xml-parser) from geostyler-style Symbolizers. + * + * @param symbolizers A geostyler-style Symbolizer array. + * @return The object representation of a SLD Symbolizer (readable with fast-xml-parser) + */ + getSldSymbolizersFromSymbolizers(symbolizers) { + const sldSymbolizers = []; + const pointSymbolizerTag = this.getTagName('PointSymbolizer'); + const textSymbolizerTag = this.getTagName('TextSymbolizer'); + const lineSymbolizerTag = this.getTagName('LineSymbolizer'); + const polygonSymbolizerTag = this.getTagName('PolygonSymbolizer'); + const rasterSymbolizerTag = this.getTagName('RasterSymbolizer'); + symbolizers.forEach(symb => { + const sldSymbolizer = {}; + let sldSymb; + switch (symb.kind) { + case 'Mark': + sldSymb = this.getSldPointSymbolizerFromMarkSymbolizer(symb); + sldSymbolizer[pointSymbolizerTag] = sldSymb; + break; + case 'Icon': + sldSymb = this.getSldPointSymbolizerFromIconSymbolizer(symb); + sldSymbolizer[pointSymbolizerTag] = sldSymb; + break; + case 'Text': + sldSymb = this.getSldTextSymbolizerFromTextSymbolizer(symb); + sldSymbolizer[textSymbolizerTag] = sldSymb; + break; + case 'Line': + sldSymb = this.getSldLineSymbolizerFromLineSymbolizer(symb); + sldSymbolizer[lineSymbolizerTag] = sldSymb; + break; + case 'Fill': + sldSymb = this.getSldPolygonSymbolizerFromFillSymbolizer(symb); + sldSymbolizer[polygonSymbolizerTag] = sldSymb; + break; + case 'Raster': + sldSymb = this.getSldRasterSymbolizerFromRasterSymbolizer(symb); + sldSymbolizer[rasterSymbolizerTag] = sldSymb; + break; + default: + break; + } + sldSymbolizers.push(sldSymbolizer); + }); + return sldSymbolizers; + } + /** + * Get the SLD Object (readable with fast-xml-parser) from a geostyler-style MarkSymbolizer. + * + * @param markSymbolizer A geostyler-style MarkSymbolizer. + * @return The object representation of a SLD PointSymbolizer with a Mark + */ + getSldPointSymbolizerFromMarkSymbolizer(markSymbolizer) { + const wellKnownName = this.getTagName('WellKnownName'); + const CssParameter = this.getTagName('CssParameter'); + const Fill = this.getTagName('Fill'); + const Mark = this.getTagName('Mark'); + const Stroke = this.getTagName('Stroke'); + const Opacity = this.getTagName('Opacity'); + const Rotation = this.getTagName('Rotation'); + const Size = this.getTagName('Size'); + const Graphic = this.getTagName('Graphic'); + const Displacement = this.getTagName('Displacement'); + const DisplacementX = this.getTagName('DisplacementX'); + const DisplacementY = this.getTagName('DisplacementY'); + const isFontSymbol = WELLKNOWNNAME_TTF_REGEXP.test(markSymbolizer.wellKnownName); + const mark = [{ + [wellKnownName]: [{ + '#text': isFontSymbol ? markSymbolizer.wellKnownName : markSymbolizer.wellKnownName.toLowerCase() + }] + }]; + if (markSymbolizer.color || !isNil(markSymbolizer.fillOpacity)) { + const fillCssParamaters = []; + if (markSymbolizer.color) { + if (isGeoStylerFunction(markSymbolizer.color)) { + const children = geoStylerFunctionToSldFunction(markSymbolizer.color); + fillCssParamaters.push({ + [CssParameter]: children, + ':@': { + '@_name': 'fill' + } + }); + } + else { + fillCssParamaters.push({ + [CssParameter]: [{ + '#text': markSymbolizer.color, + }], + ':@': { + '@_name': 'fill' + } + }); + } + } + if (!isNil(markSymbolizer.fillOpacity)) { + if (isGeoStylerFunction(markSymbolizer.fillOpacity)) { + const children = geoStylerFunctionToSldFunction(markSymbolizer.fillOpacity); + fillCssParamaters.push({ + [CssParameter]: children, + ':@': { + '@_name': 'fill-opacity' + } + }); + } + else { + fillCssParamaters.push({ + [CssParameter]: [{ + '#text': markSymbolizer.fillOpacity, + }], + ':@': { + '@_name': 'fill-opacity' + } + }); + } + } + mark.push({ + [Fill]: fillCssParamaters + }); + } + if (markSymbolizer.strokeColor || + Number.isFinite(markSymbolizer.strokeWidth) || + Number.isFinite(markSymbolizer.strokeOpacity)) { + const strokeCssParameters = []; + if (markSymbolizer.strokeColor) { + if (isGeoStylerFunction(markSymbolizer.strokeColor)) { + const children = geoStylerFunctionToSldFunction(markSymbolizer.strokeColor); + strokeCssParameters.push({ + [CssParameter]: children, + ':@': { + '@_name': 'stroke' + } + }); + } + else { + strokeCssParameters.push({ + [CssParameter]: [{ + '#text': markSymbolizer.strokeColor, + }], + ':@': { + '@_name': 'stroke' + } + }); + } + } + if (markSymbolizer.strokeWidth) { + if (isGeoStylerFunction(markSymbolizer.strokeWidth)) { + const children = geoStylerFunctionToSldFunction(markSymbolizer.strokeWidth); + strokeCssParameters.push({ + [CssParameter]: children, + ':@': { + '@_name': 'stroke-width' + } + }); + } + else { + strokeCssParameters.push({ + [CssParameter]: [{ + '#text': markSymbolizer.strokeWidth, + }], + ':@': { + '@_name': 'stroke-width' + } + }); + } + } + if (!isNil(markSymbolizer.strokeOpacity)) { + if (isGeoStylerFunction(markSymbolizer.strokeOpacity)) { + const children = geoStylerFunctionToSldFunction(markSymbolizer.strokeOpacity); + strokeCssParameters.push({ + [CssParameter]: children, + ':@': { + '@_name': 'stroke-opacity' + } + }); + } + else { + strokeCssParameters.push({ + [CssParameter]: [{ + '#text': markSymbolizer.strokeOpacity, + }], + ':@': { + '@_name': 'stroke-opacity' + } + }); + } + } + mark.push({ + [Stroke]: strokeCssParameters + }); + } + const graphic = [{ + [Mark]: mark + }]; + if (!isNil(markSymbolizer.opacity)) { + graphic.push({ + [Opacity]: [{ + '#text': markSymbolizer.opacity.toString() + }] + }); + } + if (markSymbolizer.radius !== undefined) { + if (isGeoStylerFunction(markSymbolizer.radius)) { + graphic.push({ + // TODO: Double check if we have to multiply this by 2 + [Size]: geoStylerFunctionToSldFunction(markSymbolizer.radius) + }); + } + else { + graphic.push({ + [Size]: [{ + '#text': (markSymbolizer.radius * 2).toString() + }] + }); + } + } + if (markSymbolizer.rotate) { + graphic.push({ + [Rotation]: [{ + '#text': markSymbolizer.rotate.toString() + }] + }); + } + if (markSymbolizer.offset && this.sldVersion === '1.1.0') { + graphic.push({ + [Displacement]: [{ + [DisplacementX]: [{ + '#text': markSymbolizer.offset[0].toString() + }] + }, { + [DisplacementY]: [{ + '#text': markSymbolizer.offset[1].toString() + }] + }] + }); + } + return [{ + [Graphic]: graphic + }]; + } + /** + * Get the SLD Object (readable with fast-xml-parser) from a geostyler-style IconSymbolizer. + * + * @param iconSymbolizer A geostyler-style IconSymbolizer. + * @return The object representation of a SLD PointSymbolizer with + * an "ExternalGraphic" (readable with fast-xml-parser) + */ + getSldPointSymbolizerFromIconSymbolizer(iconSymbolizer) { + const ExternalGraphic = this.getTagName('ExternalGraphic'); + const Format = this.getTagName('Format'); + const OnlineResource = this.getTagName('OnlineResource'); + const Opacity = this.getTagName('Opacity'); + const Rotation = this.getTagName('Rotation'); + const Size = this.getTagName('Size'); + const Graphic = this.getTagName('Graphic'); + const Displacement = this.getTagName('Displacement'); + const DisplacementX = this.getTagName('DisplacementX'); + const DisplacementY = this.getTagName('DisplacementY'); + const graphic = [{ + [ExternalGraphic]: [{ + [OnlineResource]: [], + ':@': { + '@_xlink:type': 'simple', + '@_xmlns:xlink': 'http://www.w3.org/1999/xlink', + '@_xlink:href': iconSymbolizer.image + } + }, { [Format]: [] }] + }]; + if (typeof iconSymbolizer.image === 'string' || iconSymbolizer.image instanceof String) { + const iconExt = iconSymbolizer.image.split('.').pop(); + switch (iconExt) { + case 'png': + case 'jpeg': + case 'gif': + graphic[0][ExternalGraphic][1][Format] = [{ + '#text': `image/${iconExt}` + }]; + break; + case 'jpg': + graphic[0][ExternalGraphic][1][Format] = [{ + '#text': 'image/jpeg' + }]; + break; + case 'svg': + graphic[0][ExternalGraphic][1][Format] = [{ + '#text': 'image/svg+xml' + }]; + break; + default: + break; + } + } + if (!isNil(iconSymbolizer.opacity)) { + graphic.push({ + [Opacity]: [{ + '#text': iconSymbolizer.opacity + }] + }); + } + if (iconSymbolizer.size) { + graphic.push({ + [Size]: [{ + '#text': iconSymbolizer.size + }] + }); + } + if (iconSymbolizer.rotate) { + graphic.push({ + [Rotation]: [{ + '#text': iconSymbolizer.rotate + }] + }); + } + if (iconSymbolizer.offset && this.sldVersion === '1.1.0') { + graphic.push({ + [Displacement]: [{ + [DisplacementX]: [{ + '#text': iconSymbolizer.offset[0].toString() + }] + }, { + [DisplacementY]: [{ + '#text': iconSymbolizer.offset[1].toString() + }] + }] + }); + } + return [{ + [Graphic]: graphic + }]; + } + /** + * Get the SLD Object (readable with fast-xml-parser) from a geostyler-style TextSymbolizer. + * + * @param textSymbolizer A geostyler-style TextSymbolizer. + * @return The object representation of a SLD TextSymbolizer (readable with fast-xml-parser) + */ + getSldTextSymbolizerFromTextSymbolizer(textSymbolizer) { + const CssParameter = this.getTagName('CssParameter'); + const Fill = this.getTagName('Fill'); + const Halo = this.getTagName('Halo'); + const Font = this.getTagName('Font'); + const Displacement = this.getTagName('Displacement'); + const DisplacementX = this.getTagName('DisplacementX'); + const DisplacementY = this.getTagName('DisplacementY'); + const LabelPlacement = this.getTagName('LabelPlacement'); + const PointPlacement = this.getTagName('PointPlacement'); + const LinePlacement = this.getTagName('LinePlacement'); + const Rotation = this.getTagName('Rotation'); + const Radius = this.getTagName('Radius'); + const Label = this.getTagName('Label'); + const sldTextSymbolizer = [{ + [Label]: textSymbolizer.label ? this.getSldLabelFromTextSymbolizer(textSymbolizer.label) : undefined + }]; + const fontPropertyMap = { + font: 'font-family', + size: 'font-size', + fontStyle: 'font-style', + fontWeight: 'font-weight' + }; + const fontCssParameters = Object.keys(textSymbolizer) + .filter((property) => property !== 'kind' && fontPropertyMap[property]) + .map((property) => { + if (isGeoStylerFunction(textSymbolizer[property])) { + const children = geoStylerFunctionToSldFunction(textSymbolizer[property]); + return { + [CssParameter]: children, + ':@': { + '@_name': fontPropertyMap[property] + } + }; + } + else { + return { + [CssParameter]: [{ + '#text': property === 'font' + ? textSymbolizer[property]?.[0] + : textSymbolizer[property], + }], + ':@': { + '@_name': fontPropertyMap[property] + } + }; + } + }); + if (fontCssParameters.length > 0) { + sldTextSymbolizer.push({ + [Font]: fontCssParameters + }); + } + if (textSymbolizer.placement === 'line') { + sldTextSymbolizer.push({ + [LabelPlacement]: [{ + [LinePlacement]: [] + }] + }); + } + else if (Number.isFinite(textSymbolizer.offset) + || textSymbolizer.rotate !== undefined + || textSymbolizer.placement === 'point') { + const pointPlacement = []; + if (textSymbolizer.offset) { + pointPlacement.push({ + [Displacement]: [{ + [DisplacementX]: [{ + '#text': textSymbolizer.offset[0].toString() + }] + }, { + [DisplacementY]: [{ + '#text': (-textSymbolizer.offset[1]).toString() + }] + }] + }); + } + if (textSymbolizer.rotate !== undefined) { + pointPlacement.push({ + [Rotation]: [{ + '#text': textSymbolizer.rotate.toString() + }] + }); + } + sldTextSymbolizer.push({ + [LabelPlacement]: [{ + [PointPlacement]: pointPlacement + }] + }); + } + if (Number.isFinite(textSymbolizer.haloWidth) || textSymbolizer.haloColor) { + const halo = []; + const haloFillCssParameter = []; + if (textSymbolizer.haloWidth) { + halo.push({ + [Radius]: [{ + '#text': textSymbolizer.haloWidth.toString() + }] + }); + } + if (textSymbolizer.haloColor) { + haloFillCssParameter.push({ + [CssParameter]: [{ + '#text': textSymbolizer.haloColor, + }], + ':@': { + '@_name': 'fill' + } + }); + } + if (textSymbolizer.haloOpacity) { + haloFillCssParameter.push({ + [CssParameter]: [{ + '#text': textSymbolizer.haloOpacity, + }], + ':@': { + '@_name': 'fill-opacity' + } + }); + } + if (haloFillCssParameter.length > 0) { + halo.push({ + [Fill]: haloFillCssParameter + }); + } + sldTextSymbolizer.push({ + [Halo]: halo + }); + } + if (textSymbolizer.color || Number.isFinite(textSymbolizer.opacity)) { + const fill = [{ + [CssParameter]: [{ + '#text': textSymbolizer.color || '#000000', + }], + ':@': { + '@_name': 'fill' + } + }]; + if (Number.isFinite(textSymbolizer.opacity)) { + fill.push({ + [CssParameter]: [{ + '#text': `${textSymbolizer.opacity}`, + }], + ':@': { + '@_name': 'fill-opacity' + }, + }); + } + sldTextSymbolizer.push({ + [Fill]: fill + }); + } + return sldTextSymbolizer; + } + /** + * Get the Label from a TextSymbolizer + * + * @param template The Expression representing the label + */ + getSldLabelFromTextSymbolizer = (template) => { + // TODO: parse GeoStylerFunction + if (!(typeof template === 'string' || template instanceof String)) { + return undefined; + } + const openingBraces = '{{'; + const closingBraces = '}}'; + const tokens = []; + let templateReducer = template; + while (templateReducer.length) { + let tmpTemplateReducer = templateReducer; + let tmpPreTemplateLiteral; + const openingBracesIdx = tmpTemplateReducer.indexOf(openingBraces); + if (openingBracesIdx === -1) { + if (templateReducer.includes(' ')) { + tokens.push({ + 'ogc:Literal': [{ + '#cdata': [{ + '#text': templateReducer + }] + }] + }); + } + else { + tokens.push({ + 'ogc:Literal': [{ + '#text': templateReducer + }] + }); + } + break; + } + if (openingBracesIdx > 0) { + tmpPreTemplateLiteral = tmpTemplateReducer.slice(0, openingBracesIdx); + } + tmpTemplateReducer = tmpTemplateReducer.slice(openingBracesIdx + openingBraces.length); + const closingBracesIdx = tmpTemplateReducer.indexOf(closingBraces); + if (closingBracesIdx === -1) { + if (templateReducer.includes(' ')) { + tokens.push({ + 'ogc:Literal': [{ + '#cdata': [{ + '#text': templateReducer + }] + }] + }); + } + else { + tokens.push({ + 'ogc:Literal': [{ + '#text': templateReducer + }] + }); + } + break; + } + const propertyName = tmpTemplateReducer.slice(0, closingBracesIdx); + tmpTemplateReducer = tmpTemplateReducer.slice(closingBracesIdx + closingBraces.length); + if (tmpPreTemplateLiteral) { + if (tmpPreTemplateLiteral.includes(' ')) { + tokens.push({ + 'ogc:Literal': [{ + '#cdata': [{ + '#text': tmpPreTemplateLiteral + }] + }] + }); + } + else { + tokens.push({ + 'ogc:Literal': [{ + '#text': tmpPreTemplateLiteral + }] + }); + } + } + tokens.push({ + 'ogc:PropertyName': [{ + '#text': propertyName + }] + }); + templateReducer = tmpTemplateReducer; + } + return tokens; + }; + /** + * Get the SLD Object (readable with fast-xml-parser) from a geostyler-style LineSymbolizer. + * + * @param lineSymbolizer A geostyler-style LineSymbolizer. + * @return The object representation of a SLD LineSymbolizer (readable with fast-xml-parser) + */ + getSldLineSymbolizerFromLineSymbolizer(lineSymbolizer) { + const CssParameter = this.getTagName('CssParameter'); + const Stroke = this.getTagName('Stroke'); + const GraphicStroke = this.getTagName('GraphicStroke'); + const GraphicFill = this.getTagName('GraphicFill'); + const PerpendicularOffset = this.getTagName('PerpendicularOffset'); + const propertyMap = { + color: 'stroke', + width: 'stroke-width', + opacity: 'stroke-opacity', + join: 'stroke-linejoin', + cap: 'stroke-linecap', + dasharray: 'stroke-dasharray', + dashOffset: 'stroke-dashoffset' + }; + const sldLineSymbolizer = []; + const cssParameters = Object.keys(lineSymbolizer) + .filter((property) => property !== 'kind' && propertyMap[property] && + lineSymbolizer[property] !== undefined && + lineSymbolizer[property] !== null) + .map((property) => { + let value = lineSymbolizer[property]; + if (property === 'dasharray') { + value = lineSymbolizer.dasharray ? lineSymbolizer.dasharray.join(' ') : undefined; + return { + [CssParameter]: [{ + '#text': value, + }], + ':@': { + '@_name': propertyMap[property] + } + }; + } + // simple transformation since geostyler-style uses prop 'miter' whereas sld uses 'mitre' + if (property === 'join' && value === 'miter') { + value = 'mitre'; + } + if (isGeoStylerFunction(lineSymbolizer[property])) { + const children = geoStylerFunctionToSldFunction(lineSymbolizer[property]); + return { + [CssParameter]: children, + ':@': { + '@_name': propertyMap[property] + } + }; + } + else { + return { + [CssParameter]: [{ + '#text': lineSymbolizer[property], + }], + ':@': { + '@_name': propertyMap[property] + } + }; + } + }); + if (lineSymbolizer?.graphicStroke) { + if (!Array.isArray(sldLineSymbolizer?.[0]?.[Stroke])) { + sldLineSymbolizer[0] = { [Stroke]: [] }; + } + if (lineSymbolizer?.graphicStroke?.kind === 'Mark') { + const graphicStroke = this.getSldPointSymbolizerFromMarkSymbolizer(lineSymbolizer.graphicStroke); + sldLineSymbolizer[0][Stroke].push({ + [GraphicStroke]: graphicStroke + }); + } + else if (lineSymbolizer?.graphicStroke?.kind === 'Icon') { + const graphicStroke = this.getSldPointSymbolizerFromIconSymbolizer(lineSymbolizer.graphicStroke); + sldLineSymbolizer[0][Stroke].push({ + [GraphicStroke]: graphicStroke + }); + } + } + if (lineSymbolizer?.graphicFill) { + if (!Array.isArray(sldLineSymbolizer?.[0]?.[Stroke])) { + sldLineSymbolizer[0] = { [Stroke]: [] }; + } + if (lineSymbolizer?.graphicFill?.kind === 'Mark') { + const graphicFill = this.getSldPointSymbolizerFromMarkSymbolizer(lineSymbolizer.graphicFill); + sldLineSymbolizer[0][Stroke].push({ + [GraphicFill]: graphicFill + }); + } + else if (lineSymbolizer?.graphicFill?.kind === 'Icon') { + const graphicFill = this.getSldPointSymbolizerFromIconSymbolizer(lineSymbolizer.graphicFill); + sldLineSymbolizer[0][Stroke].push({ + [GraphicFill]: graphicFill + }); + } + } + if (cssParameters.length !== 0) { + if (!Array.isArray(sldLineSymbolizer?.[0]?.[Stroke])) { + sldLineSymbolizer[0] = { [Stroke]: [] }; + } + sldLineSymbolizer[0][Stroke].push(...cssParameters); + } + if (lineSymbolizer.perpendicularOffset) { + sldLineSymbolizer.push({ + [PerpendicularOffset]: [ + { + '#text': lineSymbolizer.perpendicularOffset + } + ] + }); + } + if (sldLineSymbolizer.length === 0) { + sldLineSymbolizer.push({ + [Stroke]: {} + }); + } + return sldLineSymbolizer; + } + /** + * Get the SLD Object (readable with fast-xml-parser) from a geostyler-style FillSymbolizer. + * + * @param fillSymbolizer A geostyler-style FillSymbolizer. + * @return The object representation of a SLD PolygonSymbolizer (readable with fast-xml-parser) + */ + getSldPolygonSymbolizerFromFillSymbolizer(fillSymbolizer) { + const CssParameter = this.getTagName('CssParameter'); + const Stroke = this.getTagName('Stroke'); + const Fill = this.getTagName('Fill'); + const strokePropertyMap = { + outlineColor: 'stroke', + outlineWidth: 'stroke-width', + outlineOpacity: 'stroke-opacity', + outlineDasharray: 'stroke-dasharray', + outlineCap: 'stroke-linecap', + outlineJoin: 'stroke-linejoin' + }; + const fillPropertyMap = { + color: 'fill', + fillOpacity: 'fill-opacity' + }; + const strokeCssParameters = []; + const fillCssParameters = []; + let graphicFill; + if (fillSymbolizer?.graphicFill) { + if (fillSymbolizer?.graphicFill.kind === 'Mark') { + graphicFill = this.getSldPointSymbolizerFromMarkSymbolizer(fillSymbolizer.graphicFill); + } + else if (fillSymbolizer?.graphicFill.kind === 'Icon') { + graphicFill = this.getSldPointSymbolizerFromIconSymbolizer(fillSymbolizer.graphicFill); + } + } + Object.keys(fillSymbolizer) + .filter((property) => property !== 'kind') + .filter((property) => fillSymbolizer[property] !== undefined && + fillSymbolizer[property] !== null) + .forEach((property) => { + if (Object.keys(fillPropertyMap).includes(property)) { + if (isGeoStylerFunction(fillSymbolizer[property])) { + const children = geoStylerFunctionToSldFunction(fillSymbolizer[property]); + fillCssParameters.push({ + [CssParameter]: children, + ':@': { + '@_name': fillPropertyMap[property] + } + }); + } + else { + fillCssParameters.push({ + [CssParameter]: [{ + '#text': fillSymbolizer[property], + }], + ':@': { + '@_name': fillPropertyMap[property] + } + }); + } + } + else if (Object.keys(strokePropertyMap).includes(property)) { + let transformedValue = ''; + if (property === 'outlineDasharray') { + const paramValue = fillSymbolizer[property]; + transformedValue = ''; + paramValue.forEach((dash, idx) => { + transformedValue += dash; + if (idx < paramValue.length - 1) { + transformedValue += ' '; + } + }); + } + else if (property === 'outlineWidth') { + transformedValue = fillSymbolizer[property] + ''; + } + else if (property === 'outlineOpacity') { + transformedValue = fillSymbolizer[property] + ''; + } + else { + transformedValue = fillSymbolizer[property]; + } + if (isGeoStylerFunction(fillSymbolizer[property])) { + const children = geoStylerFunctionToSldFunction(fillSymbolizer[property]); + strokeCssParameters.push({ + [CssParameter]: children, + ':@': { + '@_name': strokePropertyMap[property] + } + }); + } + else { + strokeCssParameters.push({ + [CssParameter]: [{ + '#text': transformedValue, + }], + ':@': { + '@_name': strokePropertyMap[property] + } + }); + } + } + }); + const polygonSymbolizer = []; + if (fillCssParameters.length > 0 || graphicFill) { + if (!Array.isArray(polygonSymbolizer?.[0]?.[Fill])) { + polygonSymbolizer[0] = { [Fill]: [] }; + } + if (fillCssParameters.length > 0) { + polygonSymbolizer[0][Fill].push(...fillCssParameters); + } + if (graphicFill) { + polygonSymbolizer[0][Fill].push({ + GraphicFill: graphicFill + }); + } + } + if (strokeCssParameters.length > 0) { + polygonSymbolizer.push({ + [Stroke]: strokeCssParameters + }); + } + return polygonSymbolizer; + } + /** + * Get the SLD Object (readable with fast-xml-parser) from a geostyler-style RasterSymbolizer. + * + * @param rasterSymbolizer A geostyler-style RasterSymbolizer. + * @return The object representation of a SLD RasterSymbolizer (readable with fast-xml-parser) + */ + getSldRasterSymbolizerFromRasterSymbolizer(rasterSymbolizer) { + const sldRasterSymbolizer = []; + if (rasterSymbolizer.opacity !== undefined) { + sldRasterSymbolizer.push({}); + sldRasterSymbolizer[0].Opacity = [{ + '#text': rasterSymbolizer.opacity + }]; + } + let colorMap; + if (rasterSymbolizer.colorMap) { + colorMap = this.getSldColorMapFromColorMap(rasterSymbolizer.colorMap); + if (colorMap?.[0]) { + sldRasterSymbolizer.push({ + ColorMap: colorMap + }); + } + } + let channelSelection; + if (rasterSymbolizer.channelSelection) { + channelSelection = this.getSldChannelSelectionFromChannelSelection(rasterSymbolizer.channelSelection); + if (channelSelection?.[0]) { + sldRasterSymbolizer.push({ + ChannelSelection: channelSelection + }); + } + } + let contrastEnhancement; + if (rasterSymbolizer.contrastEnhancement) { + contrastEnhancement = this.getSldContrastEnhancementFromContrastEnhancement(rasterSymbolizer.contrastEnhancement); + if (contrastEnhancement?.[0]) { + sldRasterSymbolizer.push({ + ContrastEnhancement: contrastEnhancement + }); + } + } + return sldRasterSymbolizer; + } + /** + * Get the SLD Object (readable with fast-xml-parser) from a geostyler-style ColorMap. + * + * @param colorMap A geostyler-style ColorMap. + * @return The object representation of a SLD ColorMap (readable with fast-xml-parser) + */ + getSldColorMapFromColorMap(colorMap) { + const sldColorMap = []; + // parse colorMap.type + if (colorMap.type) { + const type = colorMap.type; + sldColorMap[':@'] = { + '@_type': type + }; + } + // parse colorMap.extended + if (colorMap.extended !== undefined) { + const extended = colorMap.extended.toString(); + if (!sldColorMap[':@']) { + sldColorMap[':@'] = {}; + } + sldColorMap[':@']['@_extended'] = extended; + } + // parse colorMap.colorMapEntries + if (colorMap.colorMapEntries && colorMap.colorMapEntries.length > 0) { + const colorMapEntries = colorMap.colorMapEntries.map((entry) => { + const result = { + ColorMapEntry: [], + ':@': {} + }; + if (entry.color) { + result[':@']['@_color'] = entry.color; + } + if (typeof entry.quantity !== 'undefined') { + result[':@']['@_quantity'] = entry.quantity.toString(); + } + if (entry.label) { + result[':@']['@_label'] = entry.label; + } + if (typeof entry.opacity !== 'undefined') { + result[':@']['@_opacity'] = entry.opacity.toString(); + } + return result; + // remove empty colorMapEntries + }).filter((entry) => Object.keys(entry).length > 0); + sldColorMap.push(...colorMapEntries); + } + return sldColorMap; + } + /** + * Get the SLD Object (readable with fast-xml-parser) from a geostyler-style ChannelSelection. + * + * @param channelSelection A geostyler-style ChannelSelection. + * @return The object representation of a SLD ChannelSelection (readable with fast-xml-parser) + */ + getSldChannelSelectionFromChannelSelection(channelSelection) { + const propertyMap = { + redChannel: 'RedChannel', + blueChannel: 'BlueChannel', + greenChannel: 'GreenChannel', + grayChannel: 'GrayChannel' + }; + const keys = Object.keys(channelSelection); + const sldChannelSelection = []; + keys.forEach((key) => { + const channel = []; + // parse sourceChannelName + const sourceChannelName = channelSelection?.[key]?.sourceChannelName; + const channelName = propertyMap[key]; + // parse contrastEnhancement + const contrastEnhancement = channelSelection?.[key]?.contrastEnhancement; + if (sourceChannelName || contrastEnhancement) { + if (sourceChannelName) { + channel.push({ + SourceChannelName: [{ + '#text': sourceChannelName + }] + }); + } + if (contrastEnhancement) { + channel.push({ + ContrastEnhancement: this.getSldContrastEnhancementFromContrastEnhancement(contrastEnhancement) + }); + } + sldChannelSelection.push({ + [channelName]: channel + }); + } + }); + return sldChannelSelection; + } + /** + * Get the SLD Object (readable with fast-xml-parser) from a geostyler-style ContrastEnhancement. + * + * @param contrastEnhancement A geostyler-style ContrastEnhancement. + * @return The object representation of a SLD ContrastEnhancement (readable with fast-xml-parser) + */ + getSldContrastEnhancementFromContrastEnhancement(contrastEnhancement) { + const sldContrastEnhancement = []; + const enhancementType = contrastEnhancement?.enhancementType; + if (enhancementType === 'normalize') { + // parse normalize + sldContrastEnhancement.push({ + Normalize: [] + }); + } + else if (enhancementType === 'histogram') { + // parse histogram + sldContrastEnhancement.push({ + Histogram: [] + }); + } + // parse gammaValue + if (contrastEnhancement.gammaValue !== undefined) { + sldContrastEnhancement.push({ + GammaValue: [{ + '#text': contrastEnhancement.gammaValue + }] + }); + } + return sldContrastEnhancement; + } + checkForUnsupportedProperties(geoStylerStyle) { + const capitalizeFirstLetter = (a) => a[0].toUpperCase() + a.slice(1); + const unsupportedProperties = {}; + geoStylerStyle.rules.forEach(rule => { + // ScaleDenominator and Filters are completely supported so we just check for symbolizers + rule.symbolizers.forEach(symbolizer => { + const key = capitalizeFirstLetter(`${symbolizer.kind}Symbolizer`); + const value = this.unsupportedProperties?.Symbolizer?.[key]; + if (value) { + if (typeof value === 'string' || value instanceof String) { + if (!unsupportedProperties.Symbolizer) { + unsupportedProperties.Symbolizer = {}; + } + unsupportedProperties.Symbolizer[key] = value; + } + else { + Object.keys(symbolizer).forEach(property => { + if (value[property]) { + if (!unsupportedProperties.Symbolizer) { + unsupportedProperties.Symbolizer = {}; + } + if (!unsupportedProperties.Symbolizer[key]) { + unsupportedProperties.Symbolizer[key] = {}; + } + unsupportedProperties.Symbolizer[key][property] = value[property]; + } + }); + } + } + }); + }); + if (Object.keys(unsupportedProperties).length > 0) { + return unsupportedProperties; + } + return undefined; + } +} +export default SldStyleParser; +//# sourceMappingURL=SldStyleParser.js.map \ No newline at end of file diff --git a/dist/SldStyleParser.js.map b/dist/SldStyleParser.js.map new file mode 100644 index 00000000..a11febee --- /dev/null +++ b/dist/SldStyleParser.js.map @@ -0,0 +1 @@ +{"version":3,"file":"SldStyleParser.js","sourceRoot":"","sources":["../src/SldStyleParser.ts"],"names":[],"mappings":"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","sourcesContent":["import {\r\n Channel,\r\n ChannelSelection,\r\n ColorMap,\r\n ColorMapEntry,\r\n ColorMapType,\r\n CombinationOperator,\r\n ComparisonFilter,\r\n ComparisonOperator,\r\n ContrastEnhancement,\r\n Expression,\r\n FillSymbolizer,\r\n Filter,\r\n IconSymbolizer,\r\n LineSymbolizer,\r\n MarkSymbolizer,\r\n PointSymbolizer,\r\n RangeFilter,\r\n RasterSymbolizer,\r\n ReadStyleResult,\r\n Rule,\r\n ScaleDenominator,\r\n Style,\r\n StyleParser,\r\n Symbolizer,\r\n TextSymbolizer,\r\n UnsupportedProperties,\r\n WellKnownName,\r\n WriteStyleResult\r\n} from 'geostyler-style/dist/style';\r\nimport { GeoStylerFunction } from 'geostyler-style/dist/functions';\r\nimport {\r\n X2jOptions,\r\n XMLBuilder,\r\n XmlBuilderOptions,\r\n XMLParser\r\n} from 'fast-xml-parser';\r\n\r\nimport { merge } from 'lodash';\r\n\r\nimport {\r\n geoStylerFunctionToSldFunction,\r\n get,\r\n getAttribute,\r\n getChildren,\r\n getParameterValue,\r\n isSymbolizer,\r\n keysByValue,\r\n numberExpression\r\n} from './Util/SldUtil';\r\nimport {\r\n isCombinationFilter,\r\n isComparisonFilter,\r\n isGeoStylerFunction,\r\n isGeoStylerNumberFunction,\r\n isNegationFilter\r\n} from 'geostyler-style/dist/typeguards';\r\n\r\nconst SLD_VERSIONS = ['1.0.0', '1.1.0'] as const;\r\n\r\nexport type SldVersion = (typeof SLD_VERSIONS)[number];\r\n\r\nexport type ParserOptions = Omit;\r\n\r\nexport type BuilderOptions = Omit;\r\n\r\nexport type ConstructorParams = {\r\n numericFilterFields?: string[];\r\n boolFilterFields?: string[];\r\n /* optional for reading style (it will be guessed from sld style) and mandatory for writing */\r\n sldVersion?: SldVersion;\r\n symbolizerUnits?: string;\r\n parserOptions?: ParserOptions;\r\n builderOptions?: XmlBuilderOptions;\r\n translations?: SldStyleParserTranslations;\r\n locale?: string;\r\n};\r\n\r\nconst WELLKNOWNNAME_TTF_REGEXP = /^ttf:\\/\\/(.+)#(.+)$/;\r\n\r\nconst COMPARISON_MAP = {\r\n PropertyIsEqualTo: '==',\r\n PropertyIsNotEqualTo: '!=',\r\n PropertyIsLike: '*=',\r\n PropertyIsLessThan: '<',\r\n PropertyIsLessThanOrEqualTo: '<=',\r\n PropertyIsGreaterThan: '>',\r\n PropertyIsGreaterThanOrEqualTo: '>=',\r\n PropertyIsNull: '==',\r\n PropertyIsBetween: '<=x<='\r\n};\r\n\r\ntype ComparisonType = keyof typeof COMPARISON_MAP;\r\n\r\nconst NEGATION_OPERATOR_MAP = {\r\n Not: '!'\r\n};\r\n\r\nconst COMBINATION_MAP = {\r\n And: '&&',\r\n Or: '||',\r\n PropertyIsBetween: '&&'\r\n};\r\n\r\ntype CombinationType = keyof typeof COMBINATION_MAP;\r\n\r\nexport type SldStyleParserTranslationKeys = {\r\n marksymbolizerParseFailedUnknownWellknownName?: (params: {wellKnownName: string}) => string;\r\n noFilterDetected?: string;\r\n symbolizerKindParseFailed?: (params: {sldSymbolizerName: string}) => string;\r\n colorMapEntriesParseFailedColorUndefined?: string;\r\n contrastEnhancParseFailedHistoAndNormalizeMutuallyExclusive?: string;\r\n channelSelectionParseFailedRGBAndGrayscaleMutuallyExclusive?: string;\r\n channelSelectionParseFailedRGBChannelsUndefined?: string;\r\n};\r\n\r\nexport type SldStyleParserTranslations = Record;\r\n\r\nexport const defaultTranslations: SldStyleParserTranslations = {\r\n en: {\r\n marksymbolizerParseFailedUnknownWellknownName: ({wellKnownName}) =>\r\n `MarkSymbolizer cannot be parsed. WellKnownName ${wellKnownName} is not supported.`,\r\n noFilterDetected: 'No Filter detected.',\r\n symbolizerKindParseFailed: ({sldSymbolizerName}) =>\r\n `Failed to parse SymbolizerKind ${sldSymbolizerName} from SldRule.`,\r\n colorMapEntriesParseFailedColorUndefined: 'Cannot parse ColorMapEntries. color is undefined.',\r\n contrastEnhancParseFailedHistoAndNormalizeMutuallyExclusive:\r\n 'Cannot parse ContrastEnhancement. Histogram and Normalize are mutually exclusive.',\r\n channelSelectionParseFailedRGBAndGrayscaleMutuallyExclusive:\r\n 'Cannot parse ChannelSelection. RGB and Grayscale are mutually exclusive.',\r\n channelSelectionParseFailedRGBChannelsUndefined:\r\n 'Cannot parse ChannelSelection. Red, Green and Blue channels must be defined.'\r\n },\r\n de: {},\r\n fr: {\r\n marksymbolizerParseFailedUnknownWellknownName: ({wellKnownName}) =>\r\n `Échec de lecture du symbole de type MarkSymbolizer. Le WellKnownName ${wellKnownName} n'est pas supporté.`,\r\n noFilterDetected: 'Aucun filtre détecté.',\r\n symbolizerKindParseFailed: ({sldSymbolizerName}) =>\r\n `Échec de lecture du type de symbole ${sldSymbolizerName} à partir de SldRule.`,\r\n colorMapEntriesParseFailedColorUndefined: 'Lecture de ColorMapEntries échoué. color n\\'est pas défini.',\r\n contrastEnhancParseFailedHistoAndNormalizeMutuallyExclusive:\r\n 'Échec de lecture des propriétés de contraste ContrastEnhancement échoué. '\r\n +'Histogram et Normalize sont mutuellement exclusifs.',\r\n channelSelectionParseFailedRGBAndGrayscaleMutuallyExclusive:\r\n 'Échec de lecture de la sélection de canaux ChannelSelection. '\r\n +'RGB et Grayscale sont mutuellement exclusifs.',\r\n channelSelectionParseFailedRGBChannelsUndefined:\r\n 'Échec de lecture de la sélection de canaux ChannelSelection. '\r\n +'Les canaux Rouge, Vert et Bleu doivent être définis.',\r\n\r\n },\r\n} as const;\r\n\r\n/**\r\n * @returns true if the provided value is null or undefined. Returns false otherwise.\r\n */\r\nconst isNil = (val: unknown): boolean => val === undefined || val === null;\r\n\r\n/**\r\n * This parser can be used with the GeoStyler.\r\n * It implements the geostyler-style StyleParser interface.\r\n *\r\n * @class SldStyleParser\r\n * @implements StyleParser\r\n */\r\nexport class SldStyleParser implements StyleParser {\r\n\r\n /**\r\n * The name of the SLD Style Parser.\r\n */\r\n public static title = 'SLD Style Parser';\r\n\r\n title = 'SLD Style Parser';\r\n\r\n unsupportedProperties: UnsupportedProperties = {\r\n Symbolizer: {\r\n MarkSymbolizer: {\r\n avoidEdges: 'none',\r\n blur: 'none',\r\n offset: {\r\n support: 'partial',\r\n info: 'Only supported for SLD Version 1.1.0'\r\n },\r\n offsetAnchor: 'none',\r\n pitchAlignment: 'none',\r\n pitchScale: 'none',\r\n visibility: 'none'\r\n },\r\n FillSymbolizer: {\r\n antialias: 'none',\r\n opacity: {\r\n support: 'none',\r\n info: 'General opacity is not supported. Use fillOpacity and strokeOpacity instead.'\r\n },\r\n visibility: 'none'\r\n },\r\n IconSymbolizer: {\r\n allowOverlap: 'none',\r\n anchor: 'none',\r\n avoidEdges: 'none',\r\n color: 'none',\r\n haloBlur: 'none',\r\n haloColor: 'none',\r\n haloOpacity: 'none',\r\n haloWidth: 'none',\r\n keepUpright: 'none',\r\n offset: {\r\n support: 'partial',\r\n info: 'Only supported for SLD Version 1.1.0'\r\n },\r\n offsetAnchor: 'none',\r\n optional: 'none',\r\n padding: 'none',\r\n pitchAlignment: 'none',\r\n rotationAlignment: 'none',\r\n textFit: 'none',\r\n image: {\r\n support: 'partial',\r\n info: 'Sprites are not supported'\r\n },\r\n textFitPadding: 'none',\r\n visibility: 'none'\r\n },\r\n LineSymbolizer: {\r\n blur: 'none',\r\n gapWidth: 'none',\r\n gradient: 'none',\r\n miterLimit: 'none',\r\n roundLimit: 'none',\r\n spacing: 'none',\r\n visibility: 'none'\r\n },\r\n RasterSymbolizer: {\r\n brightnessMax: 'none',\r\n brightnessMin: 'none',\r\n contrast: 'none',\r\n fadeDuration: 'none',\r\n hueRotate: 'none',\r\n resampling: 'none',\r\n saturation: 'none',\r\n visibility: 'none'\r\n },\r\n TextSymbolizer: {\r\n placement: {\r\n support: 'partial',\r\n info: 'Only \"line\" and \"point\" are currently supported'\r\n }\r\n }\r\n }\r\n };\r\n\r\n translations: SldStyleParserTranslations = defaultTranslations;\r\n\r\n locale: string = 'en';\r\n\r\n constructor(opts?: ConstructorParams) {\r\n this.parser = new XMLParser({\r\n ...opts?.parserOptions,\r\n // Fixed attributes\r\n ignoreDeclaration: true,\r\n removeNSPrefix: true,\r\n ignoreAttributes: false,\r\n preserveOrder: true,\r\n trimValues: true\r\n });\r\n this.builder = new XMLBuilder({\r\n ...opts?.builderOptions,\r\n // Fixed attributes\r\n cdataPropName: '#cdata',\r\n ignoreAttributes: false,\r\n suppressEmptyNode: true,\r\n preserveOrder: true\r\n });\r\n if (opts?.sldVersion) {\r\n this.sldVersion = opts?.sldVersion;\r\n }\r\n\r\n if (opts?.locale) {\r\n this.locale = opts.locale;\r\n }\r\n\r\n if (opts?.translations){\r\n this.translations = merge(this.translations, opts.translations);\r\n }\r\n\r\n Object.assign(this, opts);\r\n }\r\n\r\n translate(key: keyof SldStyleParserTranslationKeys, params?: any): string {\r\n const trans = this.translations?.[this.locale]?.[key] ?? key;\r\n\r\n if (typeof trans === 'function') {\r\n return trans(params);\r\n }\r\n\r\n return trans;\r\n }\r\n\r\n private _parser: XMLParser;\r\n get parser(): XMLParser {\r\n return this._parser;\r\n }\r\n set parser(parser: XMLParser) {\r\n this._parser = parser;\r\n }\r\n\r\n private _builder: XMLBuilder;\r\n get builder(): XMLBuilder {\r\n return this._builder;\r\n }\r\n set builder(builder: XMLBuilder) {\r\n this._builder = builder;\r\n }\r\n\r\n /**\r\n * Array of field / property names in a filter, which are casted to numerics\r\n * while parsing a SLD.\r\n */\r\n private _numericFilterFields: string[] = [];\r\n /**\r\n * Getter for _numericFilterFields\r\n * @return The numericFilterFields\r\n */\r\n get numericFilterFields(): string[] {\r\n return this._numericFilterFields;\r\n }\r\n /**\r\n * Setter for _numericFilterFields\r\n * @param numericFilterFields The numericFilterFields to set\r\n */\r\n set numericFilterFields(numericFilterFields: string[]) {\r\n this._numericFilterFields = numericFilterFields;\r\n }\r\n\r\n /**\r\n * Array of field / property names in a filter, which are casted to boolean\r\n * while parsing a SLD.\r\n */\r\n private _boolFilterFields: string[] = [];\r\n /**\r\n * Getter for _boolFilterFields\r\n * @return The boolFilterFields\r\n */\r\n get boolFilterFields(): string[] {\r\n return this._boolFilterFields;\r\n }\r\n /**\r\n * Setter for _boolFilterFields\r\n * @param boolFilterFields The boolFilterFields to set\r\n */\r\n set boolFilterFields(boolFilterFields: string[]) {\r\n this._boolFilterFields = boolFilterFields;\r\n }\r\n\r\n /**\r\n * String indicating the SLD version to use. 1.1.0 will make use of\r\n * Symbology Encoding.\r\n */\r\n private _sldVersion: SldVersion = '1.0.0';\r\n\r\n /**\r\n * Getter for _sldVersion\r\n * @return\r\n */\r\n get sldVersion(): SldVersion {\r\n return this._sldVersion;\r\n }\r\n\r\n /**\r\n * Setter for _sldVersion\r\n * @param sldVersion The _sldVersion value to set\r\n */\r\n set sldVersion(sldVersion: SldVersion) {\r\n this._sldVersion = sldVersion;\r\n }\r\n\r\n\r\n /**\r\n * String indicating the SLD version used in reading mode\r\n */\r\n private _readingSldVersion: SldVersion = '1.0.0';\r\n\r\n /**\r\n * Getter for _readingSldVersion\r\n * @return\r\n */\r\n get readingSldVersion(): SldVersion {\r\n return this._readingSldVersion;\r\n }\r\n\r\n /**\r\n * Setter for _readingSldVersion\r\n * @param sldVersion The _readingSldVersion value to set\r\n */\r\n set readingSldVersion(sldVersion: SldVersion) {\r\n this._readingSldVersion = sldVersion;\r\n }\r\n\r\n /**\r\n * Used to add a `uom` attribute to the symbolizer tag. Can be one of\r\n * `metre`, `foot` or `pixel`. Defaults to pixel.\r\n */\r\n private _symbolizerUnits: string = 'pixel';\r\n\r\n /**\r\n * Getter for _symbolizerUnits\r\n * @return {string}\r\n */\r\n get symbolizerUnits(): string {\r\n return this._symbolizerUnits;\r\n }\r\n\r\n /**\r\n * Setter for _symbolizerUnits\r\n * @param {string} symbolizerUnits The _symbolizerUnits value to set\r\n */\r\n set symbolizerUnits(symbolizerUnits: string) {\r\n this._symbolizerUnits = symbolizerUnits;\r\n }\r\n\r\n /**\r\n * The readStyle implementation of the geostyler-style StyleParser interface.\r\n * It reads a SLD as a string and returns a Promise.\r\n * The Promise itself resolves with an object containing the geostyler-style.\r\n *\r\n * @param sldString A SLD as a string.\r\n * @return The Promise resolving with an object containing the geostyler-style.\r\n */\r\n readStyle(sldString: string): Promise {\r\n return new Promise((resolve) => {\r\n try {\r\n const sldObject = this.parser.parse(sldString);\r\n\r\n const version = getAttribute(sldObject[0], 'version');\r\n if (!SLD_VERSIONS.includes(version)) {\r\n throw new Error(`SLD version must be ${SLD_VERSIONS.toString()}`);\r\n }\r\n this._readingSldVersion = version;\r\n\r\n const geoStylerStyle: Style = this.sldObjectToGeoStylerStyle(sldObject);\r\n resolve({\r\n output: geoStylerStyle\r\n });\r\n } catch (error) {\r\n resolve({\r\n errors: [error]\r\n });\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Get the geostyler-style from a SLD Object (created with fast-xml-parser).\r\n *\r\n * @param sldObject The SLD object representation (created with fast-xml-parser)\r\n * @return The geostyler-style\r\n */\r\n sldObjectToGeoStylerStyle(sldObject: any): Style {\r\n const rules = this.getRulesFromSldObject(sldObject);\r\n const name = this.getStyleNameFromSldObject(sldObject);\r\n return {\r\n name,\r\n rules\r\n };\r\n }\r\n\r\n /**\r\n * Get the geostyler-style rules from a SLD Object (created with fast-xml-parser).\r\n *\r\n * @param sldObject The SLD object representation (created with fast-xml-parser)\r\n * @return The geostyler-style rules\r\n */\r\n getRulesFromSldObject(sldObject: any): Rule[] {\r\n const layers = getChildren(sldObject[0].StyledLayerDescriptor, 'NamedLayer');\r\n const rules: Rule[] = [];\r\n layers.forEach(({ NamedLayer: layer }: any) => {\r\n getChildren(layer, 'UserStyle').forEach(({ UserStyle: userStyle }: any) => {\r\n getChildren(userStyle, 'FeatureTypeStyle').forEach(({ FeatureTypeStyle: featureTypeStyle }: any) => {\r\n getChildren(featureTypeStyle, 'Rule').forEach(({ Rule: sldRule }: any) => {\r\n const filter: Filter | undefined = this.getFilterFromRule(sldRule);\r\n const scaleDenominator: ScaleDenominator | undefined = this.getScaleDenominatorFromRule(sldRule);\r\n const symbolizers: Symbolizer[] = this.getSymbolizersFromRule(sldRule);\r\n const ruleTitle = get(sldRule, 'Title.#text');\r\n const ruleName = get(sldRule, 'Name.#text');\r\n const name = ruleTitle !== undefined\r\n ? ruleTitle\r\n : (ruleName !== undefined ? ruleName : '');\r\n const rule: Rule = {\r\n name\r\n };\r\n if (filter) {\r\n rule.filter = filter;\r\n }\r\n if (scaleDenominator) {\r\n rule.scaleDenominator = scaleDenominator;\r\n }\r\n if (symbolizers) {\r\n rule.symbolizers = symbolizers;\r\n }\r\n rules.push(rule);\r\n });\r\n });\r\n });\r\n });\r\n return rules;\r\n }\r\n\r\n /**\r\n * Get the name for the Style from the SLD Object. Returns the Title of the UserStyle\r\n * if defined or the Name of the NamedLayer if defined or an empty string.\r\n *\r\n * @param sldObject The SLD object representation (created with fast-xml-parser)\r\n * @return The name to be used for the GeoStyler Style Style\r\n */\r\n getStyleNameFromSldObject(sldObject: any): string {\r\n const userStyleTitle = get(sldObject, 'StyledLayerDescriptor.NamedLayer[0].UserStyle.Name.#text');\r\n const namedLayerName = get(sldObject, 'StyledLayerDescriptor.NamedLayer.Name.#text');\r\n return userStyleTitle ? userStyleTitle\r\n : namedLayerName ? namedLayerName : '';\r\n }\r\n\r\n /**\r\n * Get the geostyler-style Filter from a SLD Rule.\r\n *\r\n * Currently only supports one Filter per Rule.\r\n *\r\n * @param sldRule The SLD Rule\r\n * @return The geostyler-style Filter\r\n */\r\n getFilterFromRule(sldRule: any[]): Filter | undefined {\r\n const sldFilter = get(sldRule, 'Filter');\r\n if (!sldFilter || sldFilter.length === 0) {\r\n return;\r\n }\r\n const operator = Object.keys(sldFilter[0])?.[0];\r\n if (!operator) {\r\n return;\r\n }\r\n const filter = this.getFilterFromOperatorAndComparison(operator as ComparisonType, sldFilter);\r\n return filter;\r\n }\r\n\r\n /**\r\n * Get the geostyler-style ScaleDenominator from a SLD Rule.\r\n *\r\n * @param sldRule The SLD Rule\r\n * @return The geostyler-style ScaleDenominator\r\n */\r\n getScaleDenominatorFromRule(sldRule: any[]): ScaleDenominator | undefined {\r\n const scaleDenominator: ScaleDenominator = {};\r\n const min = get(sldRule, 'MinScaleDenominator.#text');\r\n if (min) {\r\n scaleDenominator.min = Number(min);\r\n }\r\n const max = get(sldRule, 'MaxScaleDenominator.#text');\r\n if (max) {\r\n scaleDenominator.max = Number(max);\r\n }\r\n\r\n return (Number.isFinite(scaleDenominator.min) || Number.isFinite(scaleDenominator.max))\r\n ? scaleDenominator\r\n : undefined;\r\n }\r\n\r\n /**\r\n * Get the geostyler-style Symbolizers from a SLD Rule.\r\n *\r\n * @param sldRule The SLD Rule\r\n * @return The geostyler-style Symbolizer array\r\n */\r\n getSymbolizersFromRule(sldRule: any[]): Symbolizer[] {\r\n const symbolizers: Symbolizer[] = sldRule\r\n .filter(isSymbolizer)\r\n .map((sldSymbolizer: any) => {\r\n const sldSymbolizerName: string = Object.keys(sldSymbolizer)[0];\r\n switch (sldSymbolizerName) {\r\n case 'PointSymbolizer':\r\n return this.getPointSymbolizerFromSldSymbolizer(sldSymbolizer.PointSymbolizer);\r\n case 'LineSymbolizer':\r\n return this.getLineSymbolizerFromSldSymbolizer(sldSymbolizer.LineSymbolizer);\r\n case 'TextSymbolizer':\r\n return this.getTextSymbolizerFromSldSymbolizer(sldSymbolizer.TextSymbolizer);\r\n case 'PolygonSymbolizer':\r\n return this.getFillSymbolizerFromSldSymbolizer(sldSymbolizer.PolygonSymbolizer);\r\n case 'RasterSymbolizer':\r\n return this.getRasterSymbolizerFromSldSymbolizer(sldSymbolizer.RasterSymbolizer);\r\n default:\r\n throw new Error(this.translate('symbolizerKindParseFailed', { sldSymbolizerName: sldSymbolizerName }));\r\n }\r\n });\r\n\r\n return symbolizers;\r\n }\r\n\r\n /**\r\n * Creates a geostyler-style Filter from a given operator name and the js\r\n * SLD object representation (created with fast-xml-parser) of the SLD Filter.\r\n *\r\n * @param sldOperatorName The Name of the SLD Filter Operator\r\n * @param sldFilter The SLD Filter\r\n * @return The geostyler-style Filter\r\n */\r\n getFilterFromOperatorAndComparison(\r\n sldOperatorName: ComparisonType | 'Function',\r\n sldFilter: any\r\n ): Filter {\r\n let filter: Filter;\r\n\r\n if (sldOperatorName === 'Function') {\r\n const functionName = sldFilter[0][':@']['@_name'];\r\n const tempFunctionName = functionName.charAt(0).toUpperCase() + functionName.slice(1);\r\n sldOperatorName = `PropertyIs${tempFunctionName}` as ComparisonType;\r\n }\r\n\r\n // we have to first check for PropertyIsBetween,\r\n // since it is also a comparisonOperator. But it\r\n // needs to be treated differently.\r\n if (sldOperatorName === 'PropertyIsBetween') {\r\n // TODO: PropertyIsBetween spec allows more than just a PropertyName as its first argument.\r\n const propertyName = get(sldFilter, 'PropertyIsBetween.PropertyName.#text');\r\n const lower = Number(get(sldFilter, 'PropertyIsBetween.LowerBoundary.Literal.#text'));\r\n const upper = Number(get(sldFilter, 'PropertyIsBetween.UpperBoundary.Literal.#text'));\r\n\r\n filter = ['<=x<=', propertyName, lower, upper];\r\n } else if (Object.keys(COMPARISON_MAP).includes(sldOperatorName)) {\r\n const comparisonOperator: ComparisonOperator = COMPARISON_MAP[sldOperatorName] as ComparisonOperator;\r\n const filterIsFunction = !!get(sldFilter, 'Function');\r\n let args: any[] = [];\r\n const childrenToArgs = (child: any) => {\r\n if (get([child], '#text') !== undefined) {\r\n return get([child], '#text');\r\n } else {\r\n return get([child], 'PropertyName.#text');\r\n }\r\n };\r\n\r\n const children = get(sldFilter, filterIsFunction ? 'Function' : sldOperatorName) || [];\r\n args = children.map(childrenToArgs);\r\n\r\n if (sldOperatorName === 'PropertyIsNull') {\r\n args[1] = null;\r\n }\r\n\r\n filter = [\r\n comparisonOperator,\r\n ...args\r\n ] as ComparisonFilter;\r\n\r\n } else if (Object.keys(COMBINATION_MAP).includes(sldOperatorName)) {\r\n const combinationOperator: CombinationOperator = COMBINATION_MAP[\r\n sldOperatorName as CombinationType] as CombinationOperator;\r\n const filters: Filter[] = get(sldFilter, sldOperatorName)?.map((op: any) => {\r\n const operatorName = Object.keys(op)?.[0];\r\n return this.getFilterFromOperatorAndComparison(operatorName as any, op);\r\n });\r\n filter = [\r\n combinationOperator,\r\n ...filters\r\n ];\r\n } else if (Object.keys(NEGATION_OPERATOR_MAP).includes(sldOperatorName)) {\r\n const negationOperator = NEGATION_OPERATOR_MAP[sldOperatorName as 'Not'];\r\n const negatedOperator = Object.keys(sldFilter[sldOperatorName][0])[0];\r\n const negatedComparison = sldFilter[sldOperatorName][0];\r\n const negatedFilter: Filter = this.getFilterFromOperatorAndComparison(\r\n negatedOperator as any,\r\n negatedComparison\r\n );\r\n filter = [\r\n negationOperator as any,\r\n negatedFilter\r\n ];\r\n } else {\r\n throw new Error(this.translate('noFilterDetected'));\r\n }\r\n return filter;\r\n }\r\n\r\n /**\r\n * Get the geostyler-style PointSymbolizer from a SLD Symbolizer.\r\n *\r\n * The opacity of the Symbolizer is taken from the .\r\n *\r\n * @param sldSymbolizer The SLD Symbolizer\r\n * @return The geostyler-style PointSymbolizer\r\n */\r\n getPointSymbolizerFromSldSymbolizer(sldSymbolizer: any): PointSymbolizer {\r\n let pointSymbolizer: PointSymbolizer;\r\n const wellKnownName: string = get(sldSymbolizer, 'Graphic.Mark.WellKnownName.#text');\r\n const externalGraphic: any = get(sldSymbolizer, 'Graphic.ExternalGraphic');\r\n if (externalGraphic) {\r\n pointSymbolizer = this.getIconSymbolizerFromSldSymbolizer(sldSymbolizer);\r\n } else {\r\n // geoserver does not set a wellKnownName for square explicitly since it is the default value.\r\n // Therefore, we have to set the wellKnownName to square if no wellKownName is given.\r\n if (!wellKnownName) {\r\n // TODO: Fix this. Idealy without lodash\r\n // _set(sldSymbolizer, 'Graphic[0].Mark[0].WellKnownName[0]._', 'square');\r\n }\r\n pointSymbolizer = this.getMarkSymbolizerFromSldSymbolizer(sldSymbolizer);\r\n }\r\n return pointSymbolizer;\r\n }\r\n\r\n /**\r\n * Get the geostyler-style LineSymbolizer from a SLD Symbolizer.\r\n *\r\n * Currently only the CssParameters are available.\r\n *\r\n * @param sldSymbolizer The SLD Symbolizer\r\n * @return The geostyler-style LineSymbolizer\r\n */\r\n getLineSymbolizerFromSldSymbolizer(sldSymbolizer: any): LineSymbolizer {\r\n const lineSymbolizer: LineSymbolizer = {\r\n kind: 'Line'\r\n };\r\n const strokeEl = get(sldSymbolizer, 'Stroke', this.readingSldVersion);\r\n const color = getParameterValue(strokeEl, 'stroke', this.readingSldVersion);\r\n const width = getParameterValue(strokeEl, 'stroke-width', this.readingSldVersion);\r\n const opacity = getParameterValue(strokeEl, 'stroke-opacity', this.readingSldVersion);\r\n const lineJoin = getParameterValue(strokeEl, 'stroke-linejoin', this.readingSldVersion);\r\n const lineCap = getParameterValue(strokeEl, 'stroke-linecap', this.readingSldVersion);\r\n const dashArray = getParameterValue(strokeEl, 'stroke-dasharray', this.readingSldVersion);\r\n const dashOffset = getParameterValue(strokeEl, 'stroke-dashoffset', this.readingSldVersion);\r\n\r\n if (!isNil(color)) {\r\n lineSymbolizer.color = color;\r\n }\r\n if (!isNil(width)) {\r\n lineSymbolizer.width = numberExpression(width);\r\n }\r\n if (!isNil(opacity)) {\r\n lineSymbolizer.opacity = numberExpression(opacity);\r\n }\r\n if (!isNil(lineJoin)) {\r\n // geostyler-style and ol use 'miter' whereas sld uses 'mitre'\r\n if (lineJoin === 'mitre') {\r\n lineSymbolizer.join = 'miter';\r\n } else {\r\n lineSymbolizer.join = lineJoin as 'bevel' | 'miter' | 'round' | undefined;\r\n }\r\n }\r\n if (!isNil(lineCap)) {\r\n lineSymbolizer.cap = lineCap as 'round' | 'butt' | 'square' | undefined;\r\n }\r\n\r\n if (!isNil(dashArray)) {\r\n const dashStringAsArray = dashArray.split(' ').map(numberExpression);\r\n lineSymbolizer.dasharray = dashStringAsArray;\r\n }\r\n if (!isNil(dashOffset)) {\r\n lineSymbolizer.dashOffset = numberExpression(dashOffset);\r\n }\r\n\r\n const graphicStroke = get(strokeEl, 'GraphicStroke');\r\n if (!isNil(graphicStroke)) {\r\n lineSymbolizer.graphicStroke = this.getPointSymbolizerFromSldSymbolizer(graphicStroke);\r\n }\r\n\r\n const graphicFill = get(strokeEl, 'GraphicFill');\r\n if (!isNil(graphicFill)) {\r\n lineSymbolizer.graphicFill = this.getPointSymbolizerFromSldSymbolizer(graphicFill);\r\n }\r\n\r\n const perpendicularOffset = get(sldSymbolizer, 'PerpendicularOffset.#text');\r\n if (!isNil(perpendicularOffset)) {\r\n lineSymbolizer.perpendicularOffset = numberExpression(perpendicularOffset);\r\n }\r\n\r\n return lineSymbolizer;\r\n }\r\n\r\n /**\r\n * Get the geostyler-style TextSymbolizer from a SLD Symbolizer.\r\n *\r\n * @param sldSymbolizer The SLD Symbolizer\r\n * @return The geostyler-style TextSymbolizer\r\n */\r\n getTextSymbolizerFromSldSymbolizer(sldSymbolizer: any): TextSymbolizer {\r\n const textSymbolizer: TextSymbolizer = {\r\n kind: 'Text'\r\n };\r\n const fontEl = get(sldSymbolizer, 'Font');\r\n const fillEl = get(sldSymbolizer, 'Fill');\r\n const labelEl = get(sldSymbolizer, 'Label');\r\n const haloEl = get(sldSymbolizer, 'Halo');\r\n const haloFillEl = get(haloEl, 'Fill');\r\n\r\n const color = getParameterValue(fillEl, 'fill', this.readingSldVersion);\r\n const opacity = getParameterValue(fillEl, 'fill-opacity', this.readingSldVersion);\r\n\r\n const fontFamily = getParameterValue(fontEl, 'font-family', this.readingSldVersion);\r\n const fontStyle = getParameterValue(fontEl, 'font-style', this.readingSldVersion);\r\n const fontSize = getParameterValue(fontEl, 'font-size', this.readingSldVersion);\r\n const fontWeight = getParameterValue(fontEl, 'font-weight', this.readingSldVersion);\r\n\r\n const haloColor = getParameterValue(haloFillEl, 'fill', this.readingSldVersion);\r\n\r\n if (!isNil(labelEl)) {\r\n textSymbolizer.label = this.getTextSymbolizerLabelFromSldSymbolizer(labelEl);\r\n }\r\n\r\n textSymbolizer.color = color ? color : '#000000';\r\n\r\n if (!isNil(opacity)) {\r\n textSymbolizer.opacity = numberExpression(opacity);\r\n }\r\n\r\n const haloRadius = get(sldSymbolizer, 'Halo.Radius.#text');\r\n if (!isNil(haloRadius)) {\r\n textSymbolizer.haloWidth = numberExpression(haloRadius);\r\n }\r\n const haloOpacity = getParameterValue(haloFillEl, 'fill-opacity', this.readingSldVersion);\r\n if (!isNil(haloOpacity)) {\r\n textSymbolizer.haloOpacity = numberExpression(haloOpacity);\r\n }\r\n if (!isNil(haloColor)) {\r\n textSymbolizer.haloColor = haloColor;\r\n }\r\n const placement = get(sldSymbolizer, 'LabelPlacement');\r\n if (!isNil(placement)) {\r\n const pointPlacement = get(placement, 'PointPlacement');\r\n const linePlacement = get(placement, 'LinePlacement');\r\n if (!isNil(pointPlacement)) {\r\n textSymbolizer.placement = 'point';\r\n const displacement = get(pointPlacement, 'Displacement');\r\n if (!isNil(displacement)) {\r\n const x = get(displacement, 'DisplacementX.#text');\r\n const y = get(displacement, 'DisplacementY.#text');\r\n textSymbolizer.offset = [\r\n Number.isFinite(x) ? numberExpression(x) : 0,\r\n Number.isFinite(y) ? -numberExpression(y) : 0,\r\n ];\r\n }\r\n const rotation = get(pointPlacement, 'Rotation.#text');\r\n if (!isNil(rotation)) {\r\n textSymbolizer.rotate = numberExpression(rotation);\r\n }\r\n } else if (!isNil(linePlacement)) {\r\n textSymbolizer.placement = 'line';\r\n }\r\n }\r\n if (!isNil(fontFamily)) {\r\n textSymbolizer.font = [fontFamily];\r\n }\r\n if (!isNil(fontStyle)) {\r\n textSymbolizer.fontStyle = fontStyle.toLowerCase() as 'normal' | 'italic' | 'oblique' | undefined;\r\n }\r\n if (!isNil(fontWeight)) {\r\n textSymbolizer.fontWeight = fontWeight.toLowerCase() as 'normal' | 'bold' | undefined;\r\n }\r\n if (!isNil(fontSize)) {\r\n textSymbolizer.size = numberExpression(fontSize);\r\n }\r\n return textSymbolizer;\r\n }\r\n\r\n /**\r\n * Create a template string from a TextSymbolizer Label element.\r\n * The ordering of the elemments inside the Label element is preserved.\r\n *\r\n * Examples:\r\n * \r\n * --> \"foo{{bar}}\"\r\n *\r\n * \r\n * --> \"{{bar}}foo\"\r\n *\r\n * \r\n * --> \"{{bar}}foo{{john}}\"\r\n *\r\n * \r\n * --> \"{{bar}}{{john}}foo\"\r\n *\r\n * \r\n * --> \"{{bar}}{{john}}foo{{doe}}\"\r\n *\r\n * @param sldLabel\r\n */\r\n getTextSymbolizerLabelFromSldSymbolizer = (sldLabel: any): string => {\r\n const label: string = sldLabel\r\n .map((labelEl: any) => {\r\n const labelName = Object.keys(labelEl)[0];\r\n switch (labelName.replace('ogc:', '')) {\r\n case '#text':\r\n return labelEl['#text'];\r\n case 'Literal':\r\n return labelEl?.[labelName]?.[0]?.['#text'] || labelEl?.[labelName]?.[0]?.['#cdata']?.[0]?.['#text'];\r\n case 'PropertyName':\r\n const propName = labelEl[labelName][0]['#text'];\r\n return `{{${propName}}}`;\r\n default:\r\n return '';\r\n }\r\n })\r\n .join('');\r\n return label;\r\n };\r\n\r\n /**\r\n * Get the geostyler-style FillSymbolizer from a SLD Symbolizer.\r\n *\r\n * PolygonSymbolizer Stroke is just partially supported.\r\n *\r\n * @param sldSymbolizer The SLD Symbolizer\r\n * @return The geostyler-style FillSymbolizer\r\n */\r\n getFillSymbolizerFromSldSymbolizer(sldSymbolizer: any): FillSymbolizer {\r\n const fillSymbolizer: FillSymbolizer = {\r\n kind: 'Fill'\r\n };\r\n const strokeEl = get(sldSymbolizer, 'Stroke');\r\n const fillEl = get(sldSymbolizer, 'Fill');\r\n\r\n const fillOpacity = getParameterValue(fillEl, 'fill-opacity', this.readingSldVersion);\r\n const color = getParameterValue(fillEl, 'fill', this.readingSldVersion);\r\n\r\n const outlineColor = getParameterValue(strokeEl, 'stroke', this.readingSldVersion);\r\n const outlineWidth = getParameterValue(strokeEl, 'stroke-width', this.readingSldVersion);\r\n const outlineOpacity = getParameterValue(strokeEl, 'stroke-opacity', this.readingSldVersion);\r\n const outlineDashArray = getParameterValue(strokeEl, 'stroke-dasharray', this.readingSldVersion);\r\n const outlineCap = getParameterValue(strokeEl, 'stroke-linecap', this.readingSldVersion);\r\n const outlineJoin = getParameterValue(strokeEl, 'stroke-linejoin', this.readingSldVersion);\r\n // const outlineDashOffset = getParameterValue(strokeEl, 'stroke-dashoffset', this.readingSldVersion);\r\n\r\n const graphicFill = get(sldSymbolizer, 'Fill.GraphicFill');\r\n if (!isNil(graphicFill)) {\r\n fillSymbolizer.graphicFill = this.getPointSymbolizerFromSldSymbolizer(\r\n graphicFill\r\n );\r\n }\r\n if (!isNil(color)) {\r\n fillSymbolizer.color = color;\r\n }\r\n if (!isNil(fillOpacity)) {\r\n fillSymbolizer.fillOpacity = numberExpression(fillOpacity);\r\n }\r\n\r\n if (!isNil(outlineColor)) {\r\n fillSymbolizer.outlineColor = outlineColor;\r\n }\r\n if (!isNil(outlineWidth)) {\r\n fillSymbolizer.outlineWidth = numberExpression(outlineWidth);\r\n }\r\n if (!isNil(outlineOpacity)) {\r\n fillSymbolizer.outlineOpacity = numberExpression(outlineOpacity);\r\n }\r\n if (!isNil(outlineDashArray)) {\r\n fillSymbolizer.outlineDasharray = outlineDashArray.split(' ').map(numberExpression);\r\n }\r\n if (!isNil(outlineCap)) {\r\n fillSymbolizer.outlineCap = outlineCap;\r\n }\r\n if (!isNil(outlineJoin)) {\r\n fillSymbolizer.outlineJoin = outlineJoin;\r\n }\r\n // TODO: seems like this is missing in the geostyer-stlye\r\n // if (outlineDashOffset) {\r\n // fillSymbolizer.outlineDashOffset = Number(outlineDashOffset);\r\n // }\r\n return fillSymbolizer;\r\n }\r\n\r\n /**\r\n * Get the geostyler-style RasterSymbolizer from a SLD Symbolizer.\r\n *\r\n * @param sldSymbolizer The SLD Symbolizer\r\n */\r\n getRasterSymbolizerFromSldSymbolizer(sldSymbolizer: any): RasterSymbolizer {\r\n const rasterSymbolizer: RasterSymbolizer = {\r\n kind: 'Raster'\r\n };\r\n // parse Opacity\r\n let opacity = get(sldSymbolizer, 'Opacity.#text');\r\n if (!isNil(opacity)) {\r\n opacity = numberExpression(opacity);\r\n rasterSymbolizer.opacity = opacity;\r\n }\r\n // parse ColorMap\r\n const sldColorMap = get(sldSymbolizer, 'ColorMap');\r\n const sldColorMapType = get(sldSymbolizer, 'ColorMap.@type');\r\n const extended = get(sldSymbolizer, 'ColorMap.@extended');\r\n if (!isNil(sldColorMap)) {\r\n const colormap = this.getColorMapFromSldColorMap(sldColorMap, sldColorMapType, extended);\r\n rasterSymbolizer.colorMap = colormap;\r\n }\r\n // parse ChannelSelection\r\n const sldChannelSelection = get(sldSymbolizer, 'ChannelSelection');\r\n if (!isNil(sldChannelSelection)) {\r\n const channelSelection = this.getChannelSelectionFromSldChannelSelection(sldChannelSelection);\r\n rasterSymbolizer.channelSelection = channelSelection;\r\n }\r\n // parse ContrastEnhancement\r\n const sldContrastEnhancement = get(sldSymbolizer, 'ContrastEnhancement');\r\n if (!isNil(sldContrastEnhancement)) {\r\n const contrastEnhancement = this.getContrastEnhancementFromSldContrastEnhancement(sldContrastEnhancement);\r\n rasterSymbolizer.contrastEnhancement = contrastEnhancement;\r\n }\r\n return rasterSymbolizer;\r\n }\r\n\r\n /**\r\n * Get the geostyler-style MarkSymbolizer from a SLD Symbolizer\r\n *\r\n * @param sldSymbolizer The SLD Symbolizer\r\n * @return The geostyler-style MarkSymbolizer\r\n */\r\n getMarkSymbolizerFromSldSymbolizer(sldSymbolizer: any): MarkSymbolizer {\r\n const wellKnownName: WellKnownName = get(sldSymbolizer, 'Graphic.Mark.WellKnownName.#text');\r\n const strokeEl = get(sldSymbolizer, 'Graphic.Mark.Stroke');\r\n const fillEl = get(sldSymbolizer, 'Graphic.Mark.Fill');\r\n\r\n const opacity = get(sldSymbolizer, 'Graphic.Opacity.#text');\r\n const size = get(sldSymbolizer, 'Graphic.Size.#text');\r\n const rotation = get(sldSymbolizer, 'Graphic.Rotation.#text');\r\n const fillOpacity = getParameterValue(fillEl, 'fill-opacity', this.readingSldVersion);\r\n const color = getParameterValue(fillEl, 'fill', this.readingSldVersion);\r\n const displacement = get(sldSymbolizer, 'Graphic.Displacement');\r\n\r\n const markSymbolizer: MarkSymbolizer = {\r\n kind: 'Mark',\r\n wellKnownName: 'circle'\r\n };\r\n\r\n if (!isNil(opacity)) {\r\n markSymbolizer.opacity = numberExpression(opacity);\r\n }\r\n if (!isNil(fillOpacity)) {\r\n markSymbolizer.fillOpacity = numberExpression(fillOpacity);\r\n }\r\n if (!isNil(color)) {\r\n markSymbolizer.color = color;\r\n }\r\n if (!isNil(rotation)) {\r\n markSymbolizer.rotate = numberExpression(rotation);\r\n }\r\n if (!isNil(size)) {\r\n // edge case where the value has to be divided by 2 which has to be considered in the function\r\n markSymbolizer.radius = isGeoStylerNumberFunction(size) ? size : Number(size) / 2;\r\n }\r\n if (displacement) {\r\n const x = get(displacement, 'DisplacementX.#text');\r\n const y = get(displacement, 'DisplacementY.#text');\r\n markSymbolizer.offset = [\r\n Number.isFinite(x) ? numberExpression(x) : 0,\r\n Number.isFinite(y) ? numberExpression(y) : 0,\r\n ];\r\n }\r\n\r\n switch (wellKnownName) {\r\n case 'arrow':\r\n case 'arrowhead':\r\n case 'asterisk_fill':\r\n case 'circle':\r\n case 'cross':\r\n case 'cross2':\r\n case 'cross_fill':\r\n case 'decagon':\r\n case 'diagonal_half_square':\r\n case 'diamond':\r\n case 'equilateral_triangle':\r\n case 'filled_arrowhead':\r\n case 'half_arc':\r\n case 'half_square':\r\n case 'heart':\r\n case 'hexagon':\r\n case 'horline':\r\n case 'left_half_triangle':\r\n case 'line':\r\n case 'octagon':\r\n case 'parallelogram_left':\r\n case 'parallelogram_right':\r\n case 'pentagon':\r\n case 'quarter_arc':\r\n case 'quarter_circle':\r\n case 'quarter_square':\r\n case 'right_half_triangle':\r\n case 'rounded_square':\r\n case 'semi_circle':\r\n case 'shield':\r\n case 'square':\r\n case 'square_with_corners':\r\n case 'star':\r\n case 'star_diamond':\r\n case 'third_arc':\r\n case 'third_circle':\r\n case 'trapezoid':\r\n case 'triangle':\r\n case 'x':\r\n case 'shape://vertline':\r\n case 'shape://horline':\r\n case 'shape://slash':\r\n case 'shape://backslash':\r\n case 'shape://dot':\r\n case 'shape://plus':\r\n case 'shape://times':\r\n case 'shape://oarrow':\r\n case 'shape://carrow':\r\n markSymbolizer.wellKnownName = wellKnownName;\r\n break;\r\n default:\r\n if (WELLKNOWNNAME_TTF_REGEXP.test(wellKnownName)) {\r\n markSymbolizer.wellKnownName = wellKnownName;\r\n break;\r\n }\r\n throw new Error(\r\n this.translate('marksymbolizerParseFailedUnknownWellknownName', { wellKnownName: wellKnownName })\r\n );\r\n }\r\n\r\n const strokeColor = getParameterValue(strokeEl, 'stroke', this.readingSldVersion);\r\n if (!isNil(strokeColor)) {\r\n markSymbolizer.strokeColor = strokeColor;\r\n }\r\n const strokeWidth = getParameterValue(strokeEl, 'stroke-width', this.readingSldVersion);\r\n if (!isNil(strokeWidth)) {\r\n markSymbolizer.strokeWidth = numberExpression(strokeWidth);\r\n }\r\n const strokeOpacity = getParameterValue(strokeEl, 'stroke-opacity', this.readingSldVersion);\r\n if (!isNil(strokeOpacity)) {\r\n markSymbolizer.strokeOpacity = numberExpression(strokeOpacity);\r\n }\r\n\r\n return markSymbolizer;\r\n }\r\n\r\n /**\r\n * Get the geostyler-style IconSymbolizer from a SLD Symbolizer\r\n *\r\n * @param sldSymbolizer The SLD Symbolizer\r\n * @return The geostyler-style IconSymbolizer\r\n */\r\n getIconSymbolizerFromSldSymbolizer(sldSymbolizer: any): IconSymbolizer {\r\n const image = get(sldSymbolizer, 'Graphic.ExternalGraphic.OnlineResource.@href');\r\n const iconSymbolizer: IconSymbolizer = {\r\n kind: 'Icon',\r\n image\r\n };\r\n const opacity: string = get(sldSymbolizer, 'Graphic.Opacity.#text');\r\n const size: string = get(sldSymbolizer, 'Graphic.Size.#text');\r\n const rotation: string = get(sldSymbolizer, 'Graphic.Rotation.#text');\r\n const displacement = get(sldSymbolizer, 'Graphic.Displacement');\r\n if (!isNil(opacity)) {\r\n iconSymbolizer.opacity = numberExpression(opacity);\r\n }\r\n if (!isNil(size)) {\r\n iconSymbolizer.size = numberExpression(size);\r\n }\r\n if (!isNil(rotation)) {\r\n iconSymbolizer.rotate = numberExpression(rotation);\r\n }\r\n if (displacement) {\r\n const x = get(displacement, 'DisplacementX.#text');\r\n const y = get(displacement, 'DisplacementY.#text');\r\n iconSymbolizer.offset = [\r\n Number.isFinite(x) ? numberExpression(x) : 0,\r\n Number.isFinite(y) ? numberExpression(y) : 0,\r\n ];\r\n }\r\n return iconSymbolizer;\r\n }\r\n\r\n /**\r\n * Get the geostyler-style ColorMap from a SLD ColorMap.\r\n *\r\n * @param sldColorMap The SLD ColorMap\r\n */\r\n getColorMapFromSldColorMap(sldColorMap: any, type: ColorMapType = 'ramp', extended?: string): ColorMap {\r\n const colorMap: ColorMap = {\r\n type\r\n };\r\n\r\n if (extended) {\r\n if (extended === 'true') {\r\n colorMap.extended = true;\r\n } else {\r\n colorMap.extended = false;\r\n }\r\n }\r\n\r\n const colorMapEntries = getChildren(sldColorMap, 'ColorMapEntry');\r\n if (Array.isArray(colorMapEntries)) {\r\n const cmEntries = colorMapEntries.map((cm) => {\r\n const color = getAttribute(cm, 'color');\r\n if (!color) {\r\n throw new Error(this.translate('colorMapEntriesParseFailedColorUndefined'));\r\n }\r\n let quantity = getAttribute(cm, 'quantity');\r\n if (quantity) {\r\n quantity = numberExpression(quantity);\r\n }\r\n const label = getAttribute(cm, 'label');\r\n let opacity = getAttribute(cm, 'opacity');\r\n if (!isNil(opacity)) {\r\n opacity = numberExpression(opacity);\r\n }\r\n return {\r\n color,\r\n quantity,\r\n label,\r\n opacity\r\n } as ColorMapEntry;\r\n });\r\n colorMap.colorMapEntries = cmEntries;\r\n }\r\n\r\n return colorMap;\r\n }\r\n\r\n /**\r\n * Get the geostyler-style ContrastEnhancement from a SLD ContrastEnhancement.\r\n *\r\n * @param sldContrastEnhancement The SLD ContrastEnhancement\r\n */\r\n getContrastEnhancementFromSldContrastEnhancement(sldContrastEnhancement: any): ContrastEnhancement {\r\n const contrastEnhancement: ContrastEnhancement = {};\r\n\r\n // parse enhancementType\r\n const hasHistogram = !!get(sldContrastEnhancement, 'Histogram');\r\n const hasNormalize = !!get(sldContrastEnhancement, 'Normalize');\r\n if (hasHistogram && hasNormalize) {\r\n throw new Error(this.translate('contrastEnhancParseFailedHistoAndNormalizeMutuallyExclusive'));\r\n } else if (hasHistogram) {\r\n contrastEnhancement.enhancementType = 'histogram';\r\n } else if (hasNormalize) {\r\n contrastEnhancement.enhancementType = 'normalize';\r\n }\r\n // parse gammavalue\r\n let gammaValue = get(sldContrastEnhancement, 'GammaValue.#text');\r\n if (gammaValue) {\r\n gammaValue = numberExpression(gammaValue);\r\n }\r\n contrastEnhancement.gammaValue = gammaValue;\r\n\r\n return contrastEnhancement;\r\n }\r\n\r\n /**\r\n * Get the geostyler-style Channel from a SLD Channel.\r\n *\r\n * @param sldChannel The SLD Channel\r\n */\r\n getChannelFromSldChannel(sldChannel: any): Channel {\r\n const sourceChannelName = get(sldChannel, 'SourceChannelName.#text')?.toString();\r\n const channel: Channel = {\r\n sourceChannelName\r\n };\r\n const contrastEnhancement = get(sldChannel, 'ContrastEnhancement');\r\n if (contrastEnhancement) {\r\n channel.contrastEnhancement = this.getContrastEnhancementFromSldContrastEnhancement(contrastEnhancement);\r\n }\r\n return channel;\r\n }\r\n\r\n /**\r\n * Get the geostyler-style ChannelSelection from a SLD ChannelSelection.\r\n *\r\n * @param sldChannelSelection The SLD ChannelSelection\r\n */\r\n getChannelSelectionFromSldChannelSelection(sldChannelSelection: any): ChannelSelection {\r\n let channelSelection: ChannelSelection;\r\n const red = get(sldChannelSelection, 'RedChannel');\r\n const blue = get(sldChannelSelection, 'BlueChannel');\r\n const green = get(sldChannelSelection, 'GreenChannel');\r\n const gray = get(sldChannelSelection, 'GrayChannel');\r\n\r\n if (gray && red && blue && green) {\r\n throw new Error(this.translate('channelSelectionParseFailedRGBAndGrayscaleMutuallyExclusive'));\r\n }\r\n if (gray) {\r\n const grayChannel = this.getChannelFromSldChannel(gray);\r\n channelSelection = {\r\n grayChannel\r\n };\r\n } else if (red && green && blue) {\r\n const redChannel = this.getChannelFromSldChannel(red);\r\n const blueChannel = this.getChannelFromSldChannel(blue);\r\n const greenChannel = this.getChannelFromSldChannel(green);\r\n channelSelection = {\r\n redChannel,\r\n blueChannel,\r\n greenChannel\r\n };\r\n } else {\r\n throw new Error(this.translate('channelSelectionParseFailedRGBChannelsUndefined'));\r\n }\r\n return channelSelection;\r\n }\r\n\r\n /**\r\n * The writeStyle implementation of the geostyler-style StyleParser interface.\r\n * It reads a geostyler-style and returns a Promise.\r\n * The Promise itself resolves with a SLD string.\r\n *\r\n * @param geoStylerStyle A geostyler-style.\r\n * @return The Promise resolving with the SLD as a string.\r\n */\r\n writeStyle(geoStylerStyle: Style): Promise> {\r\n return new Promise>(resolve => {\r\n const unsupportedProperties = this.checkForUnsupportedProperties(geoStylerStyle);\r\n try {\r\n const sldObject = this.geoStylerStyleToSldObject(geoStylerStyle);\r\n const sldString = this.builder.build(sldObject);\r\n resolve({\r\n output: sldString,\r\n unsupportedProperties,\r\n warnings: unsupportedProperties && ['Your style contains unsupportedProperties!']\r\n });\r\n } catch (error) {\r\n resolve({\r\n errors: [error]\r\n });\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Get the correct tagName in dependency to the configured sldVersion.\r\n *\r\n * @param tagName\r\n * @returns The tagName as used by the configured sldVersion\r\n */\r\n getTagName(tagName: string): string {\r\n const ogcList = ['Filter'];\r\n if (ogcList.includes(tagName)) {\r\n return tagName;\r\n }\r\n if (tagName === 'CssParameter') {\r\n return this.sldVersion === '1.1.0' ? 'se:SvgParameter' : 'CssParameter';\r\n }\r\n return this.sldVersion === '1.1.0' ? `se:${tagName}` : tagName;\r\n }\r\n\r\n /**\r\n * Get the SLD Object (readable with fast-xml-parser) from a geostyler-style\r\n *\r\n * @param geoStylerStyle A geostyler-style.\r\n * @return The object representation of a SLD Style (readable with fast-xml-parser)\r\n */\r\n geoStylerStyleToSldObject(geoStylerStyle: Style): any {\r\n const rules: any[] = this.getSldRulesFromRules(geoStylerStyle.rules);\r\n // add the ogc namespace to the filter element, if a filter is present\r\n rules.forEach(rule => {\r\n const ruleEl = get(rule, this.getTagName('Rule'));\r\n const filter = getChildren(ruleEl, 'Filter').at(0);\r\n if (filter) {\r\n filter[':@'] = {\r\n '@_xmlns': 'http://www.opengis.net/ogc'\r\n };\r\n }\r\n });\r\n\r\n const featureTypeStyle = [\r\n ...rules\r\n ];\r\n const Name = this.getTagName('Name');\r\n const Title = this.getTagName('Title');\r\n const FeatureTypeStyle = this.getTagName('FeatureTypeStyle');\r\n\r\n const attributes = {\r\n '@_version': this.sldVersion,\r\n '@_xsi:schemaLocation': 'http://www.opengis.net/sld StyledLayerDescriptor.xsd',\r\n '@_xmlns': 'http://www.opengis.net/sld',\r\n '@_xmlns:ogc': 'http://www.opengis.net/ogc',\r\n '@_xmlns:xlink': 'http://www.w3.org/1999/xlink',\r\n '@_xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance',\r\n '@_xmlns:se': 'http://www.opengis.net/se'\r\n };\r\n\r\n const userStyle = [];\r\n userStyle.push({\r\n [Name]: [{ '#text': geoStylerStyle.name || '' }]\r\n });\r\n if (this.sldVersion === '1.0.0') {\r\n userStyle.push({\r\n [Title]: [{ '#text': geoStylerStyle.name || '' }]\r\n });\r\n }\r\n userStyle.push({\r\n [FeatureTypeStyle]: featureTypeStyle\r\n });\r\n\r\n return [{\r\n '?xml': [{ '#text': '' }],\r\n ':@': {\r\n '@_version': '1.0',\r\n '@_encoding': 'UTF-8',\r\n '@_standalone': 'yes'\r\n },\r\n }, {\r\n StyledLayerDescriptor: [{\r\n NamedLayer: [{\r\n [Name]: [{ '#text': geoStylerStyle.name || '' }]\r\n }, {\r\n UserStyle: userStyle\r\n }]\r\n }],\r\n ':@': attributes\r\n }];\r\n }\r\n\r\n /**\r\n * Get the SLD Object (readable with fast-xml-parser) from a geostyler-style Rule.\r\n *\r\n * @param rules An array of geostyler-style Rules.\r\n * @return The object representation of a SLD Rule (readable with fast-xml-parser)\r\n */\r\n getSldRulesFromRules(rules: Rule[]): any[] {\r\n const Name = this.getTagName('Name');\r\n const filterTag = this.getTagName('Filter');\r\n const ruleTag = this.getTagName('Rule');\r\n const MinScaleDenominator = this.getTagName('MinScaleDenominator');\r\n const MaxScaleDenominator = this.getTagName('MaxScaleDenominator');\r\n\r\n return rules.map((rule: Rule) => {\r\n const sldRule: any = {\r\n [ruleTag]: []\r\n };\r\n if (rule.name) {\r\n sldRule[ruleTag].push({\r\n [Name]: [{\r\n '#text': rule.name\r\n }]\r\n });\r\n }\r\n if (rule.filter) {\r\n const filter = this.getSldFilterFromFilter(rule.filter);\r\n sldRule[ruleTag].push({\r\n [filterTag]: filter\r\n });\r\n }\r\n if (rule.scaleDenominator) {\r\n const { min, max } = rule.scaleDenominator;\r\n if (min && Number.isFinite(min)) {\r\n sldRule[ruleTag].push({\r\n [MinScaleDenominator]: [{\r\n '#text': min\r\n }]\r\n });\r\n }\r\n if (max && Number.isFinite(max)) {\r\n sldRule[ruleTag].push({\r\n [MaxScaleDenominator]: [{\r\n '#text': max\r\n }]\r\n });\r\n }\r\n }\r\n\r\n // Remove empty Symbolizers and check if there is at least 1 symbolizer\r\n const symbolizers = this.getSldSymbolizersFromSymbolizers(rule.symbolizers);\r\n let symbolizerKeys: string[] = [];\r\n if (symbolizers.length > 0) {\r\n symbolizerKeys = Object.keys(symbolizers[0]);\r\n }\r\n symbolizerKeys.forEach((key: string) => {\r\n if (symbolizers[0][key].length === 0) {\r\n delete symbolizers[0][key];\r\n }\r\n });\r\n\r\n if (symbolizers.length > 0 && symbolizerKeys.length !== 0) {\r\n sldRule[ruleTag] = [\r\n ...sldRule[ruleTag],\r\n ...symbolizers\r\n ];\r\n }\r\n return sldRule;\r\n });\r\n }\r\n\r\n /**\r\n * Get the SLD Object (readable with fast-xml-parser) from a geostyler-style ComparisonFilter.\r\n *\r\n * @param comparisonFilter A geostyler-style ComparisonFilter.\r\n * @return The object representation of a SLD Filter Expression with a\r\n * comparison operator (readable with fast-xml-parser)\r\n */\r\n getSldComparisonFilterFromComparisonFilter(comparisonFilter: ComparisonFilter): any[] {\r\n const sldComparisonFilter: any = [];\r\n const operator = comparisonFilter[0];\r\n const key = comparisonFilter[1];\r\n const value = comparisonFilter[2];\r\n\r\n const sldOperators: string[] = keysByValue(COMPARISON_MAP, operator);\r\n const sldOperator: string = (sldOperators.length > 1 && value === null)\r\n ? sldOperators[1] : sldOperators[0];\r\n\r\n const propertyKey = 'PropertyName';\r\n\r\n if (isGeoStylerFunction(key) || isGeoStylerFunction(value)) {\r\n const tempOperator = sldOperator.replace('PropertyIs', '');\r\n const sldFunctionOperator = tempOperator.charAt(0).toLowerCase() + tempOperator.slice(1);\r\n const keyResult = isGeoStylerFunction(key) ? geoStylerFunctionToSldFunction(key) : key;\r\n const valueResult = isGeoStylerFunction(value) ? geoStylerFunctionToSldFunction(value) : value;\r\n\r\n const functionChildren: any = [];\r\n\r\n if (isGeoStylerFunction(key)) {\r\n functionChildren.unshift(keyResult?.[0]);\r\n } else {\r\n functionChildren.unshift({\r\n Literal: [{\r\n '#text': keyResult\r\n }]\r\n });\r\n }\r\n\r\n if (isGeoStylerFunction(value)) {\r\n functionChildren.push(valueResult?.[0]);\r\n } else {\r\n functionChildren.push({\r\n Literal: [{\r\n '#text': valueResult\r\n }]\r\n });\r\n }\r\n\r\n return [{\r\n Function: functionChildren,\r\n ':@': {\r\n '@_name': sldFunctionOperator\r\n }\r\n }];\r\n }\r\n\r\n if (sldOperator === 'PropertyIsNull') {\r\n // empty, selfclosing Literals are not valid in a propertyIsNull filter\r\n sldComparisonFilter.push({\r\n [sldOperator]: [{\r\n [propertyKey]: [{\r\n '#text': key\r\n }]\r\n }]\r\n });\r\n } else if (sldOperator === 'PropertyIsLike') {\r\n sldComparisonFilter.push({\r\n [sldOperator]: [{\r\n [propertyKey]: [{\r\n '#text': key\r\n }]\r\n }, {\r\n Literal: [{\r\n '#text': value\r\n }]\r\n }],\r\n [':@']: {\r\n '@_wildCard': '*',\r\n '@_singleChar': '.',\r\n '@_escape': '!',\r\n }\r\n });\r\n } else if (sldOperator === 'PropertyIsBetween') {\r\n // Currently we only support Literals as values.\r\n const betweenFilter = comparisonFilter as RangeFilter;\r\n sldComparisonFilter.push({\r\n [sldOperator]: [{\r\n [propertyKey]: [{\r\n '#text': key\r\n }]\r\n }, {\r\n LowerBoundary: [{\r\n Literal: [{\r\n '#text': betweenFilter[2]\r\n }]\r\n }]\r\n }, {\r\n UpperBoundary: [{\r\n Literal: [{\r\n '#text': betweenFilter[3]\r\n }]\r\n }]\r\n }]\r\n });\r\n } else {\r\n sldComparisonFilter.push({\r\n [sldOperator]: [{\r\n [propertyKey]: [{\r\n '#text': key\r\n }]\r\n }, {\r\n Literal: [{\r\n '#text': value\r\n }]\r\n }]\r\n });\r\n }\r\n\r\n\r\n return sldComparisonFilter;\r\n }\r\n\r\n /**\r\n * Get the SLD Object (readable with fast-xml-parser) from a geostyler-style Filter.\r\n *\r\n * @param filter A geostyler-style Filter.\r\n * @return The object representation of a SLD Filter Expression (readable with fast-xml-parser)\r\n */\r\n getSldFilterFromFilter(filter: Filter): any[] {\r\n let sldFilter: any[] = [];\r\n\r\n if (isComparisonFilter(filter)) {\r\n sldFilter = this.getSldComparisonFilterFromComparisonFilter(filter);\r\n } else if (isNegationFilter(filter)) {\r\n sldFilter.push({\r\n Not: this.getSldFilterFromFilter(filter[1])\r\n });\r\n } else if (isCombinationFilter(filter)) {\r\n const [\r\n operator,\r\n ...args\r\n ] = filter;\r\n const sldOperators: string[] = keysByValue(COMBINATION_MAP, operator);\r\n const combinator = sldOperators[0];\r\n const sldSubFilters = args.map(subFilter => this.getSldFilterFromFilter(subFilter)[0]);\r\n sldFilter.push({\r\n [combinator]: sldSubFilters\r\n });\r\n }\r\n return sldFilter;\r\n }\r\n\r\n /**\r\n * Get the SLD Object (readable with fast-xml-parser) from geostyler-style Symbolizers.\r\n *\r\n * @param symbolizers A geostyler-style Symbolizer array.\r\n * @return The object representation of a SLD Symbolizer (readable with fast-xml-parser)\r\n */\r\n getSldSymbolizersFromSymbolizers(symbolizers: Symbolizer[]): any {\r\n const sldSymbolizers: any = [];\r\n const pointSymbolizerTag = this.getTagName('PointSymbolizer');\r\n const textSymbolizerTag = this.getTagName('TextSymbolizer');\r\n const lineSymbolizerTag = this.getTagName('LineSymbolizer');\r\n const polygonSymbolizerTag = this.getTagName('PolygonSymbolizer');\r\n const rasterSymbolizerTag = this.getTagName('RasterSymbolizer');\r\n\r\n symbolizers.forEach(symb => {\r\n const sldSymbolizer: any = {};\r\n let sldSymb: any[];\r\n switch (symb.kind) {\r\n case 'Mark':\r\n sldSymb = this.getSldPointSymbolizerFromMarkSymbolizer(symb);\r\n sldSymbolizer[pointSymbolizerTag] = sldSymb;\r\n break;\r\n case 'Icon':\r\n sldSymb = this.getSldPointSymbolizerFromIconSymbolizer(symb);\r\n sldSymbolizer[pointSymbolizerTag] = sldSymb;\r\n break;\r\n case 'Text':\r\n sldSymb = this.getSldTextSymbolizerFromTextSymbolizer(symb);\r\n sldSymbolizer[textSymbolizerTag] = sldSymb;\r\n break;\r\n case 'Line':\r\n sldSymb = this.getSldLineSymbolizerFromLineSymbolizer(symb);\r\n sldSymbolizer[lineSymbolizerTag] = sldSymb;\r\n break;\r\n case 'Fill':\r\n sldSymb = this.getSldPolygonSymbolizerFromFillSymbolizer(symb);\r\n sldSymbolizer[polygonSymbolizerTag] = sldSymb;\r\n break;\r\n case 'Raster':\r\n sldSymb = this.getSldRasterSymbolizerFromRasterSymbolizer(symb);\r\n sldSymbolizer[rasterSymbolizerTag] = sldSymb;\r\n break;\r\n default:\r\n break;\r\n }\r\n sldSymbolizers.push(sldSymbolizer);\r\n });\r\n return sldSymbolizers;\r\n }\r\n\r\n /**\r\n * Get the SLD Object (readable with fast-xml-parser) from a geostyler-style MarkSymbolizer.\r\n *\r\n * @param markSymbolizer A geostyler-style MarkSymbolizer.\r\n * @return The object representation of a SLD PointSymbolizer with a Mark\r\n */\r\n getSldPointSymbolizerFromMarkSymbolizer(markSymbolizer: MarkSymbolizer): any {\r\n const wellKnownName = this.getTagName('WellKnownName');\r\n const CssParameter = this.getTagName('CssParameter');\r\n const Fill = this.getTagName('Fill');\r\n const Mark = this.getTagName('Mark');\r\n const Stroke = this.getTagName('Stroke');\r\n const Opacity = this.getTagName('Opacity');\r\n const Rotation = this.getTagName('Rotation');\r\n const Size = this.getTagName('Size');\r\n const Graphic = this.getTagName('Graphic');\r\n const Displacement = this.getTagName('Displacement');\r\n const DisplacementX = this.getTagName('DisplacementX');\r\n const DisplacementY = this.getTagName('DisplacementY');\r\n\r\n const isFontSymbol = WELLKNOWNNAME_TTF_REGEXP.test(markSymbolizer.wellKnownName);\r\n const mark: any[] = [{\r\n [wellKnownName]: [{\r\n '#text': isFontSymbol ? markSymbolizer.wellKnownName : markSymbolizer.wellKnownName.toLowerCase()\r\n }]\r\n }];\r\n\r\n if (markSymbolizer.color || !isNil(markSymbolizer.fillOpacity)) {\r\n const fillCssParamaters = [];\r\n if (markSymbolizer.color) {\r\n if (isGeoStylerFunction(markSymbolizer.color)) {\r\n const children = geoStylerFunctionToSldFunction(markSymbolizer.color);\r\n fillCssParamaters.push({\r\n [CssParameter]: children,\r\n ':@': {\r\n '@_name': 'fill'\r\n }\r\n });\r\n } else {\r\n fillCssParamaters.push({\r\n [CssParameter]: [{\r\n '#text': markSymbolizer.color,\r\n }],\r\n ':@': {\r\n '@_name': 'fill'\r\n }\r\n });\r\n }\r\n }\r\n if (!isNil(markSymbolizer.fillOpacity)) {\r\n if (isGeoStylerFunction(markSymbolizer.fillOpacity)) {\r\n const children = geoStylerFunctionToSldFunction(markSymbolizer.fillOpacity);\r\n fillCssParamaters.push({\r\n [CssParameter]: children,\r\n ':@': {\r\n '@_name': 'fill-opacity'\r\n }\r\n });\r\n } else {\r\n fillCssParamaters.push({\r\n [CssParameter]: [{\r\n '#text': markSymbolizer.fillOpacity,\r\n }],\r\n ':@': {\r\n '@_name': 'fill-opacity'\r\n }\r\n });\r\n }\r\n }\r\n mark.push({\r\n [Fill]: fillCssParamaters\r\n });\r\n }\r\n\r\n if (markSymbolizer.strokeColor ||\r\n Number.isFinite(markSymbolizer.strokeWidth) ||\r\n Number.isFinite(markSymbolizer.strokeOpacity)\r\n ) {\r\n const strokeCssParameters = [];\r\n if (markSymbolizer.strokeColor) {\r\n if (isGeoStylerFunction(markSymbolizer.strokeColor)) {\r\n const children = geoStylerFunctionToSldFunction(markSymbolizer.strokeColor);\r\n strokeCssParameters.push({\r\n [CssParameter]: children,\r\n ':@': {\r\n '@_name': 'stroke'\r\n }\r\n });\r\n } else {\r\n strokeCssParameters.push({\r\n [CssParameter]: [{\r\n '#text': markSymbolizer.strokeColor,\r\n }],\r\n ':@': {\r\n '@_name': 'stroke'\r\n }\r\n });\r\n }\r\n }\r\n if (markSymbolizer.strokeWidth) {\r\n if (isGeoStylerFunction(markSymbolizer.strokeWidth)) {\r\n const children = geoStylerFunctionToSldFunction(markSymbolizer.strokeWidth);\r\n strokeCssParameters.push({\r\n [CssParameter]: children,\r\n ':@': {\r\n '@_name': 'stroke-width'\r\n }\r\n });\r\n } else {\r\n strokeCssParameters.push({\r\n [CssParameter]: [{\r\n '#text': markSymbolizer.strokeWidth,\r\n }],\r\n ':@': {\r\n '@_name': 'stroke-width'\r\n }\r\n });\r\n }\r\n }\r\n if (!isNil(markSymbolizer.strokeOpacity)) {\r\n if (isGeoStylerFunction(markSymbolizer.strokeOpacity)) {\r\n const children = geoStylerFunctionToSldFunction(markSymbolizer.strokeOpacity);\r\n strokeCssParameters.push({\r\n [CssParameter]: children,\r\n ':@': {\r\n '@_name': 'stroke-opacity'\r\n }\r\n });\r\n } else {\r\n strokeCssParameters.push({\r\n [CssParameter]: [{\r\n '#text': markSymbolizer.strokeOpacity,\r\n }],\r\n ':@': {\r\n '@_name': 'stroke-opacity'\r\n }\r\n });\r\n }\r\n }\r\n mark.push({\r\n [Stroke]: strokeCssParameters\r\n });\r\n }\r\n\r\n const graphic: any[] = [{\r\n [Mark]: mark\r\n }];\r\n\r\n if (!isNil(markSymbolizer.opacity)) {\r\n graphic.push({\r\n [Opacity]: [{\r\n '#text': markSymbolizer.opacity!.toString()\r\n }]\r\n });\r\n }\r\n\r\n if (markSymbolizer.radius !== undefined) {\r\n if (isGeoStylerFunction(markSymbolizer.radius)) {\r\n graphic.push({\r\n // TODO: Double check if we have to multiply this by 2\r\n [Size]: geoStylerFunctionToSldFunction(markSymbolizer.radius)\r\n });\r\n } else {\r\n graphic.push({\r\n [Size]: [{\r\n '#text': (markSymbolizer.radius * 2).toString()\r\n }]\r\n });\r\n }\r\n }\r\n\r\n if (markSymbolizer.rotate) {\r\n graphic.push({\r\n [Rotation]: [{\r\n '#text': markSymbolizer.rotate.toString()\r\n }]\r\n });\r\n }\r\n\r\n if (markSymbolizer.offset && this.sldVersion === '1.1.0') {\r\n graphic.push({\r\n [Displacement]: [{\r\n [DisplacementX]: [{\r\n '#text': markSymbolizer.offset[0].toString()\r\n }]\r\n }, {\r\n [DisplacementY]: [{\r\n '#text': markSymbolizer.offset[1].toString()\r\n }]\r\n }]\r\n });\r\n }\r\n\r\n return [{\r\n [Graphic]: graphic\r\n }];\r\n }\r\n\r\n /**\r\n * Get the SLD Object (readable with fast-xml-parser) from a geostyler-style IconSymbolizer.\r\n *\r\n * @param iconSymbolizer A geostyler-style IconSymbolizer.\r\n * @return The object representation of a SLD PointSymbolizer with\r\n * an \"ExternalGraphic\" (readable with fast-xml-parser)\r\n */\r\n getSldPointSymbolizerFromIconSymbolizer(iconSymbolizer: IconSymbolizer): any {\r\n const ExternalGraphic = this.getTagName('ExternalGraphic');\r\n const Format = this.getTagName('Format');\r\n const OnlineResource = this.getTagName('OnlineResource');\r\n const Opacity = this.getTagName('Opacity');\r\n const Rotation = this.getTagName('Rotation');\r\n const Size = this.getTagName('Size');\r\n const Graphic = this.getTagName('Graphic');\r\n const Displacement = this.getTagName('Displacement');\r\n const DisplacementX = this.getTagName('DisplacementX');\r\n const DisplacementY = this.getTagName('DisplacementY');\r\n\r\n const graphic: any[] = [{\r\n [ExternalGraphic]: [{\r\n [OnlineResource]: [],\r\n ':@': {\r\n '@_xlink:type': 'simple',\r\n '@_xmlns:xlink': 'http://www.w3.org/1999/xlink',\r\n '@_xlink:href': iconSymbolizer.image\r\n }\r\n }, {[Format]: []}]\r\n }];\r\n\r\n if (typeof iconSymbolizer.image === 'string' || iconSymbolizer.image instanceof String) {\r\n const iconExt = iconSymbolizer.image.split('.').pop();\r\n switch (iconExt) {\r\n case 'png':\r\n case 'jpeg':\r\n case 'gif':\r\n graphic[0][ExternalGraphic][1][Format] = [{\r\n '#text': `image/${iconExt}`\r\n }];\r\n break;\r\n case 'jpg':\r\n graphic[0][ExternalGraphic][1][Format] = [{\r\n '#text': 'image/jpeg'\r\n }];\r\n break;\r\n case 'svg':\r\n graphic[0][ExternalGraphic][1][Format] = [{\r\n '#text': 'image/svg+xml'\r\n }];\r\n break;\r\n default:\r\n break;\r\n }\r\n }\r\n\r\n if (!isNil(iconSymbolizer.opacity)) {\r\n graphic.push({\r\n [Opacity]: [{\r\n '#text': iconSymbolizer.opacity\r\n }]\r\n });\r\n }\r\n if (iconSymbolizer.size) {\r\n graphic.push({\r\n [Size]: [{\r\n '#text': iconSymbolizer.size\r\n }]\r\n });\r\n }\r\n if (iconSymbolizer.rotate) {\r\n graphic.push({\r\n [Rotation]: [{\r\n '#text': iconSymbolizer.rotate\r\n }]\r\n });\r\n }\r\n if (iconSymbolizer.offset && this.sldVersion === '1.1.0') {\r\n graphic.push({\r\n [Displacement]: [{\r\n [DisplacementX]: [{\r\n '#text': iconSymbolizer.offset[0].toString()\r\n }]\r\n }, {\r\n [DisplacementY]: [{\r\n '#text': iconSymbolizer.offset[1].toString()\r\n }]\r\n }]\r\n });\r\n }\r\n return [{\r\n [Graphic]: graphic\r\n }];\r\n }\r\n\r\n /**\r\n * Get the SLD Object (readable with fast-xml-parser) from a geostyler-style TextSymbolizer.\r\n *\r\n * @param textSymbolizer A geostyler-style TextSymbolizer.\r\n * @return The object representation of a SLD TextSymbolizer (readable with fast-xml-parser)\r\n */\r\n getSldTextSymbolizerFromTextSymbolizer(textSymbolizer: TextSymbolizer): any {\r\n const CssParameter = this.getTagName('CssParameter');\r\n const Fill = this.getTagName('Fill');\r\n const Halo = this.getTagName('Halo');\r\n const Font = this.getTagName('Font');\r\n const Displacement = this.getTagName('Displacement');\r\n const DisplacementX = this.getTagName('DisplacementX');\r\n const DisplacementY = this.getTagName('DisplacementY');\r\n const LabelPlacement = this.getTagName('LabelPlacement');\r\n const PointPlacement = this.getTagName('PointPlacement');\r\n const LinePlacement = this.getTagName('LinePlacement');\r\n const Rotation = this.getTagName('Rotation');\r\n const Radius = this.getTagName('Radius');\r\n const Label = this.getTagName('Label');\r\n\r\n const sldTextSymbolizer: any = [{\r\n [Label]: textSymbolizer.label ? this.getSldLabelFromTextSymbolizer(textSymbolizer.label) : undefined\r\n }];\r\n\r\n const fontPropertyMap = {\r\n font: 'font-family',\r\n size: 'font-size',\r\n fontStyle: 'font-style',\r\n fontWeight: 'font-weight'\r\n };\r\n\r\n const fontCssParameters: any[] = Object.keys(textSymbolizer)\r\n .filter((property: any) => property !== 'kind' && fontPropertyMap[property as keyof typeof fontPropertyMap])\r\n .map((property: any) => {\r\n if (isGeoStylerFunction(textSymbolizer[property as keyof typeof fontPropertyMap])) {\r\n const children = geoStylerFunctionToSldFunction(textSymbolizer[\r\n property as keyof typeof textSymbolizer] as GeoStylerFunction);\r\n return {\r\n [CssParameter]: children,\r\n ':@': {\r\n '@_name': fontPropertyMap[property as keyof typeof fontPropertyMap]\r\n }\r\n };\r\n } else {\r\n return {\r\n [CssParameter]: [{\r\n '#text': property === 'font'\r\n ? (textSymbolizer[property as keyof typeof textSymbolizer] as any[])?.[0]\r\n : textSymbolizer[property as keyof typeof textSymbolizer],\r\n }],\r\n ':@': {\r\n '@_name': fontPropertyMap[property as keyof typeof fontPropertyMap]\r\n }\r\n };\r\n }\r\n });\r\n\r\n if (fontCssParameters.length > 0) {\r\n sldTextSymbolizer.push({\r\n [Font]: fontCssParameters\r\n });\r\n }\r\n\r\n if (textSymbolizer.placement === 'line') {\r\n sldTextSymbolizer.push({\r\n [LabelPlacement]: [{\r\n [LinePlacement]: []\r\n }]\r\n });\r\n } else if (Number.isFinite(textSymbolizer.offset)\r\n || textSymbolizer.rotate !== undefined\r\n || textSymbolizer.placement === 'point'\r\n ) {\r\n const pointPlacement: any = [];\r\n if (textSymbolizer.offset) {\r\n pointPlacement.push({\r\n [Displacement]: [{\r\n [DisplacementX]: [{\r\n '#text': textSymbolizer.offset[0].toString()\r\n }]\r\n }, {\r\n [DisplacementY]: [{\r\n '#text': (-textSymbolizer.offset[1]).toString()\r\n }]\r\n }]\r\n });\r\n }\r\n if (textSymbolizer.rotate !== undefined) {\r\n pointPlacement.push({\r\n [Rotation]: [{\r\n '#text': textSymbolizer.rotate.toString()\r\n }]\r\n });\r\n }\r\n sldTextSymbolizer.push({\r\n [LabelPlacement]: [{\r\n [PointPlacement]: pointPlacement\r\n }]\r\n });\r\n }\r\n\r\n if (Number.isFinite(textSymbolizer.haloWidth) || textSymbolizer.haloColor) {\r\n const halo: any = [];\r\n const haloFillCssParameter = [];\r\n if (textSymbolizer.haloWidth) {\r\n halo.push({\r\n [Radius]: [{\r\n '#text': textSymbolizer.haloWidth.toString()\r\n }]\r\n });\r\n }\r\n if (textSymbolizer.haloColor) {\r\n haloFillCssParameter.push({\r\n [CssParameter]: [{\r\n '#text': textSymbolizer.haloColor,\r\n }],\r\n ':@': {\r\n '@_name': 'fill'\r\n }\r\n });\r\n }\r\n if (textSymbolizer.haloOpacity) {\r\n haloFillCssParameter.push({\r\n [CssParameter]: [{\r\n '#text': textSymbolizer.haloOpacity,\r\n }],\r\n ':@': {\r\n '@_name': 'fill-opacity'\r\n }\r\n });\r\n }\r\n if (haloFillCssParameter.length > 0) {\r\n halo.push({\r\n [Fill]: haloFillCssParameter\r\n });\r\n }\r\n sldTextSymbolizer.push({\r\n [Halo]: halo\r\n });\r\n }\r\n if (textSymbolizer.color || Number.isFinite(textSymbolizer.opacity)) {\r\n const fill = [{\r\n [CssParameter]: [{\r\n '#text': textSymbolizer.color || '#000000',\r\n }],\r\n ':@': {\r\n '@_name': 'fill'\r\n }\r\n }];\r\n if (Number.isFinite(textSymbolizer.opacity)) {\r\n fill.push({\r\n [CssParameter]: [{\r\n '#text': `${textSymbolizer.opacity}`,\r\n }],\r\n ':@': {\r\n '@_name': 'fill-opacity'\r\n },\r\n });\r\n }\r\n sldTextSymbolizer.push({\r\n [Fill]: fill\r\n });\r\n }\r\n\r\n return sldTextSymbolizer;\r\n }\r\n\r\n /**\r\n * Get the Label from a TextSymbolizer\r\n *\r\n * @param template The Expression representing the label\r\n */\r\n getSldLabelFromTextSymbolizer = (template: Expression): any => {\r\n // TODO: parse GeoStylerFunction\r\n if (!(typeof template === 'string' || template instanceof String)) {\r\n return undefined;\r\n }\r\n\r\n const openingBraces = '{{';\r\n const closingBraces = '}}';\r\n\r\n const tokens = [];\r\n let templateReducer = template;\r\n\r\n while (templateReducer.length) {\r\n let tmpTemplateReducer = templateReducer;\r\n let tmpPreTemplateLiteral;\r\n const openingBracesIdx = tmpTemplateReducer.indexOf(openingBraces);\r\n if (openingBracesIdx === -1) {\r\n if (templateReducer.includes(' ')) {\r\n tokens.push({\r\n 'ogc:Literal': [{\r\n '#cdata': [{\r\n '#text': templateReducer\r\n }]\r\n }]\r\n });\r\n } else {\r\n tokens.push({\r\n 'ogc:Literal': [{\r\n '#text': templateReducer\r\n }]\r\n });\r\n }\r\n break;\r\n }\r\n\r\n if (openingBracesIdx > 0) {\r\n tmpPreTemplateLiteral = tmpTemplateReducer.slice(0, openingBracesIdx);\r\n }\r\n tmpTemplateReducer = tmpTemplateReducer.slice(openingBracesIdx + openingBraces.length);\r\n\r\n const closingBracesIdx = tmpTemplateReducer.indexOf(closingBraces);\r\n if (closingBracesIdx === -1) {\r\n if (templateReducer.includes(' ')) {\r\n tokens.push({\r\n 'ogc:Literal': [{\r\n '#cdata': [{\r\n '#text': templateReducer\r\n }]\r\n }]\r\n });\r\n } else {\r\n tokens.push({\r\n 'ogc:Literal': [{\r\n '#text': templateReducer\r\n }]\r\n });\r\n }\r\n break;\r\n }\r\n const propertyName = tmpTemplateReducer.slice(0, closingBracesIdx);\r\n tmpTemplateReducer = tmpTemplateReducer.slice(closingBracesIdx + closingBraces.length);\r\n if (tmpPreTemplateLiteral) {\r\n if (tmpPreTemplateLiteral.includes(' ')) {\r\n tokens.push({\r\n 'ogc:Literal': [{\r\n '#cdata': [{\r\n '#text': tmpPreTemplateLiteral\r\n }]\r\n }]\r\n });\r\n } else {\r\n tokens.push({\r\n 'ogc:Literal': [{\r\n '#text': tmpPreTemplateLiteral\r\n }]\r\n });\r\n }\r\n }\r\n tokens.push({\r\n 'ogc:PropertyName': [{\r\n '#text': propertyName\r\n }]\r\n });\r\n templateReducer = tmpTemplateReducer;\r\n }\r\n\r\n return tokens;\r\n };\r\n\r\n /**\r\n * Get the SLD Object (readable with fast-xml-parser) from a geostyler-style LineSymbolizer.\r\n *\r\n * @param lineSymbolizer A geostyler-style LineSymbolizer.\r\n * @return The object representation of a SLD LineSymbolizer (readable with fast-xml-parser)\r\n */\r\n getSldLineSymbolizerFromLineSymbolizer(lineSymbolizer: LineSymbolizer): any[] {\r\n const CssParameter = this.getTagName('CssParameter');\r\n const Stroke = this.getTagName('Stroke');\r\n const GraphicStroke = this.getTagName('GraphicStroke');\r\n const GraphicFill = this.getTagName('GraphicFill');\r\n const PerpendicularOffset = this.getTagName('PerpendicularOffset');\r\n\r\n const propertyMap = {\r\n color: 'stroke',\r\n width: 'stroke-width',\r\n opacity: 'stroke-opacity',\r\n join: 'stroke-linejoin',\r\n cap: 'stroke-linecap',\r\n dasharray: 'stroke-dasharray',\r\n dashOffset: 'stroke-dashoffset'\r\n };\r\n\r\n const sldLineSymbolizer: any = [];\r\n\r\n const cssParameters: any[] = Object.keys(lineSymbolizer)\r\n .filter((property: any) => property !== 'kind' && propertyMap[property as keyof typeof propertyMap] &&\r\n lineSymbolizer[property as keyof typeof lineSymbolizer] !== undefined &&\r\n lineSymbolizer[property as keyof typeof lineSymbolizer] !== null)\r\n .map((property: any) => {\r\n let value = lineSymbolizer[property as keyof typeof lineSymbolizer];\r\n if (property === 'dasharray') {\r\n value = lineSymbolizer.dasharray ? lineSymbolizer.dasharray.join(' ') : undefined;\r\n\r\n return {\r\n [CssParameter]: [{\r\n '#text': value,\r\n }],\r\n ':@': {\r\n '@_name': propertyMap[property as keyof typeof propertyMap]\r\n }\r\n };\r\n }\r\n // simple transformation since geostyler-style uses prop 'miter' whereas sld uses 'mitre'\r\n if (property === 'join' && value === 'miter') {\r\n value = 'mitre';\r\n }\r\n\r\n if (isGeoStylerFunction(lineSymbolizer[property as keyof typeof lineSymbolizer])) {\r\n const children = geoStylerFunctionToSldFunction(lineSymbolizer[\r\n property as keyof typeof lineSymbolizer] as GeoStylerFunction);\r\n return {\r\n [CssParameter]: children,\r\n ':@': {\r\n '@_name': propertyMap[property as keyof typeof propertyMap]\r\n }\r\n };\r\n } else {\r\n return {\r\n [CssParameter]: [{\r\n '#text': lineSymbolizer[property as keyof typeof lineSymbolizer],\r\n }],\r\n ':@': {\r\n '@_name': propertyMap[property as keyof typeof propertyMap]\r\n }\r\n };\r\n }\r\n\r\n });\r\n\r\n if (lineSymbolizer?.graphicStroke) {\r\n if (!Array.isArray(sldLineSymbolizer?.[0]?.[Stroke])) {\r\n sldLineSymbolizer[0] = { [Stroke]: [] };\r\n }\r\n if (lineSymbolizer?.graphicStroke?.kind === 'Mark') {\r\n const graphicStroke = this.getSldPointSymbolizerFromMarkSymbolizer(lineSymbolizer.graphicStroke);\r\n sldLineSymbolizer[0][Stroke].push({\r\n [GraphicStroke]: graphicStroke\r\n });\r\n } else if (lineSymbolizer?.graphicStroke?.kind === 'Icon') {\r\n const graphicStroke = this.getSldPointSymbolizerFromIconSymbolizer(lineSymbolizer.graphicStroke);\r\n sldLineSymbolizer[0][Stroke].push({\r\n [GraphicStroke]: graphicStroke\r\n });\r\n }\r\n }\r\n\r\n if (lineSymbolizer?.graphicFill) {\r\n if (!Array.isArray(sldLineSymbolizer?.[0]?.[Stroke])) {\r\n sldLineSymbolizer[0] = { [Stroke]: [] };\r\n }\r\n if (lineSymbolizer?.graphicFill?.kind === 'Mark') {\r\n const graphicFill = this.getSldPointSymbolizerFromMarkSymbolizer(lineSymbolizer.graphicFill);\r\n sldLineSymbolizer[0][Stroke].push({\r\n [GraphicFill]: graphicFill\r\n });\r\n } else if (lineSymbolizer?.graphicFill?.kind === 'Icon') {\r\n const graphicFill = this.getSldPointSymbolizerFromIconSymbolizer(lineSymbolizer.graphicFill);\r\n sldLineSymbolizer[0][Stroke].push({\r\n [GraphicFill]: graphicFill\r\n });\r\n }\r\n }\r\n\r\n if (cssParameters.length !== 0) {\r\n if (!Array.isArray(sldLineSymbolizer?.[0]?.[Stroke])) {\r\n sldLineSymbolizer[0] = { [Stroke]: [] };\r\n }\r\n sldLineSymbolizer[0][Stroke].push(...cssParameters);\r\n }\r\n if (lineSymbolizer.perpendicularOffset) {\r\n sldLineSymbolizer.push({\r\n [PerpendicularOffset]: [\r\n {\r\n '#text': lineSymbolizer.perpendicularOffset\r\n }\r\n ]\r\n });\r\n }\r\n\r\n if (sldLineSymbolizer.length === 0) {\r\n sldLineSymbolizer.push({\r\n [Stroke]: {}\r\n });\r\n }\r\n\r\n return sldLineSymbolizer;\r\n }\r\n\r\n /**\r\n * Get the SLD Object (readable with fast-xml-parser) from a geostyler-style FillSymbolizer.\r\n *\r\n * @param fillSymbolizer A geostyler-style FillSymbolizer.\r\n * @return The object representation of a SLD PolygonSymbolizer (readable with fast-xml-parser)\r\n */\r\n getSldPolygonSymbolizerFromFillSymbolizer(fillSymbolizer: FillSymbolizer): any {\r\n const CssParameter = this.getTagName('CssParameter');\r\n const Stroke = this.getTagName('Stroke');\r\n const Fill = this.getTagName('Fill');\r\n const strokePropertyMap = {\r\n outlineColor: 'stroke',\r\n outlineWidth: 'stroke-width',\r\n outlineOpacity: 'stroke-opacity',\r\n outlineDasharray: 'stroke-dasharray',\r\n outlineCap: 'stroke-linecap',\r\n outlineJoin: 'stroke-linejoin'\r\n };\r\n const fillPropertyMap = {\r\n color: 'fill',\r\n fillOpacity: 'fill-opacity'\r\n };\r\n const strokeCssParameters: any[] = [];\r\n const fillCssParameters: any[] = [];\r\n let graphicFill: any;\r\n\r\n if (fillSymbolizer?.graphicFill) {\r\n if (fillSymbolizer?.graphicFill.kind === 'Mark') {\r\n graphicFill = this.getSldPointSymbolizerFromMarkSymbolizer(fillSymbolizer.graphicFill);\r\n } else if (fillSymbolizer?.graphicFill.kind === 'Icon') {\r\n graphicFill = this.getSldPointSymbolizerFromIconSymbolizer(fillSymbolizer.graphicFill);\r\n }\r\n }\r\n\r\n Object.keys(fillSymbolizer)\r\n .filter((property: any) => property !== 'kind')\r\n .filter((property: any) => fillSymbolizer[property as keyof typeof fillSymbolizer] !== undefined &&\r\n fillSymbolizer[property as keyof typeof fillSymbolizer] !== null)\r\n .forEach((property: any) => {\r\n if (Object.keys(fillPropertyMap).includes(property)) {\r\n if (isGeoStylerFunction(fillSymbolizer[property as keyof typeof fillSymbolizer])) {\r\n const children = geoStylerFunctionToSldFunction(fillSymbolizer[\r\n property as keyof typeof fillSymbolizer] as GeoStylerFunction);\r\n fillCssParameters.push({\r\n [CssParameter]: children,\r\n ':@': {\r\n '@_name': fillPropertyMap[property as keyof typeof fillPropertyMap]\r\n }\r\n });\r\n } else {\r\n fillCssParameters.push({\r\n [CssParameter]: [{\r\n '#text': fillSymbolizer[property as keyof typeof fillSymbolizer],\r\n }],\r\n ':@': {\r\n '@_name': fillPropertyMap[property as keyof typeof fillPropertyMap]\r\n }\r\n });\r\n }\r\n } else if (Object.keys(strokePropertyMap).includes(property)) {\r\n\r\n let transformedValue: string = '';\r\n\r\n if (property === 'outlineDasharray') {\r\n const paramValue: number[] = fillSymbolizer[property as keyof typeof fillSymbolizer] as number[];\r\n transformedValue = '';\r\n paramValue.forEach((dash: number, idx) => {\r\n transformedValue += dash;\r\n if (idx < paramValue.length - 1) {\r\n transformedValue += ' ';\r\n }\r\n });\r\n } else if (property === 'outlineWidth') {\r\n transformedValue = fillSymbolizer[property as keyof typeof fillSymbolizer] + '';\r\n } else if (property === 'outlineOpacity') {\r\n transformedValue = fillSymbolizer[property as keyof typeof fillSymbolizer] + '';\r\n } else {\r\n (transformedValue as any) = fillSymbolizer[property as keyof typeof fillSymbolizer];\r\n }\r\n\r\n if (isGeoStylerFunction(fillSymbolizer[property as keyof typeof fillSymbolizer])) {\r\n const children = geoStylerFunctionToSldFunction((fillSymbolizer as any)[property]);\r\n strokeCssParameters.push({\r\n [CssParameter]: children,\r\n ':@': {\r\n '@_name': strokePropertyMap[property as keyof typeof strokePropertyMap]\r\n }\r\n });\r\n } else {\r\n strokeCssParameters.push({\r\n [CssParameter]: [{\r\n '#text': transformedValue,\r\n }],\r\n ':@': {\r\n '@_name': strokePropertyMap[property as keyof typeof strokePropertyMap]\r\n }\r\n });\r\n }\r\n\r\n }\r\n });\r\n\r\n const polygonSymbolizer: any = [];\r\n if (fillCssParameters.length > 0 || graphicFill) {\r\n if (!Array.isArray(polygonSymbolizer?.[0]?.[Fill])) {\r\n polygonSymbolizer[0] = { [Fill]: [] };\r\n }\r\n if (fillCssParameters.length > 0) {\r\n polygonSymbolizer[0][Fill].push(...fillCssParameters);\r\n }\r\n if (graphicFill) {\r\n polygonSymbolizer[0][Fill].push({\r\n GraphicFill: graphicFill\r\n });\r\n }\r\n }\r\n\r\n if (strokeCssParameters.length > 0) {\r\n polygonSymbolizer.push({\r\n [Stroke]: strokeCssParameters\r\n });\r\n }\r\n\r\n return polygonSymbolizer;\r\n }\r\n\r\n /**\r\n * Get the SLD Object (readable with fast-xml-parser) from a geostyler-style RasterSymbolizer.\r\n *\r\n * @param rasterSymbolizer A geostyler-style RasterSymbolizer.\r\n * @return The object representation of a SLD RasterSymbolizer (readable with fast-xml-parser)\r\n */\r\n getSldRasterSymbolizerFromRasterSymbolizer(rasterSymbolizer: RasterSymbolizer): any {\r\n const sldRasterSymbolizer: any = [];\r\n if (rasterSymbolizer.opacity !== undefined) {\r\n sldRasterSymbolizer.push({});\r\n sldRasterSymbolizer[0].Opacity = [{\r\n '#text': rasterSymbolizer.opacity\r\n }];\r\n }\r\n\r\n let colorMap: any;\r\n if (rasterSymbolizer.colorMap) {\r\n colorMap = this.getSldColorMapFromColorMap(rasterSymbolizer.colorMap);\r\n if (colorMap?.[0]) {\r\n sldRasterSymbolizer.push({\r\n ColorMap: colorMap\r\n });\r\n }\r\n }\r\n\r\n let channelSelection: any;\r\n if (rasterSymbolizer.channelSelection) {\r\n channelSelection = this.getSldChannelSelectionFromChannelSelection(rasterSymbolizer.channelSelection);\r\n if (channelSelection?.[0]) {\r\n sldRasterSymbolizer.push({\r\n ChannelSelection: channelSelection\r\n });\r\n }\r\n }\r\n\r\n let contrastEnhancement: any;\r\n if (rasterSymbolizer.contrastEnhancement) {\r\n contrastEnhancement = this.getSldContrastEnhancementFromContrastEnhancement(rasterSymbolizer.contrastEnhancement);\r\n if (contrastEnhancement?.[0]) {\r\n sldRasterSymbolizer.push({\r\n ContrastEnhancement: contrastEnhancement\r\n });\r\n }\r\n }\r\n\r\n return sldRasterSymbolizer;\r\n }\r\n\r\n /**\r\n * Get the SLD Object (readable with fast-xml-parser) from a geostyler-style ColorMap.\r\n *\r\n * @param colorMap A geostyler-style ColorMap.\r\n * @return The object representation of a SLD ColorMap (readable with fast-xml-parser)\r\n */\r\n getSldColorMapFromColorMap(colorMap: ColorMap): any {\r\n const sldColorMap: any[] = [];\r\n // parse colorMap.type\r\n if (colorMap.type) {\r\n const type = colorMap.type;\r\n (sldColorMap as any)[':@'] = {\r\n '@_type': type\r\n };\r\n }\r\n // parse colorMap.extended\r\n if (colorMap.extended !== undefined) {\r\n const extended = colorMap.extended.toString();\r\n if (!(sldColorMap as any)[':@']) {\r\n (sldColorMap as any)[':@'] = {};\r\n }\r\n (sldColorMap as any)[':@']['@_extended'] = extended;\r\n }\r\n // parse colorMap.colorMapEntries\r\n if (colorMap.colorMapEntries && colorMap.colorMapEntries.length > 0) {\r\n const colorMapEntries: any[] = colorMap.colorMapEntries.map((entry: ColorMapEntry) => {\r\n const result: any = {\r\n ColorMapEntry: [],\r\n ':@': {}\r\n };\r\n if (entry.color) {\r\n result[':@']['@_color'] = entry.color;\r\n }\r\n if (typeof entry.quantity !== 'undefined') {\r\n result[':@']['@_quantity'] = entry.quantity.toString();\r\n }\r\n if (entry.label) {\r\n result[':@']['@_label'] = entry.label;\r\n }\r\n if (typeof entry.opacity !== 'undefined') {\r\n result[':@']['@_opacity'] = entry.opacity.toString();\r\n }\r\n return result;\r\n // remove empty colorMapEntries\r\n }).filter((entry: any) => Object.keys(entry).length > 0);\r\n sldColorMap.push(...colorMapEntries);\r\n }\r\n return sldColorMap;\r\n }\r\n\r\n /**\r\n * Get the SLD Object (readable with fast-xml-parser) from a geostyler-style ChannelSelection.\r\n *\r\n * @param channelSelection A geostyler-style ChannelSelection.\r\n * @return The object representation of a SLD ChannelSelection (readable with fast-xml-parser)\r\n */\r\n getSldChannelSelectionFromChannelSelection(channelSelection: ChannelSelection): any {\r\n const propertyMap = {\r\n redChannel: 'RedChannel',\r\n blueChannel: 'BlueChannel',\r\n greenChannel: 'GreenChannel',\r\n grayChannel: 'GrayChannel'\r\n };\r\n const keys = Object.keys(channelSelection);\r\n const sldChannelSelection: any[] = [];\r\n keys.forEach((key: string) => {\r\n const channel: any = [];\r\n // parse sourceChannelName\r\n const sourceChannelName = (channelSelection?.[key as keyof ChannelSelection] as any)?.sourceChannelName;\r\n const channelName = propertyMap[key as keyof typeof propertyMap];\r\n // parse contrastEnhancement\r\n const contrastEnhancement = (channelSelection?.[key as keyof ChannelSelection] as any)?.contrastEnhancement;\r\n if (sourceChannelName || contrastEnhancement) {\r\n if (sourceChannelName) {\r\n channel.push({\r\n SourceChannelName: [{\r\n '#text': sourceChannelName\r\n }]\r\n });\r\n }\r\n if (contrastEnhancement) {\r\n channel.push({\r\n ContrastEnhancement: this.getSldContrastEnhancementFromContrastEnhancement(contrastEnhancement)\r\n });\r\n }\r\n sldChannelSelection.push({\r\n [channelName]: channel\r\n });\r\n }\r\n });\r\n\r\n return sldChannelSelection;\r\n }\r\n\r\n /**\r\n * Get the SLD Object (readable with fast-xml-parser) from a geostyler-style ContrastEnhancement.\r\n *\r\n * @param contrastEnhancement A geostyler-style ContrastEnhancement.\r\n * @return The object representation of a SLD ContrastEnhancement (readable with fast-xml-parser)\r\n */\r\n getSldContrastEnhancementFromContrastEnhancement(contrastEnhancement: ContrastEnhancement): any {\r\n const sldContrastEnhancement: any = [];\r\n const enhancementType = contrastEnhancement?.enhancementType;\r\n if (enhancementType === 'normalize') {\r\n // parse normalize\r\n sldContrastEnhancement.push({\r\n Normalize: []\r\n });\r\n } else if (enhancementType === 'histogram') {\r\n // parse histogram\r\n sldContrastEnhancement.push({\r\n Histogram: []\r\n });\r\n }\r\n // parse gammaValue\r\n if (contrastEnhancement.gammaValue !== undefined) {\r\n sldContrastEnhancement.push({\r\n GammaValue: [{\r\n '#text': contrastEnhancement.gammaValue\r\n }]\r\n });\r\n }\r\n return sldContrastEnhancement;\r\n }\r\n\r\n checkForUnsupportedProperties(geoStylerStyle: Style): UnsupportedProperties | undefined {\r\n const capitalizeFirstLetter = (a: string) => a[0].toUpperCase() + a.slice(1);\r\n const unsupportedProperties: UnsupportedProperties = {};\r\n geoStylerStyle.rules.forEach(rule => {\r\n // ScaleDenominator and Filters are completely supported so we just check for symbolizers\r\n rule.symbolizers.forEach(symbolizer => {\r\n const key = capitalizeFirstLetter(`${symbolizer.kind}Symbolizer`);\r\n const value = (this.unsupportedProperties?.Symbolizer as any)?.[key];\r\n if (value) {\r\n if (typeof value === 'string' || value instanceof String) {\r\n if (!unsupportedProperties.Symbolizer) {\r\n unsupportedProperties.Symbolizer = {};\r\n }\r\n (unsupportedProperties.Symbolizer as any)[key] = value;\r\n } else {\r\n Object.keys(symbolizer).forEach(property => {\r\n if (value[property]) {\r\n if (!unsupportedProperties.Symbolizer) {\r\n unsupportedProperties.Symbolizer = {};\r\n }\r\n if (!unsupportedProperties.Symbolizer[key as keyof typeof unsupportedProperties.Symbolizer]) {\r\n (unsupportedProperties.Symbolizer as any)[key] = {};\r\n }\r\n (unsupportedProperties.Symbolizer as any)[key][property] = value[property];\r\n }\r\n });\r\n }\r\n }\r\n });\r\n });\r\n if (Object.keys(unsupportedProperties).length > 0) {\r\n return unsupportedProperties;\r\n }\r\n return undefined;\r\n }\r\n\r\n}\r\n\r\nexport default SldStyleParser;\r\n"]} \ No newline at end of file diff --git a/dist/Util/SldUtil.d.ts b/dist/Util/SldUtil.d.ts new file mode 100644 index 00000000..05abe8e1 --- /dev/null +++ b/dist/Util/SldUtil.d.ts @@ -0,0 +1,91 @@ +import { Expression, PropertyType } from 'geostyler-style/dist/style'; +import { SldVersion } from '../SldStyleParser'; +import { GeoStylerFunction, GeoStylerNumberFunction } from 'geostyler-style/dist/functions'; +/** + * Cast to Number if it is not a GeoStylerFunction + * + * @param exp The GeoStylerExpression + * @returns The value casted to a number or the GeoStylerNumberFunction + */ +export declare function numberExpression(exp: Expression): GeoStylerNumberFunction | number; +/** + * This converts a GeoStylerFunction into a fast-xml-parser representation + * of a sld function. + * + * @param geostylerFunction A GeoStylerFunction + * @returns + */ +export declare function geoStylerFunctionToSldFunction(geostylerFunction: GeoStylerFunction): any; +/** + * This converts the fast-xml-parser representation of a sld function into + * a GeoStylerFunction. + * + * @param sldFunction An array of objects as created by the fast-xml-parser + * @returns The GeoStylerFunction + */ +export declare function sldFunctionToGeoStylerFunction(sldFunction: any[]): GeoStylerFunction; +/** + * Get all child objects with a given tag name. + * + * @param elements An array of objects as created by the fast-xml-parser. + * @param tagName The tagname to get. + * @returns An array of objects as created by the fast-xml-parser. + */ +export declare function getChildren(elements: any[], tagName: string): any[]; +/** + * Get the child object with a given tag name. + * + * @param elements An array of objects as created by the fast-xml-parser. + * @param tagName The tagname to get. + * @returns An object as created by the fast-xml-parser. + */ +export declare function getChild(elements: any[], tagName: string): any; +/** + * Get the value of a Css-/SvgParameter. + * + * @param elements An array of objects as created by the fast-xml-parser. + * @param parameter The parameter name to get. + * @param sldVersion The sldVersion to distinguish if CssParameter or SvgParameter is used. + * @returns The string value of the searched parameter. + */ +export declare function getParameterValue(elements: any[], parameter: string, sldVersion: SldVersion): any; +/** + * Get the attribute value of an object. + * + * @param obj The object to check. + * @param name The name of the attribute + * @returns The value of the requested parameter (if available) + */ +export declare function getAttribute(obj: any, name: string): any | undefined; +/** + * Determine if a fast-xml-parser object is a symbolizer representation. + * + * @param obj The object to check. + * @returns Whether the passed object is a symbolizer representation or not. + */ +export declare function isSymbolizer(obj: any): boolean; +/** + * Generic get function which tries to get the nested value of the given object or array. + * It contains some SLD specific handling and tries to be smart but keep the syntax easy. + * It always takes the first child of an array if no index was specified in the path argument. + * e.g. + * Get text value: get(sldSymbolizer, 'Graphic.Mark.WellKnownName.#text') + * Get an attribute value: get(sldSymbolizer, 'Graphic.ExternalGraphic.OnlineResource.@xlink:href') + * Get an Css-/SvgParameter value: get(sldSymbolizer, 'Graphic.Mark.Fill.$fill-opacity', '1.1.0') + * Use with an index: get(sldObject, 'StyledLayerDescriptor.NamedLayer[1].UserStyle.Title.#text') + * + * @param obj A part of the parser result of the fast-xml-parser. + * @param path The path to get the value from. + * @param sldVersion The SLD version to use. + * @returns + */ +export declare function get(obj: any, path: string, sldVersion?: SldVersion): any | undefined; +/** + * Returns the keys of an object where the value is equal to the passed in + * value. + * + * @param object The object to get the key from. + * @param value The value to get the matching key from. + * @return The matching keys. + */ +export declare function keysByValue(object: any, value: any): string[]; diff --git a/dist/Util/SldUtil.js b/dist/Util/SldUtil.js new file mode 100644 index 00000000..371066b2 --- /dev/null +++ b/dist/Util/SldUtil.js @@ -0,0 +1,223 @@ +import { isGeoStylerFunction, isGeoStylerNumberFunction } from 'geostyler-style/dist/typeguards'; +/** + * Cast to Number if it is not a GeoStylerFunction + * + * @param exp The GeoStylerExpression + * @returns The value casted to a number or the GeoStylerNumberFunction + */ +export function numberExpression(exp) { + return isGeoStylerNumberFunction(exp) ? exp : Number(exp); +} +/** + * This converts a GeoStylerFunction into a fast-xml-parser representation + * of a sld function. + * + * @param geostylerFunction A GeoStylerFunction + * @returns + */ +export function geoStylerFunctionToSldFunction(geostylerFunction) { + const { name } = geostylerFunction; + // TODO: Typing of functions without args should be refactored in geostyler-style + if (name === 'pi' || name === 'random') { + return [{ + Function: [], + ':@': { + '@_name': name + } + }]; + } + if (name === 'property') { + return { + PropertyName: [{ + '#text': geostylerFunction.args[0] + }] + }; + } + const sldFunctionArgs = geostylerFunction.args.map(arg => { + if (isGeoStylerFunction(arg)) { + const argAsFunction = geoStylerFunctionToSldFunction(arg); + return Array.isArray(argAsFunction) ? argAsFunction[0] : argAsFunction; + } + else { + return { + Literal: [{ + '#text': arg + }] + }; + } + }); + const sldFunctionObj = [{ + Function: sldFunctionArgs, + ':@': { + '@_name': name + } + }]; + return sldFunctionObj; +} +/** + * This converts the fast-xml-parser representation of a sld function into + * a GeoStylerFunction. + * + * @param sldFunction An array of objects as created by the fast-xml-parser + * @returns The GeoStylerFunction + */ +export function sldFunctionToGeoStylerFunction(sldFunction) { + const name = sldFunction?.[0]?.[':@']?.['@_name']; + const args = sldFunction?.[0].Function.map((sldArg) => { + if (sldArg.Function) { + return sldFunctionToGeoStylerFunction([sldArg]); + } + else if (sldArg.PropertyName) { + return { + name: 'property', + args: [sldArg?.PropertyName?.[0]?.['#text']] + }; + } + else { + return sldArg?.Literal?.[0]?.['#text']; + } + }); + const geoStylerFunction = { name }; + if (args.length > 0) { + geoStylerFunction.args = args; + } + return geoStylerFunction; +} +/** + * Get all child objects with a given tag name. + * + * @param elements An array of objects as created by the fast-xml-parser. + * @param tagName The tagname to get. + * @returns An array of objects as created by the fast-xml-parser. + */ +export function getChildren(elements, tagName) { + return elements?.filter(obj => Object.keys(obj).includes(tagName)); +} +/** + * Get the child object with a given tag name. + * + * @param elements An array of objects as created by the fast-xml-parser. + * @param tagName The tagname to get. + * @returns An object as created by the fast-xml-parser. + */ +export function getChild(elements, tagName) { + return elements?.find(obj => Object.keys(obj).includes(tagName)); +} +/** + * Get the value of a Css-/SvgParameter. + * + * @param elements An array of objects as created by the fast-xml-parser. + * @param parameter The parameter name to get. + * @param sldVersion The sldVersion to distinguish if CssParameter or SvgParameter is used. + * @returns The string value of the searched parameter. + */ +export function getParameterValue(elements, parameter, sldVersion) { + if (!elements) { + return undefined; + } + const paramKey = sldVersion === '1.0.0' ? 'CssParameter' : 'SvgParameter'; + const element = elements + .filter(obj => Object.keys(obj)?.includes(paramKey)) + .find(obj => obj?.[':@']?.['@_name'] === parameter); + // we expected a value but received an array so we check if we have a function + if (element?.[paramKey]?.[0]?.Function) { + return sldFunctionToGeoStylerFunction(element?.[paramKey]); + } + // … or a Literal + if (element?.[paramKey]?.[0]?.Literal) { + return element?.[paramKey]?.[0]?.Literal?.[0]?.['#text']; + } + return element?.[paramKey]?.[0]?.['#text']; +} +/** + * Get the attribute value of an object. + * + * @param obj The object to check. + * @param name The name of the attribute + * @returns The value of the requested parameter (if available) + */ +export function getAttribute(obj, name) { + return obj?.[':@']?.[`@_${name}`]; +} +/** + * Determine if a fast-xml-parser object is a symbolizer representation. + * + * @param obj The object to check. + * @returns Whether the passed object is a symbolizer representation or not. + */ +export function isSymbolizer(obj) { + return Object.keys(obj).some(key => key.endsWith('Symbolizer')); +} +/** + * Generic get function which tries to get the nested value of the given object or array. + * It contains some SLD specific handling and tries to be smart but keep the syntax easy. + * It always takes the first child of an array if no index was specified in the path argument. + * e.g. + * Get text value: get(sldSymbolizer, 'Graphic.Mark.WellKnownName.#text') + * Get an attribute value: get(sldSymbolizer, 'Graphic.ExternalGraphic.OnlineResource.@xlink:href') + * Get an Css-/SvgParameter value: get(sldSymbolizer, 'Graphic.Mark.Fill.$fill-opacity', '1.1.0') + * Use with an index: get(sldObject, 'StyledLayerDescriptor.NamedLayer[1].UserStyle.Title.#text') + * + * @param obj A part of the parser result of the fast-xml-parser. + * @param path The path to get the value from. + * @param sldVersion The SLD version to use. + * @returns + */ +export function get(obj, path, sldVersion) { + const parts = path.split(/\.(.*)/s); + let key = parts[0]; + const rest = parts[1]; + let target = obj; + let index = 0; + // handle queries for attributes + if (rest?.startsWith('@')) { + target = getChildren(obj, key)[index]; + return getAttribute(target, rest.substring(1)); + } + if (Array.isArray(obj)) { + // we expected a value + if (key === '#text') { + // … so we check if we have a function + if (target[0]?.Function) { + return sldFunctionToGeoStylerFunction(target); + } + // … or a Literal + if (target[0]?.Literal) { + return target[0]?.Literal?.[0]?.['#text']; + } + } + // we expected a value but received an array so we check if we have a function + if (key === '#text' && target[0]?.Function) { + return sldFunctionToGeoStylerFunction(target); + } + // handle queries for CssParameter/SvgParameter + if (key.startsWith('$') && sldVersion) { + return getParameterValue(target, key.substring(1), sldVersion); + } + // handle queries with specified indexes + if (key.endsWith(']')) { + index = Number(key.split('[')[1].split(']')[0]); + key = key.split('[')[0]; + } + target = getChildren(obj, key)[index]; + } + if (!target) { + return undefined; + } + if (rest) { + return get(target[key], rest, sldVersion); + } + return target[key]; +} +/** + * Returns the keys of an object where the value is equal to the passed in + * value. + * + * @param object The object to get the key from. + * @param value The value to get the matching key from. + * @return The matching keys. + */ +export function keysByValue(object, value) { + return Object.keys(object).filter(key => object[key] === value); +} +//# sourceMappingURL=SldUtil.js.map \ No newline at end of file diff --git a/dist/Util/SldUtil.js.map b/dist/Util/SldUtil.js.map new file mode 100644 index 00000000..aeca256d --- /dev/null +++ b/dist/Util/SldUtil.js.map @@ -0,0 +1 @@ +{"version":3,"file":"SldUtil.js","sourceRoot":"","sources":["../../src/Util/SldUtil.ts"],"names":[],"mappings":"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","sourcesContent":["import { Expression, PropertyType } from 'geostyler-style/dist/style';\r\nimport { SldVersion } from '../SldStyleParser';\r\nimport { GeoStylerFunction, GeoStylerNumberFunction } from 'geostyler-style/dist/functions';\r\nimport { isGeoStylerFunction, isGeoStylerNumberFunction } from 'geostyler-style/dist/typeguards';\r\n\r\n/**\r\n * Cast to Number if it is not a GeoStylerFunction\r\n *\r\n * @param exp The GeoStylerExpression\r\n * @returns The value casted to a number or the GeoStylerNumberFunction\r\n */\r\nexport function numberExpression(exp: Expression): GeoStylerNumberFunction | number {\r\n return isGeoStylerNumberFunction(exp) ? exp : Number(exp);\r\n}\r\n\r\n/**\r\n * This converts a GeoStylerFunction into a fast-xml-parser representation\r\n * of a sld function.\r\n *\r\n * @param geostylerFunction A GeoStylerFunction\r\n * @returns\r\n */\r\nexport function geoStylerFunctionToSldFunction(geostylerFunction: GeoStylerFunction): any {\r\n const {\r\n name\r\n } = geostylerFunction;\r\n\r\n // TODO: Typing of functions without args should be refactored in geostyler-style\r\n if (name === 'pi' || name === 'random') {\r\n return [{\r\n Function: [],\r\n ':@': {\r\n '@_name': name\r\n }\r\n }];\r\n }\r\n\r\n if (name === 'property') {\r\n return {\r\n PropertyName: [{\r\n '#text': geostylerFunction.args[0]\r\n }]\r\n };\r\n }\r\n\r\n const sldFunctionArgs = geostylerFunction.args.map(arg => {\r\n if (isGeoStylerFunction(arg)) {\r\n const argAsFunction = geoStylerFunctionToSldFunction(arg);\r\n return Array.isArray(argAsFunction) ? argAsFunction[0] : argAsFunction;\r\n } else {\r\n return {\r\n Literal: [{\r\n '#text': arg\r\n }]\r\n };\r\n }\r\n });\r\n\r\n const sldFunctionObj = [{\r\n Function: sldFunctionArgs,\r\n ':@': {\r\n '@_name': name\r\n }\r\n }];\r\n\r\n return sldFunctionObj;\r\n}\r\n\r\n/**\r\n * This converts the fast-xml-parser representation of a sld function into\r\n * a GeoStylerFunction.\r\n *\r\n * @param sldFunction An array of objects as created by the fast-xml-parser\r\n * @returns The GeoStylerFunction\r\n */\r\nexport function sldFunctionToGeoStylerFunction(sldFunction: any[]): GeoStylerFunction {\r\n const name = sldFunction?.[0]?.[':@']?.['@_name'];\r\n const args = sldFunction?.[0].Function.map((sldArg: any) => {\r\n if (sldArg.Function) {\r\n return sldFunctionToGeoStylerFunction([sldArg]);\r\n } else if (sldArg.PropertyName) {\r\n return {\r\n name: 'property',\r\n args: [sldArg?.PropertyName?.[0]?.['#text']]\r\n };\r\n } else {\r\n return sldArg?.Literal?.[0]?.['#text'];\r\n }\r\n });\r\n\r\n const geoStylerFunction: any = { name };\r\n if (args.length > 0) {\r\n geoStylerFunction.args = args;\r\n }\r\n return geoStylerFunction;\r\n}\r\n\r\n/**\r\n * Get all child objects with a given tag name.\r\n *\r\n * @param elements An array of objects as created by the fast-xml-parser.\r\n * @param tagName The tagname to get.\r\n * @returns An array of objects as created by the fast-xml-parser.\r\n */\r\nexport function getChildren(elements: any[], tagName: string): any[] {\r\n return elements?.filter(obj => Object.keys(obj).includes(tagName));\r\n}\r\n\r\n/**\r\n * Get the child object with a given tag name.\r\n *\r\n * @param elements An array of objects as created by the fast-xml-parser.\r\n * @param tagName The tagname to get.\r\n * @returns An object as created by the fast-xml-parser.\r\n */\r\nexport function getChild(elements: any[], tagName: string): any {\r\n return elements?.find(obj => Object.keys(obj).includes(tagName));\r\n}\r\n\r\n/**\r\n * Get the value of a Css-/SvgParameter.\r\n *\r\n * @param elements An array of objects as created by the fast-xml-parser.\r\n * @param parameter The parameter name to get.\r\n * @param sldVersion The sldVersion to distinguish if CssParameter or SvgParameter is used.\r\n * @returns The string value of the searched parameter.\r\n */\r\nexport function getParameterValue(elements: any[], parameter: string, sldVersion: SldVersion): any {\r\n if (!elements) {\r\n return undefined;\r\n }\r\n const paramKey = sldVersion === '1.0.0' ? 'CssParameter' : 'SvgParameter';\r\n const element = elements\r\n .filter(obj => Object.keys(obj)?.includes(paramKey))\r\n .find(obj => obj?.[':@']?.['@_name'] === parameter);\r\n\r\n // we expected a value but received an array so we check if we have a function\r\n if (element?.[paramKey]?.[0]?.Function) {\r\n return sldFunctionToGeoStylerFunction(element?.[paramKey]);\r\n }\r\n // … or a Literal\r\n if (element?.[paramKey]?.[0]?.Literal) {\r\n return element?.[paramKey]?.[0]?.Literal?.[0]?.['#text'];\r\n }\r\n\r\n return element?.[paramKey]?.[0]?.['#text'];\r\n}\r\n\r\n/**\r\n * Get the attribute value of an object.\r\n *\r\n * @param obj The object to check.\r\n * @param name The name of the attribute\r\n * @returns The value of the requested parameter (if available)\r\n */\r\nexport function getAttribute(obj: any, name: string): any | undefined {\r\n return obj?.[':@']?.[`@_${name}`];\r\n}\r\n\r\n/**\r\n * Determine if a fast-xml-parser object is a symbolizer representation.\r\n *\r\n * @param obj The object to check.\r\n * @returns Whether the passed object is a symbolizer representation or not.\r\n */\r\nexport function isSymbolizer(obj: any): boolean {\r\n return Object.keys(obj).some(key => key.endsWith('Symbolizer'));\r\n}\r\n\r\n/**\r\n * Generic get function which tries to get the nested value of the given object or array.\r\n * It contains some SLD specific handling and tries to be smart but keep the syntax easy.\r\n * It always takes the first child of an array if no index was specified in the path argument.\r\n * e.g.\r\n * Get text value: get(sldSymbolizer, 'Graphic.Mark.WellKnownName.#text')\r\n * Get an attribute value: get(sldSymbolizer, 'Graphic.ExternalGraphic.OnlineResource.@xlink:href')\r\n * Get an Css-/SvgParameter value: get(sldSymbolizer, 'Graphic.Mark.Fill.$fill-opacity', '1.1.0')\r\n * Use with an index: get(sldObject, 'StyledLayerDescriptor.NamedLayer[1].UserStyle.Title.#text')\r\n *\r\n * @param obj A part of the parser result of the fast-xml-parser.\r\n * @param path The path to get the value from.\r\n * @param sldVersion The SLD version to use.\r\n * @returns\r\n */\r\nexport function get(obj: any, path: string, sldVersion?: SldVersion): any | undefined {\r\n const parts = path.split(/\\.(.*)/s);\r\n let key = parts[0];\r\n const rest = parts[1];\r\n let target = obj;\r\n let index = 0;\r\n // handle queries for attributes\r\n if (rest?.startsWith('@')) {\r\n target = getChildren(obj, key)[index];\r\n return getAttribute(target, rest.substring(1));\r\n }\r\n if (Array.isArray(obj)) {\r\n // we expected a value\r\n if (key === '#text') {\r\n // … so we check if we have a function\r\n if (target[0]?.Function) {\r\n return sldFunctionToGeoStylerFunction(target);\r\n }\r\n // … or a Literal\r\n if (target[0]?.Literal) {\r\n return target[0]?.Literal?.[0]?.['#text'];\r\n }\r\n }\r\n // we expected a value but received an array so we check if we have a function\r\n if (key === '#text' && target[0]?.Function) {\r\n return sldFunctionToGeoStylerFunction(target);\r\n }\r\n // handle queries for CssParameter/SvgParameter\r\n if (key.startsWith('$') && sldVersion) {\r\n return getParameterValue(target, key.substring(1), sldVersion);\r\n }\r\n // handle queries with specified indexes\r\n if(key.endsWith(']')) {\r\n index = Number(key.split('[')[1].split(']')[0]);\r\n key = key.split('[')[0];\r\n }\r\n target = getChildren(obj, key)[index];\r\n }\r\n if (!target) {\r\n return undefined;\r\n }\r\n if (rest) {\r\n return get(target[key], rest, sldVersion);\r\n }\r\n return target[key];\r\n}\r\n\r\n/**\r\n * Returns the keys of an object where the value is equal to the passed in\r\n * value.\r\n *\r\n * @param object The object to get the key from.\r\n * @param value The value to get the matching key from.\r\n * @return The matching keys.\r\n */\r\nexport function keysByValue(object: any, value: any): string[] {\r\n return Object.keys(object).filter(key => object[key] === value);\r\n}\r\n"]} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 56dbd7b1..18cb373b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "license": "BSD-2-Clause", "dependencies": { "fast-xml-parser": "^4.4.1", - "geostyler-style": "^9.1.0", + "geostyler-style": "github:pozi/geostyler-style#v1.0.0", "lodash": "^4.17.21" }, "devDependencies": { @@ -4586,9 +4586,9 @@ } }, "node_modules/geostyler-style": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/geostyler-style/-/geostyler-style-9.1.0.tgz", - "integrity": "sha512-kExQDe2mf4YaVMZPKE7h2uxU5qSyAQoX2U2hLXyAWubJjeNoFe0nxt6rKn7C9Q1DE/9DVZopOdNLCXMtqOE6QA==", + "version": "9.2.0", + "resolved": "git+ssh://git@github.com/pozi/geostyler-style.git#6576664aeb6a0c35ad17dd813615b146afdfea29", + "license": "BSD-2-Clause", "engines": { "node": ">=20.6.0", "npm": ">=10.0.0" diff --git a/package.json b/package.json index 5ad3a7a1..c223e3be 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ }, "dependencies": { "fast-xml-parser": "^4.4.1", - "geostyler-style": "^9.1.0", + "geostyler-style": "github:pozi/geostyler-style#v1.0.0", "lodash": "^4.17.21" }, "devDependencies": {