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!