UNPKG

s2maps-gpu

Version:

S2 Maps GPU - An open source, high-performance, and GPU-accelerated map engine for rendering large-scale, interactive maps.

102 lines (101 loc) 3.71 kB
const language = navigator.language.split('-')[0] ?? 'en'; /** * Coalesce text layout property "field" * * examples: * * ```ts * // example 1 * const properties = { abbr: 'U.S.', name: 'United States', ... } * const field = ["\"", "?abbr,?name", "\""] // here we coallese to abbr if the property exists, otherwise we fallback on name * cooalesceField(field) // returns "U.S." or "United States" depending on whether abbr exists * * // example 2 * const properties = { type: 'airplane', ... } * const field = ["?type", "-16"] * cooalesceField(field) // 'airplane-16' * ``` * @param field - string field, array of string fields, or nested key * @param properties - properties to coalesce * @param fieldIsKey - whether the field is the key in properties or a value to coalesce * @returns the coalesced field */ export default function coalesceField(field, properties, fieldIsKey = false) { // first dive into nested properties while (typeof field === 'object' && 'key' in field) { properties = (properties[field.nestedKey ?? ''] ?? {}); field = field.key; } // now coalesce the field if (Array.isArray(field)) { return field.reduce((acc, cur) => { return acc + coalesceText(cur, properties, fieldIsKey); }, ''); } else { return coalesceText(field, properties, fieldIsKey); } } /** * Parse unique strings that start with: * - "?": coalesce from properties * - "!": transform the result * - - "U": uppercase * - - "L": lowercase * - - "C": capitalize * - "P": language aquisition (e.g. "XX" -> "en"). Defined by navigator.language (browser) * @param field - field string to parse * @param properties - properties to coalesce * @param fieldIsKey - whether the field is the key in properties or a value to coalesce * @returns the coalesced field */ function coalesceText(field, properties, fieldIsKey) { if (field[0] === '?') { // corner case - use defined that they needed to start with a ? if (field[1] === '?') return field.slice(1); const pieces = field.split(','); for (let piece of pieces) { // prep variables let charIndex = 1; let nextChar; const transforms = []; while (piece[charIndex] === '!') { charIndex++; nextChar = piece[charIndex]; charIndex++; if (nextChar === 'U') transforms.push((input) => { return input.toUpperCase(); }); // all uppercase else if (nextChar === 'L') transforms.push((input) => { return input.toLowerCase(); }); // all lowercase else if (nextChar === 'C') transforms.push((input) => { return input .split(' ') .map((i) => i[0].toUpperCase() + i.slice(1).toLowerCase()) .join(' '); }); // first letter capitalized, rest lower else if (nextChar === 'P') piece = piece.replaceAll('XX', language); } const key = piece.slice(charIndex); if (properties[key] !== undefined) { let res = String(properties[key]); for (const transform of transforms) res = transform(res); return res; } } return ''; } else { return (fieldIsKey ? properties[field] : field); } }