As this hackathon has a vacation theme, we decided that would be the best place to begin to brainstorm. We began to reminisce about our best vacation experiences and what made them so special. We came to the conclusion that when we were able to experience a culture from the locals, the vacations became even more meaningful and satisfying. Now while we are unable to physically travel to these different places due to the current situation, we still wanted to come close to reproducing this experience. And so staycate was created, a website that allows users to experience different places directly from the locals by showing social media posts from the area.

What it does

Our app has an interactive map which the user can use to move around the world. As they travel through the world, they see images posted by locals about those areas popping around the screen. The search bar provides a way for users to quickly jump to different landmarks or places. Once they do that, a top posts of the location will pop up to allow the user to take in the location they looked for. We take advantage of Instagram's hashtags to search for certain types of photos, prioritizing those tagged with landmarks and tourist attractions to give the user a better sense of the location. We believe this website is novel as it provides users with constantly updated posts from social media, rather than Google Images, giving the user content directly from the locals.

How we built it

Our website is consisted of two main parts the client side which is comprised of all of the javascript, HTML, and CSS and the server side which is powered by Python, Flask and our scraping API.

On the server side, we used Flask, a micro web framework, that handles all of our web requests. It then directs the user to the correct html template with the correct data. In addition, Python and the Instagram API are used to scrape the images off of Instagram and then send them over to the client side.

On the client side, HTML and CSS allow us to create the framework and major styles of the website. We are also using Bootstrap to add a further layer of polish onto the UI and because we just love the flat aesthetic it provides. We utilized Javascript for the brunt of the client-side functionality. Leaflet.js, a lightweight Javascript map framework, was used to create the interactive map on our website. It also enabled us to drop pins at different coordinates and render the posts. Mapbox API was used to reverse geocode the coordinates that we wanted to display pins at and find their addresses. This information was then used to generate search parameters to query the Instagram database for the relevant top daily posts. Google Places API, hosted on Google Cloud, was used to generate more specific information about the local tourist attractions and points of interest to further fine tune our hashtag search and provide the user with more relevant posts.

To jump between the client and server side, we used a number AJAX requests to query data from the server and send it back to the client.

Finally our whole website is hosted on Heroku so that others can try it out!

Challenges we ran into

As we were balancing using so many different APIs, all of which were completely foreign to us, linking them all together proved to be a challenge. Since each individual API didn't fully provide us the functionality we needed, we needed to combine leaflet.js, Mapbox and Google Places to get all information we needed which proved to be challenging as each of the APIs used different standards for encoding location data. The search bar is another example of multiple APIs working together to provide functionality. The search bar was implemented using leaflet.js but then uses Google Places API for the autocomplete functionality, which then returns the result back into leaflet to pan to that location.

In addition, as leaflet.js is so lightweight, it doesn't provide significant support for other UI elements on the map. Therefore, we had to get a search bar working on our own and we ran into a number of difficulties with positioning UI elements on the website. After a few hours of fiddling around with the UI though, we do feel that we have reached a state that we are happy with.

Finally, we spent a lot of time trying to optimize the user experience and minimize the timings of the requests so that it felt fast and snappy for the user to use. We still have not perfected that balance, yet we made significant performance improvements. In particular, the biggest reduction in our runtime was made by choosing to query for a larger radius. This was initially unintuitive because we figured that a bunch of queries for a smaller radius would be quicker, but because the limiting factor of the query is the web connection and not the data lookup, querying once for a big radius made our website feel a lot snappier.

Accomplishments that we're proud of

The biggest thing that we're proud of is the way that we interface different APIs and leverage different data sources like Google Cloud and Instagram to make our app. It was a big challenge managing all of that data but it was really satisfying once we were able to sort it all out. It seems like it should be pretty intuitive but because each API has its own quirks we had to finagle a lot of difference services. It's really cool the way that we are able to utilize the Google Cloud API to get specific locations and then generate hashtags based on those locations. This was a clever way to get around the fact that location searching with the Instagram API was incredibly slow. So instead of having to deal with locations in Instagram, we used the Google Cloud API to produce location hashtags. This also worked because we found that people who are vacationing often post with the hashtag of wherever they are.

What we learned

While we all had some prior experience using flask, this was our first time using javascript to such an extent. We learned about the hardship and pain of ajax queries but also the amazing community support that javascript has. Since all of us on the team have little experience with APIs, it was cool to learn about what they are and how they work at a deeper level. Specifically, we learned about asynchronous ajax API requests which speed up processing time by a significant amount. We learned a lot about modern-day computational cartography by getting into the nitty-gritty of leaflet.js and the Google Cloud Places API. We also got to learn about web-scraping because of the Instagram API integration (which required quite a bit of scraping to function).

What's next for Staycate

In the future, we hope to further narrow down the social media scraping so that we can be sure that we are getting posts about the location. In addition, we would like to integrate a wider variety of API like Snapchat to enhance the posts that we display to the user. Ideally we could also even display information from Yelp and Tripadvisor about nearby events and restaurants to further immerse the user. Finally, we would like to clean up the interface a little bit, maybe experimenting with different post styles. Regardless, we are still incredibly proud of what we have accomplished!

Share this project: