AltFilm was a project I worked on at the 2011 Culture Hackday held in the Lost Boys International offices. The aim of the hack was for me to provide a tool for independent and world cinema buffs to discover venues around them that screen films, so they can experience watching films in unique venues.
Birth of an idea
I first arrived at the Culture Hackday without an idea of what to work on. Speaking to the British Film Institute (BFI), I found out they had a database of every venue that has ever shown a film in the UK, as provided by the UK Film Council (UKFC). Although a significant number of these were regular cinemas, I also noticed a wide range of community centres, pubs, cafes, libraries, culture spaces and many more.
I thought it was a shame that I did not know about these spaces around me, and set about finding a solution: building a website that would present users with a list of venues near them which are known to show films.
Capturing and presenting data
With the UKFC’s data in hand, I had to find a way to suggest venues near a user’s location. There were three steps to doing this:
- Determine the latitude and longitude of each venue.
- Determine the latitude and longitude of the user.
- Sort the venues by proximity and return a list of the top N venues.
Geolocation of a venue
The the UKFC’s data did not contain any geolocation information. It did contain postcodes (sometimes). I iterated over every venue in the data set, and queried the Google geolocation APIs for a latitude and longitude (using the postcode - if available, or the name of the venue if not).
With the geolocation information obtained, I saved every venue in the database, with latitude and longitude information saved alongside its name and address.
Determining the geolocation of a user
With the location information roughly gathered, this information was passed to the Google Maps API through an AJAX request. The latitude and longitude of the location, as well as a human-readable version of the location was retrieved asynchronously.
Once the results from my API obtained, the human-readable version of the location replaced the information in the input box. This allowed the user to verify their location information was correctly understood. At the same time, a query to my suggestion API was made. The outcome of that query — a JSON list of venues near that user, resulted in a list presented to the user. They were then free to change the input query whenever they wished, repeating the process.
Sorting the venues by location
With the user interface complete, I got to work on my suggestion API. I developed a RESTful API using Django.
Note: in 2011, this seemed like a reasonable choice. Now I would most likely use Flask-RESTful or Node.js+Express for a RESTful API.
The API would take in a latitude and longitude input, and return a list of nearby venues, with their address.
To do this, my Django-powered API queried the database and retrieved all newly stored locations from the database. I modified the venues Model in Django so it had an extra field “distance”, which returned the euclidean distance based on an input latitude and longitude. I then let Django sort the objects by this field. This approach, although quite neat and very Django-friendly was of course, completely crazy. It required all venues to be loaded in memory and a euclidean calculation to be performed thousands of time over. If I were to do this again, I would use a database which allows geolocation-based querying. This would allow scaling well beyond the number of venues I tried it with.
With the API returning a list of venues, I was ready to plug the three parts together. Returning a list of nearby venues to the user’s query.
This was really quite a simple hack. A front-end to a database. The most interesting part for me was sorting records in Django by distance, using latitude and longitude. However, it would be much more effective to use a database that supports that query mechanism directly, as it avoids having to load the entire database in a Python object. With many more results, a sharded database could work much more effectively.
Perhaps a project for another time soon!