From 614e63a593d389776223a8d164e1f4d138927919 Mon Sep 17 00:00:00 2001 From: jansule Date: Tue, 13 Feb 2024 15:54:42 +0100 Subject: [PATCH] feat: write line styles --- data/masterportal/line-cap.ts | 22 +++++++++ data/masterportal/line-dash.ts | 12 +++++ data/masterportal/line-join.ts | 22 +++++++++ data/masterportal/line-simpleline.ts | 13 +++++ data/styles/line-cap.ts | 36 ++++++++++++++ data/styles/line-dash.ts | 18 +++++++ data/styles/line-join.ts | 36 ++++++++++++++ data/styles/line-simpleline.ts | 19 ++++++++ src/MasterportalStyleParser.spec.ts | 38 +++++++++++++-- src/MasterportalStyleParser.ts | 72 +++++++++++++++++++++++++++- src/Util/MpUtil.spec.ts | 18 +++++++ src/Util/MpUtil.ts | 9 ++++ 12 files changed, 310 insertions(+), 5 deletions(-) create mode 100644 data/masterportal/line-cap.ts create mode 100644 data/masterportal/line-dash.ts create mode 100644 data/masterportal/line-join.ts create mode 100644 data/masterportal/line-simpleline.ts create mode 100644 data/styles/line-cap.ts create mode 100644 data/styles/line-dash.ts create mode 100644 data/styles/line-join.ts create mode 100644 data/styles/line-simpleline.ts create mode 100644 src/Util/MpUtil.spec.ts create mode 100644 src/Util/MpUtil.ts diff --git a/data/masterportal/line-cap.ts b/data/masterportal/line-cap.ts new file mode 100644 index 0000000..5cdef2a --- /dev/null +++ b/data/masterportal/line-cap.ts @@ -0,0 +1,22 @@ +const lineSimpleline = { + styleId: 'simpleline', + rules: [ + { + style: { + lineStrokeCap: 'butt' + } + }, + { + style: { + lineStrokeCap: 'round' + } + }, + { + style: { + lineStrokeCap: 'square' + } + } + ] +}; + +export default lineSimpleline; diff --git a/data/masterportal/line-dash.ts b/data/masterportal/line-dash.ts new file mode 100644 index 0000000..a297d1b --- /dev/null +++ b/data/masterportal/line-dash.ts @@ -0,0 +1,12 @@ +const lineSimpleline = { + styleId: 'simpleline', + rules: [ + { + style: { + lineStrokeDash: [1, 2] + } + } + ] +}; + +export default lineSimpleline; diff --git a/data/masterportal/line-join.ts b/data/masterportal/line-join.ts new file mode 100644 index 0000000..e2f7e49 --- /dev/null +++ b/data/masterportal/line-join.ts @@ -0,0 +1,22 @@ +const lineSimpleline = { + styleId: 'simpleline', + rules: [ + { + style: { + lineStrokeJoin: 'bevel' + } + }, + { + style: { + lineStrokeJoin: 'round' + } + }, + { + style: { + lineStrokeJoin: 'miter' + } + } + ] +}; + +export default lineSimpleline; diff --git a/data/masterportal/line-simpleline.ts b/data/masterportal/line-simpleline.ts new file mode 100644 index 0000000..2757dd7 --- /dev/null +++ b/data/masterportal/line-simpleline.ts @@ -0,0 +1,13 @@ +const lineSimpleline = { + styleId: 'simpleline', + rules: [ + { + style: { + lineStrokeColor: [197, 219, 110, 1], + lineStrokeWidth: 1 + } + } + ] +}; + +export default lineSimpleline; diff --git a/data/styles/line-cap.ts b/data/styles/line-cap.ts new file mode 100644 index 0000000..4aa7a26 --- /dev/null +++ b/data/styles/line-cap.ts @@ -0,0 +1,36 @@ +import { Style } from 'geostyler-style'; + +const lineSimpleline: Style = { + name: 'simpleline', + rules: [ + { + name: '', + symbolizers: [ + { + kind: 'Line', + cap: 'butt' + } + ] + }, + { + name: '', + symbolizers: [ + { + kind: 'Line', + cap: 'round' + } + ] + }, + { + name: '', + symbolizers: [ + { + kind: 'Line', + cap: 'square' + } + ] + } + ] +}; + +export default lineSimpleline; diff --git a/data/styles/line-dash.ts b/data/styles/line-dash.ts new file mode 100644 index 0000000..73b5751 --- /dev/null +++ b/data/styles/line-dash.ts @@ -0,0 +1,18 @@ +import { Style } from 'geostyler-style'; + +const lineSimpleline: Style = { + name: 'simpleline', + rules: [ + { + name: '', + symbolizers: [ + { + kind: 'Line', + dasharray: [1, 2] + } + ] + } + ] +}; + +export default lineSimpleline; diff --git a/data/styles/line-join.ts b/data/styles/line-join.ts new file mode 100644 index 0000000..a6ab894 --- /dev/null +++ b/data/styles/line-join.ts @@ -0,0 +1,36 @@ +import { Style } from 'geostyler-style'; + +const lineSimpleline: Style = { + name: 'simpleline', + rules: [ + { + name: '', + symbolizers: [ + { + kind: 'Line', + join: 'bevel' + } + ] + }, + { + name: '', + symbolizers: [ + { + kind: 'Line', + join: 'round' + } + ] + }, + { + name: '', + symbolizers: [ + { + kind: 'Line', + join: 'miter' + } + ] + } + ] +}; + +export default lineSimpleline; diff --git a/data/styles/line-simpleline.ts b/data/styles/line-simpleline.ts new file mode 100644 index 0000000..3cff006 --- /dev/null +++ b/data/styles/line-simpleline.ts @@ -0,0 +1,19 @@ +import { Style } from 'geostyler-style'; + +const lineSimpleline: Style = { + name: 'simpleline', + rules: [ + { + name: '', + symbolizers: [ + { + kind: 'Line', + color: '#c5db6e', + width: 1 + } + ] + } + ] +}; + +export default lineSimpleline; diff --git a/src/MasterportalStyleParser.spec.ts b/src/MasterportalStyleParser.spec.ts index 483c5ae..baae56a 100644 --- a/src/MasterportalStyleParser.spec.ts +++ b/src/MasterportalStyleParser.spec.ts @@ -1,7 +1,16 @@ -import MasterportalStyleParser from './MasterportalStyleParser'; +import MpStyleParser from './MasterportalStyleParser'; + +import lineSimpleline from '../data/styles/line-simpleline'; +import mpLineSimpleline from '../data/masterportal/line-simpleline'; +import lineJoin from '../data/styles/line-join'; +import mpLineJoin from '../data/masterportal/line-join'; +import lineCap from '../data/styles/line-cap'; +import mpLineCap from '../data/masterportal/line-cap'; +import lineDash from '../data/styles/line-dash'; +import mpLineDash from '../data/masterportal/line-dash'; it('MasterportalStyleParser is defined', () => { - expect(MasterportalStyleParser).toBeDefined(); + expect(MpStyleParser).toBeDefined(); }); describe('MasterportalStyleParser implements StyleParser', () => { @@ -11,6 +20,29 @@ describe('MasterportalStyleParser implements StyleParser', () => { }); describe('#writeStyle', () => { - + it('is defined', () => { + const mpStyleParser = new MpStyleParser(); + expect(mpStyleParser.writeStyle).toBeDefined(); + }); + it('writes a simple linesymbolizer', async () => { + const mpStyleParser = new MpStyleParser(); + const {output: mpStyle} = await mpStyleParser.writeStyle(lineSimpleline); + expect(mpStyle).toEqual(mpLineSimpleline); + }); + it('writes a linesymbolizer with join', async () => { + const mpStyleParser = new MpStyleParser(); + const {output: mpStyle} = await mpStyleParser.writeStyle(lineJoin); + expect(mpStyle).toEqual(mpLineJoin); + }); + it('writes a linesymbolizer with cap', async () => { + const mpStyleParser = new MpStyleParser(); + const {output: mpStyle} = await mpStyleParser.writeStyle(lineCap); + expect(mpStyle).toEqual(mpLineCap); + }); + it('writes a linesymbolizer with dasharray', async () => { + const mpStyleParser = new MpStyleParser(); + const {output: mpStyle} = await mpStyleParser.writeStyle(lineDash); + expect(mpStyle).toEqual(mpLineDash); + }); }); }); diff --git a/src/MasterportalStyleParser.ts b/src/MasterportalStyleParser.ts index f24ac8e..a63ec09 100644 --- a/src/MasterportalStyleParser.ts +++ b/src/MasterportalStyleParser.ts @@ -1,9 +1,14 @@ import { + LineSymbolizer, ReadStyleResult, + Rule, Style, StyleParser, - WriteStyleResult + Symbolizer, + WriteStyleResult, + isGeoStylerFunction } from 'geostyler-style'; +import { hexToRgba } from './Util/MpUtil'; type MpStyle = {[key: string]: any}; @@ -46,7 +51,10 @@ export class MasterportalStyleParser implements StyleParser { writeStyle(geoStylerStyle: Style): Promise> { return new Promise>(resolve => { try { - resolve({}); + const mpStyle: MpStyle = this.geoStylerStyleToMpStyle(geoStylerStyle); + resolve({ + output: mpStyle + }); } catch (e) { resolve({ errors: [e] @@ -54,6 +62,66 @@ export class MasterportalStyleParser implements StyleParser { } }); } + + geoStylerStyleToMpStyle(geoStylerStyle: Style): MpStyle { + const styleId = geoStylerStyle.name || ''; + const mpStyle: MpStyle = { + styleId, + rules: geoStylerStyle.rules.map(rule => this.geoStylerRuleToMpRule(rule)) + }; + + return mpStyle; + } + + geoStylerRuleToMpRule(rule: Rule): any { + const style = this.geoStylerSymbolizersToMpRuleStyle(rule.symbolizers); + const mpRule = { + style + }; + return mpRule; + } + + geoStylerSymbolizersToMpRuleStyle(symbolizers: Symbolizer[]): any { + const mpRuleStyles = symbolizers.map(symbolizer => this.geoStylerSymbolizerToMpRuleStyle(symbolizer)); + const mpRuleStyle = mpRuleStyles.reduce((prev, cur) => ({...prev, ...cur}), {}); + return mpRuleStyle; + } + + geoStylerSymbolizerToMpRuleStyle(symbolizer: Symbolizer): any { + switch (symbolizer.kind) { + case 'Line': + return this.geoStylerLineSymbolizerToMpLineStyle(symbolizer); + default: + return {}; + } + } + + geoStylerLineSymbolizerToMpLineStyle(symbolizer: LineSymbolizer): any { + const { + cap, + color, + dasharray, + join, + width + } = symbolizer; + const mpLineStyle: any = {}; + if (color !== undefined && !isGeoStylerFunction(color)) { + mpLineStyle.lineStrokeColor = hexToRgba(color, 1); + } + if (width !== undefined && !isGeoStylerFunction(width)) { + mpLineStyle.lineStrokeWidth = width; + } + if (join !== undefined && !isGeoStylerFunction(join)) { + mpLineStyle.lineStrokeJoin = join; + } + if (cap !== undefined && !isGeoStylerFunction(cap)) { + mpLineStyle.lineStrokeCap = cap; + } + if (dasharray !== undefined && !isGeoStylerFunction(dasharray)) { + mpLineStyle.lineStrokeDash = [...dasharray]; + } + return mpLineStyle; + } } export default MasterportalStyleParser; diff --git a/src/Util/MpUtil.spec.ts b/src/Util/MpUtil.spec.ts new file mode 100644 index 0000000..3a1e5cc --- /dev/null +++ b/src/Util/MpUtil.spec.ts @@ -0,0 +1,18 @@ +import { hexToRgba } from './MpUtil'; + +describe('MpUtil', () => { + describe('hexToRgba', () => { + it('converts a hex color to rgba', () => { + const hex = '#ff0000'; + const alpha = 1; + const rgba = hexToRgba(hex, alpha); + expect(rgba).toEqual([255, 0, 0, 1]); + }); + it('returns undefined for invalid hex', () => { + const hex = '#ff00'; + const alpha = 1; + const rgba = hexToRgba(hex, alpha); + expect(rgba).toBeUndefined(); + }); + }); +}); diff --git a/src/Util/MpUtil.ts b/src/Util/MpUtil.ts new file mode 100644 index 0000000..6a03963 --- /dev/null +++ b/src/Util/MpUtil.ts @@ -0,0 +1,9 @@ +export const hexToRgba = (hex: string, alpha: number): number[] | undefined => { + if (hex.length !== 7) { + return; + } + const r = parseInt(hex.slice(1, 3), 16); + const g = parseInt(hex.slice(3, 5), 16); + const b = parseInt(hex.slice(5, 7), 16); + return [r, g, b, alpha]; +};