PDA

View Full Version : Archived: CSV to KML geocoder


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