article.txt

最近特别想做一个地铁图,能显示大湾区地铁线路,还能手动添加维护的,找到了mini metro web这个项目。非常适合。于是进行了一些修改,对数据进行维护,用到下面这些代码

mini metro web中,线路和站点信息是以json格式存储的,下面这个代码能对json文件进行维护,尤其是在数据量较大的情况下比较使用。不过添加站点和线路的代码,我没有亲自测试,添加的时候我还是用了手动添加的方式,非常麻烦,而且稍微出错就容易加载不上来。因为我站点信息特别多,又涉及到合并多个原有地图的数据,所以站点和线路ID都不再是INT类型,直接用编辑器维护站点线路会报错。但是改颜色改排版没关系。

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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
import json

def extend_ids(json_file_name, prefix):
"""
处理指定JSON文件的函数,按照要求对文件中的内容进行修改

参数:
json_file_name (str):需要处理的JSON文件的文件名,包含扩展名,需与脚本在同一文件夹下
prefix (str):要添加的前缀,默认值为"HK",方便全局修改
"""
try:
# 读取同文件夹下的指定JSON文件,指定编码为utf-8
with open(json_file_name, 'r', encoding='utf-8') as file:
data = json.load(file)

# 处理stations中的一级子结构体
if'stations' in data:
for station in data['stations']:
# 处理stationId和lineIds属性
if'stationId' in station:
station_id_value = station["stationId"]
station['stationId'] = f'"{prefix}{station_id_value}"'[1:-1]
if 'lineIds' in station:
station['lineIds'] = [f'"{prefix}{line_id}"'[1:-1] for line_id in station['lineIds']]

# 处理lines中的一级子结构体
if 'lines' in data:
for line in data['lines']:
# 处理lineId属性
if 'lineId' in line:
line_id_value = line["lineId"]
line['lineId'] = f'"{prefix}{line_id_value}"'[1:-1]
# 处理stationIds属性
if'stationIds' in line:
line['stationIds'] = [f'"{prefix}{station_id}"'[1:-1] for station_id in line['stationIds']]

# 将修改后的数据写回原文件,指定编码为utf-8,避免非ASCII字符转义
with open(json_file_name, 'w', encoding='utf-8') as file:
json.dump(data, file, indent=4, ensure_ascii=False)

print(f"{json_file_name} 文件处理成功!")
except FileNotFoundError:
print(f"找不到 {json_file_name} 文件,请确保文件存在于脚本所在的文件夹中。")
except json.JSONDecodeError:
print(f"{json_file_name} 文件格式有误,请检查文件内容是否符合JSON格式要求。")


def merge_files(file_name1, file_name2):
"""
将两个JSON文件进行合并的函数,把两个文件中的stations和lines结构体的子元素添加到新文件的相应结构体中

参数:
file_name1 (str):第一个JSON文件的文件名,需与脚本在同一文件夹下
file_name2 (str):第二个JSON文件的文件名,需与脚本在同一文件夹下
"""
try:
# 读取第一个JSON文件
with open(file_name1, 'r', encoding='utf-8') as f1:
data1 = json.load(f1)

# 读取第二个JSON文件
with open(file_name2, 'r', encoding='utf-8') as f2:
data2 = json.load(f2)

merged_data = {}
# 合并stations结构体的子元素
merged_stations = []
if'stations' in data1:
merged_stations.extend(data1['stations'])
if'stations' in data2:
merged_stations.extend(data2['stations'])
merged_data['stations'] = merged_stations

# 合并lines结构体的子元素
merged_lines = []
if 'lines' in data1:
merged_lines.extend(data1['lines'])
if 'lines' in data2:
merged_lines.extend(data2['lines'])
merged_data['lines'] = merged_lines

# 生成新的文件名
new_file_name = f"{file_name1.split('.')[0]}_{file_name2.split('.')[0]}_merge.json"

# 将合并后的数据写入新文件
with open(new_file_name, 'w', encoding='utf-8') as new_file:
json.dump(merged_data, new_file, indent=4, ensure_ascii=False)

print(f"已成功合并 {file_name1} 和 {file_name2} 为 {new_file_name}")
except FileNotFoundError:
print(f"找不到文件,请确保 {file_name1} 和 {file_name2} 都存在于脚本所在的文件夹中。")
except json.JSONDecodeError:
print(f"{file_name1} 或 {file_name2} 文件格式有误,请检查文件内容是否符合JSON格式要求。")

def move_tracks(file_name, x, y):
try:
# 读取同文件夹下的指定JSON文件,指定编码为utf-8
with open(file_name, 'r', encoding='utf-8') as file:
data = json.load(file)

# 处理stations中的一级子结构体
if'stations' in data:
for station in data['stations']:
# 处理position属性
if 'position' in station:
position_values = station['position']
position_values[0] = position_values[0] + x
position_values[1] = position_values[1] + y
station['position'] = position_values

# 将修改后的数据写回原文件,指定编码为utf-8,避免非ASCII字符转义
with open(file_name, 'w', encoding='utf-8') as file:
json.dump(data, file, indent=4, ensure_ascii=False)

print(f"{file_name} 文件处理成功!")
except FileNotFoundError:
print(f"找不到 {file_name} 文件,请确保文件存在于脚本所在的文件夹中。")
except json.JSONDecodeError:
print(f"{file_name} 文件格式有误,请检查文件内容是否符合JSON格式要求。")


def move_tracks_conditioned(file_name, x, y):
"""
根据指定的坐标偏移量来更新JSON文件中stations里符合条件的元素的position属性值

参数:
file_name (str):需要处理的JSON文件的文件名,需与脚本在同一文件夹下,包含扩展名
x (int):横坐标方向的偏移量
y (int):纵坐标方向的偏移量
"""
try:
# 读取同文件夹下的指定JSON文件,指定编码为utf-8
with open(file_name, 'r', encoding='utf-8') as file:
data = json.load(file)

# 处理stations中的一级子结构体
if'stations' in data:
for station in data['stations']:
# 判断stationId是否存在且开头两个字母
if'stationId' in station and isinstance(station['stationId'], str) and station['stationId'].startswith('HK'):
# 处理position属性
if 'position' in station:
position_values = station['position']
position_values[0] = position_values[0] + x
position_values[1] = position_values[1] + y
station['position'] = position_values

# 将修改后的数据写回原文件,指定编码为utf-8,避免非ASCII字符转义
with open(file_name, 'w', encoding='utf-8') as file:
json.dump(data, file, indent=4, ensure_ascii=False)

print(f"{file_name} 文件处理成功!")
except FileNotFoundError:
print(f"找不到 {file_name} 文件,请确保文件存在于脚本所在的文件夹中。")
except json.JSONDecodeError:
print(f"{file_name} 文件格式有误,请检查文件内容是否符合JSON格式要求。")


def generate_railway_info(filename, dest, prefix, start_x, start_y, line_id, line_name):
stations = []
station_id_counter = 1
with open(filename, 'r', encoding='utf-8') as file:
lines = file.readlines()
for index, line in enumerate(lines):
station_name = line.strip()
station_id = prefix + str(station_id_counter)
station_id_counter += 1
x = start_x
y = start_y + index * 50
position = [x, y]
station_info = {
"stationId": station_id,
"stationName": station_name,
"position": position,
"shape": "cicle",
"lineIds": [line_id],
"tagDirection": 1
}
stations.append(station_info)

line_info = {
"lineId": line_id,
"lineName": line_name,
"color": "#60269E",
"stationIds": [station["stationId"] for station in stations],
"sign": line_name,
"order": 14,
"bendFirst": [True] * len(stations)
}

result_data = {
"stations": stations,
"lines": [line_info]
}

with open(dest, 'w', encoding='utf-8') as out_file:
json.dump(result_data, out_file, indent=4)


def add_station(dest, prefix, station_name, start_x, start_y, line_id):
"""
向目标文件中添加一个单独的车站信息。

参数:
dest: 目标文件名(JSON格式文件)
prefix: 用于生成stationId的前缀字符串
station_name: 要添加的车站名称
start_x: 车站位置的x坐标值
start_y: 车站位置的y坐标值
line_id: 车站所属线路的id

"""
# 读取现有文件内容
try:
with open(dest, 'r', encoding='utf-8') as file:
data = json.load(file)
except FileNotFoundError:
data = {"stations": [], "lines": []}

# 生成新车站的stationId
station_id_counter = 1
if data["stations"]:
last_station_id = data["stations"][-1]["stationId"]
station_id_counter = int(last_station_id[len(prefix):]) + 1
station_id = prefix + str(station_id_counter)

# 构建新车站的结构体信息
new_station = {
"stationId": station_id,
"stationName": station_name,
"position": [start_x, start_y],
"shape": "cicle",
"lineIds": [line_id],
"tagDirection": 1
}

# 将新车站信息添加到stations列表中
data["stations"].append(new_station)

# 更新对应的线路信息中的stationIds(假设只有一条对应的线路)
if data["lines"]:
for line in data["lines"]:
if line["lineId"] == line_id:
line["stationIds"].append(station_id)
line["bendFirst"].append(True)
break

# 将更新后的数据写回文件
with open(dest, 'w', encoding='utf-8') as file:
json.dump(data, file, indent=4)


if __name__ == "__main__":


这个react应用默认地图是原神里面提瓦特的地图,要修改的话需要对Data里面的ts文件进行修改,从外部文件导入json结构体作为数据,于是就需要将json文件拆分成station和lines两部分。下面这个脚本可以做到这一点。方便反复对json文件进行维护并导入为app的预设地图。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import json

def main():
# 读取 checkpoint.json 文件
with open('Metro-2025-01-15_18-01-01.json', 'r', encoding='utf8') as file:
data = json.load(file)

# 检查是否包含 stations 和 lines 数组
if 'stations' in data and 'lines' in data:
# 将 stations 数组保存为 stations.json
with open('stations.json', 'w', encoding='utf8') as stations_file:
json.dump(data['stations'], stations_file, indent=4, ensure_ascii=False)
print("stations 数组已保存为 stations.json")

# 将 lines 数组保存为 lines.json
with open('lines.json', 'w', encoding='utf8') as lines_file:
json.dump(data['lines'], lines_file, indent=4, ensure_ascii=False)
print("lines 数组已保存为 lines.json")
else:
print("checkpoint.json 中缺少 stations 或 lines 数组")


if __name__ == "__main__":
main()

    Comments

    2025-01-18

    回到顶部