diff --git a/data/mapbox/icon_simpleicon.ts b/data/mapbox/icon_simpleicon.ts index 7442b56..805c074 100644 --- a/data/mapbox/icon_simpleicon.ts +++ b/data/mapbox/icon_simpleicon.ts @@ -16,7 +16,8 @@ const iconSimpleIcon: MbStyle = { source: 'testsource', 'source-layer': 'foo', layout: { - 'icon-image': 'poi' + 'icon-image': 'poi', + 'icon-size': 2 } } ] diff --git a/data/mapbox_metadata/icon_simpleicon.ts b/data/mapbox_metadata/icon_simpleicon.ts index d318902..d22207c 100644 --- a/data/mapbox_metadata/icon_simpleicon.ts +++ b/data/mapbox_metadata/icon_simpleicon.ts @@ -16,7 +16,8 @@ const iconSimpleIcon: MbStyle = { 'source-layer': 'foo', type: 'symbol', layout: { - 'icon-image': 'poi' + 'icon-image': 'poi', + 'icon-size': 2 } } ], diff --git a/data/styles/icon_simpleicon.ts b/data/styles/icon_simpleicon.ts index f806377..5abd8c3 100644 --- a/data/styles/icon_simpleicon.ts +++ b/data/styles/icon_simpleicon.ts @@ -10,7 +10,8 @@ const iconSimpleIcon: Style = { source: 'https://testurl.com/sprites/mysprite.png', position: [0, 0], size: [12, 12] - } + }, + size: 24 }] }], metadata: { @@ -28,6 +29,7 @@ const iconSimpleIcon: Style = { }, sprite: { poi: { + 'icon-size': 2, position: [ 0, 0, diff --git a/src/MapboxStyleParser.ts b/src/MapboxStyleParser.ts index c624a03..822c81a 100644 --- a/src/MapboxStyleParser.ts +++ b/src/MapboxStyleParser.ts @@ -93,6 +93,7 @@ export type MapboxRef = { }; sprite?: { [key: string]: { + 'icon-size'?: number; position: [number, number]; size: [number, number]; }; @@ -423,13 +424,37 @@ export class MapboxStyleParser implements StyleParser> pitchAlignment: layout?.['icon-pitch-alignment'], rotate: mb2gsExpression(layout?.['icon-rotate']), rotationAlignment: layout?.['icon-rotation-alignment'], - size: mb2gsExpression(layout?.['icon-size']), textFit: layout?.['icon-text-fit'], // TODO: handle enum values // TODO: handle array values textFitPadding: layout?.['icon-text-fit-padding'] as IconSymbolizer['textFitPadding'], visibility: layout?.visibility && layout?.visibility !== 'none' }; + // mabpox icon-size scales the image and does not define its size + if (layout?.['icon-size'] && image) { + const scale = mb2gsExpression(layout['icon-size']); + + // multiply the mb icon-size with the width of the sprite to get the scale + if (isGeoStylerFunction(scale)) { + symbolizer.size = { + name: 'mul', + args: [ + scale, + image.size[0] + ] + }; + } else if (scale) { + symbolizer.size = scale * (image.size[0] as number); + } + + // Add icon-size to metadata + set( + this.gsMetadata['mapbox:ref'], + `sprite.${layout?.['icon-image']}.icon-size`, + layout['icon-size'] + ); + }; + if (MapboxStyleUtil.symbolizerAllUndefined(symbolizer)) { return undefined; } @@ -1510,18 +1535,23 @@ export class MapboxStyleParser implements StyleParser> visibility } = symbolizer; + const iconImage = image ? this.handleSprite(image) : undefined; + const iconSize = iconImage + ? this.gsMetadata['mapbox:ref'].sprite?.[iconImage]['icon-size'] + : gs2mbExpression(size); + const layout: SymbolLayout = { 'symbol-avoid-edges': avoidEdges as SymbolLayout['symbol-avoid-edges'], 'icon-allow-overlap': gs2mbExpression(allowOverlap), 'icon-optional': optional as SymbolLayout['icon-optional'], 'icon-rotation-alignment': gs2mbExpression (rotationAlignment) as SymbolLayout['icon-rotation-alignment'], - 'icon-size': gs2mbExpression(size), + 'icon-size': iconSize, 'icon-text-fit': gs2mbExpression(textFit) as SymbolLayout['icon-text-fit'], // TODO: handle array values 'icon-text-fit-padding': textFitPadding as SymbolLayout['icon-text-fit-padding'], // TODO: check sprite handling - 'icon-image': image ? this.handleSprite(image) : undefined, + 'icon-image': iconImage, 'icon-rotate': gs2mbExpression(rotate), 'icon-padding': gs2mbExpression(padding), 'icon-keep-upright': keepUpright as SymbolLayout['icon-keep-upright'],