Menu

Easily create .kml file to plot focal mechanisms in Google Earth

Plotting focal mechanisms in Google Earth is an annoying task to do manually. I wrote a script to convert a text file to beach balls using the obspy package and then to create the corresponding KML file. Each ball is a symbol, used by one Placemark. Below, you’ll see a view of the beachball plot result. The behaviour is the same as for normal placemarks. If beachballs are overlapping, you can spread them by simply clicking on the cluster. When the icon scale factor is small, by zooming in, the number of overlapping icons will decrease. It is easy to add information in the table that appears when clicking on the beachball.

The full code is after the break:

#!/usr/bin/python
#~ warning !: the script will draw beachball and creates the kml file to plot them in googleearth. All created element
#~ will be placed in the same directory as the one containing this script. The kml file and the beachballs have to
#~ stay in the same directory.
from lxml import etree #will manage the identation of the kml script
from pykml.factory import KML_ElementMaker as KML #import pykml library
import numpy as np
import datetime as date
def beachball(data):
"""function to draw beachball using obspy library"""
import matplotlib.pyplot as plt
from obspy.imaging.beachball import Beachball
strike,dip,rake=data[:,9],data[:,10],data[:,11]
event=data[:,0] #index to identify the beachball created
for j in range(len(strike)):
beach = Beachball([strike[j],dip[j],rake[j]],outfile=str(int(event[j])),\
facecolor='black',edgecolor='black') #create and save beachball in a outfile in the directory where the .py file is
data=np.loadtxt('path\table_w_your_data.txt',\
skiprows=1) #import your data. (table format: index yyyy mm dd hr mn ss lat lon strike dip rake) the first row isn't used
latitude = data[:,7]
longitude = data[:,8]
yyyy,mm,dd=data[:,3],data[:,2],data[:,1]
hr,mn,ss = data[:,4],data[:,5],data[:,6]
index=data[:,0]
beachball(data) #call beachball function --> put in comment this line if you don't want to draw again all beachballs
###############################################################################################################################
# create a document element with multiple label style
kmlobj = KML.kml(
KML.Document(
)
)
for j in range(len(yyyy)): #create the ref icons we will use
kmlobj.Document.append(
KML.Style(
KML.IconStyle(
KML.Icon(
KML.href('%s.png'%str(int(index[j]))),
KML.scale(0.6), #scale the beachball in googleEarth
),
KML.heading(0.0),
),
id='beach_ball_%i'%j #gives the icon a ref that will be used later
),
)
# add images to the document element
for i in range(len(yyyy)):
datum = str(date.date(int(yyyy[i]),int(mm[i]),int(dd[i])))
ev_time = str(date.time(int(hr[i]),int(mn[i]),int(ss[i])))
kmlobj.Document.append(
KML.Placemark(
#~ KML.name('%s'%str(int(index[i]))), #uncomment this to add a name to the placemark (will always appear in GoogleEarth)
KML.ExtendedData( #I add information about the earthquake, it appears in a table ('info' : value)
KML.Data(
KML.value('%s'%datum), #add value of the specific info
name ='date' #name of'info' you add.
),
KML.Data(
KML.value('%s'%ev_time), #add value of the specific info
name ='time' #name of 'info' you add.
), #more data can be added, following the same structure (line 65-68)
),
KML.styleUrl('#beach_ball_%i'%i), #get the correct beachball in the directory as marker
KML.Point(
KML.coordinates(longitude[i],',',latitude[i]),
),
),
)
print etree.tostring(etree.ElementTree(kmlobj),pretty_print=True)
outfile= file('Focal_mechanism_devy.kml','w') #save the kml structure code
outfile.write(etree.tostring(kmlobj, pretty_print=True))

Thanks for responding. I don’t have much experience with Python, so I spent significant time yesterday educating myself on some basics. I still have no idea why I’m getting that “invalid index” error. I’m sure I’m missing something very simple and basic, but I don’t know what it is.

The .txt file I’m trying to use only contains information on one focal mechanism (a test case). The entire contents of my .txt file are:

Thanks for the clarifying the things. It works fine now. One thing already we discussed is if it s possible It would be fine to give a name with the new version to the png files a combination of YYYYMMDDHHMMSS? I am adding the name as I described semi automatically.
Thanks again.

Thank you for this really useful program. I learned enough about Python, which I had not used before, in a few hours to run the program and adapt it to add a few features (e.g. coloured beachballs for different fault types, display depth in info box). It is also easy to convert the kml output file to shapefile format for ArcGIS, using the Arc Toolbox, join the new shapefile to the original data file, and display the beachballs in ArcMap with their attributes.

Meta

This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Cookie settingsACCEPT

Privacy & Cookies Policy

Privacy Overview

This website uses cookies to improve your experience while you navigate through the website. Out of these cookies, the cookies that are categorized as necessary are stored on your browser as they are essential for the working of basic functionalities of the website. We also use third-party cookies that help us analyze and understand how you use this website. These cookies will be stored in your browser only with your consent. You also have the option to opt-out of these cookies. But opting out of some of these cookies may have an effect on your browsing experience.

Necessary cookies are absolutely essential for the website to function properly. This category only includes cookies that ensures basic functionalities and security features of the website. These cookies do not store any personal information.

Any cookies that may not be particularly necessary for the website to function and is used specifically to collect user personal data via analytics, ads, other embedded contents are termed as non-necessary cookies. It is mandatory to procure user consent prior to running these cookies on your website.