aboutsummaryrefslogtreecommitdiff
path: root/scripts/generate_map_img.py
blob: ee30cd90720eab38e7571ff74d140d284e320488 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#!/usr/bin/env python3
import argparse
import cv2
import pathlib
import numpy
import os
from typing import MutableMapping
import yaml

MAP_ROOT = pathlib.Path(os.getcwd())
TILES_DIR = MAP_ROOT / '../assets/tiles'
SHOW_MAP = False


def get_tile_path(tile: str) -> pathlib.Path:
    """Return the corresponding image file name for a tile"""
    return TILES_DIR / f'{tile.lower().replace(" ", "_")}.png'


def generate_img(map_path: pathlib.Path):
    """Generate a image from a map file"""
    with open(map_path, 'r') as map_file:
        map_definition = yaml.full_load(map_file)

    # remove the trailing new line
    map_string = map_definition['map'][:-1]
    # ensure that all keys are actually strings
    symbols = {str(k): v for k, v in map_definition['symbols'].items()}

    # build up tiles
    tiles = []
    for line in map_string.splitlines():
        row = []
        for symbol in line:
            tile = "neutral"
            if symbol != ' ':
                if symbol not in symbols:
                    print(f'WARNING unknown symbol "{symbol}"')
                else:
                    tile = symbols[symbol]
            row.append(tile)
        tiles.append(row)

    rows_imgs = []
    for i, row in enumerate(tiles):
        tile_imgs = []
        for j, tile in enumerate(row):
            # find the right street and rotation
            if tile == 'street':
                # check continuations
                left = j > 1 and row[j - 1] == 'street'
                right = j < len(row) - 1 and row[j + 1] == 'street'
                above = i > 1 and tiles[i - 1][j] == 'street'
                below = i < len(tiles) - 1 and tiles[i + 1][j] == 'street'

                connections = len(
                    [b for b in [left, right, above, below] if b == True])
                # straight lines
                if connections == 1 or (connections == 2 and
                                        ((left and right) or
                                         (above and below))):
                    tile_img = cv2.imread(str(get_tile_path('street')))
                    if above or below:
                        tile_img = numpy.rot90(tile_img)
                # elbow
                elif connections == 2:
                    # normal orientation above and right
                    tile_img = cv2.imread(str(get_tile_path('street_2')))
                    if right and below:
                        tile_img = numpy.rot90(tile_img, 3)
                    elif left and below:
                        tile_img = numpy.rot90(tile_img, 2)
                    elif above and left:
                        tile_img = numpy.rot90(tile_img)
                elif connections == 3:
                    # normal orientation left above right
                    tile_img = cv2.imread(str(get_tile_path('street_3')))
                    if above and right and below:
                        tile_img = numpy.rot90(tile_img, 3)
                    elif left and below and right:
                        tile_img = numpy.rot90(tile_img, 2)
                    elif below and left and above:
                        tile_img = numpy.rot90(tile_img)
                elif connections == 4:
                    tile_img = cv2.imread(str(get_tile_path('street_4')))
            else:
                tile_img = cv2.imread(str(get_tile_path(tile)))

            tile_imgs.append(tile_img)

        row_img = cv2.hconcat(tile_imgs)
        rows_imgs.append(row_img)

    map_img = cv2.vconcat(rows_imgs)
    if SHOW_MAP:
        cv2.imshow(f'{map_path.stem}.png', map_img)
        cv2.waitKey(0)
    cv2.imwrite(f'{map_path.stem}.png', map_img)


def main():
    """Generate map images from map files"""

    parser = argparse.ArgumentParser(
        description='generate latex standalone cards')
    parser.add_argument('map_input',
                        help='map file or directory containing map files')
    parser.add_argument('--map-root', help='path to the map root directory')
    parser.add_argument('--show-map',
                        help='show the generated map',
                        action='store_true')

    args = parser.parse_args()

    if args.map_root:
        global MAP_ROOT
        MAP_ROOT = pathlib.Path(args.latex_root)
        global TILES_DIR
        TILES_DIR = MAP_ROOT / '../assets/tiles'

    if args.show_map:
        global SHOW_MAP
        SHOW_MAP = True

    map_path = pathlib.Path(args.map_input)
    map_files = [map_path]
    if map_path.is_dir():
        map_files = map_path.glob('*.yml')

    for m in map_files:
        generate_img(m)


if __name__ == '__main__':
    main()