Untitled

 avatar
unknown
plain_text
10 months ago
4.1 kB
11
Indexable
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import math
import contextily as ctx
from shapely.geometry import LineString
import geopandas as gpd
from moviepy.editor import VideoFileClip, AudioFileClip, CompositeAudioClip, concatenate_audioclips

# -------------------------------
# Locations (lat, lon)
# -------------------------------
locations = [
    ("Hippalgaon", (19.52, 77.35)),
    ("Srisailam", (16.0726, 78.8686)),
    ("Mahanandi", (15.5122, 78.4564)),
    ("Tirupati", (13.6288, 79.4192)),
    ("Tirumala", (13.6833, 79.35)),
    ("Srikalahasti", (13.7490, 79.7000)),
    ("Hampi", (15.3350, 76.4600)),
    ("Pandharpur", (17.6746, 75.3234)),
    ("Tuljapur", (18.0139, 76.0711)),
    ("Hippalgaon", (19.52, 77.35)),  # back
]

lats = np.array([p[1][0] for p in locations])
lons = np.array([p[1][1] for p in locations])
names = [p[0] for p in locations]

# -------------------------------
# Interpolate route with pauses
# -------------------------------
dists = np.sqrt(np.diff(lats)**2 + np.diff(lons)**2)
total_dist = np.sum(dists)

fps = 25
duration_sec = 40
total_frames = fps * duration_sec
segment_frames = np.maximum(1, np.round(dists / total_dist * total_frames).astype(int))

diff = total_frames - np.sum(segment_frames)
segment_frames[-1] += diff

pause_frames = int(2.5 * fps)  # 2.5s pause

path_lats, path_lons = [], []
stop_frames = []

for i in range(len(dists)):
    n = segment_frames[i]
    start_lat, start_lon = lats[i], lons[i]
    end_lat, end_lon = lats[i+1], lons[i+1]

    for t in range(n):
        alpha = t / n
        path_lats.append(start_lat*(1-alpha) + end_lat*alpha)
        path_lons.append(start_lon*(1-alpha) + end_lon*alpha)

    # pause at stop
    for _ in range(pause_frames):
        path_lats.append(end_lat)
        path_lons.append(end_lon)

    stop_frames.append(len(path_lats)-1)

path_lats = np.array(path_lats)
path_lons = np.array(path_lons)

# -------------------------------
# Setup map
# -------------------------------
line = LineString(list(zip(path_lons, path_lats)))
gdf = gpd.GeoDataFrame(index=[0], geometry=[line], crs="EPSG:4326").to_crs(epsg=3857)

fig, ax = plt.subplots(figsize=(10, 8))
ax.set_axis_off()
ctx.add_basemap(ax, crs="EPSG:4326", source=ctx.providers.OpenStreetMap.Mapnik,
                zoom=6, attribution=False)

for name, (lat, lon) in locations:
    ax.plot(lon, lat, 'ro', markersize=5)
    ax.text(lon+0.2, lat+0.2, name, fontsize=8, color="black")

route_line, = ax.plot([], [], 'b-', lw=2)
car_dot, = ax.plot([], [], marker=">", color="red", markersize=12)
place_text = ax.text(0.02, 0.95, "", transform=ax.transAxes,
                     fontsize=14, va="top", ha="left",
                     bbox=dict(boxstyle="round,pad=0.4",
                               facecolor="white", alpha=0.8))

displayed_stop = -1
def animate(frame):
    global displayed_stop
    x, y = path_lons[frame], path_lats[frame]
    car_dot.set_data([x], [y])
    route_line.set_data(path_lons[:frame+1], path_lats[:frame+1])

    for idx, sf in enumerate(stop_frames):
        if frame == sf and displayed_stop < idx:
            displayed_stop = idx
            place_text.set_text(f"Reached: {names[idx+1]}")
            break
    return route_line, car_dot, place_text

ani = animation.FuncAnimation(fig, animate, frames=len(path_lats),
                              interval=1000/fps, blit=True)
ani.save("travel_temp.mp4", fps=fps, dpi=150, bitrate=4000)
plt.close(fig)

# -------------------------------
# Add honk/ding sound
# -------------------------------
video = VideoFileClip("travel_temp.mp4")
stop_times = [sf / fps for sf in stop_frames]

# Use your own ding/honk mp3 (download or record one)
honk_file = "honk.mp3"  # put a short sound file in same folder

sounds = []
for t in stop_times:
    snd = AudioFileClip(honk_file).set_start(t)
    sounds.append(snd)

final_audio = CompositeAudioClip([video.audio] + sounds)
final_video = video.set_audio(final_audio)

final_video.write_videofile("travel_route_with_sound.mp4", fps=fps)
Editor is loading...
Leave a Comment