diff --git a/data/mapfiles/point_symbol_style_in_label.map b/data/mapfiles/point_symbol_style_in_label.map new file mode 100644 index 0000000..6ada171 --- /dev/null +++ b/data/mapfiles/point_symbol_style_in_label.map @@ -0,0 +1,69 @@ +LAYER + NAME point_symbol_style_in_label + MAXSCALEDENOM 35000 + TYPE POINT + EXTENT -20026376.39 -20048966.10 20026376.39 20048966.10 + PROJECTION + "init=epsg:3857" + END + CLASS + MAXSCALEDENOM 35000 + LABEL + SIZE 6.644432194046306 + COLOR "#ffffff" + TEXT '[ref]' + PARTIALS false + FONT "ptsansbold" + TYPE truetype + STYLE + SYMBOL "simple_point_1_symbol_svg" + END + STYLE + SYMBOL "simple_point_2_symbol_svg" + END + END + END + CLASS + MAXSCALEDENOM 25000 + LABEL + SIZE 5.644432194046306 + COLOR "#ffffff" + TEXT '[ref]' + PARTIALS false + FONT "ptsansbold" + TYPE truetype + STYLE + SYMBOL "simple_point_2_symbol_svg" + END + END + END + CLASS + MAXSCALEDENOM 20000 + LABEL + SIZE 4.644432194046306 + COLOR "#ffffff" + TEXT '[ref]' + PARTIALS false + FONT "ptsansbold" + TYPE truetype + STYLE + SYMBOL "simple_point_3_symbol_svg" + END + END + END +END +SYMBOL + NAME simple_point_1_symbol_svg + IMAGE "simple_point_1_symbol.svg" + TYPE svg +END +SYMBOL + NAME simple_point_2_symbol_svg + IMAGE "simple_point_2_symbol.svg" + TYPE svg +END +SYMBOL + NAME simple_point_3_symbol_svg + IMAGE "simple_point_3_symbol.svg" + TYPE svg +END diff --git a/data/styles/point_symbol_style_in_label.ts b/data/styles/point_symbol_style_in_label.ts new file mode 100644 index 0000000..c2e73a6 --- /dev/null +++ b/data/styles/point_symbol_style_in_label.ts @@ -0,0 +1,53 @@ +import { Style } from 'geostyler-style'; + +const pointSymbolStyle: Style = [ + { + name: 'point_symbol_style_in_label', + rules: [ + { + name: '', + scaleDenominator: { max: 35000 }, + symbolizers: [ + { kind: 'Icon', image: 'simple_point_1_symbol.svg' }, + { kind: 'Icon', image: 'simple_point_2_symbol.svg' }, + { + kind: 'Text', + label: '{{ref}}', + font: ['ptsansbold'], + size: 6.644432194046306, + color: '#ffffff' + } + ] + }, + { + name: '', + scaleDenominator: { max: 25000 }, + symbolizers: [ + { kind: 'Icon', image: 'simple_point_2_symbol.svg' }, + { + kind: 'Text', + label: '{{ref}}', + font: ['ptsansbold'], + size: 5.644432194046306, + color: '#ffffff' + } + ] + }, + { + name: '', + scaleDenominator: { max: 20000 }, + symbolizers: [ + { kind: 'Icon', image: 'simple_point_3_symbol.svg' }, + { + kind: 'Text', + label: '{{ref}}', + font: ['ptsansbold'], + size: 4.644432194046306, + color: '#ffffff' + } + ] + } + ] + } +]; +export default pointSymbolStyle; diff --git a/src/MapfileStyleParser.spec.ts b/src/MapfileStyleParser.spec.ts index 526ec02..8d87922 100644 --- a/src/MapfileStyleParser.spec.ts +++ b/src/MapfileStyleParser.spec.ts @@ -25,6 +25,7 @@ import raster_resampling_average from '../data/styles/raster_resampling_average' import raster_resampling_bilinear from '../data/styles/raster_resampling_bilinear'; import raster_resampling_nearest from '../data/styles/raster_resampling_nearest'; import line_set_of_expressions from '../data/styles/line_set_of_expressions'; +import point_symbol_style_in_label from '../data/styles/point_symbol_style_in_label'; it('MapfileStyleParser is defined', () => { @@ -203,6 +204,13 @@ describe('MapfileStyleParser implements StyleParser', () => { expect(geoStylerStyle).toBeDefined(); expect(geoStylerStyle).toEqual(line_set_of_expressions); }); + it('can read a simple MapFile with symbol style in label', async () => { + expect.assertions(2); + const mapfile = fs.readFileSync( './data/mapfiles/point_symbol_style_in_label.map', 'utf8'); + const geoStylerStyle = await styleParser.readMultiStyles(mapfile); + expect(geoStylerStyle).toBeDefined(); + expect(geoStylerStyle).toEqual(point_symbol_style_in_label); + }); it('can translate Mapfile to SLD', async () => { const mapfile = fs.readFileSync('./data/mapfiles/point_simple_point.map', 'utf8'); diff --git a/src/MapfileStyleParser.ts b/src/MapfileStyleParser.ts index 6050b3c..be24515 100644 --- a/src/MapfileStyleParser.ts +++ b/src/MapfileStyleParser.ts @@ -421,7 +421,7 @@ export class MapfileStyleParser implements StyleParser { getIconSymbolizerFromMapfileStyle(mapfileStyle: MapfileStyle): IconSymbolizer { const iconSymbolizer: IconSymbolizer = { kind: 'Icon', - image: mapfileStyle.symbol.image, + image: mapfileStyle.symbol.image } as IconSymbolizer; if (mapfileStyle.size) { @@ -810,6 +810,13 @@ export class MapfileStyleParser implements StyleParser { mapfileLayerLabelItem = mapfileClass.text ? mapfileClass.text : mapfileLayerLabelItem; mapfileClass.labels.forEach((mapfileLabel) => { mapfileLabel.text = mapfileLabel.text ? mapfileLabel.text : mapfileLayerLabelItem; + + // Set Icons in front of the associated label + const labelIcons = this.getIconsFromMapfileLabel(mapfileLabel); + labelIcons?.forEach(labelIcon => { + symbolizers.push(labelIcon); + }); + const symbolizer = Object.assign( this.getTextSymbolizerFromMapfileStyle(mapfileLabel), this.getBaseSymbolizerFromMapfileStyle(mapfileLabel) @@ -824,6 +831,24 @@ export class MapfileStyleParser implements StyleParser { return symbolizers; } + /** + * Collect icon data if defined within the label tag + * + * @param {MapfileLabel} mapfileLabel Mapfile label data + * @return {IconSymbolizer[]} The IconSymbolizer + */ + getIconsFromMapfileLabel(mapfileLabel: MapfileLabel): IconSymbolizer[] { + const labelStyles: IconSymbolizer[] = []; + mapfileLabel?.styles?.forEach((style: MapfileStyle) => { + if (style.symbol) { + labelStyles.push(this.getIconSymbolizerFromMapfileStyle( + {symbol: {image: style.symbol}} as unknown as MapfileStyle + )); + } + }); + return labelStyles; + } + /** * Get the GeoStyler-Style Rule from an Mapfile Object. * diff --git a/src/mapfile2js/mapfileTypes.ts b/src/mapfile2js/mapfileTypes.ts index ea0287f..9bd9dbb 100644 --- a/src/mapfile2js/mapfileTypes.ts +++ b/src/mapfile2js/mapfileTypes.ts @@ -131,6 +131,7 @@ export interface MapfileLabel { color: string; outlinecolor: string; outlinewidth: number; + styles?: MapfileStyle[]; } interface MapfileScaleTokenValue {} diff --git a/src/mapfile2js/parse/resolveSymbolset.ts b/src/mapfile2js/parse/resolveSymbolset.ts index 4f57c22..dd7428d 100644 --- a/src/mapfile2js/parse/resolveSymbolset.ts +++ b/src/mapfile2js/parse/resolveSymbolset.ts @@ -53,6 +53,23 @@ export function resolveSymbolsFromMapfile(mapfile: Mapfile): Mapfile { }); } }); + } else if (mclass.labels) { + // parse symbol data within a style tag of a label + mclass.labels.forEach((label) => { + const styles: MapfileStyle[] = label.styles as MapfileStyle[]; + styles?.forEach((style: MapfileStyle) => { + symbols?.forEach((symbol: any) => { + if ( + symbol.name && + symbol.image && + symbol.name === style.symbol + ) { + style.symbol = (parse(symbol.image) + .base as unknown) as MapfileSymbol; + } + }); + }); + }); } }); }