Python to batch generate QR codes

This is an overview of a script I developed utilizing python urllib, google’s chart api, and NOAA’s live stream monitoring charts. I created this proof of concept for a paper map that includes some graphic labels for stream monitoring stations, including a QR code that can be scanned to bring up the live chart for the stream gauge. Here’s the map as a proof of concept (the QR’s in the map below are dummy, so they won’t really take you anywhere, real one’s to follow).

Capture

Here’s the VNCC1 QR code:

vncc1

Screenshot using google goggles for the QR Capture:

Screenshot_2016-03-24-13-13-22

The cart for VNCC1 right now (3/24/2016 6:44am):

VNCC1

And a screen shot after hitting the link in goggles:

Screenshot_2016-03-24-13-13-42

This proof of concept was well received and we are going to utilize the labels in a variety of ways for a big mapbook project.

As a preemptive measure, I went ahead and developed a way to generate the labels for each station in California. The first part of this is to obtain/download the QR code for each gauge. First thing I did was to grab the national shapefile of the monitoring stations at NOAA.

This shapefile happens to have the URL for each monitoring station hydrograph.

001

First thing to notice is that the URL is consistent up to the point “wfo=…” I did a little testing and I know that the “wfo=mtr&” portion can just be removed, so a valid URL for any given gauge hydrograph is (plus a shorter URL is better for QR codes):

http://water.weather.gov/ahps2/hydrograph.php?gage=

…with the gauge ID on the end. For instance hit, http://water.weather.gov/ahps2/hydrograph.php?gage=vncc1

Next step is to select the California gauges and copy the table from the shapefile into excel and build the corrected URLs. Next, I perform a spatial selection of gauge points within the bounds of California, then right click to the left of one of the selected points in the attribute table and hit Copy Selected.

002

Then paste into excel and delete all columns except the ‘URL’ field.

003

Now, calculate a simplified URL into column B with the formula, in cell B2:

=”http://water.weather.gov/ahps2/hydrograph.php?gage=”&RIGHT(A2,5)

Copy the formula down the whole column (with B2 highlighted, double-click the little green box in the lower right corner), then hit ctrl+c to copy all URLs…

003

..and paste them into a text editor (I use notepad++).

004

Now save this as a text file, mine is here, C:\Users\brian\Desktop\QRs\00 urls.txt.

Next is the python, commented below.

import urllib
import os

#this is the google chart api url to create a 300x300 px QR code of the url after chl=
pre = "https://chart.googleapis.com/chart?chs=300x300&cht=qr&chl="

#text file with all the URLs
text=r"C:\Users\brian\Desktop\QRs\00 urls.txt"

#directory i want my QR code image to go
dir=r"C:\Users\brian\Desktop\QRs"

#make the directory above if it's not there
if not os.path.exists(dir):
    os.makedirs(dir)

#opens the address list text file (from the 'text' variable defined above) in read mode ("r")
with open(text,"r") as text_file:
  #creates a list of lines from the text file 'text'
  lines = [line.rstrip('\n') for line in open(text)]
  #loops each line
  for URL in lines:
    #concatenates the URL for the QR code and the google chart API url
    image = pre + URL
    #name for the QR code image text right of = in url, will be the station ID 
    name = URL.split('=')[-1]
    #creates the output file name for the QR .png image with the dir and name
    filename = os.path.join(dir,name+".png")
    #try to download the image and save it to the path else skip
    try:
      urllib.urlretrieve(image, filename)
    except KeyboardInterrupt:
      break
    except:
      print "Timed-out or got some other exception: "+image

Now, save that python script in the same spot as the text file, double-click it, and watch some magic. My next step is to extend the table a little bit and run it through InDesign data merge to auto generate the label boxes for each gauge station.

Boom,whole bunch of QR codes and a reusable script/system.

005