Route finder app — 100 days of golang day 10–20
After 2 weeks of learning golang I thought might as well go to a hackathon to throw myself into the deep. I found this travel hackathon at Microsoft Reactor through Eddie (with whom I was at the Hack for Good hackathon last year).
My goal was to join a team and write a golang API.
Team and idea
I found an awesome team after a bit of networking: River (dev), David (dev), Aristos (designer) and Angela (marketing).
River came up with the idea of creating a route finder that uses satellite imaging to find lit up routes so people can go home safely at night, assuming that lighter streets are safer. We ended up skipping the imaging part and just used the meta data and street data provided by OpenStreetMap. We called the app LightPath. It not only supposed to help you with a safe route planner but also avoids racial bias using crime report data.
Stack and tech
For frontend River used Vue.js with Stamen and Leaflet.
For the backend we used golang. The process was the following:
- Choose a small area of London using http://bboxfinder.com/#51.543522,-0.103871,51.546898,-0.094215
- Download Openstreetmap data into .osm https://wiki.openstreetmap.org/wiki/Developer_FAQ
- Convert into geojson using https://github.com/tyrasd/osmtogeojson
- Load into graph data structure
- Create an API with user posting start and end coordinates
- Find nodes in the graph
- Find path between those nodes optimising for meta data on footway, sidewalk and lightness of street
- Return path in geojson format via a REST API
Here are some notes about what I learnt during this hackathon about golang.
Parsing GeoJSON into struct
It took us quite a file to get going with JSON parsing, coming from Node JS development I think it was hard to get used to this, but we managed it in the end.
Code split and packages
- Code can be split into multiple files by specifying package main
- This way all definitions will live in the same namespace and therefore no import is needed, functions and types can be used across files
- To run the code we either have to do go run *.go or build and run executable
- With split code there should be only one main function
- Otherwise, if we want to have separate packages, we can set them up by having sub folders and specify a different package name
- Packages can have their own main function
- Packages need to be imported
- Imported packages reside at the GOROOT or at a subfolder of the GOPATH
Run and build
To run the go program:
go run *.go
To build and run:
The REST API was our entry point for the app.
- I learnt how to marshal and unmarshal between JSON and struct
- Allowed CORS
- Created a POST endpoint for the coordinates of start and endpoint
This tool was very useful for working with latitude/longitude data. We used this to select an area for the route finding app. We also used this tool to test the API by selecting start and end coordinates on this map, posting it to the API.
To check if our API returned a meaningful GeoJSON result, we used this tool:
From the GeoJSON data, which is made up of features that have their own geometry made up of coordinates, we had to load relevant data into a data model that we can use for the route search. We wanted to find streets only so we filtered for LineString elements.
We wanted to load this data into a graph structure where we had nodes (each end of a street) and edges (connection between nodes).
River coded up a simple interface for the search functionality, the repo can be found here:
What more to learn
Well I skipped through the whole path finding algo as that was done by David and I need to learn the following:
- Breadth-first search
- Binary tree search
- A* search
I need to learn more about deploying too, David deployed the app on Heroku but I want to learn:
- Dependency management
- Environment configs
Oh, and btw we won!
We got some kiwi.com vouchers and a trip to Prague — hope we can visit their headquarters. They seem like a cool company!
We will cleanup the repo and make some adjustments in the next few days and prepare for the global round. But all in all the weekend was SO MUCH FUN!
The backend code can be found here:
The frontend here: