Run Rabbit Run — Path tracking with React Native and the Geolocation API
How to build a simple path tracker for iOS with the Geolocation API and Native MapView
Disclaimer: I‘ll be honest with you, I didn’t really walk or run the 6.46km shown in the image above. Instead, I cheated and used the Xcode simulator’s — City Bicycle Ride. You can easily take advantage of this setting by selecting Simulator > Debug > Location > City Bicycle Ride. This simulation was able to provide me with some nice, clean GPS data to work with whilst building out this feature. If you want, you can get access the full source code here.
To follow along make sure you set your simulator location to City Bicycle Ride as described above. Also to enable geolocation on iOS you will need to include the NSLocationWhenInUseUsageDescription key in the Info.plist (this should already be good to go if you have initialised your project with react-native init).
As a starting point we need to create a component which renders a native MapView with a nav bar on top. This should look something like the following.
One thing to note is that React Native will draw elements on top of one another according to their sequence in the render method (i.e. the latest element is drawn on top of the previous one). As such we need to position the nav bar after the MapView as we want it to sit on top. I have the left styles out from the code snippet above for the sake of brevity. If you are coding along, styles can be found here.
Drawing our path
For this part we are going to be utilising React Native’s Geolocation Polyfill to retrieve location coordinates as we move about. The Geolocation API provides us with the methods getCurrentPosition and watchPosition which will give us access to the updated location data in the format described below.
Once we receive the updated location data we will then pass this information into MapView’s overlay property in order to draw our path on the map. Before we do, we need to transform it into the following.
To achieve this transformation we’ll use lodash’s handy pick function to ‘pick’ the latitude and longitude properties out of the updated position coords and concatenate these onto our routeCoordinates array. Once this is done all we need to do is pass this.state.routeCoordinates into the Overlay property of the MapView along with some style properties and the app should now be mapping out the path we have travelled.
Calculating the distance travelled
To calculate our distance travelled we are going to be utilising the Haversine formula. This formula is used to calculate the shortest distance between two points on the earths surface. Luckily for us the node ecosystem has us covered with this awesome Haversine module.
After importing the haversine module we need to add the properties distanceTravelled and prevLatLng to our components state. With this in place we can add a calcDistance method to our component which calculates the distance between the previous position and the current position. Adding this calculated distance to our accumulated distanceTravelled results in the total distance travelled.
With all of the above in place our little app should now draw the path we have taken whilst also keeping track of distance travelled.
I hope this demo has been helpful. Please feel free to leave any feedback, hints or tips and of course I’m always looking for better solutions!