Completed
Pull Request — master (#304)
by
unknown
01:14
created

CodePointMapping.__len__()   A

Complexity

Conditions 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
c 1
b 0
f 0
dl 0
loc 3
rs 10
1
# Copyright (c) 2008-2015 MetPy Developers.
2
# Distributed under the terms of the BSD 3-Clause License.
3
# SPDX-License-Identifier: BSD-3-Clause
4
"""Simplify using the weather symbol font.
5
6
See WMO manual 485 Vol 1 for more info on the symbols.
7
"""
8
9
import matplotlib.font_manager as fm
10
from pkg_resources import resource_filename
11
12
# Create a matplotlib font object pointing to our weather symbol font
13
wx_symbol_font = fm.FontProperties(fname=resource_filename('metpy.plots',
14
                                                           'fonts/wx_symbols.ttf'))
15
16
# Deal with the fact that Python 2 chr() can't handle unicode, but unichr is gone
17
# on python 3
18
try:
19
    code_point = unichr
20
except NameError:
21
    code_point = chr
22
23
24
class CodePointMapping(object):
25
    """Map integer values to font code points."""
26
27
    def __init__(self, num, font_start, font_jumps=None, char_jumps=None):
28
        """Initialize the instance.
29
30
        Parameters
31
        ----------
32
        num : int
33
            The number of values that will be mapped
34
        font_start : int
35
            The first code point in the font to use in the mapping
36
        font_jumps : list[int, int], optional
37
            Sequence of code point jumps in the font. These are places where the next
38
            font code point does not correspond to a new input code. This is usually caused
39
            by there being multiple symbols for a single code. Defaults to :data:`None`, which
40
            indicates no jumps.
41
        char_jumps : list[int, int], optional
42
            Sequence of code jumps. These are places where the next code value does not
43
            have a valid code point in the font. This usually comes from place in the WMO
44
            table where codes have no symbol. Defaults to :data:`None`, which indicates no
45
            jumps.
46
        """
47
        next_font_jump = self._safe_pop(font_jumps)
48
        next_char_jump = self._safe_pop(char_jumps)
49
        font_point = font_start
50
        self.chrs = []
51
        code = 0
52
        while code < num:
53
            if next_char_jump and code >= next_char_jump[0]:
54
                jump_len = next_char_jump[1]
55
                code += jump_len
56
                self.chrs.extend([''] * jump_len)
57
                next_char_jump = self._safe_pop(char_jumps)
58
            else:
59
                self.chrs.append(code_point(font_point))
60
                if next_font_jump and code >= next_font_jump[0]:
61
                    font_point += next_font_jump[1]
62
                    next_font_jump = self._safe_pop(font_jumps)
63
                code += 1
64
                font_point += 1
65
66
    @staticmethod
67
    def _safe_pop(l):
68
        """Safely pop from a list.
69
70
        Returns None if list empty.
71
        """
72
        return l.pop(0) if l else None
73
74
    def __call__(self, code):
75
        """Return the Unicode code point corresponding to `code`."""
76
        return self.chrs[code]
77
78
    def __len__(self):
79
        """Return the number of codes supported by this mapping."""
80
        return len(self.chrs)
81
82
    def alt_char(self, code, alt):
83
        """Get one of the alternate code points for a given value.
84
85
        In the WMO tables, some code have multiple symbols. This allows getting that
86
        symbol rather than main one.
87
88
        Parameters
89
        ----------
90
        code : int
91
            The code for looking up the font code point
92
        alt : int
93
            The number of the alternate symbol
94
95
        Returns
96
        -------
97
        int
98
            The appropriate code point in the font
99
        """
100
        return code_point(ord(self(code)) + alt)
101
102
103
#
104
# Set up mapping objects for various groups of symbols. The integer values follow from
105
# the WMO.
106
#
107
108
#: Current weather
109
current_weather = CodePointMapping(100, 0xE9A2, [(7, 2), (93, 2), (94, 2), (95, 2), (97, 2)],
110
                                   [(0, 4)])
111
112
#: Current weather from an automated station
113
current_weather_auto = CodePointMapping(100, 0xE94B, [(92, 2), (95, 2)],
114
                                        [(6, 4), (13, 5), (19, 1), (36, 4), (49, 1), (59, 1),
115
                                         (69, 1), (79, 1), (88, 1), (97, 2)])
116
117
#: Low clouds
118
low_clouds = CodePointMapping(10, 0xE933, [(7, 1)], [(0, 1)])
119
120
#: Mid-altitude clouds
121
mid_clouds = CodePointMapping(10, 0xE93D, char_jumps=[(0, 1)])
122
123
#: High clouds
124
high_clouds = CodePointMapping(10, 0xE946, char_jumps=[(0, 1)])
125
126
#: Sky cover symbols
127
sky_cover = CodePointMapping(12, 0xE90A)
128
129
#: Pressure tendency
130
pressure_tendency = CodePointMapping(10, 0xE900)
131