Thursday, September 15, 2016

My Project: Travel time bot with Google Maps API and Python - Part 1 - Finding the Data [Programming]

My son will be starting university in just under a week at a school where my wife is also a professor. This means they are going to be carpooling on many days. Since the school is about 60 miles from our house, it is important to keep tabs on the driving time as here in Los Angeles, these times can change dramatically over the course of the day. This need to track driving time gave me an excuse to dive back into programming — which I was never that fond of anyway — despite my 30+ years working in computer support and consulting.

Here is a step by step story of the project and where it stands today.

Get the Data

The first step, of course, is to figure out where I can get the real-time routing and drive time data. I immediately thought about Google Maps and found the Google Maps API pages.

Google maps api

It is free to sign up for a developer account, which gives you an API key for each request you make to the Google Maps API servers. For me, my usage of the API is well below the number of free API requests per day, so there is no cost to run my program and gather the data — even if I were to request it about once per minute throughout the day. If you re going to develop high-usage commercial application, you’d have to sign up for one of Google API payment plants, based on the number of requests you make.

The specific Google Maps API I am using is the Directions API, which allows you to calculate directions between locations and returns a JSON-encoded file with a wide variety of information. They provide a basic example URL to get you started and then there are a host of options you can fine tune for your specific needs.

https://maps.googleapis.com/maps/api/directions/json?origin=Disneyland&destination=Universal+Studios+Hollywood4&key=YOUR_API_KEY

After a bit of trial and error, I came up with an appropriate URL that I could request manually and see the results returned.

https://maps.googleapis.com/maps/api/directions/json?origin=34.178026,-118.4528837&destination=34.057835,-117.8217123&departure_time=now&key=YOUR_API_KEY

This URL returns this JSON file...

{
   "geocoded_waypoints" : [
      {
         "geocoder_status" : "OK",
         "place_id" : "EjE1OTE0LTU5MTggQ2Vkcm9zIEF2ZSwgU2hlcm1hbiBPYWtzLCBDQSA5MTQxMSwgVVNB",
         "types" : [ "street_address" ]
      },
      {
         "geocoder_status" : "OK",
         "place_id" : "ChIJLVP1K64uw4ARc3vu78f00B0",
         "types" : [ "street_address" ]
      }
   ],
   "routes" : [
      {
         "bounds" : {
            "northeast" : {
               "lat" : 34.1794199,
               "lng" : -117.8012388
            },
            "southwest" : {
               "lat" : 34.0452654,
               "lng" : -118.453076
            }
         },
         "copyrights" : "Map data ©2016 Google",
         "legs" : [
            {
               "distance" : {
                  "text" : "46.2 mi",
                  "value" : 74333
               },
               "duration" : {
                  "text" : "54 mins",
                  "value" : 3251
               },
               "duration_in_traffic" : {
                  "text" : "58 mins",
                  "value" : 3455
               },
               "end_address" : "9 Olive Lane Walk, Pomona, CA 91768, USA",
               "end_location" : {
                  "lat" : 34.0577836,
                  "lng" : -117.8221829
               },
               "start_address" : "5914-5918 Cedros Ave, Sherman Oaks, CA 91411, USA",
               "start_location" : {
                  "lat" : 34.1780256,
                  "lng" : -118.4530714
               },

[… more information snipped…]

So far, so good. 

No I needed to figure out how to get the data out of this raw JSON file and into a form I could use it. The fact is, the API returns a lot more data than I really need, so I am only pulling out 2 pieces of information that are important to me. 

Navigating JSON Data Structures

Of course, now that I have the raw JSON data — which is a series of dicts, keys and values — I had to figure out the structure of the data and which pieces I needed. This was one of the more difficult learning parts for me. I understood that the JSOn file was a nested database of data, but figuring out how to get an individual pieces of data took me some time. Once I figured it out, though, it opened the door to any API that returns data in JSON format — a huge leap in my programming knowledge.

Visualizing JSON Data

Looking at a JSON file, especially a large one, and trying to discern the structure of the data can be a bit difficult. Levels of indentation aren’t always lear and nested curly braces always give me a headache. (LAUGH) Thankfully I searched out a web page that would allow me to view the data in a more database-like fashion, clearly showing how each piece of data was nested in the file.

JSONViewer.stack.hu allows you to either load a JSON file by URL or copy and paste a JSON file into the viewer. You can then click the Viewer Tab to see the data in its hierarchical format — expanding and collapsing nodes as needed.

Jsonviewer

Finding the Data I Needed

After a short while poking around in the Google Maps API JSON file, I found the 2 pieces of information I was most interested in — the summary or route of travel and the duration_in_traffic field.

Gmaps json expanded

This information would allow me to tell my wife and son which route was suggested by Google Maps (which can change based on traffic, road work and incidents) and the travel time in both text format and seconds. I did some basic checking with the interactive version of Google Maps to make sure the travel times were similar and saw that the duration field was a bit optimistic in its estimates. The duration_in_traffic field seemed to present a more realistic estimate, especially based on our heavy traffic here in Los Angeles.

Ok, so now I had the data I needed, how was I going to manipulate and use this data to make something useful?

In Part 2 of this series, I’ll dive into my Python program and discuss how I learned to process JSON data in Python, how I learned enough Python to do this and more and show off my working, if extremely basic, program. 

Sample Screen Output from Python program
[DEW-Mini:~/Downloads/py] dewelch% python cpp2.py

Via CA-134 E and I-210 E
Duration: 58 Minutes
0 Hours and 58 Minutes

Congratulations! You've fired the cpp event
[DEW-Mini:~/Downloads/py] dewelch% 

In future parts, I’ll discuss how I presented the data via screen, text, email and voice and how I got the code running on an Arduino Yun in preparation for creating a passive information device that will visually show the current travel time via graphical icons, colored lights and more!

No comments: