Blender: How to Scale Down Coordinates for a Map Scene

A GifGuide 2 Maps

Getting coordinates to scale properly to Blender units has been extremely frustrating for me since I started attempting more 3D maps. So, finally, in a fit of rage this weekend, I wrote a function to do it for me.

It scales the latitude and longitude down along the Z (height) and X (width) axes, taking into account the size of a base map oriented along those axes. In my version, it places a sphere at each coordinate set, but that can be easily changed to other objects.

Raw Materials for Testing:

The map outline of the states you see in the GIF above was courtesy of shapefiles provided by The United States Census Bureau. I loaded those into QGIS in order to look up the latitude and longitude of the northern, southern, western, and eastern borders of the U.S.

That’s separate from the 1888 Topographic Survey Map I took from Wikimedia Commons to give the background a little dash of color.

The list of state capitals with their coordinates can be plucked off

Formatting the Coordinates List:

We’ve talked about lists before. In Python, those are just enclosed in brackets. As written, the mapping function assumes a list made of strings formatted as State, City, Latitude, Longitude. Like so:

caps = [“Alabama”, “Montgomery”, “32.3617”, “-86.2792”, “Arizona”, “Phoenix”, “33.45”, “-112.067”, “Arkansas”, “Little Rock”, “34.7361”, “-92.3311”, “California”, “Sacramento”, “38.5556”, “-121.469”, “Colorado”, “Denver”, “39.7618”, “-104.881”, “Connecticut”, “Hartford”, “41.7627”, “-72.6743”, “Delaware”, “Dover”, “39.1619”, “-75.5267”, “Florida”, “Tallahassee”, “30.455”, “-84.2533”, “Georgia”, “Atlanta”, “33.755”, “-84.39”, “Idaho”, “Boise”, “43.6167”, “-116.2”, “Illinois”, “Springfield”, “39.6983”, “-89.6197”, “Indiana”, “Indianapolis”, “39.791”, “-86.148”, “Iowa”, “Des Moines”, “41.5908”, “-93.6208”, “Kansas”, “Topeka”, “39.0558”, “-95.6894”, “Kentucky”, “Frankfort”, “38.197”, “-84.863”, “Louisiana”, “Baton Rouge”, “30.45”, “-91.14”, “Maine”, “Augusta”, “44.307”, “-69.782”, “Maryland”, “Annapolis”, “38.9729”, “-76.5012”, “Massachusetts”, “Boston”, “42.3581”, “-71.0636”, “Michigan”, “Lansing”, “42.7336”, “-84.5467”, “Minnesota”, “Saint Paul”, “44.9442”, “-93.0936”, “Mississippi”, “Jackson”, “32.2989”, “-90.1847”, “Missouri”, “Jefferson City”, “38.5767”, “-92.1736”, “Montana”, “Helena”, “46.5958”, “-112.027”, “Nebraska”, “Lincoln”, “40.8106”, “-96.6803”, “Nevada”, “Carson City”, “39.1608”, “-119.754”, “New Hampshire”, “Concord”, “43.2067”, “-71.5381”, “New Jersey”, “Trenton”, “40.2237”, “-74.764”, “New Mexico”, “Santa Fe”, “35.6672”, “-105.964”, “New York”, “Albany”, “42.6525”, “-73.7572”, “North Carolina”, “Raleigh”, “35.7667”, “-78.6333”, “North Dakota”, “Bismarck”, “46.8133”, “-100.779”, “Ohio”, “Columbus”, “39.9833”, “-82.9833”, “Oklahoma”, “Oklahoma City”, “35.4822”, “-97.535”, “Oregon”, “Salem”, “44.9308”, “-123.029”, “Pennsylvania”, “Harrisburg”, “40.2697”, “-76.8756”, “Rhode Island”, “Providence”, “41.8236”, “-71.4222”, “South Carolina”, “Columbia”, “34.0006”, “-81.0347”, “South Dakota”, “Pierre”, “44.368”, “-100.336”, “Tennessee”, “Nashville”, “36.1667”, “-86.7833”, “Texas”, “Austin”, “30.25”, “-97.75”, “Utah”, “Salt Lake City”, “40.75”, “-111.883”, “Vermont”, “Montpelier”, “44.2597”, “-72.575”, “Virginia”, “Richmond”, “37.5333”, “-77.4667”, “Washington”, “Olympia”, “47.0425”, “-122.893”, “West Virginia”, “Charleston”, “38.3472”, “-81.6333”, “Wisconsin”, “Madison”, “43.0667”, “-89.4”, “Wyoming”, “Cheyenne”, “41.1456”, “-104.802”]

The Map Function:

Note the function takes 7 parameters total. The map length and width in Blender units, the boundary coordinates of the base map, and the coordinate list. Below is what it looks like with almost everything plugged in. All it lacks is the latitudes and longitudes. Keep in mind, the bpy.ops.mesh.primitive_uv_sphere_add(size=.02, location=(x,y,z)) line is where you can customize the meshes that will be placed at the coordinates provided.

import bpy

#Latitude is Z axis
#Longitude is Y axis

def map(maplength, mapwidth, lat_south, lat_north, long_west, long_east, list):
lat_calc = (maplength) / (lat_north - lat_south)
long_calc = (mapwidth) / -((long_west - long_east))
a = 0
while a < len(list):
alat = float(list[a+2])-lat_south
along = float(list[a+3]) - long_west
y = long_calc * along
z = lat_calc * alat
bpy.ops.mesh.primitive_uv_sphere_add(size=.02, location=(x,y,z))
a = a + 4
#End of function but can't get WordPress to indent properly
caps = [ ]

ml = 2.88135
ls = 25.119
ln = 49.006
mw = 6.98
lw = -124.733
le = -66.951

map(ml, mw, ls, ln, lw, le, caps)

Also, keep in mind the indentation is off because WordPress doesn’t like tabs. You’ll need to indent the function lines so that Blender will know where it stops, or it’ll throw out an error.




10 thoughts on “Blender: How to Scale Down Coordinates for a Map Scene

      1. But I like the color coding and line numbers 😕 Whhhhhhhhhhhhhhhhhhhhhhhyyyyyyyyyyyyyyyy can’t it come with indents, WordPress? It’s okay with things like Processing where the indents don’t really matter, but it’s a real hassle with Python. You use GitHub at all? I’ve heard some people write coding posts here but link to the actual code over there?


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s