isLocation
Check it out here
Problem:
Working with coordinates and location data is a tedious process. I mean, ok, I guess it depends on how you work with it. I usually use a cross-platform mobile solution, so take something like Xamarin.Forms or Jasonette and you realize that there’s no native library to work with locations.The same applies for web applications.
For example, if I want the rough distance between two points, I usually end up searching the web till I end up finding a solution like this on StackOverflow:
var R = 6371; // km
//has a problem with the .toRad() method below.
var x1 = lat2-lat1;
var dLat = x1.toRad();
var x2 = lon2-lon1;
var dLon = x2.toRad();
var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(lat1.toRad()) * Math.cos(lat2.toRad()) *
Math.sin(dLon/2) * Math.sin(dLon/2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
I then add that to a local library to reuse it.
Of course, this means that for every solution I work with, I’m pasting this over and over again into its own class. I can probably write a library, but I work on apps in so many different languages. One day I’m working with C#, the other day with Javascript. I don’t want to keep track of all these libraries and their fifty thousand methods. I wish there was a standardized way I could just call to do all the location stuff for me.Of course, coordinates by themselves aren’t all that useful either, I often end up having to reverse geocode or search for an actual address. Hmm, I wish there was a service to do this for me.
Getting Started
I was inspired a few days earlier by a project I saw on Indiehacker. It’s called Page.Rest. The premises for the service is to fetch metadata for a given website, similar to how Facebook and Twitter fetch information. I wanted to something similar in the earlier in the year and it wasn’t easy. This service was beautiful, it took all the manual work out of scraping metadata from websites. The pricing is a mere $5 a YEAR, and that’s it. Here’s a website that solves a problem, makes money from it, and that’s how it lives.
That’s what I wanted to do! Follow in a similar model, except build a service to solve the problems with location. So to kick off my project, I began by writing a few of the requirements I wanted this service to have.
What are the requirements that this service should have?
This was what I jotted down in my notes app as is:
Use Cases:
- [Boolean] Take User Location and Check within Range of a Target Place
- [Float] Return Distance to a particular point (Maybe by type)
- [Filtered List] Take a List of locations and get everything with a Certain range
- [Lat & Long] Geocode Location
- [Address Object] Reverse Lat/Long or vice versa
Writing The Docs
I really wanted this project to end up in the hands of customers. I didn’t want it just to be another personal project. So instead of diving head first into building out my service, I started writing the documentation prior to building it out. This helped me plan out what I was building and think of more use cases to justify buying into it.
I took my original list and I broke them down into a few important functions. I created a use case for each function so people would know how this method might be helpful:
Function | Desc. | Uses |
---|---|---|
Distance | Get the distance between Point A to Point B | How far things are |
Center | Take in a set of coordinates and find the center | Need to know the halfway point (like where to meet in between |
Radius | Check if a set of coordinates is in range of a location | Want to trigger an action near something |
Sort | Order a set of coordinates with a reference | If there are a lot of locations, we can get the closest one to a user |
Geocode | Helpful to have a function that can reverse lat/long | Useful from going from location to POI |
Nearby | Get places that are close to a lat/long | Useful for getting POI near a particular area |
I got acquainted with MKDocs and used markdown to write out each document. I didn’t want to build a dynamic solution to update and manage these docs. I want a static website because they’re virtually free to host with little overhead.
The Serverless Solution
I’ve built APIs before, primarily using AWS API Gateway and AWS Lambda. So I designed my specifications as if I were calling a function in the cloud.
AWS Lambda and API Gateway are a charm building publishable APIs. API Gateway handles everything from rate-limiting to route authentication, so I don’t have to worry. All of my server-side code fit into one AWS Lambda function. I then wired the function to my routes and I was off to the races.
Check out my quick-start guide for making Lambda Functions and pairing it with API Gateway.
Building the Payments Gateway
I never used Stripe before, but I didn’t want to bother keeping track of my customers. All I care is about their API token and how they’re using my service. So Stripe was a perfect solution, it does all the hard work for me. I didn’t even have to build a form because Stripe had its own checkout form. Perfect! Stripe rocks.
Of course, this meant a couple things. I had to set-up a webhook on my end to authorize the purchase. Generate an API token, add it to a usage plan and then return it back to the user to give them their newly purchased plan. It took me a few hours, but it was a satisfying feeling to see an HTML page popup with the token. Pay, get your token, and you’re ready to go instantly.
I was thinking about sending an e-mail, but that meant configuring an AWS SES or AWS SNS account, and I didn’t want to keep track of all these resources for a simple project.
SSL is a Pain
Perfect! Now all I had to do was setup a custom domain for my website. How hard could that be right?
No. Turns out, I think this was the hardest part. I bought a domain through Amazon Route 53 for www.islocation.com. Amazon has this nice way to offer free SSL certificates, so I thought it would work out of the box. My website required HTTPS because Stripe needs the client to have HTTPS enabled.
I just thought I could host on Github, point to my domain, and I’d be good to go. That was not the case. Turns out, Amazon only provisions SSL certs for resources within AWS. Makes sense from their business side. So this means I had to host my entire website on S3.
Of course, S3 websites by themselves don’t support HTTPS out of the box either. Turns out the way to get an SSL by AWS meant I needed to set up a “CloudFront” distribution. This is an Edge CDN network that caches your website content closer to a customer. I had 0 insights into SSL and DNS prior to this project. Of course.
I found a couple of good resources to help me along the way:
-> [AWS CloudFront and HTTPS] (http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/using-https.html) -> [S3 Static Website Hosting and Cloudfront] (https://miketabor.com/host-static-website-using-aws-s3/)
###Conclusion So that’s how I built out isLocation over a weekend. It was a fun project. I built an entire product from draft to market over the course of a weekend. Easy to maintain and self-sustaining. It doesn’t cost me much to just have it sit, but it will pay for itself with just a few customers. I need to market it some more, but I’m hoping it’ll see some use. In any case, a lot of great things I learned over the weekend that I can reuse. I want to build more weekend products! Maybe one can help me enough to buy lunch everyday.