Retrieving weather data

Next, we will retrieve our final data element: the weather. As mentioned earlier, we will use the WeatherUnderground service that allows us to gather historical weather reports for any place in the world. The weather API is REST-based and JSON-based, so we'll use the urllib module to request the data and the JSON library to parse it. Note that in this section, we cache the data locally so that you can run the script offline to test, if need be. Early on in this section is where you place your WeatherUnderground API key that is flagged by the text, YOUR KEY HERE:

log.info("Creating weather summary")

# Get the bounding box centroid for georeferencing weather data
centx = minx + ((maxx-minx)/2)
centy = miny + ((maxy-miny)/2)

# WeatherUnderground API key
# You must register for free at wunderground.com
# to get a key to insert here.
api_key = "YOUR API KEY GOES HERE"

# Get the location id of the route using the bounding box
# centroid and the geolookup api
geolookup_req = "http://api.wunderground.com/api/{}".format(api_key)
geolookup_req += "/geolookup/q/{},{}.json".format(centy, centx)
request = urllib.request.urlopen(geolookup_req)
geolookup_data = request.read().decode("utf-8")

# Cache lookup data for testing if needed
with open("geolookup.json", "w") as f:
    f.write(geolookup_data)
js = json.loads(open("geolookup.json").read())
loc = js["location"]
route_url = loc["requesturl"]

# Grab the latest route time stamp to query weather history
t = times[-1]
history_req = "http://api.wunderground.com/api/{}".format(api_key)
name_info = [t.tm_year, t.tm_mon, t.tm_mday, route_url.split(".")[0]]
history_req += "/history_{0}{1:02d}{2:02d}/q/{3}.json" .format(*name_info)
request = urllib.request.urlopen(history_req)
weather_data = request.read()

# Cache weather data for testing
with open("weather.json", "w") as f:
    f.write(weather_data.decode("utf-8"))

# Retrieve weather data
js = json.loads(open("weather.json").read())
history = js["history"]

# Grab the weather summary data.
# First item in a list.
daily = history["dailysummary"][0]

# Max temperature in Imperial units (Farenheit).
# Celsius would be metric: "maxtempm"
maxtemp = daily["maxtempi"]

# Minimum temperature
mintemp = daily["mintempi"]

# Maximum humidity
maxhum = daily["maxhumidity"]

# Minimum humidity
minhum = daily["minhumidity"]

# Precipitation in inches (cm = precipm)
precip = daily["precipi"]

Now that we have the weather data stored in variables, we can complete the final step: adding it all to a PDF report.

The fpdf library has no dependencies except PIL, in some cases. For our purposes, it will work quite well. We will proceed down the page and add the elements. The fpdf.ln() function separates rows, while fpdf.cells contains text and allows for more precise layouts:

# Simple fpdf.py library for our report.
# New pdf, portrait mode, inches, letter size
# (8.5 in. x 11 in.)
pdf = fpdf.FPDF("P", "in", "Letter")

# Add our one report page
pdf.add_page()

# Set up the title
pdf.set_font('Arial', 'B', 20)

# Cells contain text or space items horizontally
pdf.cell(6.25, 1, 'GPX Report', border=0, align="C")

# Lines space items vertically (units are in inches)
pdf.ln(h=1)
pdf.cell(1.75)

# Create a horizontal rule line
pdf.cell(4, border="T")
pdf.ln(h=0)
pdf.set_font('Arial', style='B', size=14)

# Set up the route map
pdf.cell(w=1.2, h=1, txt="Route Map", border=0, align="C")
pdf.image("{}_topo.jpg".format(osm_img), 1, 2, 4, 4)
pdf.ln(h=4.35)

# Add the elevation chart
pdf.set_font('Arial', style='B', size=14)
pdf.cell(w=1.2, h=1, txt="Elevation Profile", border=0, align="C")
pdf.image("{}_profile.png".format(elv_img), 1, 6.5, 4, 2)
pdf.ln(h=2.4)

# Write the weather summary
pdf.set_font('Arial', style='B', size=14)
pdf.cell(1.2, 1, "Weather Summary", align="C")
pdf.ln(h=.25)
pdf.set_font('Arial', style='', size=12)
pdf.cell(1.2, 1, "Min. Temp.: {}".format(mintemp), align="C")
pdf.cell(1.2, 1, "Max. Hum.: {}".format(maxhum), align="C")
pdf.ln(h=.25)
pdf.cell(1.2, 1, "Max. Temp.: {}".format(maxtemp), align="C")
pdf.cell(1.2, 1, "Precip.: {}".format(precip), align="C")
pdf.ln(h=.25)
pdf.cell(1.2, 1, "Min. Hum.: {}".format(minhum), align="C")

# Give WeatherUnderground credit for a great service
pdf.image("wundergroundLogo_black_horz.jpg", 3.5, 9, 1.75, .25)

# Save the report
log.info("Saving report pdf")
pdf.output('report.pdf', 'F')

You should have a PDF document in your working directory called report.pdf containing your finished product. It should look like the image shown in the following screenshot:

Retrieving weather data
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset