Using Blender or other tool with OpenStreetMap data for animations

Hi,

I’d like to make some animations of the maps on openstreetmap - I’ve seen the http://www.itoworld.com/static/osmmapper which can animate changes to the map, but I’m looking for something to make smooth zoom ins & outs of the maps themselves, not the changes recently added to the maps.

Has anyone seen anything that might do it? I was hoping there might be a script for export from OSM to Blender.
This looks cool but prohibitively costly: http://www.youtube.com/watch?v=Su0kdgOgd8E

I’m not looking for 3D animations, just smooth video zoom ins on the existing maps.

Any tips much appreciated, and thanks for such a cool project.

Hello Tom!

Last night I happened to hack together a Blender python script that does some of what you are looking for.

As yet, It only imports the raw node and way data, but can be used as a starting point for a full geometry exporter/generator.

I was drawn to this problem after reading a blog from the author of CityEngine, on how he use OSM data as a basis for some of his city synthesis projects.

Currently, this will generate only the raw edges that define the map, but if you go into edit mode, and select the region of the map you like, and do an “extrude”, moving the new set of vertices about a roads width, diagonally, this gives you faces you can see in a render.

Please reply/contact me if you are still interested/need help in this!
I am interested in improving and extending this script to do more stuff!



# written by manthrax at hotmail.com. If you use it for something cool, send me an email and let me know!

from Blender import Scene, Mesh, Window, sys, Group, Object, Draw
from Blender.Mathutils import Matrix, Vector, ProjectVecs, DotVecs, AngleBetweenVecs, TranslationMatrix
import Blender,BPyMessages

from xml.dom import minidom

fileName = 'C:/dev/art/map (2).osm' # Replace this path with the full path to your datafile!
xmldoc = minidom.parse(fileName)

cache = []
tidx=0
nmap={}
scl=100.0
def    parseBranch(nodes,nme):
    global tidx
    global nmap
    global scl
    inNode = 0
    dlat = dlong = clat = clong = minlat = maxlat = minlong = maxlong = 0.0
    for node in nodes:
        if node.localName == "bounds":
            if node.hasAttributes():
                for i in range(0,node.attributes.length):
                    at=node.attributes.item(i)
                    if at.name == "minlat":
                        minlat = float(at.nodeValue)
                    elif at.name == "minlon":
                        minlong = float(at.nodeValue)
                    elif at.name == "maxlat":
                        maxlat = float(at.nodeValue)
                    elif at.name == "maxlon":
                        maxlong = float(at.nodeValue)
                dlat = maxlat-minlat
                dlong = maxlong-minlong
                clat = (maxlat+minlat)*0.5
                clong = (maxlong+minlong)*0.5
                
                print dlat,dlong, clat, clong
            
        if node.localName == "way":
            nid=None
            refs=[]
            #if node.hasAttributes():
                #for i in range(0,node.attributes.length):
                #    at=node.attributes.item(i)
                #    print at.name
                
                
            for ch in node.childNodes:
                if ch.localName=="nd":
                    for i in range(0,ch.attributes.length):
                        at=ch.attributes.item(i)
                        #print at.name
                        if at.name == "ref":
                            refs.append(long(at.nodeValue))
            
            first = 1
            for r in refs:
                if first==0:
                    nme.faces.extend(nmap[pr],nmap[r],nmap[r])    
                else: first = 0
                pr=r
                
        if node.localName == "node":
            if node.hasAttributes():
                nid=None
                nlong=None
                nlat=None
                logged = 0
                for i in range(0,node.attributes.length):
                    at=node.attributes.item(i)
                    #print at.name
                    if at.name == "id":
                        nid = at.nodeValue
                    elif at.name == "lon":
                        nlong = at.nodeValue
                    elif at.name == "lat":
                        nlat = at.nodeValue
                
                    if nid!=None and nlat!=None and nlong != None:
                        fla = (float(nlat)-clat)*scl/dlat
                        flo = (float(nlong)-clong)*scl/dlat
                        nme.verts.extend(Vector(fla,flo,0.0))
                        nmap[long(nid)]=nme.verts[-1]
                        logged=1
                        break
        tidx+=1
        #if tidx > 1000:
        #    break
        parseBranch(node.childNodes,nme)

print "Starting parse..."
nme = Mesh.New()
parseBranch(xmldoc.childNodes,nme)    
print nme.verts
part = Object.New('Mesh', 'mapMesh')
part.link(nme)
nme.update()
sce = Scene.GetCurrent()
sce.link(part)

print "Parse done... %d" % tidx



Like this?: http://stuphi.co.uk/wordpress/2009/11/03/mapnik-fun/ (I have no idea how this was done, you’d have to ask the author).

Cheers
Colin