-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathosm_history_animation.py
86 lines (80 loc) · 3.17 KB
/
osm_history_animation.py
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
# Wrapper for https://github.com/amandasaurus/osm-mapping-party-before-after script to generate animation of OSM map changes
# UNIX ONLY, ffmpeg required
import os, sys, subprocess, shutil
bbox = "24.709036,59.397752,24.913141,59.464277"
bbox = "-74.281479,39.931876,-74.100891,40.067059"
bbox = "-74.28856,39.9383,-74.13,40.0"
script_dir = "/home/user/osm-mapping-party-before-after"
script_location = script_dir + "/make.sh"
region_dir = script_dir + "/NE-USA" # EMPTY Dir which is used for image frames
map_filename = "~/estonia-internal-2021-07-27"
map_filename = "~/us-northeast-internal-2021-08-01"
map_filename_ext = ".osh.pbf"
min_zoom = 14
max_zoom = max(min_zoom, 14)
mp4_zoom = 14
# Base 4 conversion was experimant to make bounding boxes unique by appending zeroes to them. It didn't work.
def to_base_4(n):
s = ""
while n:
s = str(n % 4) + s
n =n //4
return "0"*(4-len(s))+s
def gen_dates():
start_date = datetime.datetime(2007, 1, 1)
end_date = datetime.datetime.now()
# Examples from https://stackoverflow.com/questions/35066588
# step = relativedelta(weeks=1) # Next week
# step = relativedelta(months=+1, day=1, weekday=MO(1)) # First monday of next month
step = relativedelta(months=+1, day=1) # 1st of next month
# Hourly or even minutely changes are supported as well.
c=0
output = [start_date]
while output[-1] <end_date:
c+=1
# We are using multiplication, not regular increments due to 28 days of february.
# Example 01-29 > 02-28 > 03-29 vs 01-29 > 02-28 > 03-28.
output.append(start_date + step * c)
print(c, output[-1])
output.pop(-1)
return list(map(lambda x: x.strftime('%Y-%m-%dT%H:%M:%SZ'), output))
ts=gen_dates()
os.system("createdb")
c = 0
try:
while ts:
zeros=list(map(lambda x: "0"*int(x), to_base_4(c)))
date1=ts.pop(0)
c += 1
if not ts:
date2=date1
else:
date2=ts.pop(0)
# box=f"24.709036{zeros[0]}001,59.397752{zeros[1]}001,24.913141{zeros[2]}001,59.464277{zeros[3]}001"
print(date1, date2)
cmd=f"{script_location} {map_filename}{map_filename_ext} {date1} {date2} {bbox} {min_zoom} {max_zoom} 2> /dev/null"
print(cmd)
print()
res=os.system(cmd)
if res:
print("ERROR with",cmd)
except KeyboardInterrupt:
print("interrupt received")
input("Press Ctrl+C again")
# Find files used for animation
files = os.listdir(script_dir)
frames = list(sorted(filter(lambda x: (not 'progress' in x) and 'z'+str(mp4_zoom)+'.png' in x, files)))
# Move animation frames to separate folder.
shutil.rmtree(region_dir)
os.makedirs(region_dir)
for file in frames:
os.rename(script_dir+'/'+file, region_dir+'/'+file)
# Make mp4
FPS = 6
QUALITY = 4 # Lower is better, higher gives smaller filesize
OUT_FNAME = 'NE-USA'
os.chdir(script_dir)
# ffmpeg -r 15 -f image2 -pattern_type glob -i "*?png" -vcodec libx264 -crf 12 -pix_fmt yuv420p output_q12.mp4
cmd = f'ffmpeg -r {FPS} -f image2 -pattern_type glob -i "{region_dir}/*?png" -vcodec libx264 -crf {QUALITY} -vf scale=240:-2 -pix_fmt yuv420p {OUT_FNAME}_q{QUALITY}.mp4'
print(cmd)
res=os.system(cmd)