-
-
Save Wikunia/76c90cc6832cc38be0b024469add98e8 to your computer and use it in GitHub Desktop.
Taxi Trip visualization
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Animations | |
using Colors | |
using CSV | |
using Dates | |
using Geodesy | |
using DataFrames | |
using JSON3 | |
using Javis | |
import Unitful: @u_str, uconvert, ustrip | |
# trips = CSV.read("/home/ole/Documents/KaggleTaxi/train.csv", DataFrame) | |
const minlat = 41 # most southern part | |
const minlon = -8.8 | |
const maxlat = 41.3 # most northern part | |
const maxlon = -8.4 | |
function ground(video, args...) | |
background("black") | |
sethue("white") | |
# bottom left corner is now at 0, 0 | |
translate(-video.width/2, -video.height/2) | |
end | |
function draw_trips(vid, trips; max_timestamp=Inf, weekday_float=0) | |
@JShape begin | |
weekday = convert(Int, round(weekday_float)) | |
for i in 1:100:nrow(trips) | |
trip = trips[i,:] | |
date = unix2datetime(trip.TIMESTAMP) | |
if trip.TIMESTAMP < max_timestamp && (weekday == 0 || weekday == dayofweek(date)) | |
draw_trip(vid, trip, (max_timestamp-trip.TIMESTAMP)/15) | |
end | |
end | |
weekdays = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"] | |
if weekday != 0 | |
sethue("white") | |
fontsize(50) | |
text(weekdays[weekday], Point(vid.width/2, 50); halign=:center) | |
end | |
end max_timestamp=max_timestamp weekday_float=weekday_float | |
end | |
function get_dist(p1, p2) | |
p1_lla = LLA(p1.y, p1.x, 0.0) | |
p2_lla = LLA(p2.y, p2.x, 0.0) | |
return euclidean_distance(p1_lla, p2_lla)*u"m" | |
end | |
function draw_trip(video, trip, max_len) | |
@layer begin | |
json = JSON3.read(trip.POLYLINE) | |
isempty(json) && return | |
vertices = Vector{Point}(undef, length(json)) | |
for (i,vertex) in enumerate(json) | |
vertices[i] = Point(vertex...) | |
end | |
dists = [get_dist(p1, p2) for (p1, p2) in zip(vertices[1:end-1], vertices[2:end])] | |
speeds = dists ./ 15u"s" | |
speeds_kmh = ustrip.(u"km/hr", speeds) | |
any(speeds_kmh .> 150) && return | |
abs_lat = abs(minlat-maxlat) | |
abs_lon = abs(minlon-maxlon) | |
vertices = [Point( | |
(vertex.x-minlon)*(video.width/abs_lon), | |
(maxlat-vertex.y)*(video.height/abs_lat) | |
) for vertex in vertices] | |
color_scale = Animation( | |
[0, 30, 50, 90], | |
[colorant"black", colorant"red", colorant"yellow", colorant"white"], | |
[linear() for i in 1:3] | |
) | |
line_scale = Animation( | |
[0, 30, 50, 90], | |
[0.0, 0.1, 1.0, 3.0], | |
[Animations.linear() for i in 1:3] | |
) | |
setopacity(0.2) | |
for (i, v1, v2, speed) in zip(1:length(speeds_kmh), vertices[1:end-1], vertices[2:end], speeds_kmh) | |
i > max_len && break | |
sethue(color_scale(speed)) | |
setline(line_scale(speed)) | |
line(v1, v2, :stroke) | |
end | |
end | |
end | |
function main(trips) | |
vid = Video(1000, 1000) | |
nframes = 30 | |
Background(1:nframes, ground) | |
min_timestamp, max_timestamp = extrema(trips.TIMESTAMP) | |
max_timestamp += 3600 | |
porto = Object(1:nframes, draw_trips(vid, trips; max_timestamp=max_timestamp, weekday_float=1)) | |
act!(porto, Action(1:nframes, change(:weekday_float, 1 => 7))) | |
render(vid; pathname=joinpath(@__DIR__, "images/weekday.gif")) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment