Animal Farm Pig
07-14-2009, 06:48 PM
Hi, I recently needed to import a bunch of names & addresses into Google Earth. The Pro version has this option, but the free version does not. So, I looked at the Google Maps API tutorial and modified it to suit my purposes.
This takes a CSV in the format of:
Name, Address
All other columns are ignored. Somewhere down the line, I might expand this so other columns show up as attributes of the placemarks in Google Earth.
Here's the code:
import urllib, time, csv, sys
import xml.dom.minidom
def geocode(address):
# This function queries the Google Maps API geocoder with an
# address. It gets back a csv file, which it then parses and
# returns a string with the longitude and latitude of the address.
mapsKey = 'ABQIAAAAqxWwhKo7TcjZIR22f2ACsRSrJseKwc0-gGI4_Lx5WC90eRmmBhQUPGvL0KDbantm6RAl1Tj3lB2MbA'
mapsUrl = 'http://maps.google.com/maps/geo?q='
# This joins the parts of the URL together into one string.
url = ''.join([mapsUrl,urllib.quote(address),'&output=csv&key=',mapsKey])
# This retrieves the URL from Google.
coordinates = urllib.urlopen(url).read().split(',')
# This parses out the longitude and latitude, and then combines them into a string.
if(not coordinates[0] == '200'):
print "Something messed up-- %s" %(address)
print coordinates[0]
while(coordinates[0] == '620'):
print "Code 620-- retrying"
time.sleep(1)
coordinates = urllib.urlopen(url).read().split(',')
coorText = '%s,%s' % (coordinates[3],coordinates[2])
return coorText
class Site:
def __init__(self, Name, Address = None, Coordinates = None):
self.Name = Name
self.Address = Address
self.Coordinates = Coordinates
def Geocode(self):
self.Coordinates = geocode(self.Address)
def KMLfromSiteList(SiteList):
kmlDoc = xml.dom.minidom.Document()
kmlElement = kmlDoc.createElementNS('http://earth.google.com/kml/2.2', 'kml')
kmlElement = kmlDoc.appendChild(kmlElement)
documentElement = kmlDoc.createElement('Document')
documentElement = kmlElement.appendChild(documentElement)
for Site in SiteList:
placemarkElement = kmlDoc.createElement('Placemark')
#Add Name data
nameElement = kmlDoc.createElement('name')
nameText = kmlDoc.createTextNode(Site.Name)
nameElement.appendChild(nameText)
placemarkElement.appendChild(nameElement)
#Add Address data
addressElement = kmlDoc.createElement('description')
addressText = kmlDoc.createTextNode(Site.Address)
addressElement.appendChild(addressText)
placemarkElement.appendChild(addressElement)
#Add coordinates
pointElement = kmlDoc.createElement('Point')
placemarkElement.appendChild(pointElement)
coorElement = kmlDoc.createElement('coordinates')
coorText = kmlDoc.createTextNode(Site.Coordinates)
coorElement.appendChild(coorText)
pointElement.appendChild(coorElement)
#Add to document
documentElement.appendChild(placemarkElement)
return kmlDoc
def ImportCSV(Filename):
MyFile = open(Filename, 'r')
MyReader = csv.reader(MyFile)
SiteList = []
for Row in MyReader:
SiteList.append(Site(Row[0], Row[1]))
MyFile.close()
return SiteList
def WriteKML(KMLfile, Outfile):
MyOutput = open(Outfile, 'w')
MyOutput.write(KMLfile.toprettyxml(' '))
MyOutput.close()
if __name__ == '__main__':
InFile = sys.argv[1]
OutFile = sys.argv[2]
MySiteList = ImportCSV(InFile)
map(lambda a: a.Geocode(), MySiteList)
MyKML = KMLfromSiteList(MySiteList)
WriteKML(MyKML, OutFile)
Here's a screenshot of how it comes out looking in Google Earth:
http://i32.tinypic.com/v8d0s5.png
This takes a CSV in the format of:
Name, Address
All other columns are ignored. Somewhere down the line, I might expand this so other columns show up as attributes of the placemarks in Google Earth.
Here's the code:
import urllib, time, csv, sys
import xml.dom.minidom
def geocode(address):
# This function queries the Google Maps API geocoder with an
# address. It gets back a csv file, which it then parses and
# returns a string with the longitude and latitude of the address.
mapsKey = 'ABQIAAAAqxWwhKo7TcjZIR22f2ACsRSrJseKwc0-gGI4_Lx5WC90eRmmBhQUPGvL0KDbantm6RAl1Tj3lB2MbA'
mapsUrl = 'http://maps.google.com/maps/geo?q='
# This joins the parts of the URL together into one string.
url = ''.join([mapsUrl,urllib.quote(address),'&output=csv&key=',mapsKey])
# This retrieves the URL from Google.
coordinates = urllib.urlopen(url).read().split(',')
# This parses out the longitude and latitude, and then combines them into a string.
if(not coordinates[0] == '200'):
print "Something messed up-- %s" %(address)
print coordinates[0]
while(coordinates[0] == '620'):
print "Code 620-- retrying"
time.sleep(1)
coordinates = urllib.urlopen(url).read().split(',')
coorText = '%s,%s' % (coordinates[3],coordinates[2])
return coorText
class Site:
def __init__(self, Name, Address = None, Coordinates = None):
self.Name = Name
self.Address = Address
self.Coordinates = Coordinates
def Geocode(self):
self.Coordinates = geocode(self.Address)
def KMLfromSiteList(SiteList):
kmlDoc = xml.dom.minidom.Document()
kmlElement = kmlDoc.createElementNS('http://earth.google.com/kml/2.2', 'kml')
kmlElement = kmlDoc.appendChild(kmlElement)
documentElement = kmlDoc.createElement('Document')
documentElement = kmlElement.appendChild(documentElement)
for Site in SiteList:
placemarkElement = kmlDoc.createElement('Placemark')
#Add Name data
nameElement = kmlDoc.createElement('name')
nameText = kmlDoc.createTextNode(Site.Name)
nameElement.appendChild(nameText)
placemarkElement.appendChild(nameElement)
#Add Address data
addressElement = kmlDoc.createElement('description')
addressText = kmlDoc.createTextNode(Site.Address)
addressElement.appendChild(addressText)
placemarkElement.appendChild(addressElement)
#Add coordinates
pointElement = kmlDoc.createElement('Point')
placemarkElement.appendChild(pointElement)
coorElement = kmlDoc.createElement('coordinates')
coorText = kmlDoc.createTextNode(Site.Coordinates)
coorElement.appendChild(coorText)
pointElement.appendChild(coorElement)
#Add to document
documentElement.appendChild(placemarkElement)
return kmlDoc
def ImportCSV(Filename):
MyFile = open(Filename, 'r')
MyReader = csv.reader(MyFile)
SiteList = []
for Row in MyReader:
SiteList.append(Site(Row[0], Row[1]))
MyFile.close()
return SiteList
def WriteKML(KMLfile, Outfile):
MyOutput = open(Outfile, 'w')
MyOutput.write(KMLfile.toprettyxml(' '))
MyOutput.close()
if __name__ == '__main__':
InFile = sys.argv[1]
OutFile = sys.argv[2]
MySiteList = ImportCSV(InFile)
map(lambda a: a.Geocode(), MySiteList)
MyKML = KMLfromSiteList(MySiteList)
WriteKML(MyKML, OutFile)
Here's a screenshot of how it comes out looking in Google Earth:
http://i32.tinypic.com/v8d0s5.png