* styleMatch * @param {Object} tags - OSM tags to match to a display style * @return {Object} Styling info for the given tags
(tags)
| 597 | * @return {Object} Styling info for the given tags |
| 598 | */ |
| 599 | styleMatch(tags) { |
| 600 | const defaults = this.STYLE_DECLARATIONS.DEFAULTS; |
| 601 | |
| 602 | let matched = defaults; |
| 603 | let styleScore = 999; // lower numbers are better |
| 604 | // eventually expose this to the caller? |
| 605 | // it may be useful to know what `k=v` pair matched |
| 606 | let styleKey; // the key controlling the styling, if any |
| 607 | // let styleVal; // the value controlling the styling, if any |
| 608 | |
| 609 | // First, match the tags to the best matching `styleID`.. |
| 610 | for (const [k, v] of Object.entries(tags)) { |
| 611 | const selector = this.STYLE_SELECTORS[k]; |
| 612 | if (!selector || !v) continue; |
| 613 | |
| 614 | // Exception: only consider 'service' when a 'highway' tag is present (not 'railway'), see Rapid#1252 |
| 615 | if (k === 'service' && getTag(tags, 'highway') === undefined) continue; |
| 616 | |
| 617 | const styleID = selector[v] ?? selector['*']; // '*' = fallback value |
| 618 | let score = Object.keys(selector).length; // smaller groups are more selective |
| 619 | if (lifecycleVals.has(v)) score = 999; // exception: lifecycle values |
| 620 | |
| 621 | if (styleID && score <= styleScore) { |
| 622 | const declaration = this.STYLE_DECLARATIONS[styleID]; |
| 623 | if (!declaration) { |
| 624 | console.error(`invalid styleID: ${styleID}`); // eslint-disable-line |
| 625 | continue; |
| 626 | } |
| 627 | |
| 628 | matched = declaration; |
| 629 | styleScore = score; |
| 630 | styleKey = k; |
| 631 | // styleVal = v; |
| 632 | |
| 633 | if (styleScore === 1) break; // no need to keep looking at tags |
| 634 | } |
| 635 | } |
| 636 | |
| 637 | // Also scan for lifecycle keywords in any of their various forms. |
| 638 | // The feature will be drawn with dashed lines. |
| 639 | // see Rapid#1312, Rapid#1199, Rapid#791, Rapid #535 |
| 640 | let hasLifecycleTag = false; |
| 641 | for (const [k, v] of Object.entries(tags)) { |
| 642 | // Lifecycle key, e.g. `demolished=yes` |
| 643 | // (applies to all tags, styleKey doesn't matter) |
| 644 | if (lifecycleVals.has(k) && v !== 'no') { |
| 645 | hasLifecycleTag = true; |
| 646 | break; |
| 647 | |
| 648 | // Lifecycle value, e.g. `railway=demolished` |
| 649 | // (applies only if `k` is styleKey or there is no styleKey controlling styling) |
| 650 | } else if ((!styleKey || k === styleKey) && lifecycleVals.has(v)) { |
| 651 | hasLifecycleTag = true; |
| 652 | break; |
| 653 | |
| 654 | // Lifecycle key prefix, e.g. `demolished:railway=rail` |
| 655 | // (applies only if there is no styleKey controlling the styling) |
| 656 | } else if (!styleKey && lifecycleRegex.test(k) && v !== 'no') { |
no test coverage detected