layer_themes_categorized.mjs
/**
### mapp.layer.themes.categorized()
The module exports the categorized function as a mapp.layer.theme.
@module /layer/themes/categorized
*/
/**
@function categorized
@description
The categorized theme method will assign a style from category matching the features properties.
Cluster features may not be styled by a categorized theme.
A theme can have a fields array to apply an icon style array for the individual property fields.
@param {Object} theme The theme configuration object.
@param {string} [theme.field] The feature property field to theme.
@param {array} [theme.fields] A fields array to style multiple feature properties.
@param {Array} theme.categories
@param {Object} feature
@param {Object} feature.properties
@param {Array} [feature.properties.features] A cluster feature will have a features array property.
*/
export default function categorized(theme, feature) {
// The categorized theme requires feature.properties.
if (!feature.properties) return;
// Cluster features can not be styled by category.
if (feature.properties.features?.length > 1) return;
let flat;
// Theme is using multiple fields.
if (Array.isArray(theme.fields)) {
// Map different theme fields
feature.style.icon = theme.fields
.map((field) => {
// Get the field value from feature properties
const catValue = feature.properties[field];
// Find category matching field and catValue
const cat = theme.categories.find(
(cat) =>
(cat.value === encodeURIComponent(catValue) ||
cat.value === catValue) &&
cat.field === field,
);
if (!cat) return;
flat ||= Array.isArray(cat.style.icon);
return cat.style.icon;
// Filter out empty icon entries from map response.
})
.filter((icon) => !!icon);
if (flat) {
feature.style.icon = feature.style.icon.flat();
}
return;
}
const catValue = feature.properties[theme.field];
const cat = theme.categories.find(
(cat) =>
cat.value === encodeURIComponent(catValue) || cat.value === catValue,
);
if (!cat) return;
if (cat.style === null) {
feature.style = null;
return;
}
// Spread cat style to retain scale property
feature.style = {
...feature.style,
...cat.style,
};
}