Creating KML files to show country weights within a fund
Note: This page contains the Python code used to create the KML files for the “Where in the world is my money? – Version 1.0” post.
Data:
The data used for the examples in the blog post comes from the iShares “Fact Sheet” for EFA, and from the Vanguard website for VWO.
The data is transfered into a spreadsheet (example) and the spreadsheet is then saved as a CSV file for use by the script.
Code:
Two Python files are used to generate the KML files. The first file reads the CSV file with the fund data and uses Google’s Geocode API to get the latitude and longitude for each country. The filenames for the input CSV file and the output KML file can be changed as desired. The second file contains functions which the first file calls to generate the KML file. This file is read by the main script using the “import” function.
Main File:
import urllib import libxml2 import csv import time from pykml_gen import * #Open csv file inputfile = csv.reader(open('efacountryweight.csv','rb'),delimiter=',') firstrow = inputfile.next() # template for URL to grab geocode data template = "http://maps.googleapis.com/maps/api/geocode/xml?address=%s&sensor=false" weights = [] countries = [] hkml = kml_create('EFACountryWeights.kml') for row in inputfile: country = row[0] print country if country != 'Other' and country != '': url = template %(country) url = url.replace(" ","+") time.sleep(0.5) stuff = libxml2.parseDoc(urllib.urlopen(url).read()) lats = [node.content for node in stuff.xpathEval('//lat')] lngs = [node.content for node in stuff.xpathEval('//lng')] print lats[0] # Grab first latitude (center of country) print lngs[0] # Grab first longitude (center of country) countries.append(country) try: percent = round(100*float(row[1]),1) #print percent except: percent = 0 weights.append(percent) # Create Placemark if weight is greater than 0.1% if percent > 0.1: #color = 'ffff0000' # Blue color = 'ff0000ff' # Red size =(percent**0.5) description = "Country weight in "+firstrow[0]+" on "+firstrow[1] kml_style(hkml, size, country,color) kml_placemark(hkml, country, percent, lngs[0], lats[0],description) kml_close(hkml)
This next section of code is contains the functions used to build the KML file. This file must be saved as “pykml_gen.py” and it must be stored in the same directory as the main script.
from __future__ import print_function def kml_create(fname): hkml = open(fname, 'w') print("""<kml xmlns=\"http://www.opengis.net/kml/2.2\"> <Document> """,file=hkml) return hkml def kml_folder_start(hkml,folder): print("""<Folder> <name>"""+folder+"""</name>""", file=hkml) def kml_folder_stop(hkml): print("""</Folder>""", file=hkml) def kml_close(hkml): print("""</Document> </kml>""", file=hkml) hkml.close() def kml_style(hkml,size,name,color): print("""<Style id="sn_target_"""+name+""""> <IconStyle> <color>"""+color+"""</color> <scale>"""+str(size)+"""</scale> <Icon> <href>http://maps.google.com/mapfiles/kml/shapes/shaded_dot.png</href> </Icon> </IconStyle> <LabelStyle> <scale>1.0</scale> </LabelStyle> <ListStyle> </ListStyle> </Style>""", file=hkml) def kml_placemark(hkml, name, percent, lon, lat, desc = 'Portfolio Weights'): print("""<Placemark> <name>"""+name,str(percent)+"%"+"""</name> <styleUrl>#sn_target_"""+name+"""</styleUrl> <description> <![CDATA[ <p>"""+name,str(percent)+"%"+"""</p> <p>"""+desc+"""</p> ]]> </description> <Point> <coordinates>"""+lon+""","""+lat+"""</coordinates> </Point> </Placemark>""", file=hkml)