Skip to content

Commit

Permalink
feat: parse placement of TextSymbolizer
Browse files Browse the repository at this point in the history
  • Loading branch information
Faouzi Homsani committed Oct 27, 2023
1 parent 77d8e8b commit db86af1
Show file tree
Hide file tree
Showing 8 changed files with 192 additions and 6 deletions.
14 changes: 14 additions & 0 deletions data/olStyles/text_placement_line.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import OlStyleText from 'ol/style/Text';
import OlStyle from 'ol/style/Style';
import OlStyleStroke from 'ol/style/Stroke';
const olTextPlacementStyle = new OlStyle({
text: new OlStyleText({
text: 'name',
placement:'line',
stroke: new OlStyleStroke({
width: 5
})
})
});

export default olTextPlacementStyle;
14 changes: 14 additions & 0 deletions data/olStyles/text_placement_point.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import OlStyleText from 'ol/style/Text';
import OlStyle from 'ol/style/Style';
import OlStyleStroke from 'ol/style/Stroke';
const olTextPlacementStyle = new OlStyle({
text: new OlStyleText({
text: 'name',
placement:'point',
stroke: new OlStyleStroke({
width: 5
})
})
});

export default olTextPlacementStyle;
6 changes: 5 additions & 1 deletion data/styles/point_styledLabel_static.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,18 @@ const pointStyledLabel: Style = {
name: 'OL Style Rule 0',
symbolizers: [{
kind: 'Text',
allowOverlap: undefined,
fontStyle: undefined,
fontWeight: undefined,
color: '#000000',
label: 'name',
font: ['Arial'],
size: 12,
offset: [0, 5],
haloColor: '#000000',
haloWidth: 5,
rotate: 45
rotate: 45,
placement: 'point'
}]
}
]
Expand Down
27 changes: 27 additions & 0 deletions data/styles/text_palcement_line_center.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { Style } from 'geostyler-style';

const textStyle: Style = {
name: 'OL Style',
rules: [
{
name: 'OL Style Rule 0',
symbolizers: [{
kind: 'Text',
placement:'line-center',
allowOverlap: undefined,
fontStyle: undefined,
fontWeight: undefined,
color: '#333',
label: 'name',
font: undefined,
size: undefined,
offset: [0,0],
haloColor: undefined,
haloWidth: 5,
rotate: undefined
}]
}
]
};

export default textStyle;
27 changes: 27 additions & 0 deletions data/styles/text_placement_line.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { Style } from 'geostyler-style';

const textStyle: Style = {
name: 'OL Style',
rules: [
{
name: 'OL Style Rule 0',
symbolizers: [{
kind: 'Text',
placement:'line',
allowOverlap: undefined,
fontStyle: undefined,
fontWeight: undefined,
color: '#333',
label: 'name',
font: undefined,
size: undefined,
offset: [0,0],
haloColor: undefined,
haloWidth: 5,
rotate: undefined
}]
}
]
};

export default textStyle;
27 changes: 27 additions & 0 deletions data/styles/text_placement_point.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { Style } from 'geostyler-style';

const textStyle: Style = {
name: 'OL Style',
rules: [
{
name: 'OL Style Rule 0',
symbolizers: [{
kind: 'Text',
placement:'point',
allowOverlap: undefined,
fontStyle: undefined,
fontWeight: undefined,
color: '#333',
label: 'name',
font: undefined,
size: undefined,
offset: [0,0],
haloColor: undefined,
haloWidth: 5,
rotate: undefined
}]
}
]
};

export default textStyle;
56 changes: 56 additions & 0 deletions src/OlStyleParser.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ import point_fontglyph from '../data/styles/point_fontglyph';
import unsupported_properties from '../data/styles/unsupported_properties';
import function_boolean from '../data/styles/function_boolean';
import function_case from '../data/styles/function_case';
import text_placement_point from '../data/styles/text_placement_point';
import text_placement_line from '../data/styles/text_placement_line';
import text_placement_line_center from '../data/styles/text_palcement_line_center';

import ol_function_marksymbolizer from '../data/olStyles/function_markSymbolizer';
import ol_function_nested_fillsymbolizer from '../data/olStyles/function_nested_fillSymbolizer';
Expand All @@ -76,6 +79,8 @@ import ol_multi_simplefillSimpleline from '../data/olStyles/multi_simplefillSimp
import ol_point_styledLabel_static from '../data/olStyles/point_styledLabel_static';
import ol_point_fontglyph from '../data/olStyles/point_fontglyph';
import ol_unsupported_properties from '../data/olStyles/unsupported_properties';
import ol_text_placement_point from '../data/olStyles/text_placement_point';
import ol_text_placement_line from '../data/olStyles/text_placement_line';
import {
olBoolean1 as ol_function_boolean_fillsymbolizer1,
olBoolean2 as ol_function_boolean_fillsymbolizer2
Expand Down Expand Up @@ -249,6 +254,16 @@ describe('OlStyleParser implements StyleParser', () => {
expect(geoStylerStyle).toBeDefined();
expect(geoStylerStyle).toEqual(point_styledLabel_static);
});
it('can read an OpenLayers Text Placement Point', async () => {
const { output: geoStylerStyle } = await styleParser.readStyle(ol_text_placement_point);
expect(geoStylerStyle).toBeDefined();
expect(geoStylerStyle).toEqual(text_placement_point);
});
it('can read an OpenLayers Text Placement line', async () => {
const { output: geoStylerStyle } = await styleParser.readStyle(ol_text_placement_line);
expect(geoStylerStyle).toBeDefined();
expect(geoStylerStyle).toEqual(text_placement_line);
});
// it('can read an OpenLayers style with a filter', () => {
// expect.assertions(2);
// const sld = fs.readFileSync( './data/slds/point_simplepoint_filter.sld', 'utf8');
Expand Down Expand Up @@ -1126,6 +1141,47 @@ describe('OlStyleParser implements StyleParser', () => {
expect(geoStylerStyle).toBeDefined();
expect(geoStylerStyle).toEqual(ol_polygon_simple);
});
it('can write a text placement point', async () => {
let { output: olStyle } = await styleParser.writeStyle(text_placement_point);
olStyle = olStyle as OlParserStyleFct;
expect(olStyle).toBeDefined();

const testFeature = new OlFeature({name: 'GeoStyler'});
const styles = olStyle(testFeature, 1);
expect(styles).toHaveLength(1);

const style: OlStyle = styles[0];
const olPlacement = style.getText().getPlacement();
expect(olPlacement).toEqual('point');
});

it('can write a text placement line', async () => {
let { output: olStyle } = await styleParser.writeStyle(text_placement_line);
olStyle = olStyle as OlParserStyleFct;
expect(olStyle).toBeDefined();

const testFeature = new OlFeature({name: 'GeoStyler'});
const styles = olStyle(testFeature, 1);
expect(styles).toHaveLength(1);

const style: OlStyle = styles[0];
const olPlacement = style.getText().getPlacement();
expect(olPlacement).toEqual('line');
});

it('can write a text placement line-center to line ', async () => {
let { output: olStyle } = await styleParser.writeStyle(text_placement_line_center);
olStyle = olStyle as OlParserStyleFct;
expect(olStyle).toBeDefined();

const testFeature = new OlFeature({name: 'GeoStyler'});
const styles = olStyle(testFeature, 1);
expect(styles).toHaveLength(1);

const style: OlStyle = styles[0];
const olPlacement = style.getText().getPlacement();
expect(olPlacement).toEqual('line');
});

it('can write a Marksymbolizer with GeoStylerFunction', async () => {
let { output: geoStylerStyle } = await styleParser.writeStyle(function_marksymbolizer);
Expand Down
27 changes: 22 additions & 5 deletions src/OlStyleParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,13 @@ export class OlStyleParser implements StyleParser<OlStyleLike> {
graphicStroke: 'none',
perpendicularOffset: 'none'
},
RasterSymbolizer: 'none'
RasterSymbolizer: 'none',
TextSymbolizer: {
placement: {

Check failure on line 118 in src/OlStyleParser.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

Type '{ placement: { support: string; info: string; }; }' is not assignable to type 'SupportDef | { kind?: SupportDef | undefined; allowOverlap?: SupportDef | undefined; anchor?: SupportDef | undefined; label?: SupportDef | undefined; ... 28 more ...; visibility?: SupportDef | undefined; } | undefined'.

Check failure on line 118 in src/OlStyleParser.ts

View workflow job for this annotation

GitHub Actions / build (20.x)

Type '{ placement: { support: string; info: string; }; }' is not assignable to type 'SupportDef | { kind?: SupportDef | undefined; allowOverlap?: SupportDef | undefined; anchor?: SupportDef | undefined; label?: SupportDef | undefined; ... 28 more ...; visibility?: SupportDef | undefined; } | undefined'.
support:'partial',
info: 'point and line supported. line-center will be mapped to line.'
}
}
},
Function: {
double2bool: {
Expand Down Expand Up @@ -403,13 +409,13 @@ export class OlStyleParser implements StyleParser<OlStyleLike> {
const font = olTextStyle.getFont();
const rotation = olTextStyle.getRotation();
const allowOverlap = olTextStyle.getOverflow() ? olTextStyle.getOverflow() : undefined;
const placement = olTextStyle.getPlacement();
const text = olTextStyle.getText();
const label = Array.isArray(text) ? text[0] : text;
let fontSize: number = Infinity;
let fontFamily: string[]|undefined = undefined;
let fontWeight: 'normal' | 'bold' | undefined = undefined;
let fontStyle: 'normal' | 'italic' | 'oblique' | undefined = undefined;

if (font) {
const fontObj = parseFont(font);
if (fontObj['font-weight']) {
Expand All @@ -430,6 +436,7 @@ export class OlStyleParser implements StyleParser<OlStyleLike> {
return {
kind: 'Text',
label,
placement,

Check failure on line 439 in src/OlStyleParser.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

Type '{ kind: "Text"; label: string | undefined; placement: TextPlacement; allowOverlap: boolean | undefined; color: string | undefined; size: number | undefined; font: string[] | undefined; ... 5 more ...; rotate: number | undefined; }' is not assignable to type 'TextSymbolizer'.

Check failure on line 439 in src/OlStyleParser.ts

View workflow job for this annotation

GitHub Actions / build (20.x)

Type '{ kind: "Text"; label: string | undefined; placement: TextPlacement; allowOverlap: boolean | undefined; color: string | undefined; size: number | undefined; font: string[] | undefined; ... 5 more ...; rotate: number | undefined; }' is not assignable to type 'TextSymbolizer'.
allowOverlap,
color: olFillStyle ? OlStyleUtil.getHexColor(olFillStyle.getColor() as string) : undefined,
size: isFinite(fontSize) ? fontSize : undefined,
Expand Down Expand Up @@ -1398,8 +1405,18 @@ export class OlStyleParser implements StyleParser<OlStyleLike> {
(symbolizer as any)[key] = OlStyleUtil.evaluateFunction((symbolizer as any)[key], feat);
}
}

const color = symbolizer.color as string;
let placement = symbolizer.placement;

Check failure on line 1409 in src/OlStyleParser.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

Property 'placement' does not exist on type 'TextSymbolizer'.

Check failure on line 1409 in src/OlStyleParser.ts

View workflow job for this annotation

GitHub Actions / build (20.x)

Property 'placement' does not exist on type 'TextSymbolizer'.
if (!placement) {
// When setting placement it must not be undefined.
// So we set it to the OL default value.
placement = 'point';
}
if (placement === 'line-center') {
// line-center not supported by OL.
// So we use the closest supported value.
placement = 'line';
}
const opacity = symbolizer.opacity as number;
const fColor = color && Number.isFinite(opacity)
? OlStyleUtil.getRgbaColor(color, opacity)
Expand All @@ -1410,7 +1427,6 @@ export class OlStyleParser implements StyleParser<OlStyleLike> {
const sColor = haloColor && Number.isFinite(opacity)
? OlStyleUtil.getRgbaColor(haloColor, opacity)
: haloColor;

const baseProps: OlStyleTextOptions = {
font: OlStyleUtil.getTextFont(symbolizer),
fill: new this.OlStyleFillConstructor({
Expand All @@ -1423,7 +1439,8 @@ export class OlStyleParser implements StyleParser<OlStyleLike> {
overflow: symbolizer.allowOverlap as boolean,
offsetX: (symbolizer.offset ? symbolizer.offset[0] : 0) as number,
offsetY: (symbolizer.offset ? symbolizer.offset[1] : 0) as number,
rotation: typeof(symbolizer.rotate) === 'number' ? symbolizer.rotate * Math.PI / 180 : undefined
rotation: typeof(symbolizer.rotate) === 'number' ? symbolizer.rotate * Math.PI / 180 : undefined,
placement: placement as 'line' | 'point'
// TODO check why props match
// textAlign: symbolizer.pitchAlignment,
// textBaseline: symbolizer.anchor
Expand Down

0 comments on commit db86af1

Please sign in to comment.