Python, KML and Parishes
When looking for phone numbers for various churches, I thought wouldn’t it be neat to put the locations on a map?
Python to the rescue. After some scraping to generate a CSV listing, I geocoded the addresses, then I used the OGR to convert into a KML document, using the same approach I previously blogged about. Nice!
Looking deeper, I wanted to have more exhaustive content within the <description> element. Turns out ogr2ogr has a -dsco DescriptionField=fieldname option, but I wanted more than that. So I decided to hack the original CSV:
#!/usr/bin/python
import csv
import urllib2
import urllib
from lxml import etree
r = csv.reader(open('greek_churches_canada.csv'))
node = etree.Element('kml', nsmap={None: 'http://www.opengis.net/kml/2.2'})
r.next()
for row in r:
params = '%s,%s,%s,%s' % (row[1], row[2], row[3], row[4])
url = 'http://maps.google.com/maps/geo?output=csv&q=%s' % urllib.quote_plus(params)
#print url
content = urllib2.urlopen(url)
status, accuracy, lat, lon = content.read().split(',')
#print status, accuracy, lat, lon
if status == '200':
row.append(lat)
row.append(lon)
subnode = etree.Element('Placemark')
subsubnode = etree.Element('name')
subsubnode.text = row[0]
subsubnode2 = etree.Element('description')
description = '<p>'
description += '%s<br/>' % row[1]
description += '%s, %s<br/>' % (row[2], row[3])
description += '%s<br/>' % row[4]
if row[5] != 'none':
description += '%s<br/>' % row[5]
if row[6] != 'none':
description += '%s<br/>' % row[6]
if row[7] != 'none':
description += '<a href="%s">Website</a><br/>' % row[7]
if row[8] != 'none':
description += '<a href="mailto:%s">Email</a><br/>' % row[8]
description += '%s<br/>' % row[9]
description += '</p>'
subsubnode2.text = etree.CDATA(description)
subsubnode3 = etree.Element('Point')
subsubsubnode = etree.Element('coordinates')
subsubsubnode.text = '%s, %s' %(lon, lat)
subsubnode3.append(subsubsubnode)
subnode.append(subsubnode)
subnode.append(subsubnode2)
subnode.append(subsubnode3)
node.append(subnode)
print etree.tostring(node, xml_declaration=True, encoding='UTF-8', pretty_print=True)
I wonder whether an OGR -dsco DescriptionTemplate=foo.txt, where foo.txt would look like:
<table>
<tr>
<th>City</th>
<td>[city]</td>
<th>Province</th>
<td>[province]</td>
</tr>
</table>
Or anything the user specified, for that matter. Then OGR would then use for each feature’s <description> element.
Anyways, here’s the resulting map. Cool!
