So it was thursday night and I was snarfing the web as usual and I came across an interesting github repo: dantaeyoung’s continuous-sunset. A 2018 vintage. truly exceptional. ripened perfectly. OK so I’m digging through these files and eventually I surmise the premise of the website: you go to the website during any time and it will show you a live video of a sunset somewhere in the world. I think it’s a cool idea and one that I could implement in a few hours. It didn’t look like dantaeyoung made very much progress. It looks like he is tackling the problem a little too precisely.
Sunsets are big things. The pattern is simple: every 24 hours sun goes down. Sure it changes with the seasons but I think for the first iteration of this I will choose to not calculate the exact azimuth of the sun. Sunsets last about 40 mins. So we only need about 24/(40/60) = 35 locations for an MVP website. Will 35 be enough? Maybe. We don’t want the sun to actually set—then it wouldn’t be eternal sunset. We are trying to create limbo here. For the MVP I will consider it a success if the sun doesn’t set but we might see the sun be too high in the sky to be considered “sunset mode” by victorian-era scholars.
Let’s build!
Despite what you have been taught, the first step of building is planning. Any time spent planning will generally give you 5x reduction of building time.
To make sure we are getting the right data we should first think about what kind of data we would need to make this website then we should think about how we should structure this data (data types).
What data do we need?
The answer might not seem simple to you. I think this skill comes with practice. For this project I think we will be fine using only two pieces of data: 1) the current UTC time 2) a list of videos streams to play
Streaming video used to be a royal pain in the butt; YouTube changed that.
How should we store this data?
For later iterations it would be nice too add some variation to the site. 400 locations would not be too much work to add. We won’t do that right now—good heavens, no! But planning ahead will allow us to easily add features in the future. So we need some kind of list. If we had a big list then what we could do is just filter out which ones don’t have a sunset at the current time and then choose randomly from that subset.
For the big list I think an array of objects would be an appropriate choice. For an MVP with only 35 locations we could probably get by with only a string array of youtube links but it would probably be nice to include some metadata about each city like the pre-calculated sunset start and sunset end times (using SunCalc or Wolfram Alpha). We can also include the geospatial coordinates of the city so that if we find that we need to calculate the azimuth in a later version all the data will already be there for us. All of this city data is already in this very high quality dataset so we just need to figure out how to convert it into array of objects format for our website.
How do we open this file? The files inside might seem daunting at first but we don’t even need to unzip it. Just download QGIS and drag-drop the file into a new project.
Okay so we need some way to subset this data to choose 35 good locations that are near the equator so that we don’t have to account for the Earth’s wobble in our MVP.
For now I’m just going to choose Vector->Research->Select Random within Extent, Select Extent on Canvas: I’m limiting it to near the equator so the sunrise and sunset is not too wonky, number of points: 35, minimum distance between points: 8 (because we want to have enough coverage of Earth to have the sun set all the time!). This will create a bunch of random points within a square.
Then I’m going to run Distance to nearest Hub which will calculate the closest random point for every city.
Next we will save it into a GeoJSON file and only save the name, iso_a2, latitude, longitude, ne_id, and HubName (the nearest random point). Because it is GeoJSON we actually don’t need to keep the latitude and longitude attributes since those are saved in the file already.
GeoJSON has a slightly different structure than our initial design plan but it is probably a better format for this kind of data anyway.
Now we should select only one city for each HubName. And we may as well choose the city closest to the equator for each HubName. Unfortunetly, it looks like Distance to nearest Hub is not doing quite what we want here since there are only 22 results. What we really needed was a One-to-One spatial join but Hub is doing One-to-Many. Ohh I think what we should have used was NNJoin but for now we’ll just work with this and we can update the data in the next iteration of our website (after Series A funding of our sunset website).
So I think the logical way to do this would be to create a list of ne_id and the sunrise start and end. Then filter out the list of all places to only include cities where sunset has started and choose the one where the time between now and sunsetEnd is maximized. Then we will check every five minutes to see if it should switch YouTube links. (For the “swap out the video” part I’m not sure exactly how to do that but I remember astronaut.io having a similar style of video swapping.)
Since we aren’t likely to compare across days I think using minutes in the day to compare times will be okay…
Looking at actual sunsets; maybe my initial reaction was a little niave. Sunsets can be short. Maybe 4~20 mins is a better estimate. Also, looking at a cloudy sunset is a bit anti-climactic. I think we might also need to use a weather API and choose the location which has the clearest skies from our list of available live sunsets.
Maybe for an MVP we can just have a link to a youtube search of city live streams which should have a live sunset. Originally I was only planning a simple Alpine.js website but I think we may need to use the YouTube API in future iterations. To keep costs under control we will probably need a backend server so I’m going to set up Elixir LiveView to host our MVP. That will allow us to easily add features like automated YouTube searching for our little website.
edit: this post was never finished because it turns out there aren’t as many live video feeds around the world as I thought