Skip to content

Commit

Permalink
feat: Extract SLD version from SLD (#926)
Browse files Browse the repository at this point in the history
  • Loading branch information
pprev94 authored Jun 19, 2024
1 parent c31fc43 commit 56f231b
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 37 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
/build
/browser

# history
/.history

# misc
.DS_Store
.env.local
Expand Down
54 changes: 54 additions & 0 deletions src/SldParser.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
/* eslint camelcase: 0 */

import * as fs from 'fs';
import SldStyleParser from './SldStyleParser';
import { expect, it, describe } from 'vitest';

import point_simplepoint from '../data/styles/point_simplepoint';

describe('SldStyleParser implements StyleParser (reading from one version and writing to another version)', () => {
it('can read and write a SLD PointSymbolizer (from 1.0.0 version to 1.1.0 version)', async () => {
const styleParser = new SldStyleParser({sldVersion: '1.1.0'});

const sld = fs.readFileSync('./data/slds/1.0/point_simplepoint.sld', 'utf8');
const { output: geoStylerStyle } = await styleParser.readStyle(sld);
expect(geoStylerStyle).toBeDefined();
expect(geoStylerStyle).toEqual(point_simplepoint);

// writing
const {
output: sldString,
errors
} = await styleParser.writeStyle(geoStylerStyle!);
expect(sldString).toBeDefined();
expect(errors).toBeUndefined();

// As string comparison between two XML-Strings is awkward and nonsens
// we read it again and compare the json input with the parser output
const { output: readStyle } = await styleParser.readStyle(sldString!);
expect(readStyle).toEqual(point_simplepoint);
});
it('can read and write a SLD PointSymbolizer (from 1.1.0 version to 1.0.0 version)', async () => {
const styleParser = new SldStyleParser({sldVersion: '1.0.0'});

const sld = fs.readFileSync('./data/slds/1.1/point_simplepoint.sld', 'utf8');
const { output: geoStylerStyle } = await styleParser.readStyle(sld);
expect(geoStylerStyle).toBeDefined();
expect(geoStylerStyle).toEqual(point_simplepoint);

// writing
const {
output: sldString,
errors
} = await styleParser.writeStyle(geoStylerStyle!);
expect(sldString).toBeDefined();
expect(errors).toBeUndefined();

// As string comparison between two XML-Strings is awkward and nonsens
// we read it again and compare the json input with the parser output
const { output: readStyle } = await styleParser.readStyle(sldString!);
expect(readStyle).toEqual(point_simplepoint);
});
});

96 changes: 64 additions & 32 deletions src/SldStyleParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,14 @@ import {
numberExpression
} from './Util/SldUtil';

export type SldVersion = '1.0.0' | '1.1.0';
const SLD_VERSIONS = ['1.0.0', '1.1.0'] as const;

export type SldVersion = (typeof SLD_VERSIONS)[number];

export type ConstructorParams = {
numericFilterFields?: string[];
boolFilterFields?: string[];
/* optional for reading style (it will be guessed from sld style) and mandatory for writing */
sldVersion?: SldVersion;
symbolizerUnits?: string;
parserOptions?: X2jOptionsOptional;
Expand Down Expand Up @@ -271,7 +274,7 @@ export class SldStyleParser implements StyleParser<string> {

/**
* String indicating the SLD version to use. 1.1.0 will make use of
* Symbology Encoding. Default ist to use SLD 1.0.0
* Symbology Encoding.
*/
private _sldVersion: SldVersion = '1.0.0';

Expand All @@ -291,6 +294,28 @@ export class SldStyleParser implements StyleParser<string> {
this._sldVersion = sldVersion;
}


/**
* String indicating the SLD version used in reading mode
*/
private _readingSldVersion: SldVersion = '1.0.0';

/**
* Getter for _readingSldVersion
* @return
*/
get readingSldVersion(): SldVersion {
return this._readingSldVersion;
}

/**
* Setter for _readingSldVersion
* @param sldVersion The _readingSldVersion value to set
*/
set readingSldVersion(sldVersion: 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.
Expand Down Expand Up @@ -325,6 +350,13 @@ export class SldStyleParser implements StyleParser<string> {
return new Promise<ReadStyleResult>((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: Style = this.sldObjectToGeoStylerStyle(sldObject);
resolve({
output: geoStylerStyle
Expand Down Expand Up @@ -601,14 +633,14 @@ export class SldStyleParser implements StyleParser<string> {
const lineSymbolizer: GsLineSymbolizer = {
kind: 'Line'
};
const strokeEl = get(sldSymbolizer, 'Stroke');
const color = getParameterValue(strokeEl, 'stroke', this.sldVersion);
const width = getParameterValue(strokeEl, 'stroke-width', this.sldVersion);
const opacity = getParameterValue(strokeEl, 'stroke-opacity', this.sldVersion);
const lineJoin = getParameterValue(strokeEl, 'stroke-linejoin', this.sldVersion);
const lineCap = getParameterValue(strokeEl, 'stroke-linecap', this.sldVersion);
const dashArray = getParameterValue(strokeEl, 'stroke-dasharray', this.sldVersion);
const dashOffset = getParameterValue(strokeEl, 'stroke-dashoffset', this.sldVersion);
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;
Expand Down Expand Up @@ -673,15 +705,15 @@ export class SldStyleParser implements StyleParser<string> {
const haloEl = get(sldSymbolizer, 'Halo');
const haloFillEl = get(haloEl, 'Fill');

const color = getParameterValue(fillEl, 'fill', this.sldVersion);
const opacity = getParameterValue(fillEl, 'fill-opacity', this.sldVersion);
const color = getParameterValue(fillEl, 'fill', this.readingSldVersion);
const opacity = getParameterValue(fillEl, 'fill-opacity', this.readingSldVersion);

const fontFamily = getParameterValue(fontEl, 'font-family', this.sldVersion);
const fontStyle = getParameterValue(fontEl, 'font-style', this.sldVersion);
const fontSize = getParameterValue(fontEl, 'font-size', this.sldVersion);
const fontWeight = getParameterValue(fontEl, 'font-weight', this.sldVersion);
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.sldVersion);
const haloColor = getParameterValue(haloFillEl, 'fill', this.readingSldVersion);

if (!isNil(labelEl)) {
textSymbolizer.label = this.getTextSymbolizerLabelFromSldSymbolizer(labelEl);
Expand All @@ -694,7 +726,7 @@ export class SldStyleParser implements StyleParser<string> {
if (!isNil(haloRadius)) {
textSymbolizer.haloWidth = numberExpression(haloRadius);
}
const haloOpacity = getParameterValue(haloFillEl, 'fill-opacity', this.sldVersion);
const haloOpacity = getParameterValue(haloFillEl, 'fill-opacity', this.readingSldVersion);
if (!isNil(haloOpacity)) {
textSymbolizer.haloOpacity = numberExpression(haloOpacity);
}
Expand Down Expand Up @@ -815,16 +847,16 @@ export class SldStyleParser implements StyleParser<string> {
const strokeEl = get(sldSymbolizer, 'Stroke');
const fillEl = get(sldSymbolizer, 'Fill');

const fillOpacity = getParameterValue(fillEl, 'fill-opacity', this.sldVersion);
const color = getParameterValue(fillEl, 'fill', this.sldVersion);
const fillOpacity = getParameterValue(fillEl, 'fill-opacity', this.readingSldVersion);
const color = getParameterValue(fillEl, 'fill', this.readingSldVersion);

const outlineColor = getParameterValue(strokeEl, 'stroke', this.sldVersion);
const outlineWidth = getParameterValue(strokeEl, 'stroke-width', this.sldVersion);
const outlineOpacity = getParameterValue(strokeEl, 'stroke-opacity', this.sldVersion);
const outlineDashArray = getParameterValue(strokeEl, 'stroke-dasharray', this.sldVersion);
const outlineCap = getParameterValue(strokeEl, 'stroke-linecap', this.sldVersion);
const outlineJoin = getParameterValue(strokeEl, 'stroke-linejoin', this.sldVersion);
// const outlineDashOffset = getParameterValue(strokeEl, 'stroke-dashoffset', this.sldVersion);
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)) {
Expand Down Expand Up @@ -916,8 +948,8 @@ export class SldStyleParser implements StyleParser<string> {
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.sldVersion);
const color = getParameterValue(fillEl, 'fill', this.sldVersion);
const fillOpacity = getParameterValue(fillEl, 'fill-opacity', this.readingSldVersion);
const color = getParameterValue(fillEl, 'fill', this.readingSldVersion);
const displacement = get(sldSymbolizer, 'Graphic.Displacement');

const markSymbolizer: GsMarkSymbolizer = {
Expand Down Expand Up @@ -976,15 +1008,15 @@ export class SldStyleParser implements StyleParser<string> {
throw new Error('MarkSymbolizer cannot be parsed. Unsupported WellKnownName.');
}

const strokeColor = getParameterValue(strokeEl, 'stroke', this.sldVersion);
const strokeColor = getParameterValue(strokeEl, 'stroke', this.readingSldVersion);
if (!isNil(strokeColor)) {
markSymbolizer.strokeColor = strokeColor;
}
const strokeWidth = getParameterValue(strokeEl, 'stroke-width', this.sldVersion);
const strokeWidth = getParameterValue(strokeEl, 'stroke-width', this.readingSldVersion);
if (!isNil(strokeWidth)) {
markSymbolizer.strokeWidth = numberExpression(strokeWidth);
}
const strokeOpacity = getParameterValue(strokeEl, 'stroke-opacity', this.sldVersion);
const strokeOpacity = getParameterValue(strokeEl, 'stroke-opacity', this.readingSldVersion);
if (!isNil(strokeOpacity)) {
markSymbolizer.strokeOpacity = numberExpression(strokeOpacity);
}
Expand Down
10 changes: 9 additions & 1 deletion src/SldStyleParser.v1.0.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ it('SldStyleParser is defined', () => {
expect(SldStyleParser).toBeDefined();
});

describe('SldStyleParser implements StyleParser', () => {
describe('SldStyleParser implements StyleParser (reading)', () => {
let styleParser: SldStyleParser;

beforeEach(() => {
Expand Down Expand Up @@ -361,6 +361,14 @@ describe('SldStyleParser implements StyleParser', () => {
});
});
});
});

describe('SldStyleParser implements StyleParser (writing)', () => {
let styleParser: SldStyleParser;

beforeEach(() => {
styleParser = new SldStyleParser();
});

describe('#writeStyle', () => {
it('is defined', () => {
Expand Down
15 changes: 11 additions & 4 deletions src/SldStyleParser.v1.1.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,11 @@ it('SldStyleParser is defined', () => {
expect(SldStyleParser).toBeDefined();
});

describe('SldStyleParser with Symbology Encoding implements StyleParser', () => {
describe('SldStyleParser with Symbology Encoding implements StyleParser (reading)', () => {
let styleParser: SldStyleParser;

beforeEach(() => {
styleParser = new SldStyleParser({
sldVersion: '1.1.0'
});
styleParser = new SldStyleParser();
});

describe('#readStyle', () => {
Expand Down Expand Up @@ -370,11 +368,20 @@ describe('SldStyleParser with Symbology Encoding implements StyleParser', () =>
});
});
});
});

describe('SldStyleParser with Symbology Encoding implements StyleParser (writing)', () => {
let styleParser: SldStyleParser;

beforeEach(() => {
styleParser = new SldStyleParser({sldVersion: '1.1.0'});
});

describe('#writeStyle', () => {
it('is defined', () => {
expect(styleParser.writeStyle).toBeDefined();
});

it('can write a SLD 1.1 PointSymbolizer', async () => {
const { output: sldString } = await styleParser.writeStyle(point_simplepoint);
expect(sldString).toBeDefined();
Expand Down

0 comments on commit 56f231b

Please sign in to comment.