# Convert CSV Latitude longtitude to Blender coordinates

I have a table of Earthquake data in CSV, that includes Lat Long coordinates. CSV file download I want to convert them to Blender coordinates (on sphere or flat it doesn't matter as I can fit them to a map later). I hope to place an object at each location that references the magnitude value. Then I will make them appear in order over time, which is the other column of data.

I can import the CSV and convert to text objects for the magnitude with

import bpy # THIS IS A MUST TO IMPORT ALL BLENDER PYTHON MODULE
import csv # IMPORT CSV MODULE

file = csv.reader(open('\\Users\mcsweend2c\Desktop\Bearthquakes 6-9.csv', newline=''), delimiter=',')

curRow = [] #empty placeholder for current row

for idx, row in enumerate(file):
if idx<40: # this is hard coded at the moment

curRow = row

# display first data index as string
bpy.ops.object.editmode_toggle()
bpy.ops.font.delete()
bpy.ops.font.text_insert(text=curRow[0])
bpy.ops.object.editmode_toggle()


But I'm not sure how to separate and use the rest?

• see: stackoverflow.com/questions/1185408/… (for lat/lon to xyz) – zeffii Sep 1 '15 at 5:41
• that csv has mixed date information, .. 10/08/1997 and 1873/12/15, and it goes backwards in time (which makes sense) – zeffii Sep 1 '15 at 9:43
• Yes the data was cleaned in excel which doesn't recognize dates before 1900. And yes it goes backward in time. Although I'm happy to reverse that. I wasn't going to set the time accurately anyway, just straight progression. – 3pointedit Sep 1 '15 at 11:42

Here's how you read the CSV, reformat the dates, sort the quakes by date, convert lat/long to x/y/z then output each row as a text object on the outside of a hypothetical sphere (with the object name set to the date of the quake in YYYY-MM-DD format) with the text oriented so that it sits flat on the surface. Fonts and materials and other tweaks to be supplied by you. :)

# imports to make all the things work
from math import sin, cos, radians, pi, atan, tan
import csv
import bpy

# define some helpful functions for later

# a function to make, scale and rotate text objects into place
def makeathing(coords, scale, lat, long, date):
ob = bpy.context.object
# set object properties here
ob.data.body = "{:.1f}".format(float(scale))
ob.data.align = 'CENTER'
ob.rotation_mode = 'YXZ'
ob.data.size = 0.03
ob.data.extrude = 0.002
ob.data.name = date
ob.name = date

# a function to turn 3D polar coordinates into 3D cartesian coordinates
def latlonger(lat_deg, lon_deg):
# see: http://www.mathworks.de/help/toolbox/aeroblks/llatoecefposition.html
alt = 0.01
f  = 0.0                                    # flattening
ls = atan((1 - f)**2 * tan(lat))  # lambda
x = rad * cos(lat) * cos(lon) + alt * cos(lat) * cos(lon)
y = rad * cos(lat) * sin(lon) + alt * cos(lat) * sin(lon)
z = rad * sin(lat) + alt * sin(lat)
return (x, y, z)

# NB: no code has executed yet, we're just setting up functions we use further down

# read in the CSV file containing quake data
file = csv.reader(open('\\Users\mcsweend2c\Desktop\Bearthquakes 6-9.csv', newline=''), delimiter=',')

# make a blank dict variable to put quake data into
quakes = {}

# iterate through the CSV row by row and pull the data into variables
# then put the variables into a tuple and use a corrected date as the dict key
# see the last line of the for block for data order
# NB: could have used a dict instead of a tuple
# would have meant looking up e.g. quakes[x]['scale'] instead of quakes[x][0]
for idx, (scale, date, lat, lon) in enumerate(file):
(yd, m, dy) = date.split("/")
if int(yd) > int(dy):
year = yd
day = dy
else:
year = dy
day = yd
key = "{}-{:02g}-{:02g}".format( year, int(m), int(day) )
quakes[key] = (scale, lat, lon)

# go through the sorted dates in the quakes dict
# get latitude and longitude and turn into x/y/z coords with latlonger function
# then send x/y/z coordinates to makeathing function to create them in 3D space
for k in sorted(quakes.keys()):
latitude = float(quakes[k][1])
longitude = float(quakes[k][2])
coords = latlonger(latitude, longitude)
makeathing(coords, quakes[k][0], latitude, longitude, k)


You may need to offset the X of the world map texture to align the letters to their correct positions on the globe, e.g. using this texture map I had to offset X by 0.25.

• Hmm getting error, "A float is required". Should I convert the result somehow or is the result string a mismatch of type? – 3pointedit Sep 1 '15 at 6:48
• fixed it - wasn't converting the strings from the CSV to floats – quollism Sep 1 '15 at 7:17
• Getting a sphere from the data, when it should return a partial sphere... – 3pointedit Sep 1 '15 at 9:04
• Yep because sin and cos expect radians not degrees, have fixed that now along with a bunch of other things. :) – quollism Sep 1 '15 at 13:07