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()
|