/**
### /utils/olStyle
The olStyle utility module exports the default olStyle method.
@module /utils/olStyle
*/
/**
@global
@typedef {Object} feature-style
A JSON mapp-style object.
@property {string} [svg] The SVG source for the icon.
@property {string} [type] The type of the icon.
@property {Array|Object} [icon] The icon configuration or an array of icon configurations.
@property {number} [width] The width of the icon or symbol.
@property {number} [height] The height of the icon or symbol.
@property {string} [strokeColor] The stroke color of the line symbol.
@property {number} [strokeWidth] The stroke width of the line symbol.
@property {string} [fillColor] The fill color of the polygon symbol.
@property {number} [fillOpacity] The fill opacity of the polygon symbol.
*/
/**
@function olStyle
@description
The olStyle method takes a mapp-style JSON representation to create an Openlayers style object for rendering Openlayers features in the Openlayers mapview.Map.
@param {feature-style} style A JSON mapp-style object.
@returns {Object} An Openlayers feature style object.
*/
export default function olStyle(style, feature) {
if (!style) return null;
// Array for OL Style objects.
const Styles = []
// The style object must always be processed as an array.
style = Array.isArray(style) ? style : [style]
// Iterate through style array.
style.forEach(style => {
// Only process icon for features if they are point geometries.
if (style.icon) {
// Iterate through icon style array.
if (Array.isArray(style.icon)) {
style.icon.forEach(icon => iconStyle(style, icon))
} else {
iconStyle(style, style.icon)
}
function iconStyle(style, icon) {
// Calculate scale for icon render.
let scale = icon.scale || 1
scale *= style.scale || 1
scale *= style.clusterScale || 1
scale *= style.fieldScale || 1
scale *= style.zoomInScale || 1
scale *= style.zoomOutScale || 1
scale *= style.highlightScale || 1
// Create icon url from svgSymbols method if not defined as url or svg source.
icon.url = icon.url || icon.svg || mapp.utils.svgSymbols[icon.type || 'dot'](icon, feature)
if (!icon.url) return;
// Push OL icon Style into Styles array.
Styles.push(new ol.style.Style({
image: new ol.style.Icon({
src: icon.url,
crossOrigin: 'anonymous',
scale: scale,
anchor: icon.anchor || [0.5, 0.5],
}),
zIndex: style.zIndex
}))
}
}
if (style.fillColor || style.strokeColor) {
// Create OL fill.
const fill = style.fillColor && new ol.style.Fill({
color: mapp.utils.hexa(style.fillColor, style.fillOpacity)
})
// Create OL stroke.
const stroke = style.strokeColor && new ol.style.Stroke({
color: mapp.utils.hexa(style.strokeColor, style.strokeOpacity),
width: parseFloat(style.strokeWidth || 1)
})
// Push OL vector Style into Styles array.
Styles.push(new ol.style.Style({ fill, stroke, zIndex: style.zIndex }))
}
// Create label style if label text is not undefined.
if (typeof style.label?.text !== 'undefined') {
const text = new ol.style.Text({
font: style.label.font || '12px sans-serif',
text: String(style.label.text),
overflow: style.label.overflow,
offsetY: style.label.offsetY,
offsetX: style.label.offsetX,
stroke: style.label.strokeColor && new ol.style.Stroke({
color: style.label.strokeColor,
width: style.label.strokeWidth || 1
}),
fill: new ol.style.Fill({
color: style.label.fillColor || '#000'
})
})
// Push OL text Style into Styles array.
Styles.push(new ol.style.Style({ text, zIndex: style.zIndex }))
}
})
// Set Styles object to cache style.
feature?.set?.('Styles', Styles, true)
return Styles
}