• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

tilezen / mapbox-vector-tile / 3746140319

pending completion
3746140319

push

github

GitHub
Pre-commit tools (#121)

74 of 96 new or added lines in 6 files covered. (77.08%)

2 existing lines in 1 file now uncovered.

558 of 727 relevant lines covered (76.75%)

3.84 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.22
/mapbox_vector_tile/geom_encoder.py
1
cmd_bits = 3
5✔
2

3
CMD_MOVE_TO = 1
5✔
4
CMD_LINE_TO = 2
5✔
5
CMD_SEG_END = 7
5✔
6
CMD_FAKE = 0
5✔
7

8

9
def omit_last(iterator):
5✔
10
    try:
5✔
11
        next_elmt = next(iterator)
5✔
12
        while True:
3✔
13
            elmt = next_elmt
5✔
14
            next_elmt = next(iterator)
5✔
15
            yield elmt
5✔
16
    except StopIteration:
5✔
17
        pass
5✔
18

19

20
def encode_cmd_length(cmd, length):
5✔
21
    return (length << cmd_bits) | (cmd & ((1 << cmd_bits) - 1))
5✔
22

23

24
def zigzag(delta):
5✔
25
    return (delta << 1) ^ (delta >> 31)
5✔
26

27

28
class GeometryEncoder:
5✔
29
    def __init__(self, y_coord_down, extents, round_fn):
5✔
30
        self._geometry = []
5✔
31
        self._y_coord_down = y_coord_down
5✔
32
        self._extents = extents
5✔
33
        self._round = round_fn
5✔
34
        self._last_x, self._last_y = 0, 0
5✔
35

36
    def coords_on_grid(self, x, y):
5✔
37
        """Snap coordinates on the grid with integer coordinates"""
38

39
        if isinstance(x, float):
5✔
40
            x = int(self._round(x))
5✔
41
        if isinstance(y, float):
5✔
42
            y = int(self._round(y))
5✔
43
        if not self._y_coord_down:
5✔
44
            y = self._extents - y
5✔
45
        return x, y
5✔
46

47
    def encode_multipoint(self, points):
5✔
48
        cmd_move_to = encode_cmd_length(CMD_MOVE_TO, len(points))
5✔
49
        self._geometry = [cmd_move_to]
5✔
50
        last_x = 0
5✔
51
        last_y = 0
5✔
52
        for point in points:
5✔
53
            x, y = self.coords_on_grid(point.x, point.y)
5✔
54
            dx, dy = x - last_x, y - last_y
5✔
55
            self._geometry.append(zigzag(dx))
5✔
56
            self._geometry.append(zigzag(dy))
5✔
57
            last_x = x
5✔
58
            last_y = y
5✔
59

60
    def encode_arc(self, coords):
5✔
61
        """Appends commands to _geometry to create an arc.
62
        - Returns False if nothing was added
63
        - Returns True and moves _last_x, _last_y if
64
            some points where added
65
        """
66
        last_x, last_y = self._last_x, self._last_y
5✔
67
        float_x, float_y = next(coords)
5✔
68
        x, y = self.coords_on_grid(float_x, float_y)
5✔
69
        dx, dy = x - last_x, y - last_y
5✔
70
        cmd_encoded = encode_cmd_length(CMD_MOVE_TO, 1)
5✔
71
        commands = [cmd_encoded, zigzag(dx), zigzag(dy), CMD_FAKE]
5✔
72
        pairs_added = 0
5✔
73
        last_x, last_y = x, y
5✔
74
        for float_x, float_y in coords:
5✔
75
            x, y = self.coords_on_grid(float_x, float_y)
5✔
76
            dx, dy = x - last_x, y - last_y
5✔
77
            if dx == 0 and dy == 0:
5✔
78
                continue
5✔
79
            commands.append(zigzag(dx))
5✔
80
            commands.append(zigzag(dy))
5✔
81
            last_x, last_y = x, y
5✔
82
            pairs_added += 1
5✔
83
        if pairs_added == 0:
5✔
84
            return False
5✔
85
        cmd_encoded = encode_cmd_length(CMD_LINE_TO, pairs_added)
5✔
86
        commands[3] = cmd_encoded
5✔
87
        self._geometry.extend(commands)
5✔
88
        self._last_x, self._last_y = last_x, last_y
5✔
89
        return True
5✔
90

91
    def encode_multilinestring(self, shape):
5✔
92
        for arc in shape.geoms:
5✔
93
            coords = iter(arc.coords)
5✔
94
            self.encode_arc(coords)
5✔
95

96
    def encode_ring(self, ring):
5✔
97
        coords = omit_last(iter(ring.coords))
5✔
98
        if not self.encode_arc(coords):
5✔
99
            return False
×
100
        cmd_seg_end = encode_cmd_length(CMD_SEG_END, 1)
5✔
101
        self._geometry.append(cmd_seg_end)
5✔
102
        return True
5✔
103

104
    def encode_polygon(self, shape):
5✔
105
        if not self.encode_ring(shape.exterior):
5✔
106
            return
×
107
        for arc in shape.interiors:
5✔
108
            self.encode_ring(arc)
5✔
109

110
    def encode_multipolygon(self, shape):
5✔
111
        for polygon in shape.geoms:
5✔
112
            self.encode_polygon(polygon)
5✔
113

114
    def encode(self, shape):
5✔
115
        if shape.type == "GeometryCollection":
5✔
116
            # do nothing
117
            pass
5✔
118
        elif shape.type == "Point":
5✔
119
            x, y = self.coords_on_grid(shape.x, shape.y)
5✔
120
            cmd_encoded = encode_cmd_length(CMD_MOVE_TO, 1)
5✔
121
            self._geometry = [cmd_encoded, zigzag(x), zigzag(y)]
5✔
122
        elif shape.type == "MultiPoint":
5✔
123
            self.encode_multipoint(shape.geoms)
5✔
124
        elif shape.type == "LineString":
5✔
125
            coords = iter(shape.coords)
5✔
126
            self.encode_arc(coords)
5✔
127
        elif shape.type == "MultiLineString":
5✔
128
            self.encode_multilinestring(shape)
5✔
129
        elif shape.type == "Polygon":
5✔
130
            self.encode_polygon(shape)
5✔
131
        elif shape.type == "MultiPolygon":
5✔
132
            self.encode_multipolygon(shape)
5✔
133
        else:
NEW
134
            raise NotImplementedError(f"Can't do {shape.type} geometries")
×
135
        return self._geometry
5✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc