1. Have a GUI that enables the user to enter a location and search terms. 2. Que
ID: 3834269 • Letter: 1
Question
1. Have a GUI that enables the user to enter a location and search terms.
2. Query Twitter and Flickr to gather tweets and photos based on the search terms and the location.
3. Display a static map with markers showing the locations of the tweets and photos returned by the search.
4. Provide a way for users to view the tweets. E.g. you could place a Label or similar widget somewhere on your GUI and display the "current" tweet on it, where current corresponds to one of the mapped tweets. The marker corresponding to that "current" tweet should look different than other markers. Users might then acccess other tweets though "Next Tweet"/"Previous Tweet" buttons.
5. Provide a way to open a browser displaying the web page corresponding to URLs embedded in the tweets.
6. Provide a way for users to view the Flickr photos. E.g. you might add an additional Label or Canvas widget on the GUI and display the "current" photo on it. Like for tweets, the marker corresponding to that "current" photo should look different than other markers..
My code:
import tkinter
from tkinter import *
import math
from urllib.request import urlopen, urlretrieve
from urllib.parse import urlencode
import json
# To use, see the last function in this file, startGUI().
# Given a string representing a location, return 2-element
# [latitude, longitude] list for that location
#
# See https://developers.google.com/maps/documentation/geocoding/
# for details
#
def geocodeAddress(addressString):
urlbase = "http://maps.googleapis.com/maps/api/geocode/json?"
adst = urlencode({'address': addressString})
url = urlbase + adst
resultFromGoogle = urlopen(url).read().decode('utf8')
jsonresult = json.loads(resultFromGoogle)
if (jsonresult['status'] != "OK"):
print("Status returned from geocoder *not* OK: {}".format(jsonresult['status']))
return
loc = jsonresult['results'][0]['geometry']['location']
return (float(loc['lat']),float(loc['lng']))
#
# Google will also "reverse geocode." That is, you can provide a latitude and longitude and
# and Google will try to provide "human readable" information about that location.
#
# E. g. geocodeLatLng(41.6613, -91.5361)
#
# Again, see https://developers.google.com/maps/documentation/geocoding/
#
def geocodeLatLng(lat, lng):
urlbase = "http://maps.googleapis.com/maps/api/geocode/json?"
latLngstring = "{},{}".format(lat,lng)
adst = urlencode({'latlng': latLngstring})
url = urlbase+adst
resultFromGoogle = urlopen(url).read().decode('utf8')
jsonresult = json.loads(resultFromGoogle)
if (jsonresult['status'] != "OK"):
print("Status returned from geocoder *not* OK: {}".format(jsonresult['status']))
return
loc = jsonresult['results'][0]['addressFormat']
return loc
# Contruct a Google Static Maps API URL that specifies a map that is:
# - width-by-height in size (in pixels)
# - is centered at latitude lat and longitude long
# - is "zoomed" to the give Google Maps zoom level
#
# See https://developers.google.com/maps/documentation/static-maps/
#
# YOU WILL NEED TO MODIFY THIS TO BE ABLE TO
# 1) DISPLAY A PIN ON THE MAP
# 2) SPECIFY MAP TYPE - terrain vs road vs ...
#
def getMapUrl(width, height, lat, lng, zoom):
urlbase = "http://maps.google.com/maps/api/staticmap?"
parameter = "center={},{}&zoom={}&size={}x{}&format=gif".format(lat,lng,zoom,width,height)
return urlbase+parameter
# Retrieve a map image via Google Static Maps API:
# - centered at the location specified by global variable mapLocation
# - zoomed according to global variable zoomLevel (Google's zoom levels range from 0 to 21)
# - width and height equal to global variable mapSize
# Store the returned image in file name specified by global variable mapFileName
#
def retrieveMap():
lat, lng = geocodeAddress(mapLocation)
url = getMapUrl(mapSize, mapSize, lat, lng, zoomLevel)
urlretrieve(url, mapFileName)
return mapFileName
##########
# very basic GUI code
# Global variables used by GUI and map code
#
rootWindow = None
mapLabel = None
defaultLocation = "Mauna Kea, Hawaii"
mapLocation = defaultLocation
mapFileName = 'googlemap.gif'
mapSize = 400
zoomLevel = 9
def readEntryAndShowMap():
global mapLocation
global E
#### you should change this function to read from the location from an Entry widget
#### instead of using the default location
mapLocation = E.get()
showMap()
def showMap():
retrieveMap()
mapImage = tkinter.PhotoImage(file=mapFileName)
mapLabel.configure(image=mapImage)
# next line necessary to "prevent (image) from being garbage collected" - http://effbot.org/tkinterbook/label.htm
mapLabel.mapImage = mapImage
def initializeGUIetc():
global rootWindow
global mapLabel
global E
rootWindow = tkinter.Tk()
rootWindow.title("HW 10")
mainFrame = tkinter.Frame(rootWindow)
mainFrame.pack()
# until you add code, pressing this button won't change the map.
# you need to add an Entry widget that allows you to type in an address
# The click function should extract the location string from the Entry widget and create
# the appropriate map.
locationLabel = tkinter.Label(mainFrame, text="Enter Location.", bd = 1)
locationLabel.pack()
E = Entry(rootWindow, bd = 5)
E.pack()
readEntryAndShowMapButton = tkinter.Button(mainFrame, text="Show me the map!", command=readEntryAndShowMap)
readEntryAndShowMapButton.pack()
# we use a tkinter Label to display the map image
mapLabel = tkinter.Label(mainFrame, bd=2, relief=tkinter.FLAT)
mapLabel.pack()
def startGUI():
initializeGUIetc()
showMap()
rootWindow.mainloop()
Explanation / Answer
import tkinter
from tkinter import *
import math
from urllib.request import urlopen, urlretrieve
from urllib.parse import urlencode
import json
# To use, see the last function in this file, startGUI().
# Given a string representing a location, return 2-element
# [latitude, longitude] list for that location
#
# See https://developers.google.com/maps/documentation/geocoding/
# for details
#
def geocodeAddress(addressString):
urlbase = "http://maps.googleapis.com/maps/api/geocode/json?"
adst = urlencode({'address': addressString})
url = urlbase + adst
resultFromGoogle = urlopen(url).read().decode('utf8')
jsonresult = json.loads(resultFromGoogle)
if (jsonresult['status'] != "OK"):
print("Status returned from geocoder *not* OK: {}".format(jsonresult['status']))
return
loc = jsonresult['results'][0]['geometry']['location']
return (float(loc['lat']),float(loc['lng']))
#
# Google will also "reverse geocode." That is, you can provide a latitude and longitude and
# and Google will try to provide "human readable" information about that location.
#
# E. g. geocodeLatLng(41.6613, -91.5361)
#
# Again, see https://developers.google.com/maps/documentation/geocoding/
#
def geocodeLatLng(lat, lng):
urlbase = "http://maps.googleapis.com/maps/api/geocode/json?"
latLngstring = "{},{}".format(lat,lng)
adst = urlencode({'latlng': latLngstring})
url = urlbase+adst
resultFromGoogle = urlopen(url).read().decode('utf8')
jsonresult = json.loads(resultFromGoogle)
if (jsonresult['status'] != "OK"):
print("Status returned from geocoder *not* OK: {}".format(jsonresult['status']))
return
loc = jsonresult['results'][0]['addressFormat']
return loc
# Contruct a Google Static Maps API URL that specifies a map that is:
# - width-by-height in size (in pixels)
# - is centered at latitude lat and longitude long
# - is "zoomed" to the give Google Maps zoom level
#
# See https://developers.google.com/maps/documentation/static-maps/
#
# YOU WILL NEED TO MODIFY THIS TO BE ABLE TO
# 1) DISPLAY A PIN ON THE MAP
# 2) SPECIFY MAP TYPE - terrain vs road vs ...
#
def getMapUrl(width, height, lat, lng, zoom):
urlbase = "http://maps.google.com/maps/api/staticmap?"
parameter = "center={},{}&zoom={}&size={}x{}&format=gif".format(lat,lng,zoom,width,height)
return urlbase+parameter
# Retrieve a map image via Google Static Maps API:
# - centered at the location specified by global variable mapLocation
# - zoomed according to global variable zoomLevel (Google's zoom levels range from 0 to 21)
# - width and height equal to global variable mapSize
# Store the returned image in file name specified by global variable mapFileName
#
def retrieveMap():
lat, lng = geocodeAddress(mapLocation)
url = getMapUrl(mapSize, mapSize, lat, lng, zoomLevel)
urlretrieve(url, mapFileName)
return mapFileName
##########
# very basic GUI code
# Global variables used by GUI and map code
#
rootWindow = None
mapLabel = None
defaultLocation = "Mauna Kea, Hawaii"
mapLocation = defaultLocation
mapFileName = 'googlemap.gif'
mapSize = 400
zoomLevel = 9
def readEntryAndShowMap():
global mapLocation
global E
#### you should change this function to read from the location from an Entry widget
#### instead of using the default location
mapLocation = E.get()
showMap()
def showMap():
retrieveMap()
mapImage = tkinter.PhotoImage(file=mapFileName)
mapLabel.configure(image=mapImage)
# next line necessary to "prevent (image) from being garbage collected" - http://effbot.org/tkinterbook/label.htm
mapLabel.mapImage = mapImage
def initializeGUIetc():
global rootWindow
global mapLabel
global E
rootWindow = tkinter.Tk()
rootWindow.title("HW 10")
mainFrame = tkinter.Frame(rootWindow)
mainFrame.pack()
# until you add code, pressing this button won't change the map.
# you need to add an Entry widget that allows you to type in an address
# The click function should extract the location string from the Entry widget and create
# the appropriate map.
locationLabel = tkinter.Label(mainFrame, text="Enter Location.", bd = 1)
locationLabel.pack()
E = Entry(rootWindow, bd = 5)
E.pack()
readEntryAndShowMapButton = tkinter.Button(mainFrame, text="Show me the map!", command=readEntryAndShowMap)
readEntryAndShowMapButton.pack()
# we use a tkinter Label to display the map image
mapLabel = tkinter.Label(mainFrame, bd=2, relief=tkinter.FLAT)
mapLabel.pack()
def startGUI():
initializeGUIetc()
showMap()
rootWindow.mainloop()
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.